annotate

package
v1.17.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 21, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package annotate assembles the production per-tool Annotator the Tools catalog projector reads OAuth / approval / metrics / content-stats / last-used / display-mode annotations through.

The seam it fills

The catalog projector (internal/tools/protocol) reads every per-tool annotation through an OPTIONAL Annotator seam. The projector ships correct; the annotations live in sibling subsystems the catalog does not itself own. This package is the concrete that aggregates them:

  • OAuth binding status ← tools/auth (read-time, no refresh).
  • approval policy ← tools/approval's per-tool policy store.
  • last-used / metrics ← the events stream (read-time windowed read).
  • content-size stats ← the events stream (MCP offload records).
  • display modes ← the MCP negotiation state.

It also implements the two admin-mutation seams the projector delegates to — SetApprovalPolicy (persists through tools/approval) and RevokeOAuth (routes through tools/auth) — so the Tools-page admin controls persist through the owning runtime subsystems, never a Console shadow store for runtime entities.

No fabrication (CLAUDE.md §13)

Every annotation is REAL runtime state or an honest representable absence: a source with no OAuth config reads "n/a"; a tool with no recorded invocations reads a zero-observation Healthy pill (an honest "no failures observed," never a degraded value); a policy with no pinned override reads "auto" (the semantic default). No method returns a canned test-grade value.

Concurrent reuse (CLAUDE.md §5)

The Annotator is immutable after NewAnnotator: it holds only the catalog + sub-reader references (each internally synchronised or read-only). Every method's per-call state lives in its arguments and locals. One Annotator serves N concurrent projection goroutines safely; the concurrent-reuse test pins it under -race.

Index

Constants

This section is empty.

Variables

View Source
var ErrMisconfigured = errors.New("tools/annotate: NewAnnotator missing a mandatory dependency")

ErrMisconfigured — NewAnnotator was called without a mandatory dependency. Fails closed (CLAUDE.md §5) rather than building an annotator that would nil-panic on the first projection.

Functions

This section is empty.

Types

type Annotator

type Annotator struct {
	// contains filtered or unexported fields
}

Annotator is the production Projector Annotator. Immutable after construction; safe for concurrent reuse.

func NewAnnotator

func NewAnnotator(deps Deps) (*Annotator, error)

NewAnnotator builds the production Annotator. Catalog + Approval are mandatory; the rest are optional-but-honest. The returned *Annotator is immutable after construction and safe for concurrent use by N goroutines.

func (*Annotator) ApprovalPolicy

func (a *Annotator) ApprovalPolicy(ctx context.Context, id identity.Identity, toolID string) prototypes.ToolApprovalPolicy

ApprovalPolicy implements protocol.Annotator. A read error degrades to the semantic default (auto) — an honest "no pinned posture," never a fabricated non-default — and is the projector's responsibility to surface; the annotator never lies with a gated/denied it cannot read.

func (*Annotator) ContentStats

func (a *Annotator) ContentStats(ctx context.Context, id identity.Identity, toolID string) prototypes.ToolContentStats

ContentStats implements protocol.Annotator. It builds a per-tool result-size histogram from the MCP offload records in the session's event stream (the ONLY per-result byte-size signal the runtime emits — tool lifecycle events are content-free by construction), reports the configured heavy-content threshold + the count at/above it, and the negotiated DisplayMode map. A tool with no offloaded results reads an empty histogram (an honest "no heavy results recorded"), never a fabricated distribution.

func (*Annotator) DisplayModes

func (a *Annotator) DisplayModes(ctx context.Context, id identity.Identity, toolID string) map[string]string

DisplayModes implements protocol.Annotator.

func (*Annotator) LastUsedAt

func (a *Annotator) LastUsedAt(ctx context.Context, id identity.Identity, toolID string) time.Time

LastUsedAt implements protocol.Annotator. It returns the most recent invocation instant of toolID in the caller's scope, or the zero value when the tool has no recorded invocation (the honest "never").

func (*Annotator) Metrics

Metrics implements protocol.Annotator. It folds the session-scoped terminal tool events (tool.completed / tool.failed) into per-window error rates + the selected window's invocation / failure counts + the health pill. A tool with no recorded terminal events reads a zero-observation Healthy pill.

func (*Annotator) OAuthStatus

func (a *Annotator) OAuthStatus(ctx context.Context, id identity.Identity, toolID string) prototypes.ToolOAuthStatus

OAuthStatus implements protocol.Annotator.

func (*Annotator) RevokeOAuth

func (a *Annotator) RevokeOAuth(ctx context.Context, id identity.Identity, toolID string) (int64, error)

