← All Go packages

github.com/anulum/director-ai/gateway/internal/scoring

package scoring // import "github.com/anulum/director-ai/gateway/internal/scoring"

Package scoring wraps the generated “director.v1.CoherenceScoring“ gRPC client
so the rest of the gateway stays transport-agnostic. A caller constructs one
“Client“ per process and passes it into middleware; the implementation handles
dial, retries, and channel lifecycle.

TYPES

type Client struct {
	// Has unexported fields.
}
    Client is a thin wrapper around the generated stub with explicit lifecycle.
    The zero value is not usable; construct with Dial.

func Dial(addr string, timeout time.Duration) (*Client, error)
    Dial opens an insecure channel to “addr“ (e.g. “localhost:50052“) and
    returns a Client. Production deployments supply a secure channel by calling
    grpc.NewClient directly and passing the result to WithConn.

func WithConn(conn *grpc.ClientConn) *Client
    WithConn builds a Client around a pre-dialled connection. The caller retains
    ownership of the connection — Close must not be called on connections passed
    here.

func (c *Client) Close() error
    Close releases the underlying channel. Safe to call on a Client that was
    built via Dial; a no-op on clients from WithConn when their connection is
    externally owned.

func (c *Client) ScoreClaim(
	ctx context.Context,
	claim string,
	documents []string,
	tenantID, requestID string,
	threshold float32,
) (*directorv1.CoherenceVerdict, int64, error)
    ScoreClaim is a one-shot scoring call. “claim“ is the candidate answer,
    “documents“ are the retrieved context snippets, and “threshold“ overrides
    the server default when positive.

func (c *Client) StartStream(ctx context.Context) (*StreamHandle, error)
    StartStream opens a bidirectional ScoreStream with the given context.
    The caller MUST call Close when done.

type Middleware struct {
	Scorer  Scorer
	Timeout time.Duration
	// ThresholdHeader, when set, lets clients tune the threshold per
	// request via an HTTP header (e.g. "X-Coherence-Threshold"). An
	// empty string keeps the server default.
	ThresholdHeader string
}
    Middleware runs ScoreClaim against the assistant response once the upstream
    handler returns. The verdict is attached to the response headers; requests
    with “Accept: text/event-stream“ bypass scoring because SSE output is not
    buffered here (streaming mode is a future-phase concern).

func (m *Middleware) Enabled() bool
    Enabled reports whether the middleware is wired to a real scorer.

func (m *Middleware) Handler(next http.Handler) http.Handler
    Handler wraps next with post-response scoring. The middleware buffers
    non-streaming responses so it can read the assistant message, calls
    ScoreClaim with it, and either:

      - adds “X-Coherence-Score“ and “X-Coherence-Halted“ headers and forwards
        the body unchanged (halted=false), or
      - rewrites the response as 422 JSON (halted=true, default), signalling a
        hallucination.

    A zero-value Middleware returns next unchanged. Use “Enabled“ to check that
    a scorer was supplied before wiring.

type Scorer interface {
	ScoreClaim(
		ctx context.Context,
		claim string,
		documents []string,
		tenantID, requestID string,
		threshold float32,
	) (*directorv1.CoherenceVerdict, int64, error)
}
    Scorer is the subset of Client methods the middleware depends on. Extracted
    so tests can inject a stub without wiring gRPC.

type StreamHandle struct {
	// Has unexported fields.
}
    StreamHandle is the active side of a ScoreStream RPC. Send emits a token;
    Recv blocks for the next verdict; Close ends the stream cleanly (half-close
    then wait for the server's trailing metadata).

func (h *StreamHandle) Close() error
    Close signals end-of-stream to the server and waits for the RPC to finish.

func (h *StreamHandle) Recv() (*directorv1.CoherenceVerdict, error)
    Recv blocks for the next verdict. Returns (verdict, io.EOF) when the server
    has closed the stream normally (e.g. after a halt).

func (h *StreamHandle) Send(req *directorv1.ScoreTokenRequest) error
    Send emits a single token request.