RevokeOAuth implements protocol.OAuthRevoker — the admin revoke path. It routes through tools/auth. A tool with no OAuth binding revokes zero (an honest count, never a fabricated success).

func (*Annotator) SetApprovalPolicy

func (a *Annotator) SetApprovalPolicy(ctx context.Context, id identity.Identity, toolID string, policy prototypes.ToolApprovalPolicy) error

SetApprovalPolicy implements protocol.ApprovalPolicySetter — the persisting admin path. It routes back through the approval subsystem's policy store (never a Console shadow store for runtime entities). The Service emits the audit event on success.

type Deps

type Deps struct {
	// Catalog resolves a wire toolID back to its runtime descriptor so
	// the annotator can read the tool's Source / Transport (the keys the
	// OAuth and display sub-readers need). Mandatory.
	Catalog tools.ToolCatalog
	// Approval is the per-tool approval-policy store — the read side of
	// the approval annotation AND the persist side of the admin write.
	// Mandatory.
	Approval approval.PolicyStore
	// Events is the canonical event bus the metrics / last-used /
	// content-stats reads window over (read-time, no new store). Optional.
	Events events.EventBus
	// OAuth resolves a tool's OAuth binding status + backs RevokeOAuth.
	// Optional — nil reads every tool "n/a".
	OAuth OAuthReader
	// Display resolves a tool's negotiated MCP DisplayMode map. Optional.
	Display DisplayReader
	// HeavyThresholdBytes is the configured heavy-content threshold
	// (RFC §6.5) the content-stats histogram reports + counts against.
	HeavyThresholdBytes int64
	// Clock is the annotator's notion of "now" for the metrics windows.
	// Nil ⇒ time.Now (UTC).
	Clock func() time.Time
}

Deps carries the annotator's aggregation dependencies. Catalog and Approval are mandatory (the catalog resolves toolID→source; the policy store backs both the read and the admin write). Events / OAuth / Display are optional-but-honest: a nil Events reader yields zero-observation metrics; a nil OAuth reader reads "n/a"; a nil Display reader reads an empty mode map — each an honest representable absence, never a fabricated value.

type DisplayReader

type DisplayReader interface {
	// Modes returns the negotiated MIME→mode map for the tool whose
	// runtime source is source, or an empty map when the tool advertises
	// no per-MIME display negotiation.
	Modes(ctx context.Context, id identity.Identity, source tools.ToolSourceID) map[string]string
}

DisplayReader is the seam the annotator reads a tool's negotiated MCP-Apps DisplayMode map through. Non-MCP tools read an empty map.

type OAuthReader

type OAuthReader interface {
	// Status returns the OAuth binding status for source under id. A
	// source with no OAuth configuration reads ToolOAuthNotApplicable.
	Status(ctx context.Context, id identity.Identity, source tools.ToolSourceID) prototypes.ToolOAuthStatus
	// Revoke revokes every OAuth binding for source under id and returns
	// the count revoked. A source with no bindings returns (0, nil).
	Revoke(ctx context.Context, id identity.Identity, source tools.ToolSourceID) (int64, error)
}

OAuthReader is the read + revoke seam the annotator resolves a tool's OAuth binding status through. It keys on the tool's runtime Source (the provider that produced it), not its catalog name.

type ProviderOAuthReader

type ProviderOAuthReader struct {
	// contains filtered or unexported fields
}

ProviderOAuthReader is the production OAuthReader over the runtime's OAuth provider set (the same map[name]OAuthProvider the dispatch path holds). It resolves a tool's binding status by asking each provider, read-time, whether it configures the tool's Source and whether a live binding exists — never triggering a refresh or a network call.

Immutable after construction; safe for concurrent reuse.

func NewProviderOAuthReader

func NewProviderOAuthReader(providers map[string]auth.OAuthProvider) *ProviderOAuthReader

NewProviderOAuthReader builds an OAuthReader over the provider set. A nil / empty set is valid — every tool then reads "n/a" (no source requires OAuth), the honest posture for a runtime with no OAuth providers configured.

func (*ProviderOAuthReader) Revoke

Revoke implements OAuthReader.Revoke. It revokes the binding on every provider that configures source, counting successful revocations. A source no provider configures revokes zero (an honest count, never a fabricated success). The first revoke error is returned once every provider has been attempted.

func (*ProviderOAuthReader) Status

Status implements OAuthReader.Status. It scans the provider set for the one that configures source and maps its read-time binding state onto the wire status. A source no provider configures reads "n/a".

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL