Documentation
¶
Overview ¶
Package types is the single source of truth for Harbor Protocol wire types (CLAUDE.md §8). Every Protocol message struct lives here; other packages import these types, and nothing else defines a Protocol message struct. The lint formalises this — lays the foundation so that lint is a no-op formalisation, not a cleanup.
What Harbor ships ¶
Harbor ships the Protocol task control surface's wire types: the flat IdentityScope every request carries, the StartRequest / StartResponse pair, and the ControlRequest / ControlResponse pair the nine steering-control methods share. The wire shapes are deliberately flat (string identity fields + a payload map) — a Protocol type that re-exported an internal runtime Go struct would be the RFC §5.1 reject-on-sight smell ("a Protocol method that maps 1:1 to an internal Go function signature"). The runtime-facing translation lives in the protocol package's ControlSurface, not in these types.
Versioning ¶
ProtocolVersion is pinned here. Bumping it is an RFC change (RFC §5.3, CLAUDE.md §8) — the Protocol surface is versioned independently of the Runtime implementation so third-party Consoles are not whipsawed by a Runtime refactor.
Versioning discipline ¶
Harbor turns the version *pin* into a versioning *discipline*:
- Version + ParseVersion + Compatible — the pinned string parsed into a comparable Major/Minor/Patch value, so a client detects version skew mechanically (same-major ⇒ Compatible) instead of string-comparing. CurrentVersion is the parsed form of ProtocolVersion; the two cannot drift.
- Deprecation + Deprecations() — the settled structured note format for a breaking Protocol change's removal window (RFC §5.3: "Breaking changes require a deprecation window"), plus the single-home registry of active deprecations. The registry is empty at 0.1.0 — a 0.1.0 Protocol that just shipped has nothing to deprecate — but the format and its home exist so the first real deprecation lands structured, not as a free-text comment.
- Capability + Capabilities() + VersionHandshake — the capability-negotiation shape. A Protocol client asks the Runtime which surfaces are live and gets a structured VersionHandshake (the version + the advertised capability set) rather than discovering a missing surface by a 404. V1 advertises exactly the surfaces that have shipped — CapTaskControl, the surface; later Protocol-surface phases add their constant here.
None of this bumps the version: Harbor ships the *mechanism* for living with versions, not a new version. It is transport-agnostic — a SSE+REST adapter or a `harbor version` subcommand consumes these values; binds to no transport.
Index ¶
- Constants
- Variables
- func IsValidAgentStatus(s AgentStatus) bool
- func IsValidArtifactSource(s ArtifactSource) bool
- func IsValidCapability(c Capability) bool
- func IsValidFlowNodeKind(k FlowNodeKind) bool
- func IsValidFlowRunStatus(s FlowRunStatus) bool
- func IsValidMemoryDriver(d MemoryDriverName) bool
- func IsValidMemoryScope(s MemoryScope) bool
- func IsValidMemoryStrategy(s MemoryStrategyName) bool
- func IsValidPauseSnapshotState(s PauseSnapshotState) bool
- func IsValidSearchIndex(i SearchIndex) bool
- func IsValidSessionSort(s SessionSort) bool
- func IsValidSessionStatus(s SessionStatus) bool
- func IsValidTaskKind(k TaskKind) bool
- func IsValidTaskStatus(s TaskStatus) bool
- func IsValidToolApprovalPolicy(p ToolApprovalPolicy) bool
- func IsValidToolMetricsWindow(w ToolMetricsWindow) bool
- func IsValidToolOAuthStatus(s ToolOAuthStatus) bool
- func IsValidToolStatus(s ToolStatus) bool
- func IsValidToolTransport(t ToolTransport) bool
- type Agent
- type AgentAggregates
- type AgentConfig
- type AgentConfigAddMCPConnectionRequest
- type AgentConfigAddMCPConnectionResponse
- type AgentConfigConnections
- type AgentConfigConnectionsDiff
- type AgentConfigDiff
- type AgentConfigDiffRequest
- type AgentConfigDiffResponse
- type AgentConfigGetRequest
- type AgentConfigGetResponse
- type AgentConfigHooks
- type AgentConfigHooksDiff
- type AgentConfigLLMParams
- type AgentConfigLLMParamsDiff
- type AgentConfigLLMProviderDescriptor
- type AgentConfigListRevisionsRequest
- type AgentConfigListRevisionsResponse
- type AgentConfigLoadingModeChange
- type AgentConfigMCPConnectionDescriptor
- type AgentConfigNaming
- type AgentConfigNamingDiff
- type AgentConfigOAuthProviderDescriptor
- type AgentConfigOAuthProviders
- type AgentConfigOAuthProvidersDiff
- type AgentConfigPayload
- type AgentConfigPromptLayers
- type AgentConfigPromptLayersDiff
- type AgentConfigRemoveMCPConnectionRequest
- type AgentConfigRemoveMCPConnectionResponse
- type AgentConfigRemoveOAuthProviderRequest
- type AgentConfigRemoveOAuthProviderResponse
- type AgentConfigRevisionView
- type AgentConfigRollbackRequest
- type AgentConfigRollbackResponse
- type AgentConfigRunCompletionHook
- type AgentConfigSessionOverlay
- type AgentConfigSessionSetSourceDisablesRequest
- type AgentConfigSessionSetSourceDisablesResponse
- type AgentConfigSessionSetUserPromptRequest
- type AgentConfigSessionSetUserPromptResponse
- type AgentConfigSessionSkillsDeleteRequest
- type AgentConfigSessionSkillsDeleteResponse
- type AgentConfigSessionSkillsListRequest
- type AgentConfigSessionSkillsListResponse
- type AgentConfigSessionSkillsUpsertRequest
- type AgentConfigSessionSkillsUpsertResponse
- type AgentConfigSetLLMParamsRequest
- type AgentConfigSetLLMParamsResponse
- type AgentConfigSetLLMProviderRequest
- type AgentConfigSetLLMProviderResponse
- type AgentConfigSetMCPDiscoveryOriginsRequest
- type AgentConfigSetMCPDiscoveryOriginsResponse
- type AgentConfigSetOAuthProviderRequest
- type AgentConfigSetOAuthProviderResponse
- type AgentConfigSetPromptLayersRequest
- type AgentConfigSetPromptLayersResponse
- type AgentConfigSetRevisionRequest
- type AgentConfigSetRevisionResponse
- type AgentConfigSetToolExposureRequest
- type AgentConfigSetToolExposureResponse
- type AgentConfigSkillInput
- type AgentConfigSkillSummary
- type AgentConfigSkillsDeleteRequest
- type AgentConfigSkillsDeleteResponse
- type AgentConfigSkillsDiff
- type AgentConfigSkillsListRequest
- type AgentConfigSkillsListResponse
- type AgentConfigSkillsSelection
- type AgentConfigSkillsUpsertRequest
- type AgentConfigSkillsUpsertResponse
- type AgentConfigToolExposure
- type AgentConfigToolExposureDiff
- type AgentConfigUserDiffRequest
- type AgentConfigUserDiffResponse
- type AgentConfigUserGetRequest
- type AgentConfigUserGetResponse
- type AgentConfigUserListRevisionsRequest
- type AgentConfigUserListRevisionsResponse
- type AgentConfigUserPayload
- type AgentConfigUserRollbackRequest
- type AgentConfigUserRollbackResponse
- type AgentConfigUserSetRevisionRequest
- type AgentConfigUserSetRevisionResponse
- type AgentControlRequest
- type AgentControlResponse
- type AgentCostCeiling
- type AgentFilter
- type AgentGetRequest
- type AgentGetResponse
- type AgentGovernance
- type AgentGovernanceRequest
- type AgentGovernanceResponse
- type AgentHealth
- type AgentHosting
- type AgentListRequest
- type AgentListResponse
- type AgentMemoryBinding
- type AgentMemoryRequest
- type AgentMemoryResponse
- type AgentMetrics
- type AgentMetricsRequest
- type AgentMetricsResponse
- type AgentPermissions
- type AgentPermissionsRequest
- type AgentPermissionsResponse
- type AgentRateLimit
- type AgentSkillBinding
- type AgentSkillsRequest
- type AgentSkillsResponse
- type AgentStatus
- type AgentToolBinding
- type AgentToolsRequest
- type AgentToolsResponse
- type ArtifactRef
- type ArtifactRefSummary
- type ArtifactRow
- type ArtifactScope
- type ArtifactSource
- type ArtifactsDeleteRequest
- type ArtifactsDeleteResponse
- type ArtifactsGetRefRequest
- type ArtifactsGetRefResponse
- type ArtifactsListRequest
- type ArtifactsListResponse
- type ArtifactsPutOpts
- type ArtifactsPutRequest
- type ArtifactsPutResponse
- type AuthRotateTokenRequest
- type AuthRotateTokenResponse
- type Capability
- type ControlRequest
- type ControlResponse
- type Deprecation
- type DeprecationKind
- type EventAggregateRequest
- type EventAggregateResponse
- type EventBucket
- type EventFilter
- type EventsListRequest
- type EventsListResponse
- type Flow
- type FlowArtifactRef
- type FlowBudget
- type FlowBudgetConsumption
- type FlowDescribeRequest
- type FlowDescription
- type FlowEdge
- type FlowFilter
- type FlowListRequest
- type FlowListResponse
- type FlowMetrics
- type FlowMetricsBucket
- type FlowMetricsRequest
- type FlowNode
- type FlowNodeKind
- type FlowNodePolicy
- type FlowNodeRunState
- type FlowRun
- type FlowRunDescribeRequest
- type FlowRunDescription
- type FlowRunRequest
- type FlowRunResponse
- type FlowRunStatus
- type FlowRunTrigger
- type FlowRunsListRequest
- type FlowRunsListResponse
- type GovernanceGetTenantOverridesRequest
- type GovernanceGetTenantOverridesResponse
- type GovernancePostureRequest
- type GovernancePostureResponse
- type GovernanceRotateKeyRequest
- type GovernanceRotateKeyResponse
- type GovernanceSetPostureRequest
- type GovernanceSetPostureResponse
- type GovernanceSetTenantOverridesRequest
- type GovernanceSetTenantOverridesResponse
- type GovernanceTenantOverrides
- type HistogramBucket
- type IdentityScope
- type IdentityTierView
- type InterventionSummary
- type LLMPostureRequest
- type LLMPostureResponse
- type MCPAppCallToolRequest
- type MCPAppCallToolResponse
- type MCPAppRef
- type MCPAuthorizationServerView
- type MCPBindingScopeCount
- type MCPBindingView
- type MCPDiscoveryStepStatusView
- type MCPHealthBucket
- type MCPOAuthRequirementView
- type MCPPromptArg
- type MCPPromptView
- type MCPReconnect
- type MCPResourceArtifactRef
- type MCPResourceView
- type MCPScopeShortfallView
- type MCPServerBindingsListRequest
- type MCPServerBindingsListResponse
- type MCPServerGetRequest
- type MCPServerGetResponse
- type MCPServerHealthRequest
- type MCPServerHealthResponse
- type MCPServerPolicyRequest
- type MCPServerPolicyResponse
- type MCPServerProbeRequest
- type MCPServerProbeResponse
- type MCPServerPromptsRequest
- type MCPServerPromptsResponse
- type MCPServerRefreshBindingRequest
- type MCPServerRefreshBindingResponse
- type MCPServerRefreshDiscoveryRequest
- type MCPServerRefreshDiscoveryResponse
- type MCPServerResourcesRequest
- type MCPServerResourcesResponse
- type MCPServerRevokeBindingRequest
- type MCPServerRevokeBindingResponse
- type MCPServerSetRawHTMLTrustRequest
- type MCPServerSetRawHTMLTrustResponse
- type MCPServerStateView
- type MCPServerView
- type MCPServersListRequest
- type MCPServersListResponse
- type MCPToolPolicyView
- type MemoryAggregates
- type MemoryArtifactRef
- type MemoryDeleteRequest
- type MemoryDeleteResponse
- type MemoryDriverName
- type MemoryFilter
- type MemoryGetRequest
- type MemoryGetResponse
- type MemoryHealthAggregate
- type MemoryHealthRequest
- type MemoryHealthResponse
- type MemoryItem
- type MemoryItemDetail
- type MemoryListRequest
- type MemoryListResponse
- type MemoryMetadata
- type MemoryPutRequest
- type MemoryPutResponse
- type MemoryScope
- type MemoryStrategyName
- type MemoryStrategyTrace
- type MemoryStrategyTraceRequest
- type MemoryStrategyTraceResponse
- type MemoryTurnInput
- type MetricsSnapshot
- type NamedCounter
- type NamedGauge
- type NamedHistogram
- type PauseArtifactRef
- type PauseFilter
- type PauseListRequest
- type PauseListResponse
- type PauseSnapshot
- type PauseSnapshotState
- type RateLimitView
- type ReadMCPResourceRequest
- type ReadMCPResourceResponse
- type RetentionHorizon
- type RunOverrides
- type RunSetOverridesRequest
- type RunSetOverridesResponse
- type RuntimeCounters
- type RuntimeDrivers
- type RuntimeHealth
- type RuntimeInfo
- type RuntimeInfoRequest
- type SearchArtifactRef
- type SearchFacet
- type SearchFilter
- type SearchIndex
- type SearchRequest
- type SearchResponse
- type SearchResultRow
- type SessionFilter
- type SessionRow
- type SessionSort
- type SessionStatus
- type SessionsDeleteRequest
- type SessionsDeleteResponse
- type SessionsInspectRequest
- type SessionsInspectResponse
- type SessionsListRequest
- type SessionsListResponse
- type SessionsSetTitleRequest
- type SessionsSetTitleResponse
- type SizeRange
- type StartRequest
- type StartResponse
- type StateArtifactRef
- type StateEvent
- type StateHistoryRequest
- type StateHistoryResponse
- type SubsystemDriver
- type SubsystemHealth
- type TaskCostRollup
- type TaskCostStep
- type TaskDetail
- type TaskFilter
- type TaskGetRequest
- type TaskInputArtifact
- type TaskKind
- type TaskListAggregates
- type TaskListCursor
- type TaskListRequest
- type TaskListResponse
- type TaskParentSessionRef
- type TaskParentTaskRef
- type TaskPlannerSnapshotRef
- type TaskRow
- type TaskStatus
- type TaskTrajectoryRef
- type TaskTrajectoryStep
- type TasksListStatusCounterStrip
- type TimeRange
- type Tool
- type ToolAggregates
- type ToolApprovalPolicy
- type ToolContentBucket
- type ToolContentStats
- type ToolContentStatsRequest
- type ToolContextPayload
- type ToolContextRequest
- type ToolContextResponse
- type ToolDescribeRequest
- type ToolFilter
- type ToolGetRequest
- type ToolListRequest
- type ToolListResponse
- type ToolManifest
- type ToolMetrics
- type ToolMetricsRequest
- type ToolMetricsWindow
- type ToolOAuthStatus
- type ToolRevokeOAuthRequest
- type ToolRevokeOAuthResponse
- type ToolSetApprovalPolicyRequest
- type ToolSetApprovalPolicyResponse
- type ToolStatus
- type ToolTransport
- type TopologyEdge
- type TopologyNode
- type TopologyNodeKind
- type TopologyProjection
- type TopologySnapshotRequest
- type Version
- type VersionHandshake
- type Window
Constants ¶
const ( // DefaultArtifactsLimit is the page size applied when a request omits // Limit. DefaultArtifactsLimit = 100 // MaxArtifactsLimit is the hard ceiling on an artifacts.list page. MaxArtifactsLimit = 1000 )
Default + maximum page bounds for artifacts.list.
const ( // PresignExpiryMin is the floor on a presigned-URL expiry window. PresignExpiryMin = time.Minute // PresignExpiryMax is the ceiling on a presigned-URL expiry window // (7 days — S3's documented limit). PresignExpiryMax = 7 * 24 * time.Hour // DefaultPresignExpiry is the expiry applied when a request omits it. DefaultPresignExpiry = 15 * time.Minute )
Presigned-URL expiry bounds for artifacts.get_ref, matching the internal/artifacts.Presigner interface contract (S3's documented limit).
const ( // DefaultEventsListLimit is the page size used when an `events.list` // request omits Limit (or sends zero). DefaultEventsListLimit = 50 // MaxEventsListLimit is the largest page a single `events.list` request // may ask for; a Limit above it is clamped down to this value. MaxEventsListLimit = 200 )
Default + maximum page bounds for the `events.list` read. A client that omits Limit gets DefaultEventsListLimit; a Limit above MaxEventsListLimit is clamped down to MaxEventsListLimit (a larger ask is satisfied with the maximum page, not rejected). A negative Limit is the one invalid value (`CodeInvalidRequest`). The bounds mirror `state.history` so the two windowed reads share a paging grammar.
const ( // DefaultFlowListPageSize is the page size applied when a // `flows.list` / `flows.runs.list` request omits PageSize. DefaultFlowListPageSize = 50 // MaxFlowListPageSize is the upper bound on a Flows-page request's // PageSize. A request above this is rejected with CodeInvalidRequest. MaxFlowListPageSize = 200 )
Flows-page pagination bounds. They mirror the `pause.list` / `search.*` pagination contract so the Console-side pagination component is shared across pages, not re-implemented per-method. A client that omits Page / PageSize gets the documented defaults; a request above the max gets a 400 (CodeInvalidRequest) — never a silent clamp.
const ( DefaultMemoryListPageSize = 50 MaxMemoryListPageSize = 200 )
Memory-page pagination bounds, shared by the `memory.list` method per the phase plan acceptance criteria. The values mirror the `search.*` / `pause.list` pagination contracts so a future Console-side pagination component is shared across pages, not re-implemented per-method. A client that omits Page / PageSize gets the documented defaults; a request above the max — or negative — gets a 400 (CodeInvalidRequest), never a silent clamp.
const ( DefaultPauseListPageSize = 50 MaxPauseListPageSize = 200 )
Pause-snapshot pagination bounds, shared by the `pause.list` method per the phase plan acceptance criteria. The values mirror the `search.*` pagination contract (DefaultSearchPageSize / MaxSearchPageSize) so a future Console-side pagination component is shared across pages, not re-implemented per-method. A client that omits Page / PageSize gets the documented defaults; a request above the max gets a 400 (CodeInvalidRequest) — never a silent clamp, since a silent clamp would defeat the per-row identity boundary the integration test asserts.
const ( // HealthStatusReady — the subsystem is registered and healthy. HealthStatusReady = "ready" // HealthStatusDegraded — the subsystem is registered and partially // functional. HealthStatusDegraded = "degraded" // registered but non-functional. HealthStatusUnavailable = "unavailable" )
The canonical SubsystemHealth.Status values. The set is closed: a posture seam reports one of exactly these three.
const ( // RetentionScopeRuntime — the horizon was measured over the whole // retained set, identity-free (a bare wall-clock instant, no // per-tenant/per-session content). RetentionScopeRuntime = "runtime" // RetentionScopeTenant — the horizon was measured across the caller's // tenant only. RetentionScopeTenant = "tenant" // RetentionScopeSession — the horizon was measured across the caller's // full (tenant, user, session) triple only. RetentionScopeSession = "session" )
The canonical RetentionHorizon.Scope values. The set is closed: a retention seam stamps one of exactly these three. "runtime" is the identity-free whole-retained-set scope the events horizon always uses (and the tasks/sessions horizons widen to for a verified fleet caller); "tenant" and "session" are the ordinary-caller identity-scoped folds.
const ( DefaultSearchPageSize = 20 MaxSearchPageSize = 200 )
Default + maximum pagination bounds, shared by every `search.*` method per the phase plan acceptance criteria. The defaults are the wire contract — a client that omits Page / PageSize gets the documented defaults; a client requesting more than the max gets a 400.
const ( // DefaultSessionListLimit is the page size applied when a // SessionsListRequest omits Limit (or passes a non-positive value). DefaultSessionListLimit = 50 // MaxSessionListLimit bounds the page size a client may request. MaxSessionListLimit = 200 // MaxSessionInterventionSummaries caps the RecentInterventions slice // the right-rail Session Summary projection carries. MaxSessionInterventionSummaries = 5 // MaxSessionArtifactSummaries caps the RecentArtifacts slice the // right-rail Session Summary projection carries. MaxSessionArtifactSummaries = 5 )
Sessions-page pagination bounds for `sessions.list`. Mirrors the tools.list / pause.list / search.* contract so the shared Console pagination component is reused, not re-implemented per page. A request above MaxSessionListLimit gets a 400 (CodeInvalidRequest) — never a silent clamp.
const ( // DefaultStateHistoryLimit is the window size used when a request // omits Limit (or sends zero). DefaultStateHistoryLimit = 50 // MaxStateHistoryLimit is the largest window a single request may // ask for; a Limit above it is clamped down to this value. MaxStateHistoryLimit = 200 )
Default + maximum window bounds for the `state.history` read. A client that omits Limit gets DefaultStateHistoryLimit; a Limit above MaxStateHistoryLimit is clamped down to MaxStateHistoryLimit (a larger ask is satisfied with the maximum window, not rejected). A negative Limit is the one invalid value (CodeInvalidRequest).
const ( // DefaultTaskListPageSize is the page size applied when a // TaskListRequest omits PageSize (or passes a non-positive value). DefaultTaskListPageSize = 50 // MaxTaskListPageSize bounds the page size a client may request. MaxTaskListPageSize = 200 )
Tasks-page pagination bounds for `tasks.list`. Mirrors the tools.list / pause.list / search.* contract so a future shared Console-side pagination component is reused, not re-implemented per page. A request above MaxTaskListPageSize gets a 400 (CodeInvalidRequest) — never a silent clamp.
const ( // DefaultToolListPageSize is the page size applied when a // ToolListRequest omits PageSize (or passes a non-positive value). DefaultToolListPageSize = 50 // MaxToolListPageSize bounds the page size a client may request. MaxToolListPageSize = 200 )
Tools-page pagination bounds for `tools.list`. Mirrors the pause.list / search.* contract so a future Console-side pagination component is shared, not re-implemented per page. A request above MaxToolListPageSize gets a 400 (CodeInvalidRequest) — never a silent clamp.
const DefaultAgentListPageSize = 50
DefaultAgentListPageSize is the page size `agents.list` applies when the request omits PageSize (or sends 0). Agents are slow-moving catalog data; a 50-row page is comfortable for the cards grid.
const MaxAgentListPageSize = 200
MaxAgentListPageSize bounds the `agents.list` page size. A request above this ceiling is rejected with CodeInvalidRequest rather than silently clamped (CLAUDE.md §13 — fail loudly).
const ProtocolVersion = "0.1.0"
ProtocolVersion is the pinned Harbor Protocol version. Bumping this constant is an RFC change (RFC §5.3): the Protocol surface is versioned independently of the Runtime, and a breaking change requires a deprecation window so third-party Consoles are not whipsawed.
V1 ships 0.1.0 — the task control surface is the first Protocol surface to land; the streaming-events / state-snapshot / topology / artifacts / traces / metrics surfaces (RFC §5.2) extend it in later phases without bumping the major while V1 is in flight.
Variables ¶
var CurrentVersion = mustParseVersion(ProtocolVersion)
CurrentVersion is the parsed form of the ProtocolVersion constant. It is derived from ProtocolVersion at package-init, so the two can never drift — TestCurrentVersion_MatchesProtocolVersion pins CurrentVersion.String() == ProtocolVersion. Callers that need to *reason* about the version (skew detection, ordering) use CurrentVersion; the ProtocolVersion string stays the RFC-change trip-wire.
var ErrInvalidDeprecation = stderrors.New("types: invalid Protocol deprecation")
ErrInvalidDeprecation is returned (wrapped) by Deprecation.Validate when a Deprecation is malformed.
var ErrInvalidVersion = stderrors.New("types: invalid Protocol version")
ErrInvalidVersion is returned (wrapped) by ParseVersion when the input is not a well-formed `MAJOR.MINOR.PATCH` triple of non-negative integers. Parsing fails loudly — there is no silent zero-Version degradation path (CLAUDE.md §5 "fail loudly").
var HighCardinalityLabelKeys = []string{"run_id", "trace_id", "span_id"}
HighCardinalityLabelKeys is the closed set of label keys that must NEVER appear on a metric crossing the Protocol boundary — they are unbounded per-run identifiers and would explode the metric series cardinality. The telemetry cardinality firewall gates these on the SDK side; this set lets the wire boundary re-check (a NIT cleanup, mirroring the label-lint pattern).
Functions ¶
func IsValidAgentStatus ¶
func IsValidAgentStatus(s AgentStatus) bool
IsValidAgentStatus reports whether s is one of the canonical AgentStatus values.
func IsValidArtifactSource ¶
func IsValidArtifactSource(s ArtifactSource) bool
IsValidArtifactSource reports whether s is one of the four canonical artifact sources. The artifacts handler uses this to fail loud on an unknown source value rather than silently dropping the filter.
func IsValidCapability ¶
func IsValidCapability(c Capability) bool
IsValidCapability reports whether c is one of the canonical Protocol capabilities. O(1).
func IsValidFlowNodeKind ¶
func IsValidFlowNodeKind(k FlowNodeKind) bool
IsValidFlowNodeKind reports whether k is one of the four canonical flow-node kinds.
func IsValidFlowRunStatus ¶
func IsValidFlowRunStatus(s FlowRunStatus) bool
IsValidFlowRunStatus reports whether s is one of the four canonical flow-run statuses.
func IsValidMemoryDriver ¶
func IsValidMemoryDriver(d MemoryDriverName) bool
IsValidMemoryDriver reports whether d is one of the three V1 memory-driver names.
func IsValidMemoryScope ¶
func IsValidMemoryScope(s MemoryScope) bool
IsValidMemoryScope reports whether s is one of the three canonical memory-record scopes.
func IsValidMemoryStrategy ¶
func IsValidMemoryStrategy(s MemoryStrategyName) bool
IsValidMemoryStrategy reports whether s is one of the three V1 memory-strategy names.
func IsValidPauseSnapshotState ¶
func IsValidPauseSnapshotState(s PauseSnapshotState) bool
IsValidPauseSnapshotState reports whether s is one of the two canonical pause-snapshot states.
func IsValidSearchIndex ¶
func IsValidSearchIndex(i SearchIndex) bool
IsValidSearchIndex reports whether i is one of the four canonical runtime-side indexes.
func IsValidSessionSort ¶
func IsValidSessionSort(s SessionSort) bool
IsValidSessionSort reports whether s is one of the four canonical sort orders. An empty value resolves to SessionSortStartedDesc.
func IsValidSessionStatus ¶
func IsValidSessionStatus(s SessionStatus) bool
IsValidSessionStatus reports whether s is one of the four canonical session statuses.
func IsValidTaskKind ¶
IsValidTaskKind reports whether k is one of the two canonical task kinds.
func IsValidTaskStatus ¶
func IsValidTaskStatus(s TaskStatus) bool
IsValidTaskStatus reports whether s is one of the six canonical task statuses. `tasks.list` rejects a filter naming any other value with CodeInvalidRequest.
func IsValidToolApprovalPolicy ¶
func IsValidToolApprovalPolicy(p ToolApprovalPolicy) bool
IsValidToolApprovalPolicy reports whether p is one of the three canonical approval policies. `tools.set_approval_policy` rejects any other value with CodeInvalidRequest.
func IsValidToolMetricsWindow ¶
func IsValidToolMetricsWindow(w ToolMetricsWindow) bool
IsValidToolMetricsWindow reports whether w is one of the three canonical windows.
func IsValidToolOAuthStatus ¶
func IsValidToolOAuthStatus(s ToolOAuthStatus) bool
IsValidToolOAuthStatus reports whether s is one of the canonical OAuth statuses.
func IsValidToolStatus ¶
func IsValidToolStatus(s ToolStatus) bool
IsValidToolStatus reports whether s is one of the canonical health statuses.
func IsValidToolTransport ¶
func IsValidToolTransport(t ToolTransport) bool
IsValidToolTransport reports whether t is one of the canonical tool transports.
Types ¶
type Agent ¶
type Agent struct {
// ID is the agent_id — the stable registration identity.
ID string `json:"id"`
// Name is the operator-facing display name.
Name string `json:"name"`
// Description is the operator-facing description.
Description string `json:"description"`
// Incarnation bumps on every process start.
Incarnation int64 `json:"incarnation"`
// VersionHash is the SHA-256 over canonical JSON of AgentConfig.
// Empty for a HostingRemote agent.
VersionHash string `json:"version_hash"`
// Owner is the registration key of the agent — the operator-stable
// logical-agent key the admin registered it under.
Owner string `json:"owner"`
// Status is the lifecycle status pill.
Status AgentStatus `json:"status"`
// Health is the operational-health badge.
Health AgentHealth `json:"health"`
// Hosting discriminates locally-hosted vs connect-to-remote.
Hosting AgentHosting `json:"hosting"`
// PlannerType is the configured planner ("react" / "deterministic"
// / future). Empty when not declared in AgentConfig.
PlannerType string `json:"planner_type"`
// Model is the configured model id. Empty when not declared.
Model string `json:"model"`
// ToolsCount is the number of tool bindings on the agent.
ToolsCount int `json:"tools_count"`
// MCPCount is the number of MCP-transport tool bindings.
MCPCount int `json:"mcp_count"`
// RegisteredAt is the RFC3339 timestamp of the first registration.
RegisteredAt string `json:"registered_at"`
// UpdatedAt is the RFC3339 timestamp of the most recent mutation.
UpdatedAt string `json:"updated_at"`
// Identity is the (tenant, user, session) triple the agent is
// registered within — the per-row identity attribution a coordinator
// uses to attribute a widened (fleet) `agents.list` row to its owning
// source. For a non-widened listing it is the caller's own scope; for
// an admin-widened listing it is the agent's own registration scope.
// `agent_id` (the ID field) is a registration identity, NOT an
// isolation principal — this Identity triple is the isolation
// attribution.
Identity IdentityScope `json:"identity"`
// IsDefault marks the runtime's synthetic default agent — the one
// serving the identity scope it was booted with, never written to
// the Agent Registry's StateStore. false (the zero value, omitted on
// the wire) for every real registered agent. A consumer uses this to
// distinguish "the runtime's own agent" from a registered fleet
// member; it never widens or narrows the isolation tuple. It lets a
// fleet catalog tell "one agent, not enumerable this way" apart from
// an empty page (the absence-must-be-representable class).
IsDefault bool `json:"is_default,omitempty"`
}
Agent is the catalog-row projection of one registered agent — the shape `agents.list` returns per row and `agents.get` nests in its response. ID is a registration identity, NOT an isolation principal.
type AgentAggregates ¶
type AgentAggregates struct {
// Total is the count of agents in the filtered view.
Total int64 `json:"total"`
// Active is the count of AgentStatusActive agents in the view.
Active int64 `json:"active"`
// Paused is the count of AgentStatusPaused agents in the view.
Paused int64 `json:"paused"`
// Drained is the count of AgentStatusDrained agents in the view.
Drained int64 `json:"drained"`
}
AgentAggregates is the four catalog counters over the filtered view.
type AgentConfig ¶
type AgentConfig struct {
// PlannerType is the configured planner ("react" / "deterministic").
PlannerType string `json:"planner_type"`
// PlannerConfig is the planner's key/value configuration set
// (MaxSteps, repair policy, etc.).
PlannerConfig map[string]string `json:"planner_config,omitempty"`
// Model is the configured model id.
Model string `json:"model"`
// ModelPolicy is the model-selection / model-policy key/value set.
ModelPolicy map[string]string `json:"model_policy,omitempty"`
// MaxSteps is the planner's max-steps ceiling (0 ⇒ not declared).
MaxSteps int `json:"max_steps"`
}
AgentConfig is the Protocol projection of the agent's configuration — planner config + model + max-steps + cost ceilings. It mirrors the registry's AgentConfig but is the flat wire shape, not the internal type (RFC §5.1).
type AgentConfigAddMCPConnectionRequest ¶ added in v1.5.0
type AgentConfigAddMCPConnectionRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
// Connection is the NON-SECRET descriptor (name, transport, command/URL).
Connection AgentConfigMCPConnectionDescriptor `json:"connection"`
// Headers are OPTIONAL operator-supplied auth headers used ONLY for the
// live attach (e.g. a bearer token for an http server). They are treated
// as SECRETS: they flow to the transport but are NEVER persisted in the
// recorded revision, the diff, or any emitted event (CLAUDE.md §7).
Headers map[string]string `json:"headers,omitempty"`
}
AgentConfigAddMCPConnectionRequest is the admin-scoped `agent_config.add_mcp_connection` request — add a NEW MCP server connection (the separable async-dial path). The runtime drives the real attach lifecycle (dial → initialize handshake → discover → register), records the NON-SECRET descriptor as a config revision (preserving the skills / tool-exposure / prompt-layer sections), and — for a stdio add — gates on the operator allowlist (fail-closed; argv-form only). An auth-required server parks on the unified pause/resume primitive.
type AgentConfigAddMCPConnectionResponse ¶ added in v1.5.0
type AgentConfigAddMCPConnectionResponse struct {
// Revision is the recorded config revision (set when State is "online"
// or "auth_required"; nil for a "failed" add, which records no revision).
Revision *AgentConfigRevisionView `json:"revision,omitempty"`
// Connection is the NON-SECRET descriptor that was added.
Connection AgentConfigMCPConnectionDescriptor `json:"connection"`
// State is the explicit attach lifecycle state: "online" (attached),
// "failed" (dial / handshake / discover failed — no half-attach), or
// "auth_required" (parked on the unified pause/resume primitive).
State string `json:"state"`
// Reason is a SAFE, operator-facing failure reason (set only when State
// is "failed"); never a secret.
Reason string `json:"reason,omitempty"`
// PauseToken is the unified-pause/resume token the auth_required attach
// parked on (set only when State is "auth_required"). An opaque runtime
// handle, NOT a credential.
PauseToken string `json:"pause_token,omitempty"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigAddMCPConnectionResponse is the `agent_config.add_mcp_connection` response — the recorded revision (when one was recorded), the descriptor, and the explicit attach lifecycle state.
type AgentConfigConnections ¶ added in v1.5.0
type AgentConfigConnections struct {
// Servers is the set of runtime-added MCP connection descriptors.
Servers []AgentConfigMCPConnectionDescriptor `json:"servers,omitempty"`
}
AgentConfigConnections is the wire projection of the runtime-added MCP-connection section of the config envelope — the set of NON-SECRET connection descriptors recorded in a revision (part of the agent's versioned desired state for diff / rollback).
type AgentConfigConnectionsDiff ¶ added in v1.5.0
type AgentConfigConnectionsDiff struct {
// Added are the connection names present in the to-revision but not the
// from-revision.
Added []string `json:"added,omitempty"`
// Removed are the connection names present in the from-revision but not
// the to-revision.
Removed []string `json:"removed,omitempty"`
}
AgentConfigConnectionsDiff is the wire projection of the structured runtime-added MCP-connection set-diff (by name) across two revisions.
type AgentConfigDiff ¶ added in v1.5.0
type AgentConfigDiff struct {
FromRevisionID string `json:"from_revision_id"`
ToRevisionID string `json:"to_revision_id"`
Skills AgentConfigSkillsDiff `json:"skills"`
ToolExposure AgentConfigToolExposureDiff `json:"tool_exposure"`
PromptLayers AgentConfigPromptLayersDiff `json:"prompt_layers"`
Connections AgentConfigConnectionsDiff `json:"connections"`
OAuthProviders AgentConfigOAuthProvidersDiff `json:"oauth_providers"`
LLMParams AgentConfigLLMParamsDiff `json:"llm_params"`
Hooks AgentConfigHooksDiff `json:"hooks"`
Naming AgentConfigNamingDiff `json:"naming"`
}
AgentConfigDiff is the wire projection of a server-side revision compare — the structured skills + tool-exposure + connection set-diffs, the prompt-layer text delta, the per-agent LLM-parameter delta, the run-lifecycle-hook delta, and the session auto-naming policy delta.
type AgentConfigDiffRequest ¶ added in v1.5.0
type AgentConfigDiffRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
FromRevision string `json:"from_revision"`
ToRevision string `json:"to_revision"`
}
AgentConfigDiffRequest is the `agent_config.diff` request — compare two existing revisions.
type AgentConfigDiffResponse ¶ added in v1.5.0
type AgentConfigDiffResponse struct {
Diff AgentConfigDiff `json:"diff"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigDiffResponse is the `agent_config.diff` response.
type AgentConfigGetRequest ¶ added in v1.5.0
type AgentConfigGetRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
}
AgentConfigGetRequest is the `agent_config.get` request — read the agent's current active revision.
type AgentConfigGetResponse ¶ added in v1.5.0
type AgentConfigGetResponse struct {
// Revision is the active revision; nil when the agent has no active
// config (Set is false).
Revision *AgentConfigRevisionView `json:"revision,omitempty"`
// Set reports whether an active revision exists.
Set bool `json:"set"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigGetResponse is the `agent_config.get` response.
type AgentConfigHooks ¶ added in v1.10.0
type AgentConfigHooks struct {
// RunCompletion, when non-nil, pins the agent's run-completion hook.
RunCompletion *AgentConfigRunCompletionHook `json:"run_completion,omitempty"`
}
AgentConfigHooks is the wire projection of the run-lifecycle-hook section of the config envelope. Declared as its own section so a set REPLACES only this section, preserving the sibling sections.
type AgentConfigHooksDiff ¶ added in v1.10.0
type AgentConfigHooksDiff struct {
SectionPresentChanged bool `json:"section_present_changed"`
SectionPresentFrom string `json:"section_present_from,omitempty"`
SectionPresentTo string `json:"section_present_to,omitempty"`
RunCompletionToolChanged bool `json:"run_completion_tool_changed"`
RunCompletionToolFrom string `json:"run_completion_tool_from,omitempty"`
RunCompletionToolTo string `json:"run_completion_tool_to,omitempty"`
RunCompletionTimeoutChanged bool `json:"run_completion_timeout_changed"`
RunCompletionTimeoutFrom string `json:"run_completion_timeout_from,omitempty"`
RunCompletionTimeoutTo string `json:"run_completion_timeout_to,omitempty"`
}
AgentConfigHooksDiff is the wire projection of the run-lifecycle-hook per-field delta across two revisions. Each dimension reports whether it changed plus its from / to display values (an unset hook is the empty string).
`section_present_from` / `section_present_to` render the hooks-section PRESENCE ("present" when the section exists — with or without a run-completion tool — "" when absent), because presence is semantic: a present bare `{}` hooks section is an explicit per-agent no-hook that overrides a yaml fleet hook, and the diff must show exactly that revision (absent → "present" with empty tool/timeout) rather than rendering it as no change. Mirrors the naming diff's tri-state `auto` precedent. Additive fields — the Protocol version holds.
type AgentConfigLLMParams ¶ added in v1.5.0
type AgentConfigLLMParams struct {
// Model, when set, is the model the agent's next run requests
// (overriding the tenant-wide baseline / config default).
Model *string `json:"model,omitempty"`
// Temperature, when set, is the sampling temperature for the next run.
Temperature *float64 `json:"temperature,omitempty"`
// MaxTokens, when set, is the per-message output-token ceiling.
MaxTokens *int `json:"max_tokens,omitempty"`
// ReasoningEffort, when set, is the reasoning-effort hint
// ("off" | "low" | "medium" | "high").
ReasoningEffort *string `json:"reasoning_effort,omitempty"`
}
AgentConfigLLMParams is the wire projection of an agent's per-agent LLM-parameter section in a config revision: the sampling defaults pinned for the agent (model / temperature / max-tokens / reasoning-effort). Every field is pointer-optional — an unset field falls through to the tenant-wide baseline, then the config default. Sampling parameters only; additive system-prompt text lives in AgentConfigPromptLayers.
type AgentConfigLLMParamsDiff ¶ added in v1.5.0
type AgentConfigLLMParamsDiff struct {
ModelChanged bool `json:"model_changed"`
ModelFrom string `json:"model_from,omitempty"`
ModelTo string `json:"model_to,omitempty"`
TemperatureChanged bool `json:"temperature_changed"`
TemperatureFrom string `json:"temperature_from,omitempty"`
TemperatureTo string `json:"temperature_to,omitempty"`
MaxTokensChanged bool `json:"max_tokens_changed"`
MaxTokensFrom string `json:"max_tokens_from,omitempty"`
MaxTokensTo string `json:"max_tokens_to,omitempty"`
ReasoningEffortChanged bool `json:"reasoning_effort_changed"`
ReasoningEffortFrom string `json:"reasoning_effort_from,omitempty"`
ReasoningEffortTo string `json:"reasoning_effort_to,omitempty"`
}
AgentConfigLLMParamsDiff is the wire projection of the per-agent LLM-parameter per-field delta across two revisions. Each dimension reports whether it changed plus its from / to display values (an unset dimension is the empty string).
type AgentConfigLLMProviderDescriptor ¶ added in v1.17.0
type AgentConfigLLMProviderDescriptor struct {
// Name is the unique provider-binding name. Required.
Name string `json:"name"`
// Provider is the LLM provider the pulled key authenticates (e.g.
// "openai", "anthropic"). Required.
Provider string `json:"provider"`
// CredentialSource is the inference-plane credential-source seam —
// validated to be exactly "remote" (broker-pull). An empty value is a
// LOUD reject ("" means the env source, which is config/file-only).
// Required.
CredentialSource string `json:"credential_source"`
// InferenceBroker names a boot-declared inference broker that pins every
// credential sink. Required; an unknown name fails loud. NON-SECRET.
InferenceBroker string `json:"inference_broker"`
// ModelAllow is the optional model-name allowlist the binding restricts
// the provider to. NON-SECRET. Optional.
ModelAllow []string `json:"model_allow,omitempty"`
}
AgentConfigLLMProviderDescriptor is the writable inference-provider binding — the zero-URL install shape EXACTLY: zero-URL, zero-secret. It carries NO URL of any kind, NO env-var name, and NO literal secret. Every sink-determining value (the pull endpoint, audience, scope ceiling) lives on the boot-declared `inference_broker` it references by non-secret NAME, so no admin-writable field determines where the credential is sourced (the credential-plane invariant). Because the forbidden fields (`credential_url` / `token_url` / `*_env` / any secret) are simply NOT on this struct, a `DisallowUnknownFields` decode rejects any of them BY NAME before the method runs.
The allowed field set is EXACTLY {name, provider, credential_source, inference_broker, model_allow}.
type AgentConfigListRevisionsRequest ¶ added in v1.5.0
type AgentConfigListRevisionsRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
// Limit caps the returned chain length. 0 = no cap.
Limit int `json:"limit,omitempty"`
}
AgentConfigListRevisionsRequest is the `agent_config.list_revisions` request — the agent's revision chain, newest-first.
type AgentConfigListRevisionsResponse ¶ added in v1.5.0
type AgentConfigListRevisionsResponse struct {
Revisions []AgentConfigRevisionView `json:"revisions"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigListRevisionsResponse is the `agent_config.list_revisions` response.
type AgentConfigLoadingModeChange ¶ added in v1.10.0
type AgentConfigLoadingModeChange struct {
Key string `json:"key"`
From string `json:"from,omitempty"`
To string `json:"to,omitempty"`
}
AgentConfigLoadingModeChange is the wire projection of one loading-mode override delta entry: the override at Key (a catalog name for a ToolLoadingChanges entry, an MCP source id for a ServerLoadingChanges entry) changed from From to To. An empty From/To means the override was absent (unset) on that side of the compare. Mirrors `agentcfg.LoadingModeChange`.
type AgentConfigMCPConnectionDescriptor ¶ added in v1.5.0
type AgentConfigMCPConnectionDescriptor struct {
// Name is the unique MCP source id. Required.
Name string `json:"name"`
// Transport is the wire transport — "stdio" or "http".
Transport string `json:"transport"`
// Command is the stdio argv (argv[0] is the binary; no shell). Set for
// the stdio transport.
Command []string `json:"command,omitempty"`
// URL is the http(s) endpoint. Set for the http transport.
URL string `json:"url,omitempty"`
// OAuthProvider names a declared OAuth provider to bind for per-identity
// southbound bearer injection. NON-SECRET (a provider name). Set only for
// the http transport; empty leaves the connection on its static headers.
OAuthProvider string `json:"oauth_provider,omitempty"`
// MetaAnnotations is a static, NON-SECRET set of operator key/values
// merged verbatim into the MCP `_meta` on every identity-stamped call.
// Reserved / spec-prefixed keys are rejected at attach.
MetaAnnotations map[string]string `json:"meta_annotations,omitempty"`
// OAuth is an OPTIONAL inline OAuth-provider binding carried over the wire
// for this connection (a coordinator standing up a new OAuth-fronted MCP
// server without a pre-installed provider). It is mutually exclusive with
// OAuthProvider (bind a name that already exists vs. carry the full binding
// inline). It is accepted ONLY behind the fail-closed
// `tools.allow_wire_oauth_descriptor` boot opt-in (default off): with the
// opt-in off an inline descriptor carrying any credential-sink field is
// rejected, exactly as the name-only binding rejects a sink field today. When
// opted in, the exchanged token's downstream sink (`allowed_downstream_hosts`)
// is DERIVED from this connection's own URL — never a wire-supplied list — and
// the wire `token_url` faces the identical token-exchange SSRF backstop the
// boot path uses. Set only for the http transport.
OAuth *AgentConfigOAuthProviderDescriptor `json:"oauth,omitempty"`
// OAuthDiscoveryAllowedOrigins is the explicit per-connection cross-origin
// allow-list of public https origins the OAuth-requirement discovery walker
// may fetch authorization-server metadata from. NON-SECRET (an origin
// allow-list) — revisioned + diffable + rollback-able, and writable live
// over `agent_config.set_mcp_discovery_origins`. Empty leaves the
// authorization-server hop needs-allowance (partial discovery), never a
// network hole (a granted origin is still refused at dial if it resolves
// private / loopback). Set only for the http transport.
OAuthDiscoveryAllowedOrigins []string `json:"oauth_discovery_allowed_origins,omitempty"`
}
AgentConfigMCPConnectionDescriptor is the wire projection of one runtime-added MCP server connection — the NON-SECRET descriptor only (name, transport, stdio argv command or http URL, the non-secret OAuth provider NAME, and the non-secret operator `_meta` annotations). Secret auth material (bearer headers, OAuth tokens, credentials, the minted downstream token) is NEVER part of this descriptor: it flows through the live attach + the tool-side OAuth / pause-resume path and is never persisted in a revision, diff, or event. The oauth_provider field is a NAME, not a secret — it selects a config-declared acquisition strategy.
type AgentConfigNaming ¶ added in v1.12.0
type AgentConfigNaming struct {
// Auto enables session auto-naming for the agent (false in a present
// section = an explicit off that overrides the yaml fleet default).
Auto bool `json:"auto,omitempty"`
// AfterTurns is the completed-run count at which the first auto-name
// fires; 0 inherits the runtime default (1).
AfterTurns int `json:"after_turns,omitempty"`
// RepeatEvery, when > 0, re-names every N completed turns after the
// first; 0 names once only.
RepeatEvery int `json:"repeat_every,omitempty"`
// MaxRepetitions caps the TOTAL auto-namings (including the first);
// required ≥ 1 when RepeatEvery > 0. Ignored when RepeatEvery == 0.
MaxRepetitions int `json:"max_repetitions,omitempty"`
// MaxTitleLen bounds the auto title in runes; 0 inherits the runtime
// default (80). A set value must be in [8, 200].
MaxTitleLen int `json:"max_title_len,omitempty"`
// Model, when set, is the model the auto-naming call requests (empty =
// the run's effective model).
Model string `json:"model,omitempty"`
}
AgentConfigNaming is the wire projection of the session auto-naming policy section of the config envelope. Declared as its own section so a set REPLACES only this section, preserving the siblings. Opt-in, default off: an ABSENT section means "no per-agent policy" (the yaml `runtime.naming` fleet default, then off, resolves at run start). A PRESENT section is authoritative either way — `auto: true` enables, and a bare `{auto: false}` is an explicit per-agent OPT-OUT that overrides a yaml-on fleet default (section presence is the signal; a present section is preserved verbatim through normalization, never dropped as inert).
`after_turns` and `max_title_len` resolve to their runtime defaults (1, 80) when zero; `max_repetitions` is REQUIRED ≥ 1 whenever `repeat_every` > 0 (`agent_config.set_revision` rejects a repeating policy with no cap — `invalid_request` 400 — so unbounded periodic re-naming is unrepresentable); a set `model` is validated against the configured ModelProfiles.
type AgentConfigNamingDiff ¶ added in v1.12.0
type AgentConfigNamingDiff struct {
AutoChanged bool `json:"auto_changed"`
AutoFrom string `json:"auto_from,omitempty"`
AutoTo string `json:"auto_to,omitempty"`
AfterTurnsChanged bool `json:"after_turns_changed"`
AfterTurnsFrom string `json:"after_turns_from,omitempty"`
AfterTurnsTo string `json:"after_turns_to,omitempty"`
RepeatEveryChanged bool `json:"repeat_every_changed"`
RepeatEveryFrom string `json:"repeat_every_from,omitempty"`
RepeatEveryTo string `json:"repeat_every_to,omitempty"`
MaxRepetitionsChanged bool `json:"max_repetitions_changed"`
MaxRepetitionsFrom string `json:"max_repetitions_from,omitempty"`
MaxRepetitionsTo string `json:"max_repetitions_to,omitempty"`
MaxTitleLenChanged bool `json:"max_title_len_changed"`
MaxTitleLenFrom string `json:"max_title_len_from,omitempty"`
MaxTitleLenTo string `json:"max_title_len_to,omitempty"`
ModelChanged bool `json:"model_changed"`
ModelFrom string `json:"model_from,omitempty"`
ModelTo string `json:"model_to,omitempty"`
}
AgentConfigNamingDiff is the wire projection of the session auto-naming policy per-field delta across two revisions. Each dimension reports whether it changed plus its from / to display values (an ABSENT section renders every dimension as the empty string).
`auto_from` / `auto_to` are TRI-STATE display strings — "" (section absent) / "false" / "true" — because section presence is semantic: a present bare `{auto: false}` section is an explicit per-agent opt-out that overrides a yaml-on fleet default, and the diff must show exactly that revision (absent → "false") rather than rendering it as no change.
type AgentConfigOAuthProviderDescriptor ¶ added in v1.14.0
type AgentConfigOAuthProviderDescriptor struct {
// Name is the unique provider name (a connection's oauth_provider binding
// references it). Required.
Name string `json:"name"`
// Driver is the OAuth flow driver — validated to be exactly "tokenexchange"
// (the only writable driver; the non-interactive PULL exchange). Required.
Driver string `json:"driver"`
// CredentialSource is the credential-source seam — validated to be exactly
// "remote" (broker-pull). An empty value is a LOUD reject. Required.
CredentialSource string `json:"credential_source"`
// CredentialBroker names a boot-declared credential broker that pins the
// runtime's OWN credential custody (the coordinator pull endpoint, the
// service-token env name, the org client credential). Required in BOTH the
// name-only and the dev-gated wire shape — the wire descriptor still names a
// boot broker so no credential-source URL or secret ever rides the wire.
// NON-SECRET (a name).
CredentialBroker string `json:"credential_broker"`
// Scopes is the requested OAuth scope subset. NON-SECRET; clamped to the
// broker's boot scope ceiling at build time. Optional.
Scopes []string `json:"scopes,omitempty"`
// TokenURL is the NEW server's RFC-8693 token-exchange endpoint. A wire-carried
// field: accepted ONLY behind the `tools.allow_wire_oauth_descriptor` opt-in,
// and dialed through the token-exchange SSRF backstop (private / link-local /
// ULA / unspecified refused post-DNS, every redirect refused, no proxy).
// Rejected when the opt-in is off. Optional.
TokenURL string `json:"token_url,omitempty"`
// Audience is the NEW server's exchanged-token audience. A wire-carried field:
// accepted ONLY behind the opt-in; rejected when off. Optional.
Audience string `json:"audience,omitempty"`
}
AgentConfigOAuthProviderDescriptor is the wire projection of one Protocol-installed OAuth provider. By DEFAULT it is the ZERO-URL, name-only descriptor: it carries NO URL of any kind, NO env-var name, and NO literal secret, and every credential-sink-determining value (token endpoint, credential-pull endpoint, allowed downstream hosts, audience, scope ceiling) is pinned at boot on the NAMED credential broker the descriptor references by non-secret name.
Dev-gated wire binding ¶
Behind the fail-closed, boot-only `tools.allow_wire_oauth_descriptor` opt-in (config flag OR the `HARBOR_ALLOW_WIRE_OAUTH_DESCRIPTOR` boot env; default off, all of production) the descriptor MAY additionally carry the NEW server's OAuth parameters over the wire — TokenURL, Audience, Scopes — while still NAMING a boot-declared CredentialBroker, so a coordinator can stand up a new OAuth-fronted MCP server at runtime. With the opt-in OFF, a descriptor carrying TokenURL or Audience is REJECTED (fail-loud, naming the field + the opt-in key) — the name-only posture is byte-for-byte unchanged. The relaxation stays honest even when opted in:
- The runtime's OWN credential custody stays 100% boot-declared: the credential source (the coordinator pull endpoint + the service-token env name + the org client credential) lives on the NAMED CredentialBroker, a `tools.oauth_credential_brokers[]` entry — NO credential-source URL and NO env-var name ever rides the wire. Only the NEW server's public token endpoint (TokenURL) is wire-carried.
- `allowed_downstream_hosts` is NEVER a wire field — it is DERIVED from the connected server's own URL — so an exchanged token can only reach the endpoint the connection dials.
- The wire TokenURL is dialed through the identical token-exchange SSRF backstop the boot path uses (refuse resolved private / link-local / ULA / unspecified, no proxy, every redirect refused).
The forbidden fields that would determine a credential sink WITHOUT the derived/boot-declared bounds (a raw `allowed_downstream_hosts` list, `client_id_env`, `client_secret_env`, `auth_url`, `remote`) are simply NOT on this struct, so a `DisallowUnknownFields` decode rejects any of them BY NAME.
type AgentConfigOAuthProviders ¶ added in v1.14.0
type AgentConfigOAuthProviders struct {
// Providers is the set of installed provider descriptors.
Providers []AgentConfigOAuthProviderDescriptor `json:"providers,omitempty"`
}
AgentConfigOAuthProviders is the wire projection of the Protocol-installed OAuth-provider section of the config envelope — the set of ZERO-URL provider descriptors recorded in a revision (part of the agent's versioned desired state for diff / rollback).
type AgentConfigOAuthProvidersDiff ¶ added in v1.14.0
type AgentConfigOAuthProvidersDiff struct {
// Added are the provider names present in the to-revision but not the
// from-revision.
Added []string `json:"added,omitempty"`
// Removed are the provider names present in the from-revision but not the
// to-revision.
Removed []string `json:"removed,omitempty"`
}
AgentConfigOAuthProvidersDiff is the wire projection of the structured installed-provider set-diff (by name) across two revisions.
type AgentConfigPayload ¶ added in v1.5.0
type AgentConfigPayload struct {
// PromptLayers, when non-nil, pins the agent's layered system prompt
// (operator base + optional user layer) for the revision.
PromptLayers *AgentConfigPromptLayers `json:"prompt_layers,omitempty"`
// Skills, when non-nil, pins the agent's skills membership for the
// revision.
Skills *AgentConfigSkillsSelection `json:"skills,omitempty"`
// ToolExposure, when non-nil, pins the agent's MCP-exposure / per-tool
// policy for the revision.
ToolExposure *AgentConfigToolExposure `json:"tool_exposure,omitempty"`
// Connections, when non-nil, pins the agent's runtime-added MCP
// connection descriptors (non-secret) for the revision.
Connections *AgentConfigConnections `json:"connections,omitempty"`
// OAuthProviders, when non-nil, pins the agent's Protocol-installed
// (zero-URL) OAuth provider descriptors for the revision.
OAuthProviders *AgentConfigOAuthProviders `json:"oauth_providers,omitempty"`
// LLMParams, when non-nil, pins the agent's per-agent LLM-parameter
// section (model / temperature / max-tokens / reasoning-effort) for the
// revision.
LLMParams *AgentConfigLLMParams `json:"llm_params,omitempty"`
// Hooks, when non-nil, pins the agent's run-lifecycle-hook section (the
// run-completion hook) for the revision.
Hooks *AgentConfigHooks `json:"hooks,omitempty"`
// Naming, when non-nil, pins the agent's session auto-naming policy
// section for the revision.
Naming *AgentConfigNaming `json:"naming,omitempty"`
}
AgentConfigPayload is the wire projection of an agent-config envelope. Every section is optional so later consumers extend it without a schema break.
type AgentConfigPromptLayers ¶ added in v1.5.0
type AgentConfigPromptLayers struct {
// Base is the operator-owned base prompt layer. When set it is the run's
// base system prompt (overriding the agent's configured default base);
// unset inherits the configured default.
Base *string `json:"base,omitempty"`
// User is the optional higher user-instruction layer composed above the
// base in the lower-trust guidance position.
User *string `json:"user,omitempty"`
}
AgentConfigPromptLayers is the wire projection of an agent's layered system prompt in a config revision: an operator-owned base layer plus an optional user layer that composes ABOVE the base without mutating it. The composition order is the security boundary — the user layer can extend the operator's guidance but never precede, replace, or weaken the base.
type AgentConfigPromptLayersDiff ¶ added in v1.5.0
type AgentConfigPromptLayersDiff struct {
// BaseChanged reports whether the base layer text differs.
BaseChanged bool `json:"base_changed"`
// BaseFrom / BaseTo are the base layer text in the from / to revision.
BaseFrom string `json:"base_from,omitempty"`
BaseTo string `json:"base_to,omitempty"`
// UserChanged reports whether the user layer text differs.
UserChanged bool `json:"user_changed"`
// UserFrom / UserTo are the user layer text in the from / to revision.
UserFrom string `json:"user_from,omitempty"`
UserTo string `json:"user_to,omitempty"`
}
AgentConfigPromptLayersDiff is the wire projection of the base + user prompt-layer text delta across two revisions.
type AgentConfigRemoveMCPConnectionRequest ¶ added in v1.11.0
type AgentConfigRemoveMCPConnectionRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
// Name is the runtime-added MCP source id to remove.
Name string `json:"name"`
}
AgentConfigRemoveMCPConnectionRequest is the admin-scoped `agent_config.remove_mcp_connection` request — remove a runtime-added MCP server connection by name. The verb governs REVISIONED state only: it records a new revision that drops the named descriptor AND prunes that server's tool-exposure residue (its paused/disabled/loading entries), carrying every sibling section forward. An unknown name and a boot-declared (yaml) name each fail loud with a distinct typed error (a boot-declared server is edited in yaml + restart, never through this verb). The verb itself never tears anything down — the physical teardown (deregister tools + close transport) happens at the next run-start reconcile; an in-flight run whose next step calls the detached server fails loudly (typed not-found / closed transport), never a hang or a silent success.
type AgentConfigRemoveMCPConnectionResponse ¶ added in v1.11.0
type AgentConfigRemoveMCPConnectionResponse struct {
// Revision is the recorded config revision whose connections section
// dropped the named descriptor (with the server's tool-exposure residue
// pruned in the same atomic revision).
Revision AgentConfigRevisionView `json:"revision"`
// Name is the removed MCP source id (echoed for the caller's convenience).
Name string `json:"name"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigRemoveMCPConnectionResponse is the `agent_config.remove_mcp_connection` response — the recorded removing revision and the name that was removed.
type AgentConfigRemoveOAuthProviderRequest ¶ added in v1.14.0
type AgentConfigRemoveOAuthProviderRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
// Name is the installed provider name to uninstall.
Name string `json:"name"`
}
AgentConfigRemoveOAuthProviderRequest is the admin-scoped `agent_config.remove_oauth_provider` request — uninstall a Protocol-installed OAuth provider by name. The runtime records a new revision dropping the named descriptor (carrying every sibling forward) AND uninstalls the provider live, which CLOSES it — so a still-bound connection's next call fails LOUD rather than degrading to an unauthenticated dial. Deliberately breaking; the break is confined to the owning owner by the owner-scoped run-start reconcile. An unknown name and a boot-declared name each fail loud with a distinct typed error. Admin-only; server-derived authority (never the body).
type AgentConfigRemoveOAuthProviderResponse ¶ added in v1.14.0
type AgentConfigRemoveOAuthProviderResponse struct {
// Revision is the recorded config revision whose oauth-providers section
// dropped the named descriptor.
Revision AgentConfigRevisionView `json:"revision"`
// Name is the removed provider name (echoed).
Name string `json:"name"`
// Uninstalled reports whether the provider was uninstalled live (true on
// every served success; false only degrades to the revisioned write when no
// live provider installer is wired on this runtime).
Uninstalled bool `json:"uninstalled"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigRemoveOAuthProviderResponse is the `agent_config.remove_oauth_provider` response — the recorded revision, the removed provider name, and whether the live uninstall took effect.
type AgentConfigRevisionView ¶ added in v1.5.0
type AgentConfigRevisionView struct {
// RevisionID is the revision's unique, time-ordered id.
RevisionID string `json:"revision_id"`
// ParentRevisionID is the revision this one descends from (empty for
// the first revision).
ParentRevisionID string `json:"parent_revision_id,omitempty"`
// ContentHash is the full hex SHA-256 over the revision's canonical
// payload encoding (for diff/audit correlation; never the content).
ContentHash string `json:"content_hash"`
// AuthorTenant / AuthorUser identify the author (the audit anchor).
// The author's session is intentionally omitted — the audit anchor is
// the (tenant, user) actor, not the session.
AuthorTenant string `json:"author_tenant,omitempty"`
AuthorUser string `json:"author_user,omitempty"`
// CreatedAt is the revision's creation instant.
CreatedAt time.Time `json:"created_at"`
// Payload is the config envelope this revision pins.
Payload AgentConfigPayload `json:"payload"`
}
AgentConfigRevisionView is the wire projection of one immutable config revision.
type AgentConfigRollbackRequest ¶ added in v1.5.0
type AgentConfigRollbackRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
RevisionID string `json:"revision_id"`
}
AgentConfigRollbackRequest is the admin-scoped `agent_config.rollback` request — repoint the active pointer to an existing revision.
type AgentConfigRollbackResponse ¶ added in v1.5.0
type AgentConfigRollbackResponse struct {
Revision AgentConfigRevisionView `json:"revision"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigRollbackResponse is the `agent_config.rollback` response — the revision the active pointer now points to.
type AgentConfigRunCompletionHook ¶ added in v1.10.0
type AgentConfigRunCompletionHook struct {
// Tool is the catalog tool name the transcript is dispatched to.
Tool string `json:"tool"`
// TimeoutMS is the dispatch timeout in milliseconds. Zero inherits the
// runtime default at run start.
TimeoutMS int `json:"timeout_ms,omitempty"`
}
AgentConfigRunCompletionHook is the wire projection of an agent's durable run-completion hook in a config revision: the catalog tool the run transcript is dispatched to at the run loop's terminal boundary, plus an optional dispatch timeout (milliseconds). Mirrors the static `runtime.hooks.run_completion` yaml; resolution at run start is agent-config over yaml over no hook.
type AgentConfigSessionOverlay ¶ added in v1.5.0
type AgentConfigSessionOverlay struct {
UserPrompt string `json:"user_prompt,omitempty"`
DisabledServers []string `json:"disabled_servers,omitempty"`
DisabledTools []string `json:"disabled_tools,omitempty"`
PersonalSkills []string `json:"personal_skills,omitempty"`
}
AgentConfigSessionOverlay is the wire projection of a session's safe-subset overlay: a user prompt layer that composes ABOVE the operator base, a narrow-only source/tool disable set, and the names of the session's ephemeral personal skills. There is intentionally NO base-prompt field — a session caller cannot write the operator base.
type AgentConfigSessionSetSourceDisablesRequest ¶ added in v1.5.0
type AgentConfigSessionSetSourceDisablesRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
DisabledServers []string `json:"disabled_servers,omitempty"`
DisabledTools []string `json:"disabled_tools,omitempty"`
}
AgentConfigSessionSetSourceDisablesRequest is the session-safe `agent_config.session.set_source_disables` request. It names the servers/tools the session wants DISABLED — narrow-only. There is no enable field; at projection the disable set is unioned into the admin exclusion set, so it can only narrow the admin-allowed exposure, never widen it.
type AgentConfigSessionSetSourceDisablesResponse ¶ added in v1.5.0
type AgentConfigSessionSetSourceDisablesResponse struct {
Overlay AgentConfigSessionOverlay `json:"overlay"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigSessionSetSourceDisablesResponse is the `agent_config.session.set_source_disables` response — the resulting overlay.
type AgentConfigSessionSetUserPromptRequest ¶ added in v1.5.0
type AgentConfigSessionSetUserPromptRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
UserPrompt string `json:"user_prompt"`
}
AgentConfigSessionSetUserPromptRequest is the session-safe `agent_config.session.set_user_prompt` request. It sets ONLY the user prompt layer (the shape has no base field — base is unwritable by a session caller).
type AgentConfigSessionSetUserPromptResponse ¶ added in v1.5.0
type AgentConfigSessionSetUserPromptResponse struct {
Overlay AgentConfigSessionOverlay `json:"overlay"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigSessionSetUserPromptResponse is the `agent_config.session.set_user_prompt` response — the resulting overlay.
type AgentConfigSessionSkillsDeleteRequest ¶ added in v1.5.0
type AgentConfigSessionSkillsDeleteRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
Name string `json:"name"`
}
AgentConfigSessionSkillsDeleteRequest is the session-safe `agent_config.session.skills.delete` request.
type AgentConfigSessionSkillsDeleteResponse ¶ added in v1.5.0
type AgentConfigSessionSkillsDeleteResponse struct {
Overlay AgentConfigSessionOverlay `json:"overlay"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigSessionSkillsDeleteResponse is the `agent_config.session.skills.delete` response — the resulting overlay.
type AgentConfigSessionSkillsListRequest ¶ added in v1.5.0
type AgentConfigSessionSkillsListRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
}
AgentConfigSessionSkillsListRequest is the session-safe `agent_config.session.skills.list` request — lists the session's skills (metadata only) under the caller's real triple.
type AgentConfigSessionSkillsListResponse ¶ added in v1.5.0
type AgentConfigSessionSkillsListResponse struct {
Skills []AgentConfigSkillSummary `json:"skills"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigSessionSkillsListResponse is the `agent_config.session.skills.list` response.
type AgentConfigSessionSkillsUpsertRequest ¶ added in v1.5.0
type AgentConfigSessionSkillsUpsertRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
Skill AgentConfigSkillInput `json:"skill"`
}
AgentConfigSessionSkillsUpsertRequest is the session-safe `agent_config.session.skills.upsert` request — upserts an ephemeral personal skill under the caller's real triple. The skill never promotes past the session.
type AgentConfigSessionSkillsUpsertResponse ¶ added in v1.5.0
type AgentConfigSessionSkillsUpsertResponse struct {
Skill AgentConfigSkillSummary `json:"skill"`
Overlay AgentConfigSessionOverlay `json:"overlay"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigSessionSkillsUpsertResponse is the `agent_config.session.skills.upsert` response — the upserted skill summary and the resulting overlay.
type AgentConfigSetLLMParamsRequest ¶ added in v1.5.0
type AgentConfigSetLLMParamsRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
LLMParams AgentConfigLLMParams `json:"llm_params"`
}
AgentConfigSetLLMParamsRequest is the admin-scoped `agent_config.set_llm_params` request — set the agent's per-agent LLM-parameter section (model / temperature / max-tokens / reasoning-effort) as a desired-state REPLACE of the LLM-params section (the prompt-layer + skills + tool-exposure + connection sections of the active revision are preserved). A set Model is validated against the configured ModelProfiles at set time (an unknown model is rejected). The edit records a new config revision and applies to the agent's NEXT run.
type AgentConfigSetLLMParamsResponse ¶ added in v1.5.0
type AgentConfigSetLLMParamsResponse struct {
Revision AgentConfigRevisionView `json:"revision"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigSetLLMParamsResponse is the `agent_config.set_llm_params` response — the recorded config revision (or, on an idempotent re-set, the existing active revision).
type AgentConfigSetLLMProviderRequest ¶ added in v1.17.0
type AgentConfigSetLLMProviderRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
// Provider is the ZERO-URL descriptor to install.
Provider AgentConfigLLMProviderDescriptor `json:"provider"`
}
AgentConfigSetLLMProviderRequest is the admin-scoped `agent_config.set_llm_provider` request — install (upsert) / rotate a ZERO-URL, broker-pull inference provider binding on the owner-tagged provider set. Admin-only; server-derived authority (never the body).
type AgentConfigSetLLMProviderResponse ¶ added in v1.17.0
type AgentConfigSetLLMProviderResponse struct {
// Name is the installed provider-binding name (echoed).
Name string `json:"name"`
// Installed reports whether the binding took effect on the live provider
// set (false only degrades when no live installer is wired on this
// runtime — the write is then rejected loud, never a silent no-op).
Installed bool `json:"installed"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigSetLLMProviderResponse is the `agent_config.set_llm_provider` response — the installed binding name and whether it took effect on the live provider set.
type AgentConfigSetMCPDiscoveryOriginsRequest ¶ added in v1.14.0
type AgentConfigSetMCPDiscoveryOriginsRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
// Name is the runtime-added MCP source id whose allow-list is replaced.
Name string `json:"name"`
// AllowedOrigins is the FULL replacement allow-list (empty clears it).
AllowedOrigins []string `json:"allowed_origins"`
}
AgentConfigSetMCPDiscoveryOriginsRequest is the admin-scoped `agent_config.set_mcp_discovery_origins` request — a FULL-REPLACE write of a runtime-added MCP connection's OAuth-discovery cross-origin allow-list. The verb records a new revision carrying every sibling section forward AND applies the allow-list to the live MCP registry so the very next discovery uses it (and a revoke prunes the recorded requirement's now-unallowed authorization-server entries). Origins are the SHARED origin validator's shape (https scheme://host[:port], no path/query/fragment, no IP literal). An unknown connection, a boot-declared (yaml) name, and a stdio-transport connection each fail loud with a distinct typed error. Admin-only; server-derived authority (never the body). Governs revisioned state only — a boot-declared connection's allowance is edited in yaml + restart.
type AgentConfigSetMCPDiscoveryOriginsResponse ¶ added in v1.14.0
type AgentConfigSetMCPDiscoveryOriginsResponse struct {
// Revision is the recorded config revision carrying the new allow-list.
Revision AgentConfigRevisionView `json:"revision"`
// Name is the connection whose allow-list was replaced (echoed).
Name string `json:"name"`
// Granted is the set of origins newly present versus the prior live set.
Granted []string `json:"granted,omitempty"`
// Revoked is the set of origins dropped versus the prior live set.
Revoked []string `json:"revoked,omitempty"`
// AppliedLive reports whether the allow-list was applied to the live MCP
// registry (true on every served success; false only degrades to the
// revisioned write when no live registry applier is wired on this runtime).
AppliedLive bool `json:"applied_live"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigSetMCPDiscoveryOriginsResponse is the `agent_config.set_mcp_discovery_origins` response — the recorded revision, the computed granted / revoked deltas (against the prior live allow-list), and whether the write took effect on the live registry.
type AgentConfigSetOAuthProviderRequest ¶ added in v1.14.0
type AgentConfigSetOAuthProviderRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
// Provider is the ZERO-URL descriptor to install.
Provider AgentConfigOAuthProviderDescriptor `json:"provider"`
}
AgentConfigSetOAuthProviderRequest is the admin-scoped `agent_config.set_oauth_provider` request — install (upsert) a ZERO-URL, broker-pull OAuth provider onto the agent-config revision spine. The descriptor carries `{name, driver:"tokenexchange", credential_source:"remote", credential_broker, scopes?}` — NO URL, NO env-var name, NO secret. The runtime records a new revision (carrying every sibling section forward) AND installs the provider live into the owner-tagged provider set so the next MCP attach bound to it injects the exchanged bearer. Every credential sink (the token endpoint, the credential-pull endpoint, the allowed downstream hosts, the audience, and the scope ceiling) is pinned at boot on the named broker; a write carrying a URL or env-var name is rejected BY NAME (DisallowUnknownFields). Admin-only; server-derived authority (never the body).
type AgentConfigSetOAuthProviderResponse ¶ added in v1.14.0
type AgentConfigSetOAuthProviderResponse struct {
// Revision is the recorded config revision carrying the installed provider.
Revision AgentConfigRevisionView `json:"revision"`
// Name is the installed provider name (echoed).
Name string `json:"name"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigSetOAuthProviderResponse is the `agent_config.set_oauth_provider` response — the recorded revision and the installed provider name.
type AgentConfigSetPromptLayersRequest ¶ added in v1.5.0
type AgentConfigSetPromptLayersRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
PromptLayers AgentConfigPromptLayers `json:"prompt_layers"`
}
AgentConfigSetPromptLayersRequest is the admin-scoped `agent_config.set_prompt_layers` request — set the agent's layered system prompt (operator base and/or user layer) as a desired-state REPLACE of the prompt-layer section (the skills + tool-exposure sections of the active revision are preserved). The edit records a new config revision and applies to the agent's NEXT run.
type AgentConfigSetPromptLayersResponse ¶ added in v1.5.0
type AgentConfigSetPromptLayersResponse struct {
Revision AgentConfigRevisionView `json:"revision"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigSetPromptLayersResponse is the `agent_config.set_prompt_layers` response — the recorded config revision (or, on an idempotent re-set, the existing active revision).
type AgentConfigSetRevisionRequest ¶ added in v1.5.0
type AgentConfigSetRevisionRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
Payload AgentConfigPayload `json:"payload"`
}
AgentConfigSetRevisionRequest is the admin-scoped `agent_config.set_revision` request — write a new revision and advance the active pointer.
type AgentConfigSetRevisionResponse ¶ added in v1.5.0
type AgentConfigSetRevisionResponse struct {
Revision AgentConfigRevisionView `json:"revision"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigSetRevisionResponse is the `agent_config.set_revision` response — the new (or, on an idempotent re-set, existing) revision.
type AgentConfigSetToolExposureRequest ¶ added in v1.5.0
type AgentConfigSetToolExposureRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
ToolExposure AgentConfigToolExposure `json:"tool_exposure"`
}
AgentConfigSetToolExposureRequest is the admin-scoped `agent_config.set_tool_exposure` request — set the agent's MCP-exposure / per-tool policy as a desired-state REPLACE of the tool-exposure section (the skills + prompt sections of the active revision are preserved). The edit records a new config revision and applies to the agent's NEXT run.
type AgentConfigSetToolExposureResponse ¶ added in v1.5.0
type AgentConfigSetToolExposureResponse struct {
Revision AgentConfigRevisionView `json:"revision"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigSetToolExposureResponse is the `agent_config.set_tool_exposure` response — the recorded config revision (or, on an idempotent re-set, the existing active revision).
type AgentConfigSkillInput ¶ added in v1.5.0
type AgentConfigSkillInput struct {
Name string `json:"name"`
Title string `json:"title,omitempty"`
Description string `json:"description,omitempty"`
Trigger string `json:"trigger"`
TaskType string `json:"task_type,omitempty"`
Tags []string `json:"tags,omitempty"`
Steps []string `json:"steps"`
// Origin is the skill provenance (pack | generated). A skills.upsert
// over a pack-origin skill with a non-pack input is refused (the
// `ErrPackOverwriteRefused` path surfaces as a typed Protocol error).
Origin string `json:"origin"`
// Scope is the skill visibility (session | project | tenant | global).
Scope string `json:"scope"`
}
AgentConfigSkillInput is the wire request shape for a skill upsert. It maps onto the runtime `skills.Skill` mandatory fields (name, trigger, ≥1 step, origin, scope) plus the descriptive fields.
type AgentConfigSkillSummary ¶ added in v1.5.0
type AgentConfigSkillSummary struct {
Name string `json:"name"`
Title string `json:"title,omitempty"`
Trigger string `json:"trigger,omitempty"`
TaskType string `json:"task_type,omitempty"`
Origin string `json:"origin"`
Scope string `json:"scope"`
ContentHash string `json:"content_hash,omitempty"`
UpdatedAt time.Time `json:"updated_at"`
}
AgentConfigSkillSummary is the wire projection of one skill in the agent's store — metadata only, never the full body.
type AgentConfigSkillsDeleteRequest ¶ added in v1.5.0
type AgentConfigSkillsDeleteRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
Name string `json:"name"`
}
AgentConfigSkillsDeleteRequest is the admin-scoped `agent_config.skills.delete` request.
type AgentConfigSkillsDeleteResponse ¶ added in v1.5.0
type AgentConfigSkillsDeleteResponse struct {
Revision AgentConfigRevisionView `json:"revision"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigSkillsDeleteResponse is the `agent_config.skills.delete` response — the recorded config revision after the membership change.
type AgentConfigSkillsDiff ¶ added in v1.5.0
type AgentConfigSkillsDiff struct {
// Added are the skill names present in the to-revision but not the
// from-revision.
Added []string `json:"added,omitempty"`
// Removed are the skill names present in the from-revision but not the
// to-revision.
Removed []string `json:"removed,omitempty"`
}
AgentConfigSkillsDiff is the wire projection of the structured skills set-diff across two revisions.
type AgentConfigSkillsListRequest ¶ added in v1.5.0
type AgentConfigSkillsListRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
}
AgentConfigSkillsListRequest is the `agent_config.skills.list` request.
type AgentConfigSkillsListResponse ¶ added in v1.5.0
type AgentConfigSkillsListResponse struct {
Skills []AgentConfigSkillSummary `json:"skills"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigSkillsListResponse is the `agent_config.skills.list` response.
type AgentConfigSkillsSelection ¶ added in v1.5.0
type AgentConfigSkillsSelection struct {
// Names is the membership set of skill names active for the agent.
Names []string `json:"names"`
}
AgentConfigSkillsSelection is the wire projection of an agent's skills membership in a config revision — the set of skill names active for the agent. The revision records membership (names), never skill bodies (the bodies stay in the SkillStore).
type AgentConfigSkillsUpsertRequest ¶ added in v1.5.0
type AgentConfigSkillsUpsertRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
Skill AgentConfigSkillInput `json:"skill"`
}
AgentConfigSkillsUpsertRequest is the admin-scoped `agent_config.skills.upsert` request.
type AgentConfigSkillsUpsertResponse ¶ added in v1.5.0
type AgentConfigSkillsUpsertResponse struct {
Revision AgentConfigRevisionView `json:"revision"`
Skill AgentConfigSkillSummary `json:"skill"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigSkillsUpsertResponse is the `agent_config.skills.upsert` response — the recorded config revision plus the upserted skill summary.
type AgentConfigToolExposure ¶ added in v1.5.0
type AgentConfigToolExposure struct {
// PausedServers names the MCP source ids excluded from the next run's
// projection (resume is a flag flip, not a re-dial).
PausedServers []string `json:"paused_servers,omitempty"`
// DisabledTools names the individually-disabled tools (`<source>_<tool>`).
DisabledTools []string `json:"disabled_tools,omitempty"`
// ServerLoadingModes overrides the loading mode for a server's TOOL-form
// descriptors, keyed by MCP source id.
ServerLoadingModes map[string]string `json:"server_loading_modes,omitempty"`
// ToolLoadingModes overrides the loading mode for one exact catalog
// name, unconditionally.
ToolLoadingModes map[string]string `json:"tool_loading_modes,omitempty"`
}
AgentConfigToolExposure is the wire projection of an agent's MCP-exposure / per-tool policy in a config revision: the exclusion-based pause/disable sets (paused MCP servers, individually-disabled tools) plus the runtime loading-mode override maps. Pausing a server excludes its tools from the next run's projection (the live transport stays warm); disabling a tool excludes that one tool. Tools are keyed `<source>_<tool>`; a server's tools share the source id.
ServerLoadingModes / ToolLoadingModes values are the closed set "always" | "deferred" — `agent_config.set_tool_exposure` rejects any other value with `invalid_request` (400) BEFORE recording a revision. Precedence: ToolLoadingModes[name] > ServerLoadingModes[source] (TOOL-form descriptors only) > the boot config > the driver default.
type AgentConfigToolExposureDiff ¶ added in v1.5.0
type AgentConfigToolExposureDiff struct {
// PausedAdded / PausedResumed are the MCP servers newly paused / newly
// resumed across the two revisions.
PausedAdded []string `json:"paused_added,omitempty"`
PausedResumed []string `json:"paused_resumed,omitempty"`
// DisabledAdded / DisabledEnabled are the tools newly disabled / newly
// re-enabled across the two revisions.
DisabledAdded []string `json:"disabled_added,omitempty"`
DisabledEnabled []string `json:"disabled_enabled,omitempty"`
// ServerLoadingChanges / ToolLoadingChanges are the structured deltas of
// the per-server / per-tool loading-mode override maps.
ServerLoadingChanges []AgentConfigLoadingModeChange `json:"server_loading_changes,omitempty"`
ToolLoadingChanges []AgentConfigLoadingModeChange `json:"tool_loading_changes,omitempty"`
}
AgentConfigToolExposureDiff is the wire projection of the structured MCP-exposure / per-tool policy set-diff across two revisions.
type AgentConfigUserDiffRequest ¶ added in v1.6.0
type AgentConfigUserDiffRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
FromRevision string `json:"from_revision"`
ToRevision string `json:"to_revision"`
}
AgentConfigUserDiffRequest is the `agent_config.user.diff` request — compare two existing revisions of the caller's own variant.
type AgentConfigUserDiffResponse ¶ added in v1.6.0
type AgentConfigUserDiffResponse struct {
Diff AgentConfigDiff `json:"diff"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigUserDiffResponse is the `agent_config.user.diff` response.
type AgentConfigUserGetRequest ¶ added in v1.6.0
type AgentConfigUserGetRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
}
AgentConfigUserGetRequest is the `agent_config.user.get` request — read the caller's own durable variant's active revision.
type AgentConfigUserGetResponse ¶ added in v1.6.0
type AgentConfigUserGetResponse struct {
// Revision is the active revision; nil when the caller has no durable
// variant (Set is false).
Revision *AgentConfigRevisionView `json:"revision,omitempty"`
// Set reports whether an active user revision exists.
Set bool `json:"set"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigUserGetResponse is the `agent_config.user.get` response.
type AgentConfigUserListRevisionsRequest ¶ added in v1.6.0
type AgentConfigUserListRevisionsRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
// Limit caps the returned chain length. 0 = no cap.
Limit int `json:"limit,omitempty"`
}
AgentConfigUserListRevisionsRequest is the `agent_config.user.list_revisions` request — the caller's own variant revision chain, newest-first.
type AgentConfigUserListRevisionsResponse ¶ added in v1.6.0
type AgentConfigUserListRevisionsResponse struct {
Revisions []AgentConfigRevisionView `json:"revisions"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigUserListRevisionsResponse is the `agent_config.user.list_revisions` response.
type AgentConfigUserPayload ¶ added in v1.6.0
type AgentConfigUserPayload struct {
// UserPrompt is the user instruction layer that composes ABOVE the
// operator base (the prompt projection consumes this).
UserPrompt string `json:"user_prompt,omitempty"`
// DisabledServers names the MCP servers the user narrows out (the
// tool-exposure projection consumes this); narrow-only — there is no
// enable path.
DisabledServers []string `json:"disabled_servers,omitempty"`
// DisabledTools names the individual tools the user narrows out (the
// tool-exposure projection consumes this).
DisabledTools []string `json:"disabled_tools,omitempty"`
// PersonalSkills names the user's personal skill membership for the
// variant.
PersonalSkills []string `json:"personal_skills,omitempty"`
}
AgentConfigUserPayload is the bounded safe-subset a user-scope revision persists — the ONE durable user write surface for the agent-config band. It mirrors the session overlay's field set (user prompt + narrow-only disables + personal skills) and has NO base / connections / enable / model field. The two PROJECTION-ONLY sibling phases consume its fields: the prompt projection reads UserPrompt; the tool-exposure projection reads DisabledServers / DisabledTools.
type AgentConfigUserRollbackRequest ¶ added in v1.6.0
type AgentConfigUserRollbackRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
RevisionID string `json:"revision_id"`
}
AgentConfigUserRollbackRequest is the `agent_config.user.rollback` request — repoint the caller's own variant active pointer to an existing revision.
type AgentConfigUserRollbackResponse ¶ added in v1.6.0
type AgentConfigUserRollbackResponse struct {
Revision AgentConfigRevisionView `json:"revision"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigUserRollbackResponse is the `agent_config.user.rollback` response — the revision the active pointer now points to.
type AgentConfigUserSetRevisionRequest ¶ added in v1.6.0
type AgentConfigUserSetRevisionRequest struct {
Identity IdentityScope `json:"identity"`
AgentID string `json:"agent_id"`
Payload AgentConfigUserPayload `json:"payload"`
}
AgentConfigUserSetRevisionRequest is the `agent_config.user.set_revision` request — write a new revision of the caller's durable variant from the bounded safe-subset payload.
type AgentConfigUserSetRevisionResponse ¶ added in v1.6.0
type AgentConfigUserSetRevisionResponse struct {
Revision AgentConfigRevisionView `json:"revision"`
ProtocolVersion string `json:"protocol_version"`
}
AgentConfigUserSetRevisionResponse is the `agent_config.user.set_revision` response — the new (or, on an idempotent re-set, existing) revision.
type AgentControlRequest ¶ added in v1.3.0
type AgentControlRequest struct {
// Identity is the (tenant, user, session) scope. Mandatory.
Identity IdentityScope `json:"identity"`
// ID is the agent_id to control.
ID string `json:"id"`
// Reason is the operator-supplied control reason (redacted, audited).
Reason string `json:"reason,omitempty"`
}
AgentControlRequest is the shared request body for the five fleet- control verbs (`agents.pause` / `agents.drain` / `agents.restart` / `agents.force_stop` / `agents.deregister`) —. Every control verb mutates registry state and requires the elevated `auth.ScopeAdmin` control claim. `Reason` is operator-supplied free text the registry redacts through `audit.Redactor` before it reaches the `agent.*` event; `agents.deregister` ignores it.
type AgentControlResponse ¶ added in v1.3.0
type AgentControlResponse struct {
// AgentID echoes the controlled agent_id.
AgentID string `json:"agent_id"`
// Command is the applied control verb: pause / drain / restart /
// force_stop / deregister.
Command string `json:"command"`
// Status is the agent's post-control lifecycle status.
Status AgentStatus `json:"status"`
}
AgentControlResponse is the shared reply for the five fleet-control verbs. Status is the ACTUAL post-control status the registry re-read after applying the command — NOT the verb's nominal intent (no fabrication; CLAUDE.md §13). The V1 registry's Health enum has no "paused" state, and `pause` / `restart` do not transition Health, so:
- pause → the agent's prior status, unchanged (active for a healthy agent — there is no "paused" status);
- restart → the agent's prior status, unchanged (restart bumps the incarnation but does NOT clear a prior drain/stop Health, so a restarted-after-drain agent reads `drained`, not `active`);
- drain → drained;
- force_stop → force_stopped;
- deregister → deregistered (the record is gone; not re-read).
In every case the registry emitted the matching `agent.*` event, which is the authoritative observation surface the Console also subscribes to.
type AgentCostCeiling ¶
type AgentCostCeiling struct {
// Tier is the identity tier the ceiling applies to.
Tier string `json:"tier"`
// LimitUSD is the configured spend ceiling in USD.
LimitUSD float64 `json:"limit_usd"`
// SpendUSD is the current accumulated spend in USD.
SpendUSD float64 `json:"spend_usd"`
}
AgentCostCeiling is one per-identity-tier cost ceiling.
type AgentFilter ¶
type AgentFilter struct {
// Status narrows to agents whose Status is in the set; empty = all.
Status []AgentStatus `json:"status,omitempty"`
// PlannerType narrows to agents whose PlannerType is in the set;
// empty = all.
PlannerType []string `json:"planner_type,omitempty"`
// Search is a free-text query over Name + Description (case-fold).
Search string `json:"search,omitempty"`
// TenantIDs is the admin-widened FLEET-enumeration selector: when
// non-empty, `agents.list` enumerates every registered agent across
// ALL sessions of the named tenants (a coordinator control plane
// rendering a fleet-wide Agents catalog), not just the caller's own
// triple. It mirrors `SessionFilter.TenantIDs` and the tasks analogue.
// Widening requires the verified `auth.ScopeAdmin` claim — a non-empty
// TenantIDs without the claim fails closed with the scope-mismatch
// error, never a silent narrowing. Empty (the default) is
// byte-compatible with the identity-scoped read.
TenantIDs []string `json:"tenant_ids,omitempty"`
}
AgentFilter is the server-enforced facet filter on `agents.list`.
type AgentGetRequest ¶
type AgentGetRequest struct {
// Identity is the (tenant, user, session) scope. Mandatory.
Identity IdentityScope `json:"identity"`
// ID is the agent_id to fetch.
ID string `json:"id"`
}
AgentGetRequest is the `agents.get` request body.
type AgentGetResponse ¶
type AgentGetResponse struct {
// Agent is the catalog-row projection.
Agent Agent `json:"agent"`
// Config is the agent's configuration projection.
Config AgentConfig `json:"config"`
// AgentCardRef references the canonical A2A AgentCard for a
// HostingRemote agent. Empty for a HostingLocal agent.
AgentCardRef string `json:"agent_card_ref,omitempty"`
}
AgentGetResponse is the `agents.get` reply — the full projection of one agent.
type AgentGovernance ¶
type AgentGovernance struct {
// Ceilings is the per-identity-tier cost ceilings + spend.
Ceilings []AgentCostCeiling `json:"ceilings"`
// RateLimits is the per-identity-tier rate-limit posture.
RateLimits []AgentRateLimit `json:"rate_limits"`
}
AgentGovernance is the agent's governance posture — per-identity-tier ceilings + spend + rate-limit posture.
type AgentGovernanceRequest ¶
type AgentGovernanceRequest struct {
// Identity is the (tenant, user, session) scope. Mandatory.
Identity IdentityScope `json:"identity"`
// ID is the agent_id whose governance posture to fetch.
ID string `json:"id"`
}
AgentGovernanceRequest is the `agents.governance` request body.
type AgentGovernanceResponse ¶
type AgentGovernanceResponse struct {
// AgentID echoes the requested agent_id.
AgentID string `json:"agent_id"`
// Governance is the agent's governance posture.
Governance AgentGovernance `json:"governance"`
}
AgentGovernanceResponse is the `agents.governance` reply.
type AgentHealth ¶
type AgentHealth string
AgentHealth is the operational-health enum the Agents page renders as a health badge. It mirrors the registry's Health enum projected onto operator-facing labels.
const ( // AgentHealthHealthy — the agent reported itself operational. AgentHealthHealthy AgentHealth = "Healthy" // AgentHealthDegraded — the agent reported impaired operation. AgentHealthDegraded AgentHealth = "Degraded" // AgentHealthPaused — a Pause control verb is in effect. AgentHealthPaused AgentHealth = "Paused" // AgentHealthDrained — a Drain control verb is in effect. AgentHealthDrained AgentHealth = "Drained" // AgentHealthForceStopped — a ForceStop control verb is in effect. AgentHealthForceStopped AgentHealth = "Force-Stopped" // AgentHealthUnknown — no health has been reported yet. AgentHealthUnknown AgentHealth = "Unknown" )
type AgentHosting ¶
type AgentHosting string
AgentHosting discriminates a locally-hosted agent from a connect-to-remote agent.
const ( // AgentHostingLocal — the agent is hosted by this runtime instance. AgentHostingLocal AgentHosting = "local" // AgentHostingRemote — the agent runs elsewhere; the local agent_id // is a handle and the canonical identity is the remote A2A AgentCard. AgentHostingRemote AgentHosting = "remote" )
type AgentListRequest ¶
type AgentListRequest struct {
// Identity is the (tenant, user, session) scope. Mandatory.
Identity IdentityScope `json:"identity"`
// Filter is the optional facet filter.
Filter AgentFilter `json:"filter,omitempty"`
// Page is the 1-based page index. <= 0 is treated as page 1.
Page int `json:"page,omitempty"`
// PageSize is the rows-per-page. 0 ⇒ DefaultAgentListPageSize.
PageSize int `json:"page_size,omitempty"`
}
AgentListRequest is the `agents.list` request body.
type AgentListResponse ¶
type AgentListResponse struct {
// Agents is the page of catalog rows.
Agents []Agent `json:"agents"`
// Page is the 1-based page index this response covers.
Page int `json:"page"`
// PageSize is the rows-per-page applied.
PageSize int `json:"page_size"`
// PageCount is the total number of pages in the filtered view.
PageCount int `json:"page_count"`
// TotalRows is the total row count in the filtered view.
TotalRows int64 `json:"total_rows"`
// Aggregates is the four counters over the filtered view.
Aggregates AgentAggregates `json:"aggregates"`
}
AgentListResponse is the `agents.list` reply.
type AgentMemoryBinding ¶
type AgentMemoryBinding struct {
// StrategyID is the memory strategy id.
StrategyID string `json:"strategy_id"`
// TTLSeconds is the configured memory TTL in seconds (0 ⇒ no TTL).
TTLSeconds int64 `json:"ttl_seconds"`
// Scope is the memory scope: "session" / "user" / "tenant".
Scope string `json:"scope"`
}
AgentMemoryBinding is the agent's configured memory strategy.
type AgentMemoryRequest ¶
type AgentMemoryRequest struct {
// Identity is the (tenant, user, session) scope. Mandatory.
Identity IdentityScope `json:"identity"`
// ID is the agent_id whose memory binding to fetch.
ID string `json:"id"`
}
AgentMemoryRequest is the `agents.memory` request body.
type AgentMemoryResponse ¶
type AgentMemoryResponse struct {
// AgentID echoes the requested agent_id.
AgentID string `json:"agent_id"`
// Binding is the agent's memory-strategy binding.
Binding AgentMemoryBinding `json:"binding"`
}
AgentMemoryResponse is the `agents.memory` reply.
type AgentMetrics ¶
type AgentMetrics struct {
// ActiveAgents is the count of AgentStatusActive agents in scope.
ActiveAgents int64 `json:"active_agents"`
// RunningTasks is the count of in-flight tasks across those agents.
RunningTasks int64 `json:"running_tasks"`
// TotalCostUSD is the total accumulated spend across those agents.
TotalCostUSD float64 `json:"total_cost_usd"`
// TotalTokens is the total token consumption across those agents.
TotalTokens int64 `json:"total_tokens"`
}
AgentMetrics is the registry-wide rollup the Agents page hero shows — the four "Active Agents / Running Tasks / Total Cost / Total Tokens" numbers, computed over the operator's identity scope.
type AgentMetricsRequest ¶
type AgentMetricsRequest struct {
// Identity is the (tenant, user, session) scope. Mandatory.
Identity IdentityScope `json:"identity"`
}
AgentMetricsRequest is the `agents.metrics` request body.
type AgentMetricsResponse ¶
type AgentMetricsResponse struct {
// Metrics is the registry-wide rollup.
Metrics AgentMetrics `json:"metrics"`
}
AgentMetricsResponse is the `agents.metrics` reply.
type AgentPermissions ¶
type AgentPermissions struct {
// Model is the permission model: "implicit" (V1 default) or
// "explicit" (post-V1).
Model string `json:"model"`
// Description is the operator-facing explanation of the model.
Description string `json:"description"`
// AllowedPrincipals is the explicit ACL when Model is "explicit";
// empty for the implicit model.
AllowedPrincipals []string `json:"allowed_principals,omitempty"`
}
AgentPermissions is the agent's permission model. V1 default is implicit ("every authenticated user in the tenant can invoke this agent"); an explicit ACL surface is post-V1 (page-agents.md §10).
type AgentPermissionsRequest ¶
type AgentPermissionsRequest struct {
// Identity is the (tenant, user, session) scope. Mandatory.
Identity IdentityScope `json:"identity"`
// ID is the agent_id whose permission model to fetch.
ID string `json:"id"`
}
AgentPermissionsRequest is the `agents.permissions` request body.
type AgentPermissionsResponse ¶
type AgentPermissionsResponse struct {
// AgentID echoes the requested agent_id.
AgentID string `json:"agent_id"`
// Permissions is the agent's permission model.
Permissions AgentPermissions `json:"permissions"`
}
AgentPermissionsResponse is the `agents.permissions` reply.
type AgentRateLimit ¶
type AgentRateLimit struct {
// Tier is the identity tier the rate limit applies to.
Tier string `json:"tier"`
// RequestsPerMinute is the configured per-minute request ceiling.
RequestsPerMinute int64 `json:"requests_per_minute"`
// MaxTokens is the configured per-request MaxTokens ceiling.
MaxTokens int64 `json:"max_tokens"`
}
AgentRateLimit is one per-identity-tier rate-limit posture ( ).
type AgentSkillBinding ¶
type AgentSkillBinding struct {
// SkillID is the catalog key of the attached skill.
SkillID string `json:"skill_id"`
// Name is the operator-facing skill name.
Name string `json:"name"`
// Generated reports whether the skill was generated in-runtime
// rather than imported.
Generated bool `json:"generated"`
}
AgentSkillBinding is one skill attached to an agent (built-in + generated skills).
type AgentSkillsRequest ¶
type AgentSkillsRequest struct {
// Identity is the (tenant, user, session) scope. Mandatory.
Identity IdentityScope `json:"identity"`
// ID is the agent_id whose attached skills to list.
ID string `json:"id"`
}
AgentSkillsRequest is the `agents.skills` request body.
type AgentSkillsResponse ¶
type AgentSkillsResponse struct {
// AgentID echoes the requested agent_id.
AgentID string `json:"agent_id"`
// Skills is the agent's attached skills.
Skills []AgentSkillBinding `json:"skills"`
}
AgentSkillsResponse is the `agents.skills` reply.
type AgentStatus ¶
type AgentStatus string
AgentStatus is the lifecycle-status enum the Agents page renders as a status pill. It mirrors the registry's control-verb outcomes.
const ( // AgentStatusActive — the agent is registered and accepting work. AgentStatusActive AgentStatus = "active" // AgentStatusPaused — a registry.Pause control verb is in effect. AgentStatusPaused AgentStatus = "paused" // AgentStatusDrained — a registry.Drain control verb is in effect. AgentStatusDrained AgentStatus = "drained" // AgentStatusForceStopped — a registry.ForceStop verb is in effect. AgentStatusForceStopped AgentStatus = "force_stopped" // AgentStatusDeregistered — the agent was removed from the registry. AgentStatusDeregistered AgentStatus = "deregistered" )
type AgentToolBinding ¶
type AgentToolBinding struct {
// ToolID is the catalog key of the bound tool.
ToolID string `json:"tool_id"`
// ToolName is the operator-facing tool name.
ToolName string `json:"tool_name"`
// Transport is the tool's transport ("in-proc" / "HTTP" / "MCP" /
// "A2A" / "flow").
Transport string `json:"transport"`
// AuthStatus is the per-binding OAuth status: "no_auth" / "headers"
// / "oauth_user_bound" / "oauth_agent_bound" / "oauth_expired".
AuthStatus string `json:"auth_status"`
// BindingScope is the OAuth binding scope (auth.BindingScope per):
// "user" / "agent". Empty for a non-OAuth binding.
BindingScope string `json:"binding_scope,omitempty"`
}
AgentToolBinding is one tool binding on an agent — a tool + the per-binding OAuth status.
type AgentToolsRequest ¶
type AgentToolsRequest struct {
// Identity is the (tenant, user, session) scope. Mandatory.
Identity IdentityScope `json:"identity"`
// ID is the agent_id whose tool bindings to list.
ID string `json:"id"`
}
AgentToolsRequest is the `agents.tools` request body.
type AgentToolsResponse ¶
type AgentToolsResponse struct {
// AgentID echoes the requested agent_id.
AgentID string `json:"agent_id"`
// Bindings is the agent's tool bindings.
Bindings []AgentToolBinding `json:"bindings"`
}
AgentToolsResponse is the `agents.tools` reply.
type ArtifactRef ¶
type ArtifactRef struct {
// ID is the content-addressed identifier
// (`{namespace}_{sha256[:12]}`).
ID string `json:"id"`
// MimeType is the IANA media type, when known.
MimeType string `json:"mime_type,omitempty"`
// SizeBytes is the length of the referenced bytes.
SizeBytes int64 `json:"size_bytes"`
// Filename is metadata only — never used for path construction.
Filename string `json:"filename,omitempty"`
// SHA256 is the full hex digest of the referenced bytes.
SHA256 string `json:"sha256,omitempty"`
// Namespace is the logical bucket the artifact lives in.
Namespace string `json:"namespace,omitempty"`
// Scope is the artifact's owning identity scope.
Scope ArtifactScope `json:"scope"`
}
ArtifactRef is the flat Protocol projection of the storage-side internal/artifacts.ArtifactRef. It carries the catalog-rendering metadata a Console row needs — never the artifact bytes.
type ArtifactRefSummary ¶
type ArtifactRefSummary struct {
// Filename is the artifact's display filename.
Filename string `json:"filename"`
// MIME is the artifact's content type.
MIME string `json:"mime"`
// SizeBytes is the artifact's byte size.
SizeBytes int64 `json:"size_bytes"`
// CreatedAt is when the artifact was produced.
CreatedAt time.Time `json:"created_at"`
}
ArtifactRefSummary is one entry in the right-rail Session Summary's Recent Artifacts card. Capped at MaxSessionArtifactSummaries. It carries metadata only — never inline bytes.
type ArtifactRow ¶
type ArtifactRow struct {
// Ref is the canonical artifact reference.
Ref ArtifactRef `json:"ref"`
// Tags is the chip list assigned by the producing planner / tool.
// Sourced from the storage-side `Source["tags"]` projection — never
// promoted onto the storage ArtifactRef shape (open-question
// resolution: project on the Protocol row, not the storage struct).
Tags []string `json:"tags,omitempty"`
// Source is the producer of the artifact — one of the four canonical
// ArtifactSource values.
Source ArtifactSource `json:"source,omitempty"`
// Driver is the artifact store driver that holds this artifact —
// "inmem" | "fs" | "sqlite" | "postgres" | "s3".
Driver string `json:"driver,omitempty"`
// CreatedAt is the artifact's put timestamp.
CreatedAt time.Time `json:"created_at,omitempty"`
}
ArtifactRow is the artifacts.list row shape. It wraps the canonical ArtifactRef with the catalog-only fields the Console table renders — Tags, the storage Driver name, and the creation timestamp. ArtifactRow is deliberately distinct from ArtifactRef so the Protocol's wire surface stays independent of the storage shape.
type ArtifactScope ¶
type ArtifactScope struct {
// Tenant / User / Session are the mandatory isolation triple. An
// empty component fails put / get_ref closed at the Protocol edge.
Tenant string `json:"tenant"`
User string `json:"user"`
Session string `json:"session"`
// Task is the per-task scope inside a session. Optional — empty for
// session-scoped artifacts; a list filter treats an empty Task as a
// wildcard.
Task string `json:"task,omitempty"`
}
ArtifactScope is the flat wire identity an artifacts-method request carries. It mirrors the four-field internal/artifacts.ArtifactScope shape — `(tenant, user, session, task)` — because the artifact store keys artifacts on tasks (RFC §6.10), but it is a Protocol-owned wire type, never a re-export.
Identity is mandatory: Tenant / User / Session must be non-empty for artifacts.put and artifacts.get_ref. Task is optional for session- scoped artifacts. For artifacts.list, empty fields are wildcards (tenant-wide listing requires the admin scope per the closed admin-scope set).
type ArtifactSource ¶
type ArtifactSource string
ArtifactSource is the closed enum of artifact producers. A free-text field would invite drift; the enum can be extended via a future RFC PR. Deserialisation of an unknown source returns CodeInvalidRequest loudly (the artifacts surface fails loud per CLAUDE.md §13) — there is no silent "unknown" bucket.
const ( // ArtifactSourceTool — the artifact was produced by a tool call. ArtifactSourceTool ArtifactSource = "tool" // ArtifactSourcePlanner — the artifact was produced by a planner // decision. ArtifactSourcePlanner ArtifactSource = "planner" // ArtifactSourceUserUpload — the artifact was uploaded by an operator // through the Console (or Playground) file-upload pipeline. This is // the default Source for an artifacts.put with no explicit Source. ArtifactSourceUserUpload ArtifactSource = "user_upload" // ArtifactSourceSystem — the artifact was produced by the runtime // itself (a generated report, a system dump). ArtifactSourceSystem ArtifactSource = "system" )
Canonical ArtifactSource values. The set is closed.
type ArtifactsDeleteRequest ¶ added in v1.3.0
type ArtifactsDeleteRequest struct {
// Scope is the artifact's isolation scope. The triple is mandatory.
Scope ArtifactScope `json:"scope"`
// ID is the content-addressed artifact id to evict.
ID string `json:"id"`
}
ArtifactsDeleteRequest is the wire request for the `artifacts.delete` method — the admin-gated "evict an artifact" mutation. Identity is mandatory (full triple); admin scope is required. Heavy bytes never cross the wire — only the scope + the content-addressed id.
type ArtifactsDeleteResponse ¶ added in v1.3.0
type ArtifactsDeleteResponse struct {
// Deleted reports whether the artifact existed before the delete.
// Idempotent: deleting an absent artifact returns deleted=false with
// no error (CodeNotFound is NOT raised — delete is a no-op-safe verb).
Deleted bool `json:"deleted"`
// ProtocolVersion echoes the Protocol version the Runtime answered
// under so a client can detect a version skew.
ProtocolVersion string `json:"protocol_version"`
}
ArtifactsDeleteResponse is the wire response for the `artifacts.delete` method.
type ArtifactsGetRefRequest ¶
type ArtifactsGetRefRequest struct {
// Scope is the caller's identity scope. Tenant / User / Session are
// mandatory.
Scope ArtifactScope `json:"scope"`
// ID is the content-addressed artifact identifier to resolve.
ID string `json:"id"`
// Expiry is the presigned-URL validity window. Defaults to
// DefaultPresignExpiry (15m) when zero; values outside
// [PresignExpiryMin, PresignExpiryMax] are rejected loudly.
Expiry time.Duration `json:"expiry,omitempty"`
}
ArtifactsGetRefRequest is the wire request for the artifacts.get_ref Protocol method — the read-side presigned-URL resolver. Expiry is bounded [PresignExpiryMin, PresignExpiryMax]; an out-of-range expiry is rejected with CodeInvalidRequest.
func (ArtifactsGetRefRequest) NormalisedExpiry ¶
func (r ArtifactsGetRefRequest) NormalisedExpiry() time.Duration
NormalisedExpiry returns the request's Expiry, applying DefaultPresignExpiry when the request omitted it. The handler separately bounds-checks against [PresignExpiryMin, PresignExpiryMax] so it can return CodeInvalidRequest rather than silently clamping.
type ArtifactsGetRefResponse ¶
type ArtifactsGetRefResponse struct {
// Ref is the artifact metadata reference.
Ref ArtifactRef `json:"ref"`
// PresignedURL is the time-bounded HTTPS URL the Console downloads
// the bytes from directly, bypassing the runtime's bytes path.
PresignedURL string `json:"presigned_url"`
// ExpiresAt is the wall-clock instant the presigned URL stops being
// valid.
ExpiresAt time.Time `json:"expires_at"`
// ProtocolVersion echoes the Protocol version.
ProtocolVersion string `json:"protocol_version"`
}
ArtifactsGetRefResponse is the wire response for artifacts.get_ref. It carries the time-bounded presigned URL plus the artifact metadata — the Console's Preview / Download / Share all consume this single shape.
type ArtifactsListRequest ¶
type ArtifactsListRequest struct {
// Scope is the caller's identity scope. A list filter treats empty
// fields as wildcards; a Tenant differing from the caller's verified
// tenant requires the admin scope per the closed admin-scope set.
Scope ArtifactScope `json:"scope"`
// MimeType is an OR-set of IANA media types. Empty == wildcard.
MimeType []string `json:"mime_type,omitempty"`
// Source is an OR-set of artifact producers. Empty == wildcard. An
// unknown source value fails the request with CodeInvalidRequest.
Source []ArtifactSource `json:"source,omitempty"`
// SizeRange, when set, filters by stored byte size.
SizeRange *SizeRange `json:"size_range,omitempty"`
// CreatedRange, when set, filters by put timestamp.
CreatedRange *TimeRange `json:"created_range,omitempty"`
// Tags is an OR-set of tag strings. An artifact matches when it
// carries at least one of the listed tags. Empty == wildcard.
Tags []string `json:"tags,omitempty"`
// Limit bounds the returned page. Defaults to DefaultArtifactsLimit
// (100) when zero; values above MaxArtifactsLimit (1000) are clamped.
Limit int `json:"limit,omitempty"`
}
ArtifactsListRequest is the wire request for the artifacts.list Protocol method. The filter extensions — MimeType, Source, SizeRange, CreatedRange, Tags — are all optional; an empty field is a wildcard. The handler applies them as a Go-side projection over the driver's returned slice (the V1 ArtifactStore.List signature is not extended — driver conformance stays untouched).
func (ArtifactsListRequest) NormalisedLimit ¶
func (r ArtifactsListRequest) NormalisedLimit() int
NormalisedLimit returns the request's Limit clamped to [1, MaxArtifactsLimit], applying DefaultArtifactsLimit when the request omitted it. The handler calls this so a client that omits Limit gets the documented default and one that over-asks is bounded.
func (ArtifactsListRequest) Validate ¶
func (r ArtifactsListRequest) Validate() error
Validate checks the artifacts.list filter for an unknown ArtifactSource value, failing loud (CLAUDE.md §13) rather than silently dropping it. Returns an error naming the offending value when one is found.
type ArtifactsListResponse ¶
type ArtifactsListResponse struct {
// Rows is the page slice, at most Limit rows. Empty when the filter
// matched nothing.
Rows []ArtifactRow `json:"rows"`
// TotalMatched is the count of rows matching the filter before the
// Limit truncation — the Console paginator renders "N of M".
TotalMatched int `json:"total_matched"`
// ProtocolVersion echoes the Protocol version the Runtime answered
// under so a client can detect a version skew.
ProtocolVersion string `json:"protocol_version"`
}
ArtifactsListResponse is the wire response for artifacts.list. Rows is the metadata-only page slice — never artifact bytes.
func (ArtifactsListResponse) MarshalJSON ¶
func (r ArtifactsListResponse) MarshalJSON() ([]byte, error)
MarshalJSON is the standard json.Marshaler kept explicit so the ArtifactsListResponse shape stays stable across a field-reorder refactor. Round-trip is verified by artifacts_test.go.
type ArtifactsPutOpts ¶
type ArtifactsPutOpts struct {
// MimeType is the IANA media type of the upload. Empty defaults to
// the store's own default (text/plain for PutText-shaped bytes).
MimeType string `json:"mime_type,omitempty"`
// Filename is metadata only — never used for path construction.
Filename string `json:"filename,omitempty"`
// Namespace is the logical bucket the artifact lands in. Empty
// defaults to "default" at the store.
Namespace string `json:"namespace,omitempty"`
// Source is the artifact producer. Defaults to ArtifactSourceUserUpload
// when empty (an artifacts.put IS, by construction, a user upload).
// An explicit unknown value fails the request with
// CodeInvalidRequest.
Source ArtifactSource `json:"source,omitempty"`
// Tags is the chip list to assign to the artifact.
Tags []string `json:"tags,omitempty"`
}
ArtifactsPutOpts carries the optional upload metadata an artifacts.put request supplies. It mirrors the catalog-relevant subset of the storage-side internal/artifacts.PutOpts.
type ArtifactsPutRequest ¶
type ArtifactsPutRequest struct {
// Scope is the caller's identity scope. Tenant / User / Session are
// mandatory; a body whose Tenant disagrees with the caller's
// verified tenant is rejected with CodeScopeMismatch.
Scope ArtifactScope `json:"scope"`
// Bytes is the artifact payload. JSON-encoded as a base64 string by
// the standard []byte marshaller.
Bytes []byte `json:"bytes"`
// Opts is the optional upload metadata.
Opts ArtifactsPutOpts `json:"opts,omitempty"`
}
ArtifactsPutRequest is the wire request for the artifacts.put Protocol method. The upload bytes travel inline on the request leg only — the response is a reference, never an echo of the body. Body size is bounded by config.ProtocolConfig.MaxRequestBytes; an oversize body is rejected with CodeRequestTooLarge.
type ArtifactsPutResponse ¶
type ArtifactsPutResponse struct {
// Ref is the content-addressed reference to the stored artifact.
Ref ArtifactRef `json:"ref"`
// ProtocolVersion echoes the Protocol version.
ProtocolVersion string `json:"protocol_version"`
}
ArtifactsPutResponse is the wire response for artifacts.put. It carries the canonical ArtifactRef the store minted — never the uploaded bytes.
type AuthRotateTokenRequest ¶
type AuthRotateTokenRequest struct {
// Identity is the caller's identity scope. The auth surface asserts
// the triple against the verified JWT before re-minting.
Identity IdentityScope `json:"identity"`
}
AuthRotateTokenRequest is the `auth.rotate_token` request body.
Token rotation requires no body fields beyond the identity scope — the caller's identity is carried by the verified JWT, and the Runtime re-mints for exactly that identity. The Identity field is the standard flat IdentityScope every Protocol request carries; the Runtime asserts it against the verified JWT (defence-in-depth — a caller cannot present a valid token for one identity and a body claiming another).
type AuthRotateTokenResponse ¶
type AuthRotateTokenResponse struct {
// NewToken is the re-minted Protocol-auth JWT, Bearer-shaped. The
// operator copies this exactly once.
NewToken string `json:"new_token"`
// ExpiresAt is the new token's expiry, UTC.
ExpiresAt time.Time `json:"expires_at"`
}
AuthRotateTokenResponse is the `auth.rotate_token` response body — the re-minted token. It is one-time-revealed: the Console copies `NewToken` once into its encrypted 72h `auth_profiles` blob and never displays the raw token again.
type Capability ¶
type Capability string
Capability is a Protocol surface a Runtime can advertise. The Protocol exposes several surfaces (RFC §5.2 — task control, streaming events, state snapshots, topology, artifacts, traces/metrics); a Capability is how a Runtime tells a client *which* of them are live, so a client negotiates rather than discovering a missing surface by a 404.
Capability is a fixed string enum, not a registration seam: a new Protocol surface adds its Capability constant in the phase that ships the surface (and extends canonicalCapabilities), exactly as a new Protocol method extends methods.canonicalMethods.
const ( // CapTaskControl — the task control surface (RFC §5.2 "Task // control" row): the `start` method plus the nine steering-control // methods. CapTaskControl Capability = "task_control" // CapEventsSubscribe — the streaming-events surface (RFC §5.2 // "Streaming events" row): the `events.subscribe` method and the // `events.aggregate` time-bucket method. Shipped in. CapEventsSubscribe Capability = "events_subscribe" // CapRuntimePosture — the runtime-posture surface (RFC §5.3, §6.15, // §7): the five read-only `runtime.*` / `metrics.*` methods // (`runtime.info`, `runtime.health`, `runtime.counters`, // `runtime.drivers`, `metrics.snapshot`). Shipped in. // A Protocol client negotiates "does this // Runtime advertise the posture surface?" via // `VersionHandshake.Accepts(CapRuntimePosture)`. The addition is // backward-compatible (RFC §5.3 minor-class change) — no version // bump. CapRuntimePosture Capability = "runtime_posture" // CapTopologySnapshot — the engine-graph topology projection // (`topology.snapshot`,). Conditional: a runtime // only advertises this capability when it hosts an engine (the // ControlSurface's topology accessor is non-nil). Planner / // RunLoop-shaped runtimes — including `harbor dev` against an // agent yaml — do NOT advertise it; the Console reads // `runtime.info.capabilities` at attach and gates its // `topology.snapshot` calls behind `caps.has('topology_snapshot')` // so the browser console stays clean on runtimes without the // surface (. Backward-compatible (RFC §5.3 // minor-class addition) — no version bump. CapTopologySnapshot Capability = "topology_snapshot" // CapStateSnapshots — the State-snapshots surface (RFC §5.2 "State // snapshots" row): the `state.history` windowed event-replay read (the // first of the three State-snapshots methods to land). A Protocol // client negotiates "does this Runtime advertise the state-history // surface?" via `VersionHandshake.Accepts(CapStateSnapshots)` rather // than discovering a missing route by a 404. The addition is // backward-compatible (RFC §5.3 minor-class change) — no version bump. CapStateSnapshots Capability = "state_snapshots" // CapAgentConfig — the agent-config control plane (RFC §6.16): the // versioned desired-state surface for an agent's prompt layers, // tool/MCP exposure, per-tool policy, and skills (the agent's content // surface), exposed as the `agent_config.*` methods. A Protocol client // negotiates "does this Runtime host the agent-config surface?" via // `VersionHandshake.Accepts(CapAgentConfig)` / the // `runtime.info.capabilities` list, instead of method-probing the // `agent_config.*` verbs and catching a 501/404. Conditional // per-instance: a Runtime advertises it only when the agent-config // surface is mounted. Backward-compatible (RFC §5.3 minor-class // addition) — no version bump. CapAgentConfig Capability = "agent_config" // CapSessionLifecycle — the session data-lifecycle surface: the // `sessions.delete` identity-scoped erasure method that deletes a // session and cascades deletion of its scoped State, Memory, and // Artifacts. Conditional: a runtime advertises it ONLY when it wired // an eraser (the three scoped stores + the SessionRegistry behind the // cascade). A read-only or headless runtime that did not wire an // eraser does NOT advertise it, so a Protocol client detects erasure // support via `VersionHandshake.Accepts(CapSessionLifecycle)` rather // than discovering a missing route by a 404 at call time. The addition // is backward-compatible (RFC §5.3 minor-class change) — no version // bump. CapSessionLifecycle Capability = "session_lifecycle" // CapToolAnnotations — the per-tool annotation surface (OAuth binding // status / approval policy / last-used / metrics / content-stats / // display-modes) the Tools page's OAuth + approval facets and the // catalog overview aggregates ride. Conditional: a runtime advertises it // ONLY when a per-tool Annotator concrete is wired. The V1 build ships // no Annotator (the concrete lands in the tools annotator follow-up), so no instance // advertises it yet — a Console negotiates "are the tool OAuth/approval // facets live?" via `VersionHandshake.Accepts(CapToolAnnotations)` and // disables the facet chips until the runtime advertises it, rather than // discovering an `invalid_request` loud-reject at submit time. This is // the SINGLE annotator-wired toggle the tools annotator follow-up flips from unwired to // advertised. Backward-compatible (RFC §5.3 minor-class addition) — no // version bump. CapToolAnnotations Capability = "tool_annotations" )
The V1 Protocol capability set. At Protocol 0.1.0 exactly one surface has shipped — the task control surface — so CapTaskControl is the only capability. RFC §5.2's other surfaces add their Capability constant here as their phase lands.
func Capabilities ¶
func Capabilities() []Capability
Capabilities returns the deterministic, lexicographically-sorted set of Protocol capabilities the Runtime advertises. At Protocol 0.1.0 this is exactly {CapTaskControl}.
type ControlRequest ¶
type ControlRequest struct {
// Identity is the request's identity scope. The full quadruple
// (triple + Run) is mandatory — a steering control targets a
// specific run's inbox. Scope is the caller's steering scope claim.
Identity IdentityScope `json:"identity"`
// Payload is the method-specific control payload. May be nil — a
// bare `cancel` / `pause` carries no payload. The steering
// ValidatePayload enforces the RFC §6.3 bounds (depth ≤ 6, ≤ 64
// keys, ≤ 50 list items, ≤ 4096 chars/string, ≤ 16 KiB total) at the
// edge; an oversize payload fails the request closed.
Payload map[string]any `json:"payload,omitempty"`
// EventID is the caller-supplied idempotency / correlation key
// (ULID-shaped). Optional — the control-history dedupe uses
// it. Empty is permitted.
EventID string `json:"event_id,omitempty"`
}
ControlRequest is the wire request shared by the nine steering-control Protocol methods (`cancel`, `pause`, `resume`, `redirect`, `inject_context`, `approve`, `reject`, `prioritize`, `user_message`). The method name selects which steering ControlType the surface constructs; the Payload carries the method-specific arguments (the `goal` for redirect, the `message` for user_message, the `priority` for prioritize, `hard` for a hard cancel, etc.).
The ControlSurface constructs a steering.ControlEvent from a ControlRequest and lets the Inbox.Enqueue do the validation, the RFC §6.3 payload-bounds enforcement, and the per-event scope check does not re-implement any of that (CLAUDE.md §13 forbids a second validator).
type ControlResponse ¶
type ControlResponse struct {
// Accepted is true when the control event was validated, scope-checked,
// and enqueued on the run's steering inbox. A false Accepted is never
// returned — a rejected control surfaces as a *protocol.Error from
// Dispatch, not an Accepted=false response.
Accepted bool `json:"accepted"`
// Method echoes the Protocol method name the control was submitted
// under (`cancel`, `pause`, …) so a client correlating async
// responses can match them up.
Method string `json:"method"`
// ProtocolVersion echoes the Protocol version the Runtime answered
// under so a client can detect a version skew.
ProtocolVersion string `json:"protocol_version"`
}
ControlResponse is the wire response shared by the nine steering-control Protocol methods. It is a minimal acknowledgement: the control was validated, scope-checked, and enqueued on the run's inbox. The control's *effect* on the run (the redirected goal taking hold, the pause blocking the loop, the approval advancing it) is observed via the canonical event stream (`control.received` / `control.applied`), NOT synchronously in this response — a richer synchronous response would couple the Protocol edge to the run loop's step timing.
type Deprecation ¶
type Deprecation struct {
// Subject names the Protocol element being deprecated — the method
// name, error code, `Type.Field` wire-field path, or capability
// string, depending on Kind.
Subject string `json:"subject"`
// Kind classifies what Subject is — one of the DeprecationKind
// constants.
Kind DeprecationKind `json:"kind"`
// DeprecatedIn is the Protocol version (a MAJOR.MINOR.PATCH string)
// in which Subject was first marked deprecated.
DeprecatedIn string `json:"deprecated_in"`
// RemovedIn is the Protocol version in which Subject is removed. It
// MUST sort strictly after DeprecatedIn — the span between the two
// is the deprecation window.
RemovedIn string `json:"removed_in"`
// Replacement names the Protocol element callers should migrate to.
// Optional — a deprecation with no replacement is a pure removal.
Replacement string `json:"replacement,omitempty"`
// Note is an optional human-readable migration hint.
Note string `json:"note,omitempty"`
}
Deprecation is the settled structured note format for a breaking Protocol change's removal window. RFC §5.3: "Breaking changes require a deprecation window so third-party Consoles aren't whipsawed." A deprecated Protocol element carries its window in this shape — a structured, machine-readable record — rather than a free-text code comment, so a Protocol client (or a `harbor version` subcommand, the CLI) can surface "this method is going away in 0.3.0, use X instead" mechanically.
Deprecation is a wire type — it round-trips through JSON so the negotiation surface can hand the active set to a client.
func Deprecations ¶
func Deprecations() []Deprecation
Deprecations returns a copy of the active Protocol deprecation registry, sorted deterministically by RemovedIn version then Subject. The slice is a copy — a caller cannot mutate the registry through the return value. At Protocol 0.1.0 the registry is empty.
func (Deprecation) String ¶
func (d Deprecation) String() string
String renders the settled human-readable deprecation note format:
<kind> "<subject>" is deprecated in <deprecated_in>, removed in <removed_in>[; use <replacement>][ — <note>]
This is the canonical phrasing a Protocol client / CLI surfaces to a human operator.
func (Deprecation) Validate ¶
func (d Deprecation) Validate() error
Validate reports whether the Deprecation is well-formed: a non-empty Subject, a recognised Kind, parseable DeprecatedIn / RemovedIn versions, and a RemovedIn that sorts strictly after DeprecatedIn (an empty or inverted window is a malformed deprecation). It fails loudly — a malformed Deprecation in the registry is a bug, not a silently-tolerated entry.
type DeprecationKind ¶
type DeprecationKind string
DeprecationKind classifies which Protocol element a Deprecation applies to. It is a fixed string enum — the four kinds of element the versioned Protocol surface exposes (RFC §5.2, §5.3) — not a registration seam.
const ( // DeprecationMethod — a Protocol method name (internal/protocol/ // methods) is being retired. DeprecationMethod DeprecationKind = "method" // DeprecationErrorCode — a Protocol error code (internal/protocol/ // errors) is being retired. DeprecationErrorCode DeprecationKind = "error_code" // DeprecationWireField — a field on a Protocol wire type // (internal/protocol/types) is being retired. DeprecationWireField DeprecationKind = "wire_field" // DeprecationCapability — a Protocol Capability is being retired. DeprecationCapability DeprecationKind = "capability" )
The four kinds of Protocol element a Deprecation can apply to.
type EventAggregateRequest ¶
type EventAggregateRequest struct {
// Identity is the (tenant, user, session) scope envelope every
// Protocol client carries on the body. The aggregate handler pulls
// the authoritative identity from the JWT / X-Harbor-* edge headers
// (RFC §5.5) — this field is shape-only, declared so the body
// decode's `DisallowUnknownFields` accepts the Console's standard
// payload shape (`Transport.request` auto-injects `identity` on
// every request body). Optional in the wire schema; ignored by the
// handler. Before this field existed it was the only typed request
// shape on the Console-facing surface that REFUSED the identity
// envelope, breaking every Events page `events.aggregate` call
// cross-origin.
Identity IdentityScope `json:"identity,omitempty"`
// Filter narrows the events the aggregator counts. The empty filter
// (zero EventFilter) is interpreted as "every event in the caller's
// own identity tuple" (per the EventFilter godoc).
Filter EventFilter `json:"filter"`
// Window is the inclusive lookback span. Must be > 0. The response
// covers [Now-Window, Now) where Now is the runtime's clock at
// handler entry.
Window time.Duration `json:"window"`
// Bucket is the per-bucket width. Must be > 0 and must evenly
// divide Window (Window % Bucket == 0) — a non-dividing pair is
// rejected with `CodeInvalidRequest` so the response's bucket count
// is deterministic and a rendering client never sees a fractional
// trailing bucket.
Bucket time.Duration `json:"bucket"`
// Anchor is the OPTIONAL origin of the bucket grid. When nil (the
// default), the grid is anchored at the effective Now — the
// response covers [Now-Window, Now) and a `bucket_start` is NOT
// addressable twice (two calls at two instants return two boundary
// sets). When set, bucket boundaries are floored onto the fixed grid
// `Anchor + k·Bucket`: the response still covers a `Window`'s worth
// of buckets, but aligned to that grid, so two calls at two instants
// with the SAME Anchor + Window + Bucket share boundary instants — a
// `bucket_start` is a stable coordinate a consumer can cache and
// re-request, INCLUDING across a runtime restart and across two
// fleet runtimes (the boundary is a pure function of Anchor+Bucket,
// with no residual dependence on Now). Passing the Unix epoch
// (`1970-01-01T00:00:00Z`) yields a globally-shared grid.
//
// It is a POINTER (not a `time.Time` value) because `omitempty` is a
// no-op on a struct — a value type would always serialize the zero
// time and break the additive/optional contract and its TS mirror.
//
// Grid-edge note: with an Anchor, the LAST bucket's `bucket_end` is
// the grid boundary that covers Now — it is generally AFTER Now (by
// up to one Bucket width), not equal to it. A rendering client must
// therefore not treat the final bucket as "up to this instant"; the
// grid re-phases the boundaries and never widens the read span by
// more than one Bucket at either edge. UTC.
Anchor *time.Time `json:"anchor,omitempty"`
// ByTenant opts IN to per-tenant attribution on each bucket
// (EventBucket.CountsByTenant). It is HONOURED ONLY on an
// admin-widened read (a verified `admin` / `console:fleet` cross-
// principal-or-multi-value fan-in, derived server-side); on any other
// read it is IGNORED and the response is byte-identical to a request
// that never set it (fail-closed — the body flag never elevates a
// read, and never widens what is counted).
//
// When honoured, each bucket carries CountsByTenant re-projecting that
// bucket's Counts by the counted events' existing tenant identity, so
// the widened caller can independently verify the tenant boundary the
// runtime enforced (the attribution keys must be a subset of the
// tenants it asked for, and they must sum back to the totals). It adds
// NO new identity axis and NO payload — a count per `(tenant,
// event_type)` is the whole surface. Absent/false ⇒ no attribution.
ByTenant bool `json:"by_tenant,omitempty"`
}
EventAggregateRequest is the wire request for the `events.aggregate` Protocol method. It returns a deterministic time series of event-type counts over `Window`, bucketed by `Bucket`. By default the window is anchored at the request's effective `Now` (the runtime's clock at handler entry) — the response slice runs [Now-Window, Now) bucketed at `Bucket` width. When the optional `Anchor` is set, the grid is instead floored onto `Anchor + k·Bucket` (see the field), so a `bucket_start` becomes a stable, addressable coordinate.
The request body's `filter` is the EventFilter above; the same identity-scope rules apply (a cross-tenant aggregate is gated on the `auth.ScopeAdmin` OR `auth.ScopeConsoleFleet` claim per the closed admin-scope set).
type EventAggregateResponse ¶
type EventAggregateResponse struct {
// Buckets is the per-bucket count series, oldest first. Each
// bucket's [Start, End) span is exactly `Request.Bucket` wide. When
// the request carried no `Anchor`, the last bucket's End equals the
// request's effective Now; when it carried an `Anchor`, the last
// bucket's End is the grid boundary covering Now (generally AFTER
// Now, by up to one Bucket — see EventAggregateRequest.Anchor).
Buckets []EventBucket `json:"buckets"`
// Truncated is true when the counts are PARTIAL: the aggregation could
// not observe every matching event in the window. It is set UNIFORMLY
// across drivers — a best-effort ring that has evicted matching events
// (older matches may be lost) sets it, and a durable log whose window held more
// matching events than the single-read aggregation bound could count
// sets it too. It is the honest DATA signal that a driver difference
// (retention depth, an observed horizon) changed WHAT the method
// returns without ever changing WHETHER it works: an over-wide window is
// never a request error and never a silent undercount — it is partial
// buckets flagged truncated. False means the counts are complete for the
// window.
Truncated bool `json:"truncated,omitempty"`
// ProtocolVersion echoes the Protocol version the Runtime answered
// under so a client can detect a version skew (mirrors the
// ControlResponse / StartResponse shape).
ProtocolVersion string `json:"protocol_version"`
}
EventAggregateResponse is the wire response for the `events.aggregate` Protocol method. Buckets are in chronological order (oldest first); `len(Buckets) == Window/Bucket`.
type EventBucket ¶
type EventBucket struct {
// Start is the bucket's lower bound (inclusive). UTC. The JSON tag
// is namespaced (bucket_start rather than start) so the wire
// surface does not collide with the task-control method
// name start — the single-source grep backstop is
// substring-shaped (it does not parse struct tags) and a bare
// start tag would false-positive against it.
Start time.Time `json:"bucket_start"`
// End is the bucket's upper bound (exclusive). UTC. End - Start ==
// the request's `Bucket` width.
End time.Time `json:"bucket_end"`
// Counts maps event-type string → count of events in this bucket.
// An empty map means "no matching events in this window slice" —
// the bucket is still present so the rendering client sees the gap.
Counts map[string]int64 `json:"counts"`
// CountsByTenant is the OPTIONAL per-tenant attribution of this
// bucket's Counts: tenant → event-type → count. It is present ONLY
// when the request set ByTenant AND the read was admin-widened (a
// verified `admin` / `console:fleet` fan-in, derived server-side —
// never from the request body). Absent (nil, omitted) on every other
// read, so a caller that does not opt in sees a byte-identical
// response.
//
// It is a pure re-projection of the SAME counted events by their
// existing tenant identity — no new data path, no new identity axis.
// The keys are a SUBSET of the authorized (named-or-folded)
// Filter.TenantIDs; Counts (the totals) and CountsByTenant are scoped
// to the IDENTICAL authorized filter by construction (one pass over
// the same matched events), so per bucket
// `Σ_tenant CountsByTenant[tenant][type] == Counts[type]`. That
// reconciliation is what makes the tenant boundary independently
// verifiable on an aggregate the way it already is on a row read
// (every row carries its own tenant): the widened caller can check the
// attribution keys against the entitled set it asked for.
//
// Empty buckets (no matching events) omit the field even under an
// attribution request — there is nothing to attribute.
CountsByTenant map[string]map[string]int64 `json:"counts_by_tenant,omitempty"`
}
EventBucket is a single time-bucketed count series — one stripe of the per-event-type stacked-area sparkline the Events page renders. Start (inclusive) and End (exclusive) are UTC; Counts is keyed by event-type string.
Bucket boundaries are computed deterministically by the aggregator: for a request whose window is W and bucket size is B (B divides W), the response carries exactly ceil(W/B) buckets, each spanning [Start, Start+B). Empty buckets are present (with an empty Counts map) so a rendering client can scan a contiguous time axis without gap arithmetic.
type EventFilter ¶
type EventFilter struct {
// EventTypes narrows to events whose `Type` is in the set. Empty
// matches every type (today's `events.subscribe` default). The
// strings are the registered `events.EventType` values
// (`tool.failed`, `planner.repair_exhausted`, etc.).
EventTypes []string `json:"event_types,omitempty"`
// TenantIDs / UserIDs / SessionIDs / RunIDs narrow to events whose
// identity tuple matches one of the supplied values. Empty on any
// axis is interpreted as "the caller's own component"; >1 on the
// tenant axis (or a single tenant other than the caller's) requires
// `auth.ScopeAdmin` OR `auth.ScopeConsoleFleet` per the closed admin-scope set.
TenantIDs []string `json:"tenant_ids,omitempty"`
UserIDs []string `json:"user_ids,omitempty"`
SessionIDs []string `json:"session_ids,omitempty"`
RunIDs []string `json:"run_ids,omitempty"`
// Since is the optional lower bound (inclusive) on `OccurredAt`.
// Zero means "unbounded on the lower side." UTC.
Since time.Time `json:"since,omitempty"`
// Until is the optional upper bound (exclusive) on `OccurredAt`.
// Zero means "unbounded on the upper side." UTC.
Until time.Time `json:"until,omitempty"`
}
EventFilter is the canonical wire predicate every events.* Protocol method consumes — `events.subscribe` for live subscriptions and `events.aggregate` for time-bucketed count series. The shape is identity-scope-aware: cross-tenant filters (TenantIDs with more than one entry, or a tenant other than the caller's) require the `auth.ScopeAdmin` OR `auth.ScopeConsoleFleet` claim per the closed admin-scope set — there is NO dedicated `events.crosstenant` scope (the closed two-scope set is the wire posture).
Identity is mandatory. An EventFilter with empty UserIDs / SessionIDs is interpreted as "the caller's own identity tuple" — the wire edge resolves the missing components from the caller's identity quadruple. A filter that elides the triple WITHOUT a scope claim is rejected loudly at the wire edge with `CodeIdentityRequired`; one that names multiple tenants WITHOUT a scope claim is rejected with `CodeIdentityScopeRequired` (HTTP 403).
Heavy payloads (RFC §6.5): the filter operates on event HEADER fields only (type, identity, timestamp). Predicates over event payload bytes would force the runtime to materialise heavy payloads through the LLM-edge safety net — explicitly out of scope per the design §CC-4 (substring payload search is post-V1).
Since / Until are UTC; the empty zero-value means "unbounded on that side." A non-zero Until that precedes Since is a structurally-invalid filter (`CodeInvalidRequest`).
type EventsListRequest ¶ added in v1.13.0
type EventsListRequest struct {
// Identity is the (tenant, user, session) scope envelope every
// Protocol client carries on the body. The handler pulls the
// authoritative identity from the JWT / X-Harbor-* edge headers
// (RFC §5.5) — this field is shape-only, declared so the body decode's
// `DisallowUnknownFields` accepts the Console's standard payload shape
// (`Transport.request` auto-injects `identity` on every request body).
// Optional in the wire schema; ignored by the handler.
Identity IdentityScope `json:"identity,omitempty"`
// Filter narrows the events returned. The empty filter (zero
// EventFilter) is interpreted as "every event in the caller's own
// identity tuple" (per the EventFilter godoc). A cross-tenant filter
// (a tenant other than the caller's, or multiple tenants) requires the
// verified `admin` OR `console:fleet` claim per the closed admin-scope
// set; scope is derived server-side, never from this body.
Filter EventFilter `json:"filter"`
// Cursor is the exclusive upper sequence bound (the scroll-up cursor):
// only events with Sequence < Cursor are returned. Zero means "from the
// tail" (the newest retained events). To scroll one page older, pass the
// prior response's NextCursor back here.
Cursor uint64 `json:"cursor,omitempty"`
// Limit is the page size K (clamped to MaxEventsListLimit;
// zero ⇒ DefaultEventsListLimit).
Limit int `json:"limit,omitempty"`
}
EventsListRequest is the wire request for the `events.list` Protocol method — the durable, time-ranged, cross-session raw-event read. It reuses the EventFilter above (identity axes + since/until time bounds + event-type selector) plus a tail-first, sequence-based paging cursor mirroring `state.history`'s grammar. Unlike `state.history` (by-id, single session) it honours the filter's multi-valued identity sets and, under a verified `admin` or `console:fleet` claim, fans in across sessions in global-sequence order. The rows returned are the SAME flat StateEvent projection `state.history` and the SSE stream carry — no new row shape, no redaction change, no heavy-payload inlining.
type EventsListResponse ¶ added in v1.13.0
type EventsListResponse struct {
// Events is the page's events, oldest-first within the window.
Events []StateEvent `json:"events"`
// NextCursor is the lowest Sequence in this page — the value to pass
// back as Cursor to scroll one page older. Zero when the retained head
// is reached (no older events).
NextCursor uint64 `json:"next_cursor"`
// HasMore reports whether older matching events remain before the
// page's oldest event.
HasMore bool `json:"has_more"`
// Truncated is true when the substrate's oldest retained row sits above
// the true first matching event (a best-effort ring evicted older
// events) — the honest gap signal, never a silent drop. False on the
// gap-free durable log.
Truncated bool `json:"truncated,omitempty"`
}
EventsListResponse is the `events.list` reply: a bounded page of flat events oldest-first within the window, plus a scroll-up cursor and the honest retention-gap signal. Row shape is byte-identical to `state.history`'s StateEvent projection.
type Flow ¶
type Flow struct {
// ID is the flow's stable identifier — the registered flow name.
ID string `json:"id"`
// Name is the operator-facing display name. Equal to ID at V1; the
// field exists so a future rename surface does not break the wire.
Name string `json:"name"`
// Owner is the flow's declared owner (the agent / team that
// registered it). Empty when the registration carried no owner.
Owner string `json:"owner,omitempty"`
// Version is the flow's version string. Empty when unversioned.
Version string `json:"version,omitempty"`
// PlannerFamily is the graph-family planner the flow runs on —
// "graph" / "workflow" / "deterministic". The catalog is filtered
// to graph-family planners.
PlannerFamily string `json:"planner_family,omitempty"`
// NodeCount is the number of nodes in the flow's engine graph.
NodeCount int `json:"node_count"`
// EdgeCount is the number of directed edges in the flow's graph.
EdgeCount int `json:"edge_count"`
// Runs24h is the count of invocations in the trailing 24h window
// scoped to the caller's identity (admin fans across tenants).
Runs24h int64 `json:"runs_24h"`
// P50LatencyMS is the median run latency over the window, in ms.
P50LatencyMS int64 `json:"p50_latency_ms"`
// P95LatencyMS is the 95th-percentile run latency over the window.
P95LatencyMS int64 `json:"p95_latency_ms"`
// SuccessRate is the fraction of runs in the window that succeeded,
// in [0,1].
SuccessRate float64 `json:"success_rate"`
// LastRun is the wall-clock time of the most recent invocation. The
// zero value (omitted) means the flow has never run.
LastRun time.Time `json:"last_run,omitempty"`
// Budget is the flow's per-flow Budget. Read-only at V1.
Budget FlowBudget `json:"budget"`
}
Flow is one row of the `flows.list` catalog: a registered engine-graph flow with its aggregate run metrics over the active window. A "flow" in the Console is exactly an engine node graph a graph-family planner runs on; this row is the catalog lens over it.
type FlowArtifactRef ¶
type FlowArtifactRef struct {
// ID is the content-addressed identifier.
ID string `json:"id"`
// MimeType is the IANA media type, when known.
MimeType string `json:"mime_type,omitempty"`
// SizeBytes is the length of the referenced bytes.
SizeBytes int64 `json:"size_bytes,omitempty"`
// Filename is metadata only (never used for path construction).
Filename string `json:"filename,omitempty"`
// SHA256 is the full hex digest of the referenced bytes.
SHA256 string `json:"sha256,omitempty"`
}
FlowArtifactRef is the by-reference shape a `FlowRunDescription` carries when a run's final output meets or exceeds the configured heavy-content threshold. It mirrors a subset of `internal/artifacts.ArtifactRef` but is a flat wire type, kept distinct from `PauseArtifactRef` / `SearchArtifactRef` so a future divergence in either surface does not whipsaw the other.
type FlowBudget ¶
type FlowBudget struct {
// DeadlineMS is the flow's wall-clock deadline in milliseconds. Zero
// means "no deadline cap".
DeadlineMS int64 `json:"deadline_ms,omitempty"`
// RequestCap is the flow's hop budget — the maximum number of node
// hops a single invocation may take. Zero means "no hop cap".
RequestCap int `json:"request_cap,omitempty"`
// CostCapUSD is the flow's aggregate cost cap in US dollars. Zero
// means "no cost cap".
CostCapUSD float64 `json:"cost_cap_usd,omitempty"`
// TokenCap is the flow's aggregate token cap. Zero means "no token
// cap". The token cap is a post-V1 axis on the runtime `Budget`;
// the field exists on the wire so the Budget meter can render it
// without a wire-shape break when the axis lands.
TokenCap int64 `json:"token_cap,omitempty"`
}
FlowBudget is the wire projection of a flow's per-flow Budget (the Flow-as-Tool registration). It mirrors the three caps a flow's aggregate `Budget` enforces at the flow boundary: a wall-clock deadline, a hop (request) cap, and a cost cap. It is a flat wire type — the Protocol owns its vocabulary; the runtime `flow.Budget` struct never leaks. Edit of the Budget is `flows.set_budget` — post-V1 per page-flows.md §10; at V1 the Budget is read-only.
type FlowBudgetConsumption ¶
type FlowBudgetConsumption struct {
// RequestsUsed is the hop count consumed in the active window.
RequestsUsed int `json:"requests_used"`
// CostUSDUsed is the cost consumed in the active window.
CostUSDUsed float64 `json:"cost_usd_used"`
// TokensUsed is the token count consumed in the active window.
TokensUsed int64 `json:"tokens_used"`
}
FlowBudgetConsumption is the live consumption of a flow's Budget vs. its caps, derived from the flow's run history within the active window. It is the data the Budget meter (right rail) renders as progress bars. Consumption is observation-only — there is no edit surface at V1.
type FlowDescribeRequest ¶
type FlowDescribeRequest struct {
// Identity is the mandatory caller identity scope.
Identity IdentityScope `json:"identity"`
// ID is the flow to describe. An unknown id fails with CodeNotFound.
ID string `json:"id"`
}
FlowDescribeRequest is the wire request for `flows.describe`.
type FlowDescription ¶
type FlowDescription struct {
// Flow is the catalog row for the described flow.
Flow Flow `json:"flow"`
// Nodes is the flow's node set, sorted lexicographically by ID.
Nodes []FlowNode `json:"nodes"`
// Edges is the flow's directed edge set, sorted by (From, To).
Edges []FlowEdge `json:"edges"`
// Source is the source-of-truth reference — a Go path or YAML
// descriptor path. A string reference, never executable code.
Source string `json:"source,omitempty"`
// BudgetConsumption is the flow's live Budget consumption over the
// active window — the data the Budget meter renders.
BudgetConsumption FlowBudgetConsumption `json:"budget_consumption"`
}
FlowDescription is the wire projection of a flow's full engine-graph description — the `flows.describe` payload. It carries the catalog row plus the node / edge set plus a string source reference. The source reference is a Go path or a YAML descriptor path (Go- coded V1; declarative YAML in V1.1) — it is NEVER executable code in the Console.
type FlowEdge ¶
type FlowEdge struct {
// From is the upstream node's ID.
From string `json:"from"`
// To is the downstream node's ID.
To string `json:"to"`
}
FlowEdge is one directed edge of a flow's projected engine graph.
type FlowFilter ¶
type FlowFilter struct {
// Tenants restricts the catalog to the named tenants. Empty means
// "the caller's own tenant". A value reaching outside the caller's
// tenant requires the admin scope claim.
Tenants []string `json:"tenants,omitempty"`
// PlannerFamilies restricts the catalog to the named planner
// families. Empty means "all graph-family planners".
PlannerFamilies []string `json:"planner_families,omitempty"`
// Query is a free-text substring match over the flow name / owner.
// Empty means "no text filter".
Query string `json:"query,omitempty"`
}
FlowFilter narrows the `flows.list` catalog. An empty filter means "the caller's own identity scope". Supplying a `Tenants` value that reaches OUTSIDE the caller's own tenant (or naming more than one tenant) requires the `auth.ScopeAdmin` scope claim; a missing-claim cross-tenant request is rejected loudly with CodeIdentityScopeRequired (HTTP 403) — never silently downgraded.
type FlowListRequest ¶
type FlowListRequest struct {
// Identity is the mandatory caller identity scope. An incomplete
// triple fails the request closed with CodeIdentityRequired.
Identity IdentityScope `json:"identity"`
// Filter narrows the catalog. The zero value lists the caller's
// own-tenant flows.
Filter FlowFilter `json:"filter"`
// Page is the 1-based page index. Zero is treated as page 1.
Page int `json:"page,omitempty"`
// PageSize is the per-page row count. Zero applies
// DefaultFlowListPageSize; a value above MaxFlowListPageSize is
// rejected with CodeInvalidRequest.
PageSize int `json:"page_size,omitempty"`
}
FlowListRequest is the wire request for `flows.list`.
type FlowListResponse ¶
type FlowListResponse struct {
// Flows is the catalog page, sorted lexicographically by ID for
// byte-stability across requests.
Flows []Flow `json:"flows"`
// Page is the 1-based page index this response covers.
Page int `json:"page"`
// PageSize is the per-page row count applied.
PageSize int `json:"page_size"`
// PageCount is the total number of pages for the filtered set.
PageCount int `json:"page_count"`
// TotalRows is the total number of catalog rows the filter matched
// before pagination.
TotalRows int `json:"total_rows"`
}
FlowListResponse is the wire response for `flows.list`.
type FlowMetrics ¶
type FlowMetrics struct {
// FlowID is the flow these metrics describe.
FlowID string `json:"flow_id"`
// WindowStart is the wall-clock start of the aggregation window.
WindowStart time.Time `json:"window_start"`
// WindowEnd is the wall-clock end of the aggregation window.
WindowEnd time.Time `json:"window_end"`
// Buckets are the time-bucketed aggregates, oldest first.
Buckets []FlowMetricsBucket `json:"buckets"`
// BudgetConsumption is the flow's live Budget consumption over the
// window — the data the budget sparkline renders.
BudgetConsumption FlowBudgetConsumption `json:"budget_consumption"`
}
FlowMetrics is the wire projection of a flow's sparkline aggregates — the `flows.metrics` payload. The buckets feed the Flow Metrics card (runs-per-hour, p95 latency, success rate, budget consumption).
type FlowMetricsBucket ¶
type FlowMetricsBucket struct {
// BucketStart is the wall-clock start of the bucket.
BucketStart time.Time `json:"bucket_start"`
// Runs is the count of runs that started within the bucket.
Runs int64 `json:"runs"`
// P95LatencyMS is the 95th-percentile run latency within the bucket.
P95LatencyMS int64 `json:"p95_latency_ms"`
// SuccessRate is the fraction of bucketed runs that succeeded.
SuccessRate float64 `json:"success_rate"`
// CostUSD is the total cost recorded within the bucket.
CostUSD float64 `json:"cost_usd"`
}
FlowMetricsBucket is one time bucket of a flow's sparkline metrics.
type FlowMetricsRequest ¶
type FlowMetricsRequest struct {
// Identity is the mandatory caller identity scope.
Identity IdentityScope `json:"identity"`
// FlowID is the flow whose metrics to aggregate. An empty FlowID
// fails with CodeInvalidRequest.
FlowID string `json:"flow_id"`
// WindowMS is the aggregation window in milliseconds. Zero applies
// the default 24h window.
WindowMS int64 `json:"window_ms,omitempty"`
// BucketMS is the bucket width in milliseconds. Zero applies the
// default 1h bucket.
BucketMS int64 `json:"bucket_ms,omitempty"`
}
FlowMetricsRequest is the wire request for `flows.metrics`.
type FlowNode ¶
type FlowNode struct {
// ID is the node's unique identifier within the flow.
ID string `json:"id"`
// Type is the node's role tag — subflow / tool / pause /
// artifact_emitter.
Type FlowNodeKind `json:"type"`
// Descriptor is a schema reference for the node — the tool name for
// a tool node, the nested flow id for a subflow node. It is a string
// reference, never executable code.
Descriptor string `json:"descriptor,omitempty"`
// Policy is the node's per-node policy. Nil when the node carries
// the engine default policy.
Policy *FlowNodePolicy `json:"policy,omitempty"`
}
FlowNode is one vertex of a flow's projected engine graph.
type FlowNodeKind ¶
type FlowNodeKind string
FlowNodeKind tags a node's role in the flow's engine graph. The V1 set is closed — a node is a subflow, a tool invocation, a pause point, or an artifact emitter.
const ( // FlowNodeSubflow tags a node that runs a nested flow. FlowNodeSubflow FlowNodeKind = "subflow" // FlowNodeTool tags a node that invokes a registered Tool. FlowNodeTool FlowNodeKind = "tool" // FlowNodePause tags a node that parks the run at a pause point. // The wire value is the two-word form pause_point — deliberately // distinct from the Protocol method-name vocabulary so the // single-source checker never flags this enum value. FlowNodePause FlowNodeKind = "pause_point" // FlowNodeArtifactEmitter tags a node that emits an artifact. FlowNodeArtifactEmitter FlowNodeKind = "artifact_emitter" )
The V1 flow-node-kind constants.
type FlowNodePolicy ¶
type FlowNodePolicy struct {
// MaxRetries is the per-node retry ceiling.
MaxRetries int `json:"max_retries,omitempty"`
// TimeoutMS is the per-node wall-clock timeout in milliseconds.
TimeoutMS int64 `json:"timeout_ms,omitempty"`
}
FlowNodePolicy is the wire projection of a node's per-node policy (the runtime `engine.NodePolicy` — retry / timeout). It is a flat wire type; the runtime struct never leaks.
type FlowNodeRunState ¶
type FlowNodeRunState struct {
// NodeID is the node's identifier within the flow.
NodeID string `json:"node_id"`
// Status is the node's outcome within the run.
Status FlowRunStatus `json:"status"`
// DurationMS is the node's wall-clock duration in milliseconds.
DurationMS int64 `json:"duration_ms,omitempty"`
// Retries is the number of times the node was retried.
Retries int `json:"retries,omitempty"`
// ErrorClass is a short classification of a node failure. Empty for
// a non-failed node.
ErrorClass string `json:"error_class,omitempty"`
}
FlowNodeRunState is one node's slice of a run's per-node timeline.
type FlowRun ¶
type FlowRun struct {
// RunID is the run's stable identifier.
RunID string `json:"run_id"`
// FlowID is the flow this run executed.
FlowID string `json:"flow_id"`
// Status is the run's outcome.
Status FlowRunStatus `json:"status"`
// Trigger is what initiated the run.
Trigger FlowRunTrigger `json:"trigger"`
// StartedAt is the wall-clock time the run started.
StartedAt time.Time `json:"started_at"`
// DurationMS is the run's wall-clock duration in milliseconds. Zero
// for a run still in flight.
DurationMS int64 `json:"duration_ms,omitempty"`
// CostUSD is the run's recorded cost in US dollars.
CostUSD float64 `json:"cost_usd,omitempty"`
// Identity is the (tenant, user, session) the run executed under.
Identity IdentityScope `json:"identity"`
// ErrorClass is a short classification of the failure for a failed
// run. Empty for a non-failed run.
ErrorClass string `json:"error_class,omitempty"`
}
FlowRun is one row of the `flows.runs.list` history: a single invocation of a flow with timing + outcome.
type FlowRunDescribeRequest ¶
type FlowRunDescribeRequest struct {
// Identity is the mandatory caller identity scope.
Identity IdentityScope `json:"identity"`
// RunID is the run to describe. An unknown id fails with
// CodeNotFound.
RunID string `json:"run_id"`
}
FlowRunDescribeRequest is the wire request for `flows.runs.describe`.
type FlowRunDescription ¶
type FlowRunDescription struct {
// Run is the run-history row for the described run.
Run FlowRun `json:"run"`
// NodeStates is the per-node execution timeline, in node order.
NodeStates []FlowNodeRunState `json:"node_states"`
// OutputPreview is the run's final output INLINE when its serialised
// size is below the heavy-content threshold. Empty when the run
// produced no output or when the output was routed by-reference.
OutputPreview string `json:"output_preview,omitempty"`
// OutputRef is populated when the run's final output exceeded the
// heavy-content threshold. The Console fetches the bytes via
// `artifacts.get` when it wants them. When OutputRef is set,
// OutputPreview is empty.
OutputRef *FlowArtifactRef `json:"output_ref,omitempty"`
}
FlowRunDescription is the wire projection of a single flow run's per-node timeline + final-output reference — the `flows.runs.describe` payload. Heavy outputs are shipped by-reference via OutputRef; the description NEVER inlines heavy bytes.
type FlowRunRequest ¶
type FlowRunRequest struct {
// Identity is the mandatory caller identity scope.
Identity IdentityScope `json:"identity"`
// FlowID is the flow to invoke. An empty / unknown id fails with
// CodeInvalidRequest / CodeNotFound.
FlowID string `json:"flow_id"`
// Inputs is the hand-crafted input form for the invocation. The
// runtime validates it against the flow's input schema.
Inputs map[string]any `json:"inputs,omitempty"`
}
FlowRunRequest is the wire request for `flows.run` — a one-shot invocation of a registered flow. `flows.run` is the ONLY mutating Flows-page method; it is gated on identity + the appropriate scope claim.
type FlowRunResponse ¶
type FlowRunResponse struct {
// RunID is the identifier of the accepted run.
RunID string `json:"run_id"`
// Status is the run's status at acceptance — "running" for an
// accepted run.
Status FlowRunStatus `json:"status"`
// StartedAt is the wall-clock time the run started.
StartedAt time.Time `json:"started_at"`
}
FlowRunResponse is the wire response for `flows.run` — the accepted run's identifier so the Console can drill into the run as it progresses.
type FlowRunStatus ¶
type FlowRunStatus string
FlowRunStatus is the typed enum of flow-run outcomes. The V1 set is closed — a run is still running, succeeded, failed, or was cancelled.
const ( // FlowRunRunning tags a run still in flight. FlowRunRunning FlowRunStatus = "running" // FlowRunSucceeded tags a run that completed without error. FlowRunSucceeded FlowRunStatus = "succeeded" // FlowRunFailed tags a run that terminated with an error. FlowRunFailed FlowRunStatus = "failed" // FlowRunCancelled tags a run that was cancelled before completion. FlowRunCancelled FlowRunStatus = "cancelled" )
The V1 flow-run-status constants.
type FlowRunTrigger ¶
type FlowRunTrigger string
FlowRunTrigger tags what initiated a flow run.
const ( // FlowTriggerUser tags a run initiated by an operator via // `flows.run`. FlowTriggerUser FlowRunTrigger = "user" // FlowTriggerPlanner tags a run initiated by a planner step. FlowTriggerPlanner FlowRunTrigger = "planner" // FlowTriggerSystem tags a run initiated by the runtime itself. FlowTriggerSystem FlowRunTrigger = "system" )
The V1 flow-run-trigger constants.
type FlowRunsListRequest ¶
type FlowRunsListRequest struct {
// Identity is the mandatory caller identity scope.
Identity IdentityScope `json:"identity"`
// FlowID is the flow whose run history to list. An empty FlowID
// fails with CodeInvalidRequest.
FlowID string `json:"flow_id"`
// Tenants restricts the history to the named tenants. Empty means
// "the caller's own tenant". A value reaching outside the caller's
// tenant requires the admin scope claim.
Tenants []string `json:"tenants,omitempty"`
// Page is the 1-based page index. Zero is treated as page 1.
Page int `json:"page,omitempty"`
// PageSize is the per-page row count. Zero applies
// DefaultFlowListPageSize.
PageSize int `json:"page_size,omitempty"`
// Since is an optional lower bound on a run's StartedAt (zero =
// unbounded). The bound is INCLUSIVE: a run whose StartedAt equals
// Since is retained. It mirrors TaskFilter.Since/Until exactly — same
// field shape AND same inclusive boundary semantics — so every list
// method behaves identically on a time boundary. Absent ⇒ unbounded
// (zero behaviour change for existing callers). Bounds apply on the
// server, BEFORE pagination — the page counts reflect the bounded
// set, never a client-side walk-and-filter.
Since time.Time `json:"since,omitempty"`
// Until is an optional upper bound on a run's StartedAt (zero =
// unbounded). The bound is INCLUSIVE: a run whose StartedAt equals
// Until is retained, matching TaskFilter.Until and the sessions
// started-window (a closed window [Since, Until]). A request whose
// Until precedes its Since fails CodeInvalidRequest (the same
// validation posture the task-list filter holds). Absent ⇒ unbounded.
Until time.Time `json:"until,omitempty"`
}
FlowRunsListRequest is the wire request for `flows.runs.list`.
type FlowRunsListResponse ¶
type FlowRunsListResponse struct {
// Runs is the run-history page, sorted by StartedAt descending
// (newest first).
Runs []FlowRun `json:"runs"`
// Page is the 1-based page index this response covers.
Page int `json:"page"`
// PageSize is the per-page row count applied.
PageSize int `json:"page_size"`
// PageCount is the total number of pages.
PageCount int `json:"page_count"`
// TotalRows is the total number of run rows the filter matched.
TotalRows int `json:"total_rows"`
}
FlowRunsListResponse is the wire response for `flows.runs.list`.
type GovernanceGetTenantOverridesRequest ¶ added in v1.5.0
type GovernanceGetTenantOverridesRequest struct {
// Identity is the request's identity scope. The triple is mandatory;
// the admin scope is required (reading a tenant's control-plane
// defaults is a privileged action).
Identity IdentityScope `json:"identity"`
}
GovernanceGetTenantOverridesRequest is the wire request for the admin-scoped `governance.get_tenant_overrides` method.
type GovernanceGetTenantOverridesResponse ¶ added in v1.5.0
type GovernanceGetTenantOverridesResponse struct {
// Overrides is the tenant's current default-override record. When no
// record exists (Set is false) every field is nil.
Overrides GovernanceTenantOverrides `json:"overrides"`
// Set reports whether a tenant-default record exists. False means the
// tenant inherits every runtime config default.
Set bool `json:"set"`
// ProtocolVersion echoes the Protocol version the Runtime answered
// with.
ProtocolVersion string `json:"protocol_version"`
}
GovernanceGetTenantOverridesResponse is the wire response for `governance.get_tenant_overrides`.
type GovernancePostureRequest ¶
type GovernancePostureRequest struct {
// TenantID — empty = the caller's own tenant; non-empty + different
// from the caller's resolved tenant = requires auth.ScopeAdmin.
TenantID string `json:"tenant_id,omitempty"`
}
GovernancePostureRequest is the `governance.posture` request body.
TenantID is forward-looking: an empty value (the default) reads the caller's own tenant — no scope claim required. A non-empty value that differs from the caller's identity-resolved tenant is a cross-tenant read and requires the `auth.ScopeAdmin` scope claim (closed two-scope set). V1 ships a single tenant per Harbor instance, so the cross-tenant path is reachable in code but the value space is a singleton; the field exists so a post-V1 multi-tenant deployment finds the surface ready.
type GovernancePostureResponse ¶
type GovernancePostureResponse struct {
// DefaultTier is the operator-configured default tier name applied
// to an identity that does not match a custom resolver mapping.
// Empty when no tiers are configured.
DefaultTier string `json:"default_tier"`
// ResolvedTier is the tier name the caller's identity resolves to
// via the runtime's configured TierResolver. Empty when no tier
// resolves (latent default).
ResolvedTier string `json:"resolved_tier"`
// IdentityTiers maps tier name → tier configuration (the consolidated
// shape). Always non-nil; an empty map signals no enforcement.
IdentityTiers map[string]IdentityTierView `json:"identity_tiers"`
// ProtocolVersion echoes the Protocol version the Runtime answered
// with — same field every Protocol response carries.
ProtocolVersion string `json:"protocol_version"`
}
GovernancePostureResponse is the `governance.posture` response body — the read-only projection of the runtime's governance configuration.
IdentityTiers is keyed by tier name (e.g. `"free"`, `"team"`, `"enterprise"`). An empty map (the latent-default boot / governance) means no enforcement is configured — the Console renders an explicit "No tiers configured" state, never a blank panel. The map is always non-nil in the wire JSON (`{}`, never `null`).
type GovernanceRotateKeyRequest ¶ added in v1.5.0
type GovernanceRotateKeyRequest struct {
// Identity is the request's identity scope. The triple is mandatory;
// the admin scope is required (rotating a provider credential is a
// privileged action).
Identity IdentityScope `json:"identity"`
// Provider names the provider whose key to rotate. Empty targets the
// runtime's bound provider (the common single-provider case); a value
// other than the bound provider is rejected with CodeInvalidRequest
// (multi-provider rotation is post-V1).
Provider string `json:"provider,omitempty"`
// Key is the new API key value. MANDATORY and a SECRET — it travels
// only on this request leg, is held only in the runtime's atomic key
// holder, and is NEVER logged, audited, or echoed back. An empty Key
// is rejected with CodeInvalidRequest before any swap.
Key string `json:"key"`
}
GovernanceRotateKeyRequest is the wire request for the admin-scoped `governance.rotate_key` method — rotate the LLM provider API key live.
type GovernanceRotateKeyResponse ¶ added in v1.5.0
type GovernanceRotateKeyResponse struct {
// Provider is the provider whose key was rotated.
Provider string `json:"provider"`
// Fingerprint is a non-reversible digest of the new key
// (`sha256:<prefix>`) — correlatable, never the secret.
Fingerprint string `json:"fingerprint"`
// RotatedAt is the runtime timestamp at which the key was swapped. The
// new key is effective immediately (the next call uses it).
RotatedAt time.Time `json:"rotated_at"`
// ProtocolVersion echoes the Protocol version the Runtime answered
// with.
ProtocolVersion string `json:"protocol_version"`
}
GovernanceRotateKeyResponse is the wire response for `governance.rotate_key`. It carries NO key — only the provider, a non-reversible fingerprint of the new key (for audit correlation), and the rotation timestamp.
type GovernanceSetPostureRequest ¶ added in v1.17.0
type GovernanceSetPostureRequest struct {
// DefaultTier is the default-tier assignment applied to an identity
// that resolves to no explicit tier. Required — an empty value is
// rejected when any tier is enforced.
DefaultTier string `json:"default_tier"`
// IdentityTiers is the complete tier table keyed by tier name. A tier
// present in the current effective policy but ABSENT here — or present
// with a zeroed enforced ceiling — is a fail-closed rejection, not a
// silent widening. Always keyed by tier name; the value is the read's
// `IdentityTierView` projection.
IdentityTiers map[string]IdentityTierView `json:"identity_tiers"`
}
GovernanceSetPostureRequest is the `governance.set_posture` request body — the admin-scoped WRITE sibling of `governance.posture`. It carries the WHOLE identity-tier policy table as a FULL REPLACE (never a partial merge) and REUSES the read's `IdentityTierView` + `DefaultTier` shapes.
It carries NO identity / scope field: authority is derived server-side from the verified session, never the request body. The runtime requires the `auth.ScopeAdmin` claim (a non-admin caller — including one bearing only `console:fleet` — is rejected with CodeScopeMismatch, so a leaked read-only fleet token cannot widen a budget). A submitted table that OMITS or zeroes a ceiling the current effective policy enforces is rejected fail-closed with CodeInvalidRequest before any state mutation.
type GovernanceSetPostureResponse ¶ added in v1.17.0
type GovernanceSetPostureResponse struct {
// DefaultTier is the persisted default-tier assignment.
DefaultTier string `json:"default_tier"`
// IdentityTiers is the persisted tier table (the full-replace result).
// Always non-nil in the wire JSON (`{}`, never `null`).
IdentityTiers map[string]IdentityTierView `json:"identity_tiers"`
// EnforcementPendingRestart reports an honest degradation: the policy was
// persisted and will be enforced, but this runtime booted fully latent (no
// config tiers AND no prior record) so it composed no governance wrapper —
// the new policy therefore does NOT enforce until the next restart (which
// seeds a wrapper from the now-persisted record). False on a runtime that
// booted with an active governance wrapper (the common case): the write
// enforces on the next call. Additive field — omitted (false) is the
// enforce-immediately posture.
EnforcementPendingRestart bool `json:"enforcement_pending_restart"`
// ProtocolVersion echoes the Protocol version the Runtime answered
// with, so a Console can assert wire compatibility.
ProtocolVersion string `json:"protocol_version"`
}
GovernanceSetPostureResponse echoes the persisted, resolved posture — it is byte-faithful to what the next `governance.posture` read returns.
type GovernanceSetTenantOverridesRequest ¶ added in v1.5.0
type GovernanceSetTenantOverridesRequest struct {
// Identity is the request's identity scope. The triple is mandatory.
// The runtime requires the admin scope claim and rejects a non-admin
// caller with CodeScopeMismatch.
Identity IdentityScope `json:"identity"`
// Overrides is the desired-state override record (a full REPLACE of
// the tenant's prior record).
Overrides GovernanceTenantOverrides `json:"overrides"`
}
GovernanceSetTenantOverridesRequest is the wire request for the admin-scoped `governance.set_tenant_overrides` method. The override applies to the tenant named on the IdentityScope (the caller's verified tenant); the admin scope claim is required.
type GovernanceSetTenantOverridesResponse ¶ added in v1.5.0
type GovernanceSetTenantOverridesResponse struct {
// AppliedAt is the runtime timestamp at which the tenant default was
// persisted. The new default takes effect on each session's next run.
AppliedAt time.Time `json:"applied_at"`
// ProtocolVersion echoes the Protocol version the Runtime answered
// with, so a Console can assert wire compatibility.
ProtocolVersion string `json:"protocol_version"`
}
GovernanceSetTenantOverridesResponse is the wire response for `governance.set_tenant_overrides`.
type GovernanceTenantOverrides ¶ added in v1.5.0
type GovernanceTenantOverrides struct {
// Model, when non-nil, overrides the default model name. The runtime
// validates it against the configured ModelProfiles at set time and
// rejects an unknown model with CodeInvalidRequest.
Model *string `json:"model,omitempty"`
// ExtraInstructions, when non-nil, is an ADDITIVE block appended to
// the agent's system prompt (rendered into the additional-guidance
// section). It extends the prompt; it never replaces it. nil means
// "no extension."
ExtraInstructions *string `json:"extra_instructions,omitempty"`
// Temperature, when non-nil, overrides the sampling temperature. The
// runtime rejects a value outside the closed range [0, 2] with
// CodeInvalidRequest.
Temperature *float64 `json:"temperature,omitempty"`
// MaxTokens, when non-nil, overrides the per-call token ceiling. The
// runtime rejects a non-positive value with CodeInvalidRequest.
MaxTokens *int `json:"max_tokens,omitempty"`
// ReasoningEffort, when non-nil, overrides the reasoning-effort hint.
// The runtime rejects a value outside {low, medium, high} with
// CodeInvalidRequest.
ReasoningEffort *string `json:"reasoning_effort,omitempty"`
}
GovernanceTenantOverrides is the wire projection of a tenant's default LLM-parameter overrides — an admin-set, no-deploy default applied to every session in the tenant on its NEXT run.
Every field is a pointer so the absent / present distinction is preserved on the wire: a nil field means "the tenant inherits the runtime's configured default for this dimension"; a non-nil field means "use this value." `set_tenant_overrides` is a desired-state REPLACE: the supplied record wholly replaces the tenant's prior record, so a field that was set before and is nil now is cleared.
type HistogramBucket ¶
type HistogramBucket struct {
// UpperBound is the inclusive upper bound of the bucket.
UpperBound float64 `json:"upper_bound"`
// Count is the cumulative observation count at or below
// UpperBound.
Count uint64 `json:"count"`
}
HistogramBucket is one cumulative bucket in a NamedHistogram.
type IdentityScope ¶
type IdentityScope struct {
// Tenant / User / Session are the mandatory isolation triple. An
// empty component fails the request closed at the Protocol edge.
// When impersonation is in use, these fields carry the IMPERSONATED
// identity — the identity the run executes under (matches the
// Impersonating triple component-for-component).
Tenant string `json:"tenant"`
User string `json:"user"`
Session string `json:"session"`
// Run is the per-execution scope inside a session. Mandatory for the
// nine steering-control methods (they target a specific run's inbox);
// optional for `start` (a `start` request mints a new run / task, so
// it carries no pre-existing run id).
Run string `json:"run,omitempty"`
// Scope is the caller's steering scope claim — one of the three
// canonical steering scopes (`session_user` / `owner_user` /
// `admin`). It is trust-based until a later phase Protocol auth, exactly
// as `events.Filter.Admin` is; the ControlSurface enforces the
// per-method scope via the steering CheckScope. Ignored for
// `start` (task creation is not a steering control).
Scope string `json:"scope,omitempty"`
// Actor is the verified admin identity at the request edge — the
// identity whose JWT claim was validated by the middleware.
// V1 invariant: Actor MUST equal the JWT's verified `(tenant, user,
// session)` triple; the transport rejects a body claiming a different
// Actor with CodeScopeMismatch. The Actor's audit trail ("admin X
// impersonated user Y at time T") is what makes impersonation
// accountable.
Actor *IdentityScope `json:"actor,omitempty"`
// Requester is the originating admin identity for delegated
// impersonation chains (e.g. an admin acting on behalf of another
// admin's audited request). At V1: Requester MUST equal Actor; the
// field exists so post-V1 delegated impersonation does not require a
// wire-shape break. The runtime rejects Requester != Actor with
// CodeScopeMismatch.
Requester *IdentityScope `json:"requester,omitempty"`
// Impersonating is the target identity the run executes under. When
// non-empty, MUST carry a complete `(tenant, user, session)` triple —
// identity is mandatory; the impersonated triple is identity too.
// Setting Impersonating gates on auth.ScopeAdmin on the verified JWT;
// a non-admin request with Impersonating set is rejected with
// CodeScopeMismatch before Dispatch runs.
//
// V1 semantics: the top-level Tenant/User/Session fields MUST equal
// the Impersonating triple when impersonation is in use — the run
// executes as the impersonated identity. The Actor field carries the
// audit-visible record of WHO impersonated.
Impersonating *IdentityScope `json:"impersonating,omitempty"`
}
IdentityScope is the flat wire identity a Protocol task-control request carries. It is the wire projection of the runtime's identity quadruple `(tenant, user, session, run)` plus the caller's steering scope claim — flat strings, never a re-export of `identity.Quadruple` (a Protocol type that mapped 1:1 onto an internal Go struct would be the RFC §5.1 reject-on-sight smell). The protocol.ControlSurface translates an IdentityScope into the runtime's `identity.Quadruple` + `steering.Scope` at the edge.
Identity is mandatory (CLAUDE.md §6 rule 9, RFC §5.5: "the Protocol rejects any request without an identity scope"). The ControlSurface fails closed on an incomplete triple — there is no identity-downgrading knob.
admin-impersonation extension. The three optional fields Actor / Requester / Impersonating carry the admin-on-behalf-of-user triplet so an operator with the `auth.ScopeAdmin` claim can steer a run "on behalf of" another `(tenant, user, session)` while every request still carries BOTH the requesting admin's verified identity AND the impersonated identity for audit. An IdentityScope MAY carry zero impersonation fields (today's behaviour, the verified JWT identity IS the request identity) OR all three set (admin acting on behalf of a target user). The runtime rejects any other shape loudly at the Protocol edge — never silently degrades.
func (IdentityScope) IsImpersonating ¶
func (s IdentityScope) IsImpersonating() bool
IsImpersonating reports whether this scope carries a non-empty Impersonating field. The transport edge gates impersonation behaviour off this predicate; downstream code SHOULD use it rather than checking the field directly so a future shape change (e.g. flattening the triplet) lands in one place.
type IdentityTierView ¶
type IdentityTierView struct {
// BudgetCeilingUSD is the per-identity (per tier) cost ceiling in
// USD. 0 = no ceiling.
BudgetCeilingUSD float64 `json:"budget_ceiling_usd"`
// RateLimit is the per-(identity, model) token-bucket configuration.
RateLimit RateLimitView `json:"rate_limit"`
// MaxTokens is the per-call MaxTokens cap. 0 = no enforcement.
MaxTokens int `json:"max_tokens"`
}
IdentityTierView is the wire projection of one governance tier's policy bundle (the `governance.TierConfig` shape). Every field zero = latent for that policy.
type InterventionSummary ¶
type InterventionSummary struct {
// Type is the intervention kind — a HITL pause, a tool-approval
// gate, or a tool-OAuth gate.
Type string `json:"type"`
// Reason is the operator-facing reason the intervention fired.
Reason string `json:"reason"`
// Outcome is the intervention's resolution — pending, resolved,
// approved, or rejected.
Outcome string `json:"outcome"`
// OccurredAt is when the intervention fired.
OccurredAt time.Time `json:"occurred_at"`
}
InterventionSummary is one entry in the right-rail Session Summary's Recent Interventions card. Capped at MaxSessionInterventionSummaries.
type LLMPostureRequest ¶
type LLMPostureRequest struct {
// TenantID — empty = the caller's own tenant; non-empty + different
// from the caller's resolved tenant = requires auth.ScopeAdmin.
TenantID string `json:"tenant_id,omitempty"`
}
LLMPostureRequest is the `llm.posture` request body. The TenantID field has the same forward-looking cross-tenant semantics as GovernancePostureRequest.TenantID — empty reads the caller's own tenant; a non-empty different value requires `auth.ScopeAdmin`.
type LLMPostureResponse ¶
type LLMPostureResponse struct {
// Provider is the LLM provider name (e.g. "bifrost", "mock").
Provider string `json:"provider"`
// Model is the bound model identifier (e.g. "openai/gpt-5.3-chat").
Model string `json:"model"`
// Region is the provider endpoint region; "" when not applicable
// (the Console renders an em-dash placeholder for the empty case).
Region string `json:"region"`
// MockMode is true iff the runtime booted with HARBOR_DEV_ALLOW_MOCK=1.
// The Console renders the canonical
// `[DEV-ONLY MOCK LLM — DO NOT USE IN PRODUCTION]` banner when this
// is true; hiding the banner is a §13 forbidden-practice violation.
MockMode bool `json:"mock_mode"`
// ProtocolVersion echoes the Protocol version the Runtime answered
// with — same field every Protocol response carries.
ProtocolVersion string `json:"protocol_version"`
}
LLMPostureResponse is the `llm.posture` response body — the read-only projection of the runtime's bound LLM provider.
type MCPAppCallToolRequest ¶ added in v1.4.0
type MCPAppCallToolRequest struct {
// Identity is the (tenant, user, session) scope the tool call runs
// under. Mandatory — an incomplete triple fails closed.
Identity IdentityScope `json:"identity"`
// Tool is the catalog tool name to invoke (the Harbor-side
// `<source>_<tool>` name).
Tool string `json:"tool"`
// Arguments is the raw JSON argument object the tool's schema
// validates on the wire.
Arguments json.RawMessage `json:"arguments,omitempty"`
}
MCPAppCallToolRequest is the `mcp.apps.call_tool` request body — an MCP App asking the host to invoke an MCP tool. The request carries the identity triple from the Protocol context; the runtime re-enters the EXISTING tool-invocation path (approval gate + tool-side OAuth + identity), so an app call to a gated tool parks on the unified pause primitive exactly as a planner call does. Identity is mandatory.
type MCPAppCallToolResponse ¶ added in v1.4.0
type MCPAppCallToolResponse struct {
// Tool echoes the invoked tool name.
Tool string `json:"tool"`
// Content is the inline tool-result JSON, populated ONLY when the
// encoded result is below the heavy-content threshold. Empty when
// ArtifactRef is set.
Content json.RawMessage `json:"content,omitempty"`
// ArtifactRef is the by-reference stub, populated when the encoded
// result meets or exceeds the heavy-content threshold. Nil when
// Content is set.
ArtifactRef *MCPResourceArtifactRef `json:"artifact_ref,omitempty"`
// IsError reports whether the MCP server returned a tool error
// (the result's IsError flag) — the app renders it as a failure.
IsError bool `json:"is_error"`
// App is the MCP App reference parsed from the tool result's
// `_meta.ui.resourceUri`, or nil for a non-app result.
App *MCPAppRef `json:"app,omitempty"`
// ProtocolVersion echoes the Protocol version the Runtime answered
// under so a client can detect a version skew.
ProtocolVersion string `json:"protocol_version"`
}
MCPAppCallToolResponse is the `mcp.apps.call_tool` reply. EXACTLY ONE of Content / ArtifactRef is set (the heavy-content discipline matches ReadMCPResourceResponse). App is non-nil when the tool result declared a `ui://` MCP App via `_meta.ui.resourceUri`, empty otherwise.
type MCPAppRef ¶ added in v1.4.0
type MCPAppRef struct {
// ServerID is the MCP server (source id) hosting the app's UI document
// and tools. The Console pairs it with ResourceURI to fetch the
// document via mcp.servers.read_resource — without it the renderer
// cannot resolve which server to read from. Empty for a non-app result.
ServerID string `json:"server_id,omitempty"`
// ToolCallID is the stable per-invocation id of the tool call that
// declared the app. The Console pairs it with ServerID to fetch the
// tool context (input + lowered result) via mcp.apps.tool_context.
// Empty for a non-app result.
ToolCallID string `json:"tool_call_id,omitempty"`
// ResourceURI is the `ui://`-scheme URI of the app's UI document.
// The Console fetches the document via mcp.servers.read_resource.
ResourceURI string `json:"resource_uri"`
// DisplayMode is the negotiated MCP-Apps display mode for this
// result (one of inline / fullscreen / pip), or empty when the
// server stated no preference and none was negotiated.
DisplayMode string `json:"display_mode,omitempty"`
// RawHTMLTrusted reports the per-server raw-HTML trust flag — the
// default-deny posture means the host sandboxes the iframe unless an
// operator explicitly opted in (mcp.servers.set_raw_html_trust).
RawHTMLTrusted bool `json:"raw_html_trusted"`
}
MCPAppRef is the host-side projection of an MCP App reference parsed from a tool result's `_meta.ui.resourceUri` slot. It is empty (nil on the response) for an ordinary, non-app tool result. The DisplayMode is the negotiated value the host reconciles from the server's advertised capability set; RawHTMLTrusted is the per-server raw-HTML trust posture (default-deny).
type MCPAuthorizationServerView ¶ added in v1.13.0
type MCPAuthorizationServerView struct {
// Issuer is the authorization server's issuer identifier.
Issuer string `json:"issuer"`
// AuthorizationEndpoint is the RFC 6749 authorization endpoint URL.
AuthorizationEndpoint string `json:"authorization_endpoint"`
// TokenEndpoint is the RFC 6749 token endpoint URL. NEVER dialed by Harbor.
TokenEndpoint string `json:"token_endpoint"`
// ScopesSupported is the advertised scope list. Always non-nil.
ScopesSupported []string `json:"scopes_supported"`
// CodeChallengeMethodsSupported is the advertised PKCE method list. Always
// non-nil.
CodeChallengeMethodsSupported []string `json:"code_challenge_methods_supported"`
// RegistrationEndpoint is the optional RFC 7591 dynamic-registration
// endpoint, REPORTED but never invoked.
RegistrationEndpoint string `json:"registration_endpoint,omitempty"`
// Resource is the optional RFC 8707 resource identifier.
Resource string `json:"resource,omitempty"`
// SourceURL is the URL this metadata document was fetched from.
SourceURL string `json:"source_url"`
}
MCPAuthorizationServerView is one RFC 8414 / OIDC authorization-server metadata document, verbatim. RegistrationEndpoint is reported, never invoked.
type MCPBindingScopeCount ¶
type MCPBindingScopeCount struct {
// BindingScope is the auth.BindingScope value ("user" / "agent").
BindingScope string `json:"binding_scope"`
// Count is the number of bindings at that scope.
Count int32 `json:"count"`
}
MCPBindingScopeCount is one (binding-scope, count) pair in a per-server bindings summary.
type MCPBindingView ¶
type MCPBindingView struct {
// PrincipalID is the bound principal — a user id (ScopeUser) or an
// agent id (ScopeAgent).
PrincipalID string `json:"principal_id"`
// BindingScope is the auth.BindingScope value ("user" / "agent").
BindingScope string `json:"binding_scope"`
// Scopes is the configured OAuth scope list. Always non-nil.
Scopes []string `json:"scopes"`
// ExpiresAt is the access-token expiry, or zero when no token is
// bound yet.
ExpiresAt time.Time `json:"expires_at"`
// LastUsedAt is the last-use instant, or zero when never used.
LastUsedAt time.Time `json:"last_used_at"`
}
MCPBindingView is one OAuth binding row. It NEVER carries token plaintext — only the binding metadata (invariant).
type MCPDiscoveryStepStatusView ¶ added in v1.13.0
type MCPDiscoveryStepStatusView struct {
// Step names the hop ("protected_resource" / "authorization_server").
Step string `json:"step"`
// Target is the URL the hop attempted.
Target string `json:"target"`
// OK reports whether the hop succeeded.
OK bool `json:"ok"`
// Reason is the stable machine-readable failure code (empty when OK).
Reason string `json:"reason,omitempty"`
// Detail is a human-readable message (never a credential).
Detail string `json:"detail,omitempty"`
}
MCPDiscoveryStepStatusView is one typed per-hop discovery status. A failed hop carries a stable Reason code so a partial chain reports what it refused.
type MCPHealthBucket ¶
type MCPHealthBucket struct {
// StartMs is the bucket start (Unix milliseconds).
StartMs int64 `json:"start_ms"`
// LatencyMs is the observed handshake latency for the bucket.
LatencyMs int64 `json:"latency_ms"`
}
MCPHealthBucket is one handshake-latency sparkline bucket.
type MCPOAuthRequirementView ¶ added in v1.13.0
type MCPOAuthRequirementView struct {
// ResourceMetadataURL is the RFC 9728 protected-resource-metadata URL the
// discovery walked.
ResourceMetadataURL string `json:"resource_metadata_url"`
// AuthorizationServers is the verbatim RFC 8414 metadata for each
// advertised authorization server that resolved. Always non-nil (may be
// empty when the cross-origin AS hop was refused — see Status).
AuthorizationServers []MCPAuthorizationServerView `json:"authorization_servers"`
// DiscoveredAt is the wall-clock instant discovery ran.
DiscoveredAt time.Time `json:"discovered_at"`
// Source is "challenge" (a 401 WWW-Authenticate step-up) or "probe" (an
// operator-triggered probe).
Source string `json:"source"`
// SourceURL is the resource-metadata URL discovery started from.
SourceURL string `json:"source_url"`
// Status is the typed per-hop outcome list — a partial chain reports the
// hops it refused / failed here rather than surfacing silently empty.
Status []MCPDiscoveryStepStatusView `json:"status"`
}
MCPOAuthRequirementView is the discovered MCP OAuth requirement, surfaced as inert Protocol data. The Console renders it as "discovered requirement (unverified — from the connected server)". Harbor never acts on it: no flow, no token custody, no endpoint dialing.
type MCPPromptArg ¶
type MCPPromptArg struct {
// Name is the argument name.
Name string `json:"name"`
// Description is the argument description.
Description string `json:"description,omitempty"`
// Required reports whether the argument is mandatory.
Required bool `json:"required"`
}
MCPPromptArg is one declared argument of an MCP prompt.
type MCPPromptView ¶
type MCPPromptView struct {
// Name is the prompt name.
Name string `json:"name"`
// Description is the prompt description.
Description string `json:"description,omitempty"`
// Arguments is the declared argument list. Always non-nil.
Arguments []MCPPromptArg `json:"arguments"`
}
MCPPromptView is one advertised MCP prompt.
type MCPReconnect ¶
type MCPReconnect struct {
// OccurredAt is the reconnect instant.
OccurredAt time.Time `json:"occurred_at"`
// Reason carries the reconnect cause.
Reason string `json:"reason,omitempty"`
}
MCPReconnect is one reconnect-history entry.
type MCPResourceArtifactRef ¶ added in v1.4.0
type MCPResourceArtifactRef struct {
// ID is the content-addressed identifier (`{namespace}_{sha256[:12]}`).
ID string `json:"id"`
// MimeType is the IANA media type, when known.
MimeType string `json:"mime_type,omitempty"`
// SizeBytes is the length of the referenced bytes.
SizeBytes int64 `json:"size_bytes,omitempty"`
// Filename is metadata only (never used for path construction).
Filename string `json:"filename,omitempty"`
// SHA256 is the full hex digest of the referenced bytes.
SHA256 string `json:"sha256,omitempty"`
}
MCPResourceArtifactRef is the by-reference shape the MCP Apps surface returns when fetched content (a `ui://` HTML document, or an app-tool- call result) meets or exceeds the configured heavy-content threshold (RFC §6.5). It mirrors a subset of `internal/artifacts.Ref` but is a flat wire type — the Console fetches the bytes via the artifacts surface against this stub. It is the same flat shape MemoryArtifactRef uses, kept distinct so a future divergence does not whipsaw either surface.
type MCPResourceView ¶
type MCPResourceView struct {
// URI is the resource URI.
URI string `json:"uri"`
// MimeType is the resource MIME type, or empty when the server
// declared none.
MimeType string `json:"mime_type,omitempty"`
// SizeBytes is the declared resource size, or zero when unknown.
SizeBytes int64 `json:"size_bytes,omitempty"`
// Name is the resource short name.
Name string `json:"name,omitempty"`
// Title is the resource human-readable title.
Title string `json:"title,omitempty"`
}
MCPResourceView is one advertised MCP resource.
type MCPScopeShortfallView ¶ added in v1.16.0
type MCPScopeShortfallView struct {
// ToolName is the server-side tool name the shortfall was observed on
// (empty when the observation was not tied to a specific tool call).
ToolName string `json:"tool_name"`
// DownstreamResource is the origin/host the challenge came from.
DownstreamResource string `json:"downstream_resource"`
// RequiredScopes is the parsed `scope` challenge parameter — the scopes
// the downstream demands. Always non-nil in the wire JSON.
RequiredScopes []string `json:"required_scopes"`
// GrantedScopes is the binding's most-recently-granted scope set. Always
// non-nil in the wire JSON (empty when unknown).
GrantedScopes []string `json:"granted_scopes"`
// WWWAuthenticate is the verbatim challenge header value.
WWWAuthenticate string `json:"www_authenticate"`
// Origin is the scheme://host[:port] the challenge was observed on.
Origin string `json:"origin"`
// ObservedAt is the wall-clock instant the shortfall was observed.
ObservedAt time.Time `json:"observed_at"`
}
MCPScopeShortfallView is the last observed downstream insufficient-scope step-up on a connection, surfaced as inert Protocol data. The Console renders it as "insufficient scope (from the connected server)". Harbor never acts on it: no escalation, no re-consent, no widened binding.
type MCPServerBindingsListRequest ¶
type MCPServerBindingsListRequest struct {
// Identity is the mandatory caller identity scope.
Identity IdentityScope `json:"identity"`
// Name is the MCP server name. Required.
Name string `json:"name"`
}
MCPServerBindingsListRequest is the wire shape for mcp.servers.bindings.list.
type MCPServerBindingsListResponse ¶
type MCPServerBindingsListResponse struct {
// Bindings is the OAuth binding list. Always non-nil (may be empty).
Bindings []MCPBindingView `json:"bindings"`
// ProtocolVersion is the pinned Harbor Protocol version.
ProtocolVersion string `json:"protocol_version"`
}
MCPServerBindingsListResponse is the mcp.servers.bindings.list reply.
type MCPServerGetRequest ¶
type MCPServerGetRequest struct {
// Identity is the mandatory caller identity scope.
Identity IdentityScope `json:"identity"`
// Name is the MCP server name to inspect. Required.
Name string `json:"name"`
}
MCPServerGetRequest is the wire shape for mcp.servers.get — a single-server detail read.
type MCPServerGetResponse ¶
type MCPServerGetResponse struct {
// Server is the per-server row shape.
Server MCPServerView `json:"server"`
// DisplayModesAdvertised lists the MCP-Apps DisplayMode values the
// server declares. Always non-nil in the wire JSON.
DisplayModesAdvertised []string `json:"display_modes_advertised"`
// ContentShapes lists the canonical content shapes the server's
// tools return ("string" / "ImageRef" / ...). Always non-nil.
ContentShapes []string `json:"content_shapes"`
// ToolPolicy is the read-only ToolPolicy projection.
ToolPolicy MCPToolPolicyView `json:"tool_policy"`
// BindingsSummary is the per-scope binding count rollup. Always
// non-nil in the wire JSON.
BindingsSummary []MCPBindingScopeCount `json:"bindings_summary"`
// ProtocolVersion is the pinned Harbor Protocol version.
ProtocolVersion string `json:"protocol_version"`
}
MCPServerGetResponse is the mcp.servers.get reply — the list-row shape plus per-server detail fields.
type MCPServerHealthRequest ¶
type MCPServerHealthRequest struct {
// Identity is the mandatory caller identity scope.
Identity IdentityScope `json:"identity"`
// Name is the MCP server name. Required.
Name string `json:"name"`
}
MCPServerHealthRequest is the wire shape for mcp.servers.health.
type MCPServerHealthResponse ¶
type MCPServerHealthResponse struct {
// HandshakeLatencyBuckets is the latency sparkline. Always non-nil.
HandshakeLatencyBuckets []MCPHealthBucket `json:"handshake_latency_buckets"`
// ReconnectHistory is the reconnect-history list. Always non-nil.
ReconnectHistory []MCPReconnect `json:"reconnect_history"`
// TransportErrorRate is the transport-error rate (errors / minute).
TransportErrorRate float64 `json:"transport_error_rate"`
// ProtocolVersion is the pinned Harbor Protocol version.
ProtocolVersion string `json:"protocol_version"`
}
MCPServerHealthResponse is the mcp.servers.health reply.
type MCPServerPolicyRequest ¶
type MCPServerPolicyRequest struct {
// Identity is the mandatory caller identity scope.
Identity IdentityScope `json:"identity"`
// Name is the MCP server name. Required.
Name string `json:"name"`
}
MCPServerPolicyRequest is the wire shape for mcp.servers.policy.
type MCPServerPolicyResponse ¶
type MCPServerPolicyResponse struct {
// ToolPolicy is the read-only ToolPolicy projection.
ToolPolicy MCPToolPolicyView `json:"tool_policy"`
// ProtocolVersion is the pinned Harbor Protocol version.
ProtocolVersion string `json:"protocol_version"`
}
MCPServerPolicyResponse is the mcp.servers.policy reply — the read-only ToolPolicy projection.
type MCPServerProbeRequest ¶
type MCPServerProbeRequest struct {
// Identity is the mandatory caller identity scope.
Identity IdentityScope `json:"identity"`
// Name is the MCP server name. Required.
Name string `json:"name"`
}
MCPServerProbeRequest is the wire shape for mcp.servers.probe — a control-plane verb that runs a transport ping / tools-list round-trip.
type MCPServerProbeResponse ¶
type MCPServerProbeResponse struct {
// OK reports whether the probe round-trip succeeded.
OK bool `json:"ok"`
// LatencyMs is the probe round-trip latency in milliseconds.
LatencyMs int64 `json:"latency_ms"`
// Error carries the probe failure message when OK is false.
Error string `json:"error,omitempty"`
// ProtocolVersion is the pinned Harbor Protocol version.
ProtocolVersion string `json:"protocol_version"`
}
MCPServerProbeResponse is the mcp.servers.probe reply.
type MCPServerPromptsRequest ¶
type MCPServerPromptsRequest struct {
// Identity is the mandatory caller identity scope.
Identity IdentityScope `json:"identity"`
// Name is the MCP server name. Required.
Name string `json:"name"`
}
MCPServerPromptsRequest is the wire shape for mcp.servers.prompts.
type MCPServerPromptsResponse ¶
type MCPServerPromptsResponse struct {
// Prompts is the advertised prompt list. Always non-nil.
Prompts []MCPPromptView `json:"prompts"`
// ProtocolVersion is the pinned Harbor Protocol version.
ProtocolVersion string `json:"protocol_version"`
}
MCPServerPromptsResponse is the mcp.servers.prompts reply.
type MCPServerRefreshBindingRequest ¶
type MCPServerRefreshBindingRequest struct {
// Identity is the mandatory caller identity scope.
Identity IdentityScope `json:"identity"`
// Name is the MCP server name. Required.
Name string `json:"name"`
// PrincipalID is the binding principal to (re)connect. Optional —
// empty drives the flow for the caller's own ScopeUser binding.
PrincipalID string `json:"principal_id,omitempty"`
}
MCPServerRefreshBindingRequest is the wire shape for mcp.servers.refresh_binding — an admin verb (auth.ScopeAdmin).
type MCPServerRefreshBindingResponse ¶
type MCPServerRefreshBindingResponse struct {
// AuthorizeURL is the OAuth authorization endpoint URL the Console
// navigates the popup to. NEVER a token.
AuthorizeURL string `json:"authorize_url"`
// State is the opaque flow-state the Console matches against the
// subsequent tool.auth_completed event.
State string `json:"state"`
// ProtocolVersion is the pinned Harbor Protocol version.
ProtocolVersion string `json:"protocol_version"`
}
MCPServerRefreshBindingResponse is the mcp.servers.refresh_binding reply — the AuthorizeURL the Console opens in a popup, plus the flow state for matching the completion event.
type MCPServerRefreshDiscoveryRequest ¶
type MCPServerRefreshDiscoveryRequest struct {
// Identity is the mandatory caller identity scope.
Identity IdentityScope `json:"identity"`
// Name is the MCP server name. Required.
Name string `json:"name"`
}
MCPServerRefreshDiscoveryRequest is the wire shape for mcp.servers.refresh_discovery — a control-plane verb.
type MCPServerRefreshDiscoveryResponse ¶
type MCPServerRefreshDiscoveryResponse struct {
// DiscoveryID is an opaque id correlating this refresh with the
// runtime logs.
DiscoveryID string `json:"discovery_id"`
// ToolCount / ResourceCount / PromptCount are the post-refresh
// advertised counts.
ToolCount int32 `json:"tool_count"`
ResourceCount int32 `json:"resource_count"`
PromptCount int32 `json:"prompt_count"`
// ProtocolVersion is the pinned Harbor Protocol version.
ProtocolVersion string `json:"protocol_version"`
}
MCPServerRefreshDiscoveryResponse is the mcp.servers.refresh_discovery reply — the new counts plus a discovery-id for log correlation.
type MCPServerResourcesRequest ¶
type MCPServerResourcesRequest struct {
// Identity is the mandatory caller identity scope.
Identity IdentityScope `json:"identity"`
// Name is the MCP server name. Required.
Name string `json:"name"`
}
MCPServerResourcesRequest is the wire shape for mcp.servers.resources.
type MCPServerResourcesResponse ¶
type MCPServerResourcesResponse struct {
// Resources is the advertised resource list. Always non-nil.
Resources []MCPResourceView `json:"resources"`
// ProtocolVersion is the pinned Harbor Protocol version.
ProtocolVersion string `json:"protocol_version"`
}
MCPServerResourcesResponse is the mcp.servers.resources reply.
type MCPServerRevokeBindingRequest ¶
type MCPServerRevokeBindingRequest struct {
// Identity is the mandatory caller identity scope.
Identity IdentityScope `json:"identity"`
// Name is the MCP server name. Required.
Name string `json:"name"`
// PrincipalID is the binding principal to revoke. Optional — empty
// revokes the caller's own ScopeUser binding.
PrincipalID string `json:"principal_id,omitempty"`
}
MCPServerRevokeBindingRequest is the wire shape for mcp.servers.revoke_binding — an admin verb (auth.ScopeAdmin).
type MCPServerRevokeBindingResponse ¶
type MCPServerRevokeBindingResponse struct {
// Revoked reports whether a binding was revoked.
Revoked bool `json:"revoked"`
// ProtocolVersion is the pinned Harbor Protocol version.
ProtocolVersion string `json:"protocol_version"`
}
MCPServerRevokeBindingResponse is the mcp.servers.revoke_binding reply.
type MCPServerSetRawHTMLTrustRequest ¶
type MCPServerSetRawHTMLTrustRequest struct {
// Identity is the mandatory caller identity scope.
Identity IdentityScope `json:"identity"`
// Name is the MCP server name. Required.
Name string `json:"name"`
// Trusted is the new per-server raw-HTML trust flag value.
Trusted bool `json:"trusted"`
}
MCPServerSetRawHTMLTrustRequest is the wire shape for mcp.servers.set_raw_html_trust — an admin verb (auth.ScopeAdmin).
type MCPServerSetRawHTMLTrustResponse ¶
type MCPServerSetRawHTMLTrustResponse struct {
// Name is the MCP server name the flag was set on.
Name string `json:"name"`
// Trusted is the persisted raw-HTML trust flag value.
Trusted bool `json:"trusted"`
// ProtocolVersion is the pinned Harbor Protocol version.
ProtocolVersion string `json:"protocol_version"`
}
MCPServerSetRawHTMLTrustResponse is the mcp.servers.set_raw_html_trust reply.
type MCPServerStateView ¶
type MCPServerStateView string
MCPServerStateView is the canonical state chip a Console renders for an MCP server row. The V1 set is closed.
const ( // MCPStateOnline — the transport is connected and the last // discovery / probe succeeded. MCPStateOnline MCPServerStateView = "online" // MCPStateReconnecting — the transport dropped and the driver is // re-establishing the session. MCPStateReconnecting MCPServerStateView = "reconnecting" // MCPStateOffline — the transport is down (never connected, or // closed). MCPStateOffline MCPServerStateView = "offline" // MCPStateAuthPending — the server requires an OAuth binding that // has not been completed. MCPStateAuthPending MCPServerStateView = "auth_pending" // MCPStateError — the last discovery / probe failed with a // transport error. MCPStateError MCPServerStateView = "error" )
The canonical MCP server state values.
type MCPServerView ¶
type MCPServerView struct {
// Name is the unique MCP server / source id.
Name string `json:"name"`
// Transport is the wire transport — "stdio", "http+sse",
// "streamable-http", or "websocket".
Transport string `json:"transport"`
// URLOrCommand is the transport-prefixed endpoint URL (HTTP
// transports) or the argv-form command string (stdio).
URLOrCommand string `json:"url_or_command"`
// State is the canonical state chip.
State MCPServerStateView `json:"state"`
// LastDiscoveryAt is the wall-clock instant of the last successful
// discovery. Zero when discovery has never run.
LastDiscoveryAt time.Time `json:"last_discovery_at"`
// ToolCount is the number of tools the server advertises.
ToolCount int32 `json:"tool_count"`
// ResourceCount is the number of resources the server advertises.
ResourceCount int32 `json:"resource_count"`
// PromptCount is the number of prompts the server advertises.
PromptCount int32 `json:"prompt_count"`
// RecentLatencyMs is the most recent observed handshake / probe
// latency in milliseconds.
RecentLatencyMs int64 `json:"recent_latency_ms"`
// ErrorRatePerMin is the transport-error rate over the recent
// window (errors per minute).
ErrorRatePerMin float64 `json:"error_rate_per_min"`
// OAuthBindingCount is the number of OAuth bindings configured for
// this server.
OAuthBindingCount int32 `json:"oauth_binding_count"`
// RawHTMLTrusted reports whether the per-server raw-HTML opt-in flag
// is set. Default false (default-deny).
RawHTMLTrusted bool `json:"raw_html_trusted"`
// OAuthRequirement is the OAuth requirement the server ADVERTISED and
// Harbor DISCOVERED on demand — the verbatim RFC 9728 → RFC 8414
// metadata chain plus provenance. It is inert, server-supplied, UNVERIFIED
// data: a proposal an operator confirms, never config Harbor follows —
// Harbor never runs the OAuth flow, never holds a token, and never dials a
// discovered endpoint. Present only on the DETAIL read (mcp.servers.get,
// and after a probe triggers discovery); the list projection omits it so
// the hot list row stays compact. Nil / omitted when no discovery has run.
OAuthRequirement *MCPOAuthRequirementView `json:"oauth_requirement,omitempty"`
// LastScopeShortfall is the last downstream insufficient-scope step-up
// (a `403` + `WWW-Authenticate` marking `error="insufficient_scope"`)
// observed on this connection — the required-vs-granted scope gap surfaced
// as inert data. Present only on the DETAIL read (mcp.servers.get),
// mirroring OAuthRequirement; the list projection omits it. Report-only:
// Harbor never auto-escalates or re-consents on it. Nil / omitted when no
// shortfall has been observed.
LastScopeShortfall *MCPScopeShortfallView `json:"last_scope_shortfall,omitempty"`
}
MCPServerView is the per-row payload returned by mcp.servers.list and (extended) by mcp.servers.get. It is a flat projection of the runtime MCP driver's per-server state — never a re-export of the driver type.
type MCPServersListRequest ¶
type MCPServersListRequest struct {
// Identity is the mandatory caller identity scope.
Identity IdentityScope `json:"identity"`
// State filters to servers in any of the given states. Empty = all.
State []MCPServerStateView `json:"state,omitempty"`
// Transport filters to servers on any of the given transports.
Transport []string `json:"transport,omitempty"`
// HasOAuth, when set, filters to servers with (true) / without
// (false) at least one OAuth binding.
HasOAuth *bool `json:"has_oauth,omitempty"`
// HasRecentError, when set, filters to servers with (true) /
// without (false) a recent transport error.
HasRecentError *bool `json:"has_recent_error,omitempty"`
// NamePrefix filters to servers whose name has the given prefix.
NamePrefix string `json:"name_prefix,omitempty"`
// PageToken is the opaque cursor from a prior response. Empty = the
// first page.
PageToken string `json:"page_token,omitempty"`
// PageSize is the requested maximum row count. Zero = the surface
// default; the surface clamps to a maximum.
PageSize int32 `json:"page_size,omitempty"`
}
MCPServersListRequest is the wire shape for mcp.servers.list — a paged, filterable list of the configured MCP southbound servers.
type MCPServersListResponse ¶
type MCPServersListResponse struct {
// Servers is the page of server rows. Always non-nil in the wire
// JSON (an empty list is `[]`, never `null`).
Servers []MCPServerView `json:"servers"`
// NextPageToken is the cursor for the next page, or empty when this
// is the last page.
NextPageToken string `json:"next_page_token,omitempty"`
// ProtocolVersion is the pinned Harbor Protocol version.
ProtocolVersion string `json:"protocol_version"`
}
MCPServersListResponse is the mcp.servers.list reply.
type MCPToolPolicyView ¶
type MCPToolPolicyView struct {
// TimeoutMs is the per-invocation timeout in milliseconds.
TimeoutMs int64 `json:"timeout_ms"`
// MaxRetries is the retry cap.
MaxRetries int32 `json:"max_retries"`
// ConcurrencyCap is the per-server concurrent-invocation cap. Zero
// means unbounded.
ConcurrencyCap int32 `json:"concurrency_cap"`
}
MCPToolPolicyView is the read-only projection of an MCP server's ToolPolicy. It is read-only at V1 (policy editing is post-V1).
type MemoryAggregates ¶
type MemoryAggregates struct {
// Total is the total record count across the filtered set.
Total int64 `json:"total"`
// IdentityRejected24h is the count of `memory.identity_rejected`
// events observed in the last 24 hours.
IdentityRejected24h int64 `json:"identity_rejected_24h"`
// RecoveryDropped24h is the count of `memory.recovery_dropped`
// events observed in the last 24 hours. The shipped wire
// string is `memory.recovery_dropped` — page-memory.md §12 names a
// mockup-refinement `memory.overflow_drop_oldest`; this phase uses
// the shipped constant (see the phase plan "Findings I'm departing
// from").
RecoveryDropped24h int64 `json:"recovery_dropped_24h"`
}
MemoryAggregates carries the page-level counters the Memory page's sub-header strip renders. The 24-h-window counters derive from `events.aggregate` over the `memory.*` event types — runtime-side computation
type MemoryArtifactRef ¶
type MemoryArtifactRef struct {
// ID is the content-addressed identifier (`{namespace}_{sha256[:12]}`).
ID string `json:"id"`
// MimeType is the IANA media type, when known.
MimeType string `json:"mime_type,omitempty"`
// SizeBytes is the length of the referenced bytes.
SizeBytes int64 `json:"size_bytes,omitempty"`
// Filename is metadata only (never used for path construction).
Filename string `json:"filename,omitempty"`
// SHA256 is the full hex digest of the referenced bytes.
SHA256 string `json:"sha256,omitempty"`
}
MemoryArtifactRef is the by-reference shape `memory.get` returns when the record's value serialised size meets or exceeds the configured heavy-content threshold. It mirrors a subset of `internal/artifacts.ArtifactRef` but is a flat wire type — the Protocol owns its vocabulary; runtime Go structs never leak (RFC §5.1 / CLAUDE.md §13 single-source rule). It is the same flat shape `PauseArtifactRef` / `SearchArtifactRef` use, kept as a distinct type so a future divergence in either surface does not whipsaw the other.
type MemoryDeleteRequest ¶ added in v1.3.0
type MemoryDeleteRequest struct {
// Identity is the request's identity scope. The triple is mandatory.
Identity IdentityScope `json:"identity"`
// Key is the memory turn key to evict — a value carried on a
// `MemoryItem.Key` returned by `memory.list`.
Key string `json:"key"`
}
MemoryDeleteRequest is the wire request for the `memory.delete` method the admin-gated, audited "evict a memory turn" mutation. Identity is mandatory; admin scope is required.
type MemoryDeleteResponse ¶ added in v1.3.0
type MemoryDeleteResponse struct {
// Deleted is true when the keyed turn was found and evicted.
Deleted bool `json:"deleted"`
// RemainingTurns is the turn count remaining in the session record
// after the eviction (the Console re-reads the list to refresh).
RemainingTurns int `json:"remaining_turns"`
// ProtocolVersion echoes the Protocol version the Runtime answered
// under so a client can detect a version skew.
ProtocolVersion string `json:"protocol_version"`
}
MemoryDeleteResponse is the wire response for the `memory.delete` method.
type MemoryDriverName ¶
type MemoryDriverName string
MemoryDriverName is the typed enum of the three V1 persistence drivers a `memory.list` filter facet accepts. The set matches the persistence triad (in-memory / SQLite / Postgres) every persistence- shaped subsystem ships at V1 (CLAUDE.md §9).
const ( MemoryDriverInmem MemoryDriverName = "inmem" MemoryDriverSQLite MemoryDriverName = "sqlite" MemoryDriverPostgres MemoryDriverName = "postgres" )
Canonical V1 memory-driver names.
type MemoryFilter ¶
type MemoryFilter struct {
// TenantIDs narrows to a tenant set; empty = the caller's own
// tenant. A foreign tenant OR len>1 requires auth.ScopeAdmin
// (closed set).
TenantIDs []string `json:"tenant_ids,omitempty"`
// UserIDs narrows to a user set within the visible tenants.
UserIDs []string `json:"user_ids,omitempty"`
// SessionIDs narrows to a session set.
SessionIDs []string `json:"session_ids,omitempty"`
// AgentIDs narrows to records produced by a given agent set. NOT
// an isolation filter (CLAUDE.md §6 clarifying note).
AgentIDs []string `json:"agent_ids,omitempty"`
// Scopes narrows to a subset of ["session", "user", "tenant"].
// Each value must be a canonical MemoryScope.
Scopes []string `json:"scopes,omitempty"`
// Drivers narrows to a subset of ["inmem", "sqlite", "postgres"].
// Each value must be a canonical MemoryDriverName.
Drivers []string `json:"drivers,omitempty"`
// Strategies narrows to a subset of the V1 MemoryStrategyName set.
Strategies []string `json:"strategies,omitempty"`
// ContentSearch is an optional substring matched against the
// post-redaction record value text. The match is runtime-side
// never a Console-side scan over an exported
// snapshot.
ContentSearch string `json:"content_search,omitempty"`
}
MemoryFilter narrows the `memory.list` response. An empty filter means "the caller's own identity scope, every record." Supplying a `TenantIDs` value that reaches OUTSIDE the caller's own tenant (or names more than one tenant) requires the `auth.ScopeAdmin` (or `auth.ScopeConsoleFleet`) scope claim from the closed two-scope set; a missing-claim cross-tenant request is rejected loudly with `CodeIdentityScopeRequired` (HTTP 403) — NEVER silently downgraded to an empty result set. There is NO dedicated memory scope: cross-tenant memory listing gates on the same closed set every other page uses (audit B1 resolution).
type MemoryGetRequest ¶
type MemoryGetRequest struct {
// Identity is the request's identity scope. The triple is
// mandatory; an incomplete triple fails closed with
// CodeIdentityRequired (401).
Identity IdentityScope `json:"identity"`
// Key is the memory record key — the value carried on a
// `MemoryItem.Key` returned by `memory.list`.
Key string `json:"key"`
}
MemoryGetRequest is the wire request for the `memory.get` method.
type MemoryGetResponse ¶
type MemoryGetResponse struct {
// Detail is the full record detail.
Detail MemoryItemDetail `json:"detail"`
// ProtocolVersion echoes the Protocol version the Runtime answered
// under so a client can detect a version skew.
ProtocolVersion string `json:"protocol_version"`
}
MemoryGetResponse is the wire response for the `memory.get` method.
type MemoryHealthAggregate ¶
type MemoryHealthAggregate struct {
// Total is the total memory-record count for the caller's scope.
Total int64 `json:"total"`
// IdentityRejected24h is the count of `memory.identity_rejected`
// events observed in the last 24 hours.
IdentityRejected24h int64 `json:"identity_rejected_24h"`
// RecoveryDropped24h is the count of `memory.recovery_dropped`
// events observed in the last 24 hours.
RecoveryDropped24h int64 `json:"recovery_dropped_24h"`
// DriverByScope maps each memory scope to the persistence driver
// backing it — e.g. {"session":"inmem", "tenant":"postgres"}. The
// driver-comparison rollup the Memory page renders.
DriverByScope map[string]string `json:"driver_by_scope"`
}
MemoryHealthAggregate carries the aggregate memory-health counters the Memory page's right-rail Memory-health card renders. The 24-h- window counters derive from `events.aggregate` over the `memory.*` event types — runtime-side computation
type MemoryHealthRequest ¶
type MemoryHealthRequest struct {
// Identity is the request's identity scope. The triple is
// mandatory; an incomplete triple fails closed with
// CodeIdentityRequired (401).
Identity IdentityScope `json:"identity"`
}
MemoryHealthRequest is the wire request for the `memory.health` method. The identity is read from ctx; the body Identity is the carrier-header echo, defended against the verified identity.
type MemoryHealthResponse ¶
type MemoryHealthResponse struct {
// Aggregate carries the aggregate health counters.
Aggregate MemoryHealthAggregate `json:"aggregate"`
// ProtocolVersion echoes the Protocol version the Runtime answered
// under so a client can detect a version skew.
ProtocolVersion string `json:"protocol_version"`
}
MemoryHealthResponse is the wire response for the `memory.health` method.
type MemoryItem ¶
type MemoryItem struct {
// Key is the memory record key — a deterministic per-record
// identifier the Console passes back to `memory.get`. A client
// never constructs or parses it.
Key string `json:"key"`
// Strategy is the memory strategy this record was produced under —
// one of the MemoryStrategyName values.
Strategy string `json:"strategy"`
// Scope is the record's scope — "session" | "user" | "tenant".
Scope string `json:"scope"`
// Identity is the (tenant, user, session [, run]) the record lives
// under. Flat strings — never a re-export of the runtime identity
// quadruple.
Identity IdentityScope `json:"identity"`
// AgentID is the registration identity of the agent that produced
// the record, when known. NOT an isolation principal (CLAUDE.md §6
// clarifying note) — surfaced for the Owner column only.
AgentID string `json:"agent_id,omitempty"`
// CreatedAt is the wall-clock time the record was first written.
CreatedAt time.Time `json:"created_at"`
// LastUpdatedAt is the wall-clock time the record was last touched.
LastUpdatedAt time.Time `json:"last_updated_at"`
// ExpiresAt is the record's TTL expiry; the zero value (omitted)
// means the record has no TTL.
ExpiresAt time.Time `json:"expires_at,omitempty"`
// SizeBytes is the byte length of the record's post-redaction
// value. A count only — the bytes themselves are never inlined on
// this row shape.
SizeBytes int64 `json:"size_bytes"`
// HeavyContent is true when SizeBytes meets or exceeds the
// heavy-content threshold; the Console renders a heavy-content icon
// and `memory.get` returns a `MemoryArtifactRef` for the value.
HeavyContent bool `json:"heavy_content,omitempty"`
// Driver is the persistence driver backing this record —
// "inmem" | "sqlite" | "postgres".
Driver string `json:"driver"`
}
MemoryItem is one row in the Memory page's main table — the wire projection of a single memory record. Heavy values are NEVER inlined on this row shape: a row carries the `SizeBytes` count and the `HeavyContent` flag, and the Console calls `memory.get` for the per-item detail (which produces an `MemoryArtifactRef` above the heavy-content threshold). Cross-package single source per CLAUDE.md §8; the typed Protocol client regenerates from this without hand-editing.
invariant: there is NO `Priority` field. The `Pinned` strategy overlay chip is a strategy, not a session-level priority dimension — no priority surfaces on a memory row, ever.
type MemoryItemDetail ¶
type MemoryItemDetail struct {
// Item is the row-shaped projection of the record (the same shape
// `memory.list` returns).
Item MemoryItem `json:"item"`
// Value is the post-redaction record value, populated ONLY when
// SizeBytes is below the heavy-content threshold.
Value []byte `json:"value,omitempty"`
// ValueArtifact is populated when SizeBytes meets or exceeds the
// heavy-content threshold. The Console fetches the bytes
// via `artifacts.get` against this stub. When ValueArtifact is set,
// Value is nil — and vice-versa.
ValueArtifact *MemoryArtifactRef `json:"value_artifact,omitempty"`
// Metadata carries the per-record metadata.
Metadata MemoryMetadata `json:"metadata"`
}
MemoryItemDetail is the `memory.get` result. EXACTLY ONE of `Value` / `ValueArtifact` is populated; never both. Above the heavy-content threshold, `Value` is empty and `ValueArtifact` carries the by-reference stub; below it, `Value` carries the post-redaction bytes and `ValueArtifact` is nil. A driver that returns raw heavy bytes is a leak — the runtime fails loudly rather than inlining them.
type MemoryListRequest ¶
type MemoryListRequest struct {
// Identity is the request's identity scope. The triple is
// mandatory; an incomplete triple fails the request closed at the
// Protocol edge with CodeIdentityRequired (401).
Identity IdentityScope `json:"identity"`
// Filter narrows the listed records. Empty filter = the caller's
// own identity scope, every record.
Filter MemoryFilter `json:"filter,omitempty"`
// Page is the 1-based page number; defaults to 1 when zero. A
// negative Page is rejected with CodeInvalidRequest (400).
Page int `json:"page,omitempty"`
// PageSize is the per-page row count. Defaults to
// DefaultMemoryListPageSize (50) when zero; values above
// MaxMemoryListPageSize (200) — or negative — are rejected with
// CodeInvalidRequest (400). Never silently clamped.
PageSize int `json:"page_size,omitempty"`
}
MemoryListRequest is the wire request for the `memory.list` method.
Identity is mandatory at the Protocol edge per RFC §5.5 — the request flows out of an auth-verified identity in ctx, never trusted from the body. The `Identity` field exists for the trust-based carrier-header posture and for body-side echo; the memory-list handler reads the verified identity from ctx (preferred) and defends the body identity against it.
type MemoryListResponse ¶
type MemoryListResponse struct {
// Items is the page of memory records, ordered LastUpdatedAt
// descending (newest first) for a deterministic table.
Items []MemoryItem `json:"items"`
// Page is the 1-based page number this response covers.
Page int `json:"page"`
// PageSize is the per-page row count applied.
PageSize int `json:"page_size"`
// PageCount is the total number of pages over the filtered set.
PageCount int `json:"page_count"`
// TotalRows is the total filtered row count across all pages.
TotalRows int `json:"total_rows"`
// Aggregates carries the page-level counters.
Aggregates MemoryAggregates `json:"aggregates"`
// ProtocolVersion echoes the Protocol version the Runtime answered
// under so a client can detect a version skew.
ProtocolVersion string `json:"protocol_version"`
}
MemoryListResponse is the wire response for the `memory.list` method.
type MemoryMetadata ¶
type MemoryMetadata struct {
// TTL is the record's configured time-to-live. The zero value
// means the record has no TTL.
TTL time.Duration `json:"ttl,omitempty"`
// StrategyConfig is the bounded, strategy-named knob map surfaced
// for the right-rail detail (e.g. budget tokens for `truncation`).
StrategyConfig map[string]string `json:"strategy_config,omitempty"`
// RelatedEventIDs are the recent event IDs touching this record's
// key — for the right-rail "Inspect related events" deep-link.
RelatedEventIDs []string `json:"related_event_ids,omitempty"`
}
MemoryMetadata carries the per-record metadata the Memory page's right-rail Selected-item-detail card renders.
type MemoryPutRequest ¶ added in v1.3.0
type MemoryPutRequest struct {
// Identity is the request's identity scope. The triple is mandatory.
Identity IdentityScope `json:"identity"`
// Turn is the conversation turn to append.
Turn MemoryTurnInput `json:"turn"`
}
MemoryPutRequest is the wire request for the `memory.put` method ( ) — the admin-gated, audited "add a memory turn" mutation. Identity is mandatory; admin scope is required.
type MemoryPutResponse ¶ added in v1.3.0
type MemoryPutResponse struct {
// Key is the deterministic key of the appended turn — the value a
// subsequent `memory.get` resolves.
Key string `json:"key"`
// ProtocolVersion echoes the Protocol version the Runtime answered
// under so a client can detect a version skew.
ProtocolVersion string `json:"protocol_version"`
}
MemoryPutResponse is the wire response for the `memory.put` method.
type MemoryScope ¶
type MemoryScope string
MemoryScope is the typed enum of the three memory-record scopes the `memory.list` filter accepts. Memory is session-scoped by default (CLAUDE.md §6 rule 4); user- and tenant-scoped records exist only through an explicit declared promotion policy. The Protocol owns its own vocabulary (RFC §5.1 / CLAUDE.md §13 single-source rule) — this wire enum never re-exports a runtime Go type.
const ( MemoryScopeSession MemoryScope = "session" MemoryScopeUser MemoryScope = "user" MemoryScopeTenant MemoryScope = "tenant" )
Canonical memory-record scopes. The set is closed.
type MemoryStrategyName ¶
type MemoryStrategyName string
MemoryStrategyName is the typed enum of the memory strategies a `memory.list` filter facet accepts. The three V1 values map onto the runtime-side `memory.Strategy` taxonomy; the overlay-chip names (`pinned`, `episodic`, `recent`, `persistent`) are reserved for post-V1 strategies and intentionally NOT in the closed set — a filter naming an unshipped strategy is rejected with CodeInvalidRequest, not silently dropped.
const ( MemoryStrategyNone MemoryStrategyName = "none" MemoryStrategyTruncation MemoryStrategyName = "truncation" MemoryStrategyRollingSummary MemoryStrategyName = "rolling_summary" )
Canonical V1 memory-strategy names — the wire projection of the `memory.Strategy` taxonomy shipped.
type MemoryStrategyTrace ¶ added in v1.3.0
type MemoryStrategyTrace struct {
// Strategy is the configured memory strategy — one of the
// MemoryStrategyName values.
Strategy string `json:"strategy"`
// Summary is the rolling-summary text the strategy injects into the
// planner's LLM call — the compaction OUTPUT. Empty under `none` /
// `truncation` (which keep no rolling summary) or before any
// compaction has occurred.
Summary string `json:"summary"`
// RecentTurnCount is the number of conversation turns the strategy
// currently keeps verbatim (NOT folded into the summary).
RecentTurnCount int `json:"recent_turn_count"`
// EstimatedTokens is the strategy's current estimate of the tokens
// `GetLLMContext` would inject — the planner compares this against its
// context-window budget.
EstimatedTokens int `json:"estimated_tokens"`
// Health is the memory FSM health state for this identity —
// "healthy" | "degraded" | "recovering".
Health string `json:"health"`
}
MemoryStrategyTrace is the wire projection of how the configured memory strategy is compacting the caller's session memory RIGHT NOW ( ). It is the honest, read-only projection of the strategy's live `GetLLMContext` + `Health` output — NOT a fabricated per-step "selection with rejections" (the `rolling_summary` strategy summarises; it does not select-and-reject candidates). Every field is real runtime state; an empty session projects an empty trace, never a synthesised one (CLAUDE.md §13).
type MemoryStrategyTraceRequest ¶ added in v1.3.0
type MemoryStrategyTraceRequest struct {
// Identity is the request's identity scope. The triple is mandatory;
// an incomplete triple fails closed with CodeIdentityRequired (401).
Identity IdentityScope `json:"identity"`
}
MemoryStrategyTraceRequest is the wire request for the `memory.strategy_trace` method. Identity is mandatory; the verified identity in ctx is preferred and the body Identity is defended against it.
type MemoryStrategyTraceResponse ¶ added in v1.3.0
type MemoryStrategyTraceResponse struct {
// Trace is the live strategy-compaction projection.
Trace MemoryStrategyTrace `json:"trace"`
// ProtocolVersion echoes the Protocol version the Runtime answered
// under so a client can detect a version skew.
ProtocolVersion string `json:"protocol_version"`
}
MemoryStrategyTraceResponse is the wire response for the `memory.strategy_trace` method.
type MemoryTurnInput ¶ added in v1.3.0
type MemoryTurnInput struct {
// UserMessage is the turn's user message text.
UserMessage string `json:"user_text"`
// AssistantResponse is the turn's assistant response text.
AssistantResponse string `json:"assistant_text"`
}
MemoryTurnInput is the operator-supplied conversation turn the `memory.put` admin method appends. It carries only the user / assistant text — never trajectory internals; the runtime owns the timestamp.
type MetricsSnapshot ¶
type MetricsSnapshot struct {
// Counters is the flat counter-metric slice.
Counters []NamedCounter `json:"counters"`
// Histograms is the flat histogram-metric slice.
Histograms []NamedHistogram `json:"histograms"`
// Gauges is the flat gauge-metric slice.
Gauges []NamedGauge `json:"gauges"`
// SnapshotAt is the unix-millis timestamp the metrics were read.
SnapshotAt int64 `json:"snapshot_at"`
}
MetricsSnapshot is the metrics.snapshot response: a Protocol-shaped projection over the telemetry.MetricsRegistry. The wire shape is a flat slice per metric kind — counters, histograms, gauges — carrying plain numbers. NO OpenTelemetry SDK type crosses the Protocol boundary (RFC §5.1 / CLAUDE.md §13 single-source rule).
func (MetricsSnapshot) HasHighCardinalityLabel ¶
func (m MetricsSnapshot) HasHighCardinalityLabel() (metric, label string, found bool)
HasHighCardinalityLabel reports the first (metric-name, label-key) pair in the snapshot that carries a forbidden high-cardinality label key, or empty strings + false when the snapshot is clean. It is the `cardinalitylint`-style guard for the metrics.snapshot wire boundary: a projection that lets a `run_id` / `trace_id` / `span_id` label reach the wire is a cardinality-explosion bug.
type NamedCounter ¶
type NamedCounter struct {
// Name is the metric name.
Name string `json:"name"`
// Value is the counter's current value.
Value float64 `json:"value"`
// Labels carries the metric's low-cardinality label set. A
// high-cardinality label (run_id / trace_id / span_id) never appears
// here — the cardinality firewall gates it on the SDK side,
// and MetricsSnapshot.HasHighCardinalityLabel is the wire-boundary
// cardinalitylint guard (exercised by the posture type tests).
Labels map[string]string `json:"labels,omitempty"`
}
NamedCounter is one counter metric in a MetricsSnapshot: a name, its current monotonic value, and its low-cardinality labels.
type NamedGauge ¶
type NamedGauge struct {
// Name is the metric name.
Name string `json:"name"`
// Value is the gauge's current value.
Value float64 `json:"value"`
// Labels carries the metric's low-cardinality label set.
Labels map[string]string `json:"labels,omitempty"`
}
NamedGauge is one gauge metric in a MetricsSnapshot.
type NamedHistogram ¶
type NamedHistogram struct {
// Name is the metric name.
Name string `json:"name"`
// Count is the total observation count.
Count uint64 `json:"count"`
// Sum is the sum of all observed values.
Sum float64 `json:"sum"`
// Buckets is the cumulative per-bucket count slice.
Buckets []HistogramBucket `json:"buckets,omitempty"`
// Labels carries the metric's low-cardinality label set.
Labels map[string]string `json:"labels,omitempty"`
}
NamedHistogram is one histogram metric in a MetricsSnapshot.
type PauseArtifactRef ¶
type PauseArtifactRef struct {
// ID is the content-addressed identifier (`{namespace}_{sha256[:12]}`).
ID string `json:"id"`
// MimeType is the IANA media type, when known.
MimeType string `json:"mime_type,omitempty"`
// SizeBytes is the length of the referenced bytes.
SizeBytes int64 `json:"size_bytes,omitempty"`
// Filename is metadata only (never used for path construction).
Filename string `json:"filename,omitempty"`
// SHA256 is the full hex digest of the referenced bytes.
SHA256 string `json:"sha256,omitempty"`
}
PauseArtifactRef is the by-reference shape a `PauseSnapshot` carries when the pause record's `Payload` serialised size meets or exceeds the configured heavy-content threshold. It mirrors a subset of `internal/artifacts.ArtifactRef` but is a flat wire type — the Protocol owns its vocabulary; runtime Go structs never leak (RFC §5.1 / CLAUDE.md §13 single-source rule). It is the same flat shape `SearchResultRow.Ref` (`SearchArtifactRef`) uses, kept as a distinct type so a future divergence in either surface does not whipsaw the other.
type PauseFilter ¶
type PauseFilter struct {
// Status filters by lifecycle state; empty defaults to ["paused"].
// Each value must be a canonical PauseSnapshotState.
Status []string `json:"status,omitempty"`
// TenantIDs narrows to a tenant set; empty defaults to the
// caller's own tenant. A foreign tenant OR len>1 requires admin.
TenantIDs []string `json:"tenant_ids,omitempty"`
// UserIDs narrows to a user set within the visible tenants.
UserIDs []string `json:"user_ids,omitempty"`
// SessionIDs narrows to a session set.
SessionIDs []string `json:"session_ids,omitempty"`
// RunIDs narrows to a run set.
RunIDs []string `json:"run_ids,omitempty"`
// Reasons narrows to one or more canonical pause reasons.
Reasons []string `json:"reasons,omitempty"`
// Since is an optional lower bound on PausedAt (inclusive).
Since time.Time `json:"since,omitempty"`
// Until is an optional upper bound on PausedAt (inclusive).
Until time.Time `json:"until,omitempty"`
}
PauseFilter narrows the `pause.list` response. An empty filter means "the caller's own identity scope, status=paused" — the intervention-queue default. Supplying a `TenantIDs` value that reaches OUTSIDE the caller's own tenant (or naming more than one tenant) requires the `auth.ScopeAdmin` scope claim; a missing-claim cross-tenant request is rejected loudly with `CodeIdentityScopeRequired` (HTTP 403) — NEVER silently downgraded to an empty result set.
type PauseListRequest ¶
type PauseListRequest struct {
// Identity is the request's identity scope. The triple is
// mandatory; an incomplete triple fails the request closed at the
// Protocol edge with CodeIdentityRequired (401).
Identity IdentityScope `json:"identity"`
// Filter narrows the snapshot. Empty filter = caller's own
// identity scope, status=paused.
Filter PauseFilter `json:"filter,omitempty"`
// Page is the 1-based page number; defaults to 1 when zero. A
// negative Page is rejected with CodeInvalidRequest (400).
Page int `json:"page,omitempty"`
// PageSize is the per-page row count. Defaults to
// DefaultPauseListPageSize (50) when zero; values above
// MaxPauseListPageSize (200) — or negative — are rejected with
// CodeInvalidRequest (400). Never silently clamped.
PageSize int `json:"page_size,omitempty"`
}
PauseListRequest is the wire request for the `pause.list` method.
Identity is mandatory at the Protocol edge per RFC §5.5 — the request flows out of an auth-verified identity in ctx, never trusted from the body. The `Identity` field exists for the trust-based carrier-header posture and for body-side echo; the pause-list handler reads the verified identity from ctx (preferred) and defends the body identity against it.
type PauseListResponse ¶
type PauseListResponse struct {
// Snapshots is the page of pause records, ordered PausedAt
// descending (newest first) for a deterministic intervention
// queue.
Snapshots []PauseSnapshot `json:"snapshots"`
// Page is the 1-based page number this response covers.
Page int `json:"page"`
// PageSize is the per-page row count applied.
PageSize int `json:"page_size"`
// PageCount is the total number of pages over the filtered set.
PageCount int `json:"page_count"`
// TotalRows is the total filtered row count across all pages.
TotalRows int `json:"total_rows"`
// Truncated is true when a status=resumed filter aged out beyond
// the in-memory registry's retention. The Coordinator's
// resumed-records retention is bounded by the destructive-on-resume
// contract (coordinator.go) — a resumed Token is
// queryable only until the Coordinator clears it. Operators
// inspecting historical resume activity should use
// `events.subscribe` on the `pause.resumed` topic instead.
Truncated bool `json:"truncated,omitempty"`
}
PauseListResponse is the wire response for the `pause.list` method.
type PauseSnapshot ¶
type PauseSnapshot struct {
// Token is the opaque runtime-issued pause Token (RFC §6.3). A
// client never constructs or parses it; it is the handle the
// `resume` / `approve` / `reject` methods take.
Token string `json:"token"`
// Reason is one of the four canonical pause reasons (RFC §6.3).
Reason string `json:"reason"`
// State is the lifecycle state — "paused" or "resumed".
State PauseSnapshotState `json:"state"`
// Identity is the (tenant, user, session [, run]) the pause was
// recorded under. Flat strings — never a re-export of the runtime
// identity quadruple.
Identity IdentityScope `json:"identity"`
// PausedAt is the wall-clock time the pause was recorded.
PausedAt time.Time `json:"paused_at"`
// ResumedAt is the wall-clock time Resume was called; the zero
// value (omitted) unless State == "resumed".
ResumedAt time.Time `json:"resumed_at,omitempty"`
// Payload is the sanitised pause payload INLINE when its serialised
// size is below the heavy-content threshold. Otherwise the runtime
// routes it through the ArtifactStore and ships PayloadRef instead
// (context-window safety net applied to Protocol snapshots).
// Exactly one of Payload / PayloadRef is populated for a pause
// carrying a payload; both are empty for a payload-free pause.
Payload map[string]any `json:"payload,omitempty"`
// PayloadRef is populated when the pause record's Payload exceeded
// the heavy-content threshold. The Console fetches the
// bytes via `artifacts.get` / `artifacts.get_ref` when it wants
// them. When PayloadRef is set, Payload is nil.
PayloadRef *PauseArtifactRef `json:"payload_ref,omitempty"`
}
PauseSnapshot is the wire projection of a single Coordinator pause record. Cross-package single source per CLAUDE.md §8; the typed Protocol client regenerates from this without hand-editing.
type PauseSnapshotState ¶
type PauseSnapshotState string
PauseSnapshotState is the typed enum of pause-record lifecycle states the `pause.list` snapshot projects. It is the wire projection of the runtime-internal `pauseresume.State`; the Protocol owns its own vocabulary (RFC §5.1 / CLAUDE.md §13 single-source rule) so the wire shape never re-exports a runtime Go type.
const ( PauseStatePaused PauseSnapshotState = "paused" PauseStateResumed PauseSnapshotState = "resumed" )
Canonical pause-snapshot states. The set is closed — a pause record is either still parked or already resumed.
type RateLimitView ¶
type RateLimitView struct {
// Capacity is the bucket ceiling (max reservable tokens). 0 disables
// the rate limit even if the refill knobs are set.
Capacity int `json:"capacity"`
// RefillTokens are added to the bucket every refill tick.
RefillTokens int `json:"refill_tokens"`
// RefillIntervalMS is the refill tick duration in milliseconds. The
// Go side holds a time.Duration; this is its millisecond projection.
RefillIntervalMS int64 `json:"refill_interval_ms"`
}
RateLimitView is the wire projection of a tier's token-bucket configuration. The internal `governance.RateLimitConfig` carries a `time.Duration` for the refill interval; the wire type carries the equivalent milliseconds as an int64 so the JSON is unambiguous across language clients (a `time.Duration` marshals as a raw nanosecond integer, which a non-Go client cannot interpret).
type ReadMCPResourceRequest ¶ added in v1.4.0
type ReadMCPResourceRequest struct {
// Identity is the (tenant, user, session) scope the read runs under.
// Mandatory — an incomplete triple fails closed.
Identity IdentityScope `json:"identity"`
// ServerID is the MCP server (source id) hosting the resource.
ServerID string `json:"server_id"`
// ResourceURI is the resource to fetch — the `ui://`-scheme URI of
// an MCP App's UI document for app fetches.
ResourceURI string `json:"resource_uri"`
}
ReadMCPResourceRequest is the `mcp.servers.read_resource` request body. Identity is mandatory.
type ReadMCPResourceResponse ¶ added in v1.4.0
type ReadMCPResourceResponse struct {
// ResourceURI echoes the fetched resource URI.
ResourceURI string `json:"resource_uri"`
// MIMEType is the resource's declared media type.
MIMEType string `json:"mime_type,omitempty"`
// Content is the inline resource bytes, populated ONLY when the
// content is below the heavy-content threshold. Empty when
// ArtifactRef is set.
Content string `json:"content,omitempty"`
// ArtifactRef is the by-reference stub, populated when the content
// meets or exceeds the heavy-content threshold. Nil when Content is
// set.
ArtifactRef *MCPResourceArtifactRef `json:"artifact_ref,omitempty"`
// ProtocolVersion echoes the Protocol version the Runtime answered
// under so a client can detect a version skew.
ProtocolVersion string `json:"protocol_version"`
}
ReadMCPResourceResponse is the `mcp.servers.read_resource` reply. EXACTLY ONE of Content / ArtifactRef is set. Content carries the inline bytes when the resource is below the heavy-content threshold; ArtifactRef carries the by-reference stub when it meets or exceeds the threshold (a loud bypass event accompanies the offload — never a silent truncation, never an inline leak).
type RetentionHorizon ¶ added in v1.13.0
type RetentionHorizon struct {
// Surface names the durable surface this horizon covers — one of
// "events", "tasks", "sessions". The "events" entry also covers the
// conversation-history read, whose substrate IS the event log.
Surface string `json:"surface"`
// Scope names the identity scope this horizon was measured AT — one
// of "runtime" (identity-free, the whole retained set), "tenant" (the
// caller's tenant), or "session" (the caller's full triple). It makes
// the ABSENCE of a value representable: a consumer reading a
// no-timestamp entry distinguishes `scope:"runtime"` + no-timestamp
// ("the runtime retains nothing — a trustworthy empty") from
// `scope:"session"` / `scope:"tenant"` + no-timestamp ("nothing at
// YOUR scope — the runtime-wide truth is not observable here") and so
// degrades honestly (marks a fleet window's completeness unverifiable)
// rather than silently trusting a shorter or absent horizon as
// runtime-wide truth. The `events` horizon is always "runtime"; the
// `tasks` / `sessions` horizons are "session" / "tenant" for an
// ordinary caller and widen to "runtime" for a verified admin /
// console:fleet fleet-observe caller. Omitted (empty) for an
// older/headless wiring that does not stamp a scope.
Scope string `json:"scope,omitempty"`
// OldestRetainedAt is the RFC-3339 wall-clock time of the oldest row
// the surface currently retains AT `Scope`. It is a pointer so a nil
// value is genuinely OMITTED from the JSON (a zero `time.Time` value
// would marshal as a real-looking "0001-01-01T00:00:00Z" and defeat
// the absence-representable contract). Nil/absent when the surface
// holds no rows at that scope — never a fabricated value. Read WITH
// `Scope`: an omitted timestamp is a true empty only when `Scope` is
// "runtime"; at "session" / "tenant" it means the runtime-wide horizon
// is simply not observable at the caller's scope.
OldestRetainedAt *time.Time `json:"oldest_retained_at,omitempty"`
}
RetentionHorizon is one durable surface's OBSERVED oldest-retained timestamp — the operational answer to "how far back does this runtime actually hold data?" that a fleet consumer needs BEFORE issuing a windowed read, so a merged "last 7 days" view over heterogeneous runtimes can mark "this runtime retains only back to X" rather than imply a complete window.
The value is OBSERVED, never a configured claim: it is the wall-clock time of the oldest row the surface currently retains, read live from the store. Harbor has no retention/pruning knob — the durable event log is gap-free and untrimmed — so there is no configured duration to echo; a configured "keep 7d" on a two-day-old deployment would be a lie the observed head is not. It is the honest forward-looking companion to the at-read `truncated` flag a windowed read carries: the horizon says "expect gaps before X" ahead of the read; `truncated` says "this read hit the gap" after it.
OldestRetainedAt is "oldest RETAINED", not "oldest ever": a ring-backed events surface advances its horizon as it evicts, and the session registry's idle GC reaps old sessions — so the horizon tracks what is still held, which is exactly the honest signal a consumer needs.
type RunOverrides ¶
type RunOverrides struct {
// SessionID is the session the override applies to. Mandatory — an
// empty SessionID fails the request closed at the Protocol edge
// (identity is mandatory, CLAUDE.md §6 rule 9). The tenant and user
// components of the isolation triple are inferred from the verified
// JWT; only the session is named on the wire.
SessionID string `json:"session_id"`
// ReasoningEffort, when non-nil, overrides the LLM reasoning-effort
// hint for the next message. Values follow the bound LLM provider's
// taxonomy (e.g. `low` / `medium` / `high`); the runtime validates
// the string against the provider's accepted set and rejects an
// unknown value with CodeInvalidRequest.
ReasoningEffort *string `json:"reasoning_effort,omitempty"`
// Temperature, when non-nil, overrides the sampling temperature for
// the next message. The runtime rejects a value outside the closed
// range [0, 2] with CodeInvalidRequest.
Temperature *float64 `json:"temperature,omitempty"`
// MaxTokens, when non-nil, overrides the per-message MaxTokens
// governance ceiling for the next message. The runtime rejects a
// non-positive value with CodeInvalidRequest.
MaxTokens *int `json:"max_tokens,omitempty"`
// SystemPromptOverride, when non-nil, replaces the agent's system
// prompt for the next message only. An empty string is a valid
// override (it clears the system prompt for that one message);
// nil means "leave the agent's configured system prompt in place".
SystemPromptOverride *string `json:"system_prompt_override,omitempty"`
// Model, when non-nil, overrides the model the next message's run
// requests. The runtime rejects a model with no configured
// `ModelProfile` with CodeInvalidRequest (fail loud at set time). The
// session-level model swap — it wins over the tenant default and the
// config default for that one message (session › tenant › config).
Model *string `json:"model,omitempty"`
}
RunOverrides is the wire projection of the next-message override parameters the Console Playground page records via `runs.set_overrides`.
Every tuning field is a pointer so the absent / present distinction is preserved on the wire: a nil field means "leave the runtime default in place"; a non-nil field means "apply this value to the next message". This is deliberate — an operator who sets only reasoning effort must not implicitly zero the temperature.
The override is session-scoped and one-shot: it applies to the NEXT `user_message` / `start` in the session and is consumed at that point. It does NOT apply retroactively to past messages.
type RunSetOverridesRequest ¶
type RunSetOverridesRequest struct {
// Identity is the request's identity scope. The triple is mandatory;
// the runtime cross-checks Identity.Session against
// Overrides.SessionID and rejects a mismatch with CodeScopeMismatch
// (a caller cannot set an override for a session outside its own
// verified scope).
Identity IdentityScope `json:"identity"`
// Overrides is the next-message override payload.
Overrides RunOverrides `json:"overrides"`
}
RunSetOverridesRequest is the wire request for the `runs.set_overrides` Protocol method. It carries the request's identity scope plus the override payload.
type RunSetOverridesResponse ¶
type RunSetOverridesResponse struct {
// AppliedAt is the runtime timestamp at which the override was
// recorded. It is the moment the override entered the session's
// pending-override slot — not the moment a subsequent message
// consumed it.
AppliedAt time.Time `json:"applied_at"`
// ProtocolVersion echoes the Protocol version the Runtime answered
// with, so a Console can assert wire compatibility.
ProtocolVersion string `json:"protocol_version"`
}
RunSetOverridesResponse is the wire response for the `runs.set_overrides` Protocol method.
type RuntimeCounters ¶
type RuntimeCounters struct {
// EventsPerSecond is the recent bus-emit rate.
EventsPerSecond float64 `json:"events_per_second"`
// TasksRunning is the count of foreground/background tasks
// currently in a running state.
TasksRunning int64 `json:"tasks_running"`
// BackgroundJobsActive is the count of background jobs in flight.
BackgroundJobsActive int64 `json:"background_jobs_active"`
// MCPConnectionsHealthy is the count of healthy MCP southbound
// connections.
MCPConnectionsHealthy int64 `json:"mcp_connections_healthy"`
// SessionsActive is the count of currently-active sessions.
SessionsActive int64 `json:"sessions_active"`
// SnapshotAt is the unix-millis timestamp the counters were read.
SnapshotAt int64 `json:"snapshot_at"`
}
RuntimeCounters is the runtime.counters response: the low-cardinality live counters the Console footer / sidebar chips render. Every field is a roll-up — never a per-run / per-task / per-session breakdown (the cardinality firewall posture, mirrored at the Protocol boundary).
type RuntimeDrivers ¶
type RuntimeDrivers struct {
// Subsystems is the per-subsystem driver slice.
Subsystems []SubsystemDriver `json:"subsystems"`
}
RuntimeDrivers is the runtime.drivers response: the configured driver names per persistence-shaped subsystem so an operator can see whether the Runtime is dev (in-mem) or production (Postgres) without grepping config.
type RuntimeHealth ¶
type RuntimeHealth struct {
// Subsystems is the per-subsystem readiness slice — one entry per
// subsystem the runtime knows about.
Subsystems []SubsystemHealth `json:"subsystems"`
// Retention is the observed retention horizon per durable surface —
// the oldest-retained timestamp for "events", "tasks", and
// "sessions". Additive: an older client that does not read it is
// unaffected. A surface with no rows yet, or a runtime that wired no
// retention seam for it, simply omits its entry (the whole slice is
// omitted when empty). Values are OBSERVED, never configured claims —
// see RetentionHorizon.
Retention []RetentionHorizon `json:"retention,omitempty"`
}
RuntimeHealth is the runtime.health response: a per-subsystem readiness rollup across the runtime's registered subsystems, plus the observed per-surface retention horizons.
type RuntimeInfo ¶
type RuntimeInfo struct {
// InstanceID is a stable per-deployment identifier minted at boot.
// A Console managing several Runtimes keys each attachment by it.
InstanceID string `json:"instance_id"`
// DisplayName is the operator-configured friendly name for this
// Runtime. Empty when the operator configured none — never the
// host's machine name without explicit operator config.
DisplayName string `json:"display_name,omitempty"`
// BuildVersion is the Harbor build version string (e.g. a release
// tag or a `v0.0.0-dev` dev marker).
BuildVersion string `json:"build_version"`
// BuildCommit is the VCS revision the binary was built from, or
// "unknown" when the build carried no VCS stamp.
BuildCommit string `json:"build_commit"`
// BuildDate is the build timestamp (RFC 3339), or empty when the
// build carried no date stamp.
BuildDate string `json:"build_date,omitempty"`
// BuildGoVersion is the Go toolchain version the binary was built
// with.
BuildGoVersion string `json:"build_go_version"`
// ProtocolVersion is the pinned Harbor Protocol version the Runtime
// speaks (the ProtocolVersion constant). A client parses it and
// checks Version.Compatible against its own.
ProtocolVersion string `json:"protocol_version"`
// Capabilities is the set of Protocol surfaces the Runtime
// advertises as live — the same set CurrentHandshake() carries.
Capabilities []Capability `json:"capabilities"`
// UptimeSeconds is the number of whole seconds since the Runtime
// process started.
UptimeSeconds int64 `json:"uptime_seconds"`
// MCPAppDisplayModes is the set of MCP App (`io.modelcontextprotocol/ui`)
// display modes this host can render, declared by the deployment's
// `tools.mcp_app_host.display_modes` config. A Protocol client (the
// Console) reads it to seed the `ui/initialize` host-context
// `availableDisplayModes` it advertises to a rendered app — display modes
// are a host-context value, not an MCP capability field. Empty when the
// deployment declared none.
MCPAppDisplayModes []string `json:"mcp_app_display_modes,omitempty"`
// WireSurfaceDigest is the opaque, stable name-level digest of the
// runtime's canonical Protocol wire surface — a `sha256:…` fingerprint
// over the Protocol version, method names, error codes, capability
// strings, and wire-type names. A client compares it against the digest
// it was built against and surfaces a loud drift signal on a mismatch,
// so coarse wire drift is detectable at connect-time without exposing
// field shapes over the wire. It covers the SHAPE OF NAMES, not field
// shapes and not event-type names.
WireSurfaceDigest string `json:"wire_surface_digest"`
}
RuntimeInfo is the runtime.info response: the Runtime's build identity, Protocol version, advertised capabilities, uptime, and operator-facing identifiers. A Console attached to multiple Runtimes uses InstanceID as the per-attachment stable key.
type RuntimeInfoRequest ¶
type RuntimeInfoRequest struct {
// Identity is the caller's identity scope. The PostureSurface
// validates the triple and gates cross-tenant reads on the admin
// scope claim.
Identity IdentityScope `json:"identity"`
}
RuntimeInfoRequest is the shared request shape for the five posture methods. It carries only the identity scope — the methods are read-only and take no payload.
Identity is mandatory at the Protocol edge (RFC §5.5). The Tenant field is required for every posture method; the User and Session fields are required when the projection is session-scoped (runtime.counters returns tenant-wide rollups for a Tenant-only scope, the session's slice when a Session is supplied). A cross-tenant request — Identity.Tenant differing from the caller's verified tenant requires the admin scope per the closed admin-scope set.
type SearchArtifactRef ¶
type SearchArtifactRef struct {
// ID is the content-addressed identifier (`{namespace}_{sha256[:12]}`).
ID string `json:"id"`
// MimeType is the IANA media type, when known.
MimeType string `json:"mime_type,omitempty"`
// SizeBytes is the length of the referenced bytes.
SizeBytes int64 `json:"size_bytes,omitempty"`
// Filename is metadata only (never used for path construction).
Filename string `json:"filename,omitempty"`
// SHA256 is the full hex digest of the referenced bytes.
SHA256 string `json:"sha256,omitempty"`
}
SearchArtifactRef is the by-reference shape a `SearchResultRow` carries when the underlying entity's preview payload would exceed the heavy-content threshold. It mirrors a subset of `internal/artifacts.ArtifactRef` but is a flat wire type — the Protocol owns its vocabulary; runtime Go structs never leak (RFC §5.1 / CLAUDE.md §13 single-source rule).
type SearchFacet ¶
type SearchFacet struct {
// Key is the facet dimension name (e.g. `tasks.status`).
Key string `json:"key"`
// Value is the facet's selected value (e.g. `running`).
Value string `json:"value"`
}
SearchFacet is a per-index dimension selector — e.g. `{Key:"tasks.status", Value:"running"}` or `{Key:"events.type", Value:"tool.failed"}`. Unknown facets are silently ignored at V1 (post-V1 may tighten to error).
type SearchFilter ¶
type SearchFilter struct {
// TenantIDs narrows the search to these tenants; empty defaults to
// the caller's authenticated tenant. A value outside the caller's
// own tenant requires the `auth.ScopeAdmin` claim.
TenantIDs []string `json:"tenant_ids,omitempty"`
// UserIDs narrows the search to these users; empty defaults to the
// caller's authenticated user.
UserIDs []string `json:"user_ids,omitempty"`
// SessionIDs narrows the search to these sessions; empty defaults to
// the caller's authenticated session.
SessionIDs []string `json:"session_ids,omitempty"`
// Since is the inclusive lower bound of the result time-window; the
// zero value imposes no lower bound.
Since time.Time `json:"since,omitempty"`
// Until is the inclusive upper bound of the result time-window; the
// zero value imposes no upper bound.
Until time.Time `json:"until,omitempty"`
}
SearchFilter narrows results to the caller's identity scope and optional time-window. The TenantIDs / UserIDs / SessionIDs fields default to the caller's authenticated triple; supplying values that reach OUTSIDE the caller's own scope requires the `auth.ScopeAdmin` scope claim (closed two-scope set; reuse for search). A missing-claim cross-tenant request is rejected loudly with `CodeAuthRejected` (HTTP 403) — NEVER silently downgraded to an empty result set.
type SearchIndex ¶
type SearchIndex string
SearchIndex is the typed enum of canonical search indexes the runtime-side `search.*` cluster ships in a later phase. Four indexes — sessions, tasks, events, artifacts — match the high-cardinality runtime-side split. Console-side Tools / Agents / Flows / MCP catalog searches do NOT appear here: those land in their per-page Console phases (73c/d/e/f/g/i/k) per the split.
const ( SearchIndexSessions SearchIndex = "sessions" SearchIndexTasks SearchIndex = "tasks" SearchIndexEvents SearchIndex = "events" SearchIndexArtifacts SearchIndex = "artifacts" )
Canonical search-index values. The set is closed; a new index is a new Protocol-surface phase.
type SearchRequest ¶
type SearchRequest struct {
// Query is the free-text query — substring / prefix match against
// the searched fields per index. Empty Query is permitted (lists
// everything in scope subject to filters).
Query string `json:"query,omitempty"`
// Indexes selects which runtime-side indexes `search.query` should
// fan out to. Empty means "all four." Ignored by the four per-index
// methods. Unknown index values are rejected with
// `CodeInvalidRequest`.
Indexes []SearchIndex `json:"indexes,omitempty"`
// Filter narrows results. Identity defaulting + cross-tenant gating
// happens in the search handler — the wire surface accepts every
// caller's filter and rejects elevated requests loudly.
Filter SearchFilter `json:"filter,omitempty"`
// Facets are optional per-index dimension selectors. The runtime
// applies whichever facets are recognised for the index being
// searched and silently ignores the rest.
Facets []SearchFacet `json:"facets,omitempty"`
// Page is the 1-based page number; defaults to 1 when zero.
Page int `json:"page,omitempty"`
// PageSize is the per-page row count. Defaults to
// `DefaultSearchPageSize` (20) when zero; values above
// `MaxSearchPageSize` (200) are rejected with `CodeInvalidRequest`.
PageSize int `json:"page_size,omitempty"`
}
SearchRequest is the shared wire shape for all five `search.*` methods. `search.query` honours `Indexes` (the palette dispatcher selects 1..4 of the runtime-side indexes); the four per-index methods ignore `Indexes` and operate on their own index.
Identity is mandatory at the Protocol edge per RFC §5.5 — the request flows out of an auth-verified identity in ctx, never trusted from the body. The `Filter` field supplies optional scope-narrowing within the caller's verified identity (and, with the admin claim, cross-tenant expansion).
func (SearchRequest) PageBounds ¶
func (r SearchRequest) PageBounds() (page, size int)
PageBounds returns the normalised (page, size) pair without mutating the receiver. Useful for handlers that need to validate-then-pass.
type SearchResponse ¶
type SearchResponse struct {
// Rows is the page slice — at most `PageSize` rows. Empty when
// the filter matched nothing.
Rows []SearchResultRow `json:"rows"`
// Page echoes the (defaulted) request page.
Page int `json:"page"`
// PageSize echoes the (defaulted) per-page size.
PageSize int `json:"page_size"`
// PageCount is the total page count given TotalCount + PageSize.
PageCount int `json:"page_count"`
// TotalCount is the total matching row count BEFORE pagination.
TotalCount int64 `json:"total_count"`
// HasMore is a convenience flag — true when Page < PageCount.
HasMore bool `json:"has_more"`
// ProtocolVersion echoes the Protocol version the Runtime answered
// under so a client can detect a version skew.
ProtocolVersion string `json:"protocol_version"`
}
SearchResponse is the uniform response shape returned by every `search.*` method. Pagination is identical across the cluster.
func (SearchResponse) MarshalJSON ¶
func (r SearchResponse) MarshalJSON() ([]byte, error)
MarshalJSON is the standard json.Marshaler — kept explicit so the SearchResponse shape stays stable across a refactor that might reorder fields. Round-trip is verified by search_test.go.
type SearchResultRow ¶
type SearchResultRow struct {
// Index identifies which subsystem produced the row. Required.
Index SearchIndex `json:"index"`
// ID is the entity identifier (session ID / task ID / event ID
// (composed `<session>:<sequence>`) / artifact ID).
ID string `json:"id"`
// TenantID + UserID + SessionID + RunID flatten the runtime's
// identity quadruple so a Protocol client never round-trips a
// runtime Go struct. RunID is empty for session-scoped entities.
TenantID string `json:"tenant_id"`
UserID string `json:"user_id"`
SessionID string `json:"session_id"`
RunID string `json:"run_id,omitempty"`
// OccurredAt is the row's anchor timestamp — for sessions, the
// open / last-seen / close time; for tasks, UpdatedAt; for events,
// OccurredAt; for artifacts, the put time (mirrored by the
// driver's UpdatedAt when known).
OccurredAt time.Time `json:"occurred_at,omitempty"`
// Preview is the redacted short summary (≤ heavy-content
// threshold). Empty when Ref is populated.
Preview string `json:"preview,omitempty"`
// Ref is populated when the underlying entity's preview would
// exceed the heavy-content threshold. The Console fetches
// the bytes via `artifacts.get` / `artifacts.get_ref` when it
// wants them.
Ref *SearchArtifactRef `json:"ref,omitempty"`
// Facets carries per-index dimension values relevant to the row
// (e.g. `{"status":"running"}` for tasks). The set of populated
// keys per index is documented per Searcher implementation.
Facets map[string]string `json:"facets,omitempty"`
}
SearchResultRow is the uniform result-row shape across all five `search.*` methods. `Preview` is REDACTED via `audit.Redactor` before emission. Heavy payloads (≥ the heavy-output threshold) ship as a populated `Ref` field, NEVER inline bytes — `Preview` is then empty.
type SessionFilter ¶
type SessionFilter struct {
// Statuses restricts to sessions whose Status is in this set.
Statuses []SessionStatus `json:"statuses,omitempty"`
// AgentIDs restricts to sessions whose AgentID is in this set. The
// session→agent binding is unpopulated in V1 (see SessionRow.AgentID),
// so a non-empty AgentIDs facet fails loud with `invalid_request`
// rather than returning a silent empty page. The free-text Query axis is
// NOT rejected when it touches the agent sub-fields — it still matches
// the populated session_id / user_id.
AgentIDs []string `json:"agent_ids,omitempty"`
// UserIDs restricts to sessions whose UserID is in this set.
UserIDs []string `json:"user_ids,omitempty"`
// TenantIDs restricts to sessions whose TenantID is in this set.
// A TenantIDs entry naming a tenant other than the caller's
// verified tenant requires the `auth.ScopeAdmin` claim.
TenantIDs []string `json:"tenant_ids,omitempty"`
// StartedWindow filters by the session's StartedAt timestamp.
StartedWindow Window `json:"started_window,omitempty"`
// HasIntervention, when non-nil, restricts to sessions that do
// (true) / do not (false) have a pending intervention.
HasIntervention *bool `json:"has_intervention,omitempty"`
// HasFailedTask, when non-nil, restricts to sessions that do
// (true) / do not (false) have a failed task.
HasFailedTask *bool `json:"has_failed_task,omitempty"`
// CostAboveCents, when non-nil, restricts to sessions whose
// TotalCostCents is strictly above this threshold.
CostAboveCents *int64 `json:"cost_above_cents,omitempty"`
// Query is a free-text substring filter over session id + agent
// name + user. When non-empty, the runtime forwards it to the
// `search.sessions` index and the SessionFilter
// axes are post-search refinements (forward then filter).
Query string `json:"query,omitempty"`
}
SessionFilter is the server-enforced filter on `sessions.list`. An empty facet slice matches every value on that axis. The filter is applied AFTER the identity-scope predicate — it never widens visibility (CLAUDE.md §6).
type SessionRow ¶
type SessionRow struct {
// SessionID is the stable session identifier.
SessionID string `json:"session_id"`
// Status is the session's lifecycle status.
Status SessionStatus `json:"status"`
// AgentID is the registered agent identifier the session ran under.
//
// Nullable by design: there is NO single-valued session→agent binding
// today — the Agent Registry keys agents by the identity triple
// (agent_id is NOT an isolation principal, CLAUDE.md §6) and a session
// may run several agents over its life. The runtime cannot name one
// authoritative agent, so the field is `nil` (omitted on the wire) — a
// REPRESENTABLE absence ("we don't have this") that a consumer can tell
// apart from an empty-string agent id. A `filter.agent_ids` facet over
// this unpopulated binding fails loud with `invalid_request` rather than
// returning a silent empty page; the field is never fabricated into a
// believable-but-false value.
AgentID *string `json:"agent_id,omitempty"`
// AgentName is the planner-facing agent display name. Nullable for the
// same reason as AgentID — `nil` when no single agent binding is
// modelled, omitted on the wire.
AgentName *string `json:"agent_name,omitempty"`
// UserID is the user component of the session's identity triple.
UserID string `json:"user_id"`
// TenantID is the tenant component of the session's identity triple.
TenantID string `json:"tenant_id"`
// StartedAt is the session-open timestamp.
StartedAt time.Time `json:"started_at"`
// LastActivityAt is the timestamp of the most-recent activity.
LastActivityAt time.Time `json:"last_activity_at"`
// Duration is the elapsed span (LastActivityAt-StartedAt for closed
// sessions, now-StartedAt for live ones). Marshalled as int64
// nanoseconds (Go's time.Duration JSON form).
Duration time.Duration `json:"duration"`
// TasksCount is the number of tasks the session has spawned.
TasksCount int `json:"tasks_count"`
// EventsCount is the number of events the session has emitted.
EventsCount int `json:"events_count"`
// TotalCostCents is the session's accumulated LLM cost in US cents.
TotalCostCents int64 `json:"total_cost_cents"`
// TotalTokens is the session's accumulated LLM token count.
TotalTokens int64 `json:"total_tokens"`
// HasPendingIntervention reports whether the session has a pause
// awaiting resume / approval.
HasPendingIntervention bool `json:"has_pending_intervention"`
// HasFailedTask reports whether the session has at least one failed
// task.
HasFailedTask bool `json:"has_failed_task"`
// Identity is the impersonation triplet. When
// the session is a normal non-impersonated run, only the top-level
// Tenant/User/Session carry meaning and Impersonating is nil; when
// the session is an admin-initiated impersonated run, Actor carries
// the verified admin identity and Impersonating carries the target
// identity the run executed under. The Console Sessions-page
// Identity column renders the Actor triple plus a separate
// `impersonating` chip when Impersonating is non-empty.
Identity IdentityScope `json:"identity"`
// Title is the session's human-readable name, "" when unset.
// Additive field — omitted on the wire when empty.
Title string `json:"title,omitempty"`
// TitleSource records who produced Title: "manual" (set via
// `sessions.set_title`) or "auto" (the runtime's internal auto-namer);
// "" when Title is unset. Additive field — omitted on the wire when
// empty.
TitleSource string `json:"title_source,omitempty"`
// CountersPartial reports that the bounded per-session scan that
// produced the cost / tokens / events counters hit its scan bound (or a
// retention gap): the counts are then an HONEST LOWER BOUND, not exact.
// A `cost_desc` sort or `cost_above_cents` filter over a partial row is
// non-authoritative — the runtime never silently mis-orders or excludes
// it; the consumer renders the counts with a "≥" / lower-bound
// affordance. Additive field — omitted on the wire when false (the
// common case: a session's events fit inside the scan bound).
CountersPartial bool `json:"counters_partial,omitempty"`
}
SessionRow is the catalog-row projection of a session. It is the row shape the Console Sessions-page table renders. Flat, low-cardinality fields — the Console branches on the enum fields.
There is NO Priority field — V1 dropped session-level priority from V1.
type SessionSort ¶
type SessionSort string
SessionSort is the wire enum for the `sessions.list` row ordering.
const ( // SessionSortStartedDesc orders newest-first by StartedAt (default). SessionSortStartedDesc SessionSort = "started_desc" // SessionSortStartedAsc orders oldest-first by StartedAt. SessionSortStartedAsc SessionSort = "started_asc" // SessionSortLastActivityDesc orders most-recently-active first. SessionSortLastActivityDesc SessionSort = "last_activity_desc" // SessionSortCostDesc orders most-expensive first. SessionSortCostDesc SessionSort = "cost_desc" )
Canonical session sort orders — the Sort-By toggle in the mockup.
type SessionStatus ¶
type SessionStatus string
SessionStatus is the wire enum for a session's lifecycle status.
const ( // SessionStatusRunning — the session has at least one running run. SessionStatusRunning SessionStatus = "running" // SessionStatusPaused — the session has a paused run awaiting // resume / approval. SessionStatusPaused SessionStatus = "paused" // SessionStatusCompleted — the session is closed and finished // cleanly. SessionStatusCompleted SessionStatus = "completed" // SessionStatusFailed — the session is closed and at least one run // failed. SessionStatusFailed SessionStatus = "failed" )
Canonical session statuses — the closed set the Sessions-page status facet filters on and the table renders.
type SessionsDeleteRequest ¶ added in v1.7.0
type SessionsDeleteRequest struct {
// Identity is the (tenant, user, session) scope to erase. Mandatory —
// an incomplete triple fails closed with CodeIdentityRequired.
Identity IdentityScope `json:"identity"`
}
SessionsDeleteRequest is the `sessions.delete` request body — the identity-scoped data-lifecycle erasure of a whole session and its scoped data.
The body Identity MUST equal the caller's verified identity: there is NO elevation knob and NO cross-tenant path; a caller erases only their own `(tenant, user, session)`. A body identity mismatching the verified identity is rejected `identity_required` (the defence-in-depth check fires before any further scope logic, so a foreign target can never be named). A session absent under the verified triple is `not_found` (existence is never revealed across identities). A session with a RUNNING task is refused `session_running` (409).
type SessionsDeleteResponse ¶ added in v1.7.0
type SessionsDeleteResponse struct {
// SessionID is the session that was erased.
SessionID string `json:"session_id"`
// Deleted is true when the cascade completed (the session and its
// scoped data were removed).
Deleted bool `json:"deleted"`
// StateRecordsDeleted is the number of StateStore records removed by
// the kind-agnostic scope delete (the session.lifecycle record, run-
// scoped trajectories, planner checkpoints, and the durable event
// stream all live under the triple and all go). Cumulative across
// converging attempts — see the type's doc comment.
StateRecordsDeleted int `json:"state_records_deleted"`
// ArtifactsDeleted is the number of artifacts removed from the
// session's scope. Cumulative across converging attempts — see the
// type's doc comment.
ArtifactsDeleted int `json:"artifacts_deleted"`
// MemoryPurged is true when the session's memory was flushed to a
// clean state.
MemoryPurged bool `json:"memory_purged"`
}
SessionsDeleteResponse reports the erasure outcome with non-sensitive deletion telemetry only — never any erased user content. The counts let an operator confirm the cascade reached every scoped store.
Cumulative-count semantics: if a transient fault interrupts the cascade mid-way and the caller re-invokes `sessions.delete` to converge, the counts below are the TRUE cumulative total actually removed across every attempt — never just the last (converging) attempt's own, possibly-smaller, count. A caller that only ever sees ONE successful response (the common case) reads these exactly as before; the cumulative guarantee only becomes observable across a retried sequence.
type SessionsInspectRequest ¶
type SessionsInspectRequest struct {
// Identity is the (tenant, user, session) scope. Mandatory.
Identity IdentityScope `json:"identity"`
// SessionID is the session to inspect.
SessionID string `json:"session_id"`
}
SessionsInspectRequest is the `sessions.inspect` request body.
type SessionsInspectResponse ¶
type SessionsInspectResponse struct {
// Row is the session's catalog-row projection (same shape as a
// `sessions.list` row).
Row SessionRow `json:"row"`
// RecentInterventions is the capped slice of recent interventions
// (≤ MaxSessionInterventionSummaries), most-recent first.
RecentInterventions []InterventionSummary `json:"recent_interventions"`
// RecentArtifacts is the capped slice of recent artifacts
// (≤ MaxSessionArtifactSummaries), most-recent first.
RecentArtifacts []ArtifactRefSummary `json:"recent_artifacts"`
}
SessionsInspectResponse is the `sessions.inspect` reply — the full per-session snapshot the Console Sessions detail view renders. The Row carries the same projection as a `sessions.list` row; the two capped slices feed the right-rail Recent Interventions / Recent Artifacts cards.
type SessionsListRequest ¶
type SessionsListRequest struct {
// Identity is the (tenant, user, session) scope the listing is
// projected for. Mandatory — an incomplete triple fails closed.
Identity IdentityScope `json:"identity"`
// Filter is the optional facet filter; the zero value lists every
// visible session.
Filter SessionFilter `json:"filter"`
// Sort selects the row ordering; an empty value applies
// SessionSortStartedDesc.
Sort SessionSort `json:"sort,omitempty"`
// Cursor is the opaque pagination cursor returned by a previous
// SessionsListResponse.NextCursor. Empty starts from the first page.
Cursor string `json:"cursor,omitempty"`
// Limit is the rows-per-page; a non-positive value applies
// DefaultSessionListLimit. A value above MaxSessionListLimit is a
// 400 (CodeInvalidRequest) — never a silent clamp.
Limit int `json:"limit,omitempty"`
}
SessionsListRequest is the `sessions.list` request body.
type SessionsListResponse ¶
type SessionsListResponse struct {
// Rows is the page of session rows, in the requested sort order.
Rows []SessionRow `json:"rows"`
// NextCursor is the opaque cursor for the next page; "" when this
// is the last page.
NextCursor string `json:"next_cursor"`
// Truncated is true when the candidate set hit Limit+1 rows — the
// honest "there are more" signal, NEVER a silent exact total.
Truncated bool `json:"truncated"`
}
SessionsListResponse is the `sessions.list` reply: a page of catalog rows plus the opaque next-page cursor.
There is NO exact total count — fail-loudly: an exact O(N) count under high cardinality is not promised. The server emits `Truncated: true` when the candidate set hit Limit+1 rows; the page lazily fetches more pages until NextCursor == "".
type SessionsSetTitleRequest ¶ added in v1.12.0
type SessionsSetTitleRequest struct {
// Identity is the caller's (tenant, user, session) scope. Mandatory —
// an incomplete triple fails closed with CodeIdentityRequired. Tenant
// and User MUST equal the verified identity.
Identity IdentityScope `json:"identity"`
// SessionID is the session to rename — the caller's own connecting
// session or a sibling session of the same (tenant, user).
SessionID string `json:"session_id"`
// Title is the new title. Empty (after trimming) clears the title.
Title string `json:"title"`
}
SessionsSetTitleRequest is the `sessions.set_title` request body — sets or clears a session's human-readable title.
The write scope is the owning `(tenant, user)`: Identity's Tenant/User MUST equal the caller's verified identity (the same defence-in-depth check `sessions.delete` runs — a mismatch is rejected `identity_required` before any further logic). SessionID is a DEDICATED request field and MAY name a sibling session of the caller's own `(tenant, user)` — the motivating consumer renames a sibling session from the Sessions-page list, not only the caller's own connecting session. There is NO elevation knob and NO cross-tenant / cross-user path: a SessionID belonging to a different `(tenant, user)` resolves to `not_found` (existence is never revealed across identities).
The wire verb ALWAYS writes TitleSource = "manual" (an empty Title clears both Title and TitleSource to unset) — "auto" is not expressible over the wire (the runtime's internal auto-naming writer is the only producer), so a manual title can never be forged into an auto-overwritable one.
Title is bounded and single-line: over MaxSessionTitleLen (200) runes, or containing a newline/control character, fails loud with a 400 (CodeInvalidRequest) — never a silent clamp (CLAUDE.md §13).
type SessionsSetTitleResponse ¶ added in v1.12.0
type SessionsSetTitleResponse struct {
// SessionID is the session that was renamed.
SessionID string `json:"session_id"`
// Title is the resulting title ("" when cleared).
Title string `json:"title"`
// TitleSource is the resulting source: "manual" when Title is
// non-empty, "" (unset) when cleared.
TitleSource string `json:"title_source"`
}
SessionsSetTitleResponse is the `sessions.set_title` reply — the resulting title state after the call. Title is user-derived content and is safe to echo back to the SAME caller that just supplied it (unlike the event payload, which stays content-free).
type SizeRange ¶
type SizeRange struct {
// MinBytes, when set, excludes artifacts strictly smaller than it.
MinBytes *int64 `json:"min_bytes,omitempty"`
// MaxBytes, when set, excludes artifacts strictly larger than it.
MaxBytes *int64 `json:"max_bytes,omitempty"`
}
SizeRange is an optional byte-size filter for artifacts.list. Both bounds are inclusive; a nil bound is unbounded on that side.
type StartRequest ¶
type StartRequest struct {
// Identity is the request's identity scope. The triple is mandatory;
// Run is ignored (a `start` mints the run). Scope is ignored.
Identity IdentityScope `json:"identity"`
// Query is the user-facing query that starts the run. Optional —
// some runs are kicked off without a natural-language query.
Query string `json:"query,omitempty"`
// Description is an operator-facing description of the task.
// Optional.
Description string `json:"description,omitempty"`
// Priority is the task's initial scheduling priority. Zero is the
// default priority.
Priority int `json:"priority,omitempty"`
// IdempotencyKey, when non-empty, deduplicates the spawn: a second
// `start` with the same key (namespaced by session) returns the
// existing task handle with Reused=true. Empty disables dedup.
IdempotencyKey string `json:"idempotency_key,omitempty"`
// InputArtifactIDs attach operator-uploaded
// artifacts as multimodal inputs the run consumes on its first
// planner turn. The runtime's per-MIME materializer routes each
// id: `image/*` bytes inline as `ImagePart.DataURL`; everything
// else stays an `ArtifactStub` the LLM routes through the tool
// catalog. The Playground composer's chat-attach control plumbs
// uploaded ids through this field. Empty is the text-only default.
InputArtifactIDs []string `json:"input_artifact_ids,omitempty"`
// InputArtifactDispositions carries the
// OPTIONAL per-attachment disposition hint, keyed by an
// InputArtifactIDs entry. Values: `ref` (emit an `ArtifactStub` +
// `Fetch.Tool` hint — the runtime default for non-image MIMEs),
// `inline` (DataURL inline; `image/*` only at V1.1),
// `provider_native` (opt-in provider-side understanding;
// degrades to `ref` with a logged notice until it ships), or
// `tool:<name>` (force the named catalog tool). The hint is the
// TOP precedence layer: hint > the agent's
// `multimodal.disposition` config map > the runtime default
// (`image/*` → inline, everything else → ref). A key that names
// no InputArtifactIDs entry, or a value outside the grammar, is
// rejected with CodeInvalidRequest. Omitted (the backward-
// compatible default) defers entirely to the lower layers.
InputArtifactDispositions map[string]string `json:"input_artifact_dispositions,omitempty"`
// OutputSchema opts the task-shaped run into per-task structured
// output: a JSON-Schema document (raw bytes) the completed task's
// answer is validated against. When set, the completed task's
// envelope carries the validated `answer_payload` (readable via
// `tasks.get`'s `result_inline` and via a parent run's AwaitTask
// observation); a schema-invalid answer after the correction budget
// fails the task LOUD with the `output_invalid` terminal code, never
// a schemaless success. Absent (the backward-compatible default) →
// byte-identical wire shape and spawn behaviour.
//
// The schema is validated at the Protocol edge BEFORE the task
// spawns: an empty, non-compiling, or over-cap (64 KiB) schema is
// rejected with CodeInvalidRequest and no task is created. It is
// compiled once more at driver run start (the compile the run
// consumes) via the same single implementation.
//
// Streaming posture (mirrors the run-level structured-output
// mechanism): a schema-constrained task SUPPRESSES assistant-content
// and reasoning token deltas on the per-task streaming path
// (`llm.completion.chunk`) — a validate-and-retry loop cannot retract
// already-streamed tokens, so the validated answer arrives once, in
// the envelope. Step boundaries and tool-dispatch events stream as
// today. A documented behaviour choice, not a surprise.
//
// Idempotency: `start` dedupes on `(session, idempotency_key)` and
// folds `output_schema` into the task's content identity — a genuine
// retry (same body, same schema) returns the existing handle; a
// REUSED key with a DIFFERENT schema is caller misuse and is rejected
// loud as an idempotency conflict.
OutputSchema json.RawMessage `json:"output_schema,omitempty"`
}
StartRequest is the wire request for the `start` Protocol method — it asks the Runtime to spawn a new task / foreground run. It maps onto the tasks.TaskRegistry.Spawn surface.
type StartResponse ¶
type StartResponse struct {
// TaskID is the runtime-assigned task identifier for the spawned
// (or, on an idempotency-key match, the existing) task.
TaskID string `json:"task_id"`
// Reused is true when an IdempotencyKey match returned an existing
// task rather than spawning a fresh one.
Reused bool `json:"reused"`
// ProtocolVersion echoes the Protocol version the Runtime answered
// under so a client can detect a version skew.
ProtocolVersion string `json:"protocol_version"`
}
StartResponse is the wire response for the `start` Protocol method.
type StateArtifactRef ¶ added in v1.6.0
type StateArtifactRef struct {
// ID is the content-addressed identifier
// (`{namespace}_{sha256_hex[:12]}`). Well-formed and routable to
// `artifacts.get_ref`.
ID string `json:"id"`
// MimeType is the IANA media type, when known.
MimeType string `json:"mime_type,omitempty"`
// SizeBytes is the length of the referenced bytes.
SizeBytes int64 `json:"size_bytes,omitempty"`
// Filename is metadata only (never used for path construction).
Filename string `json:"filename,omitempty"`
// SHA256 is the full hex digest of the referenced bytes.
SHA256 string `json:"sha256,omitempty"`
}
StateArtifactRef is the flat, routable artifact reference a replayed heavy-payload event carries — routed via `artifacts.get_ref` (which returns a presigned URL on an S3-compat Presigner store, or the typed `presign_unsupported` on the default CGo-free inmem/fs stores). It mirrors SearchArtifactRef / MemoryArtifactRef and deliberately does NOT reuse ArtifactRefSummary (which has no ID/SHA256 — unroutable). No inline heavy bytes ever travel through the surface.
type StateEvent ¶ added in v1.6.0
type StateEvent struct {
// Type is the canonical event type wire string.
Type string `json:"type"`
// Sequence is the per-bus monotonic, gap-free sequence assigned at
// publish. It is the page's scroll-up cursor unit.
Sequence uint64 `json:"sequence"`
// OccurredAt is the event's wall-clock instant.
OccurredAt time.Time `json:"occurred_at"`
// Tenant / User / Session flatten the event's identity triple.
Tenant string `json:"tenant"`
User string `json:"user"`
Session string `json:"session"`
// Run, when non-empty, is the run the event belongs to inside the
// session.
Run string `json:"run,omitempty"`
// Payload is the event's redaction-safe payload (post-redaction by
// construction — the durable log persists events after redaction).
Payload any `json:"payload,omitempty"`
// Extra carries the bounded low-cardinality metric labels, when set.
Extra map[string]string `json:"extra,omitempty"`
// Artifacts carries the routable references to any heavy payloads
// offloaded above the heavy-output threshold (RFC §6.5 / §6.10).
Artifacts []StateArtifactRef `json:"artifacts,omitempty"`
}
StateEvent is the flat, single-sourced exported wire projection of one durable event — the same field set the SSE wire-event projection carries, plus routable artifact refs. A page of these is what the client reduces into chat messages.
type StateHistoryRequest ¶ added in v1.6.0
type StateHistoryRequest struct {
// Identity is the caller's identity scope. The verified identity from
// the JWT (or carrier headers) is authoritative; a body identity that
// disagrees with the verified one is rejected.
Identity IdentityScope `json:"identity"`
// SessionID names the session whose durable event stream is read. An
// unknown or cross-identity session is CodeNotFound (existence is
// never revealed across identities).
SessionID string `json:"session_id"`
// Before is the exclusive upper bound: only events with
// Sequence < Before are returned. Zero means "from the tail" (the
// newest retained events). To scroll one window older, pass the prior
// response's NextCursor back here.
Before uint64 `json:"before,omitempty"`
// Limit is the window size K (clamped to MaxStateHistoryLimit;
// zero ⇒ DefaultStateHistoryLimit).
Limit int `json:"limit,omitempty"`
}
StateHistoryRequest is the `state.history` request: a by-id, bounded, tail-first backward window read of a session's durable event stream.
type StateHistoryResponse ¶ added in v1.6.0
type StateHistoryResponse struct {
// Events is the window's events, oldest-first within the window.
Events []StateEvent `json:"events"`
// HeadSequence is the lowest retained sequence for the session (the
// oldest event still in the durable log).
HeadSequence uint64 `json:"head_sequence"`
// TailSequence is the highest retained sequence for the session (the
// newest event).
TailSequence uint64 `json:"tail_sequence"`
// NextCursor is the lowest Sequence in this page — the value to pass
// back as Before to scroll one window older. Zero when the head is
// reached (no older events).
NextCursor uint64 `json:"next_cursor"`
// HasMore reports whether older events remain before the page's
// oldest event (i.e. NextCursor is above HeadSequence).
HasMore bool `json:"has_more"`
// Truncated is true when the durable log's retained head sits above
// the session's first sequence (retention trimmed older events) — the
// honest gap signal, never a silent drop.
Truncated bool `json:"truncated,omitempty"`
}
StateHistoryResponse is the `state.history` reply: a bounded page of flat events oldest-first within the window, plus the discovered head/tail sequence, a scroll-up cursor, and the honest retention-gap signal.
type SubsystemDriver ¶
type SubsystemDriver struct {
// Subsystem names the persistence-shaped subsystem ("state",
// "artifacts", "memory", "eventlog").
Subsystem string `json:"subsystem"`
// Driver is the configured driver name ("inmem", "sqlite",
// "postgres", ...). Never the DSN / connection string — only the
// driver name leaks across the Protocol boundary.
Driver string `json:"driver"`
// Mode is an optional posture detail ("readwrite", "readonly",
// "embedded"). Empty when the subsystem reports none.
Mode string `json:"mode,omitempty"`
}
SubsystemDriver is one persistence-shaped subsystem's configured driver entry in a RuntimeDrivers readout.
type SubsystemHealth ¶
type SubsystemHealth struct {
// Subsystem names the runtime subsystem (e.g. "events", "state",
// "tasks").
Subsystem string `json:"subsystem"`
// Status is the structural readiness — one of "ready", "degraded",
// or "unavailable". Read from the subsystem's own posture seam, not
// from a synthetic deep-check probe.
Status string `json:"status"`
// Detail is an optional human-readable explanation — populated for
// a degraded / unavailable subsystem with the reason.
Detail string `json:"detail,omitempty"`
}
SubsystemHealth is one subsystem's readiness entry in a RuntimeHealth rollup.
type TaskCostRollup ¶
type TaskCostRollup struct {
// TotalTokens is the total token count (prompt + output).
TotalTokens int64 `json:"total_tokens"`
// PromptTokens is the prompt-side token count.
PromptTokens int64 `json:"prompt_tokens"`
// OutputTokens is the output-side token count.
OutputTokens int64 `json:"output_tokens"`
// USD is the total dollar cost.
USD float64 `json:"usd"`
// PerStep is the cost breakdown, one entry per planner step.
PerStep []TaskCostStep `json:"per_step"`
}
TaskCostRollup is the per-task cost aggregation `tasks.get` returns — the Console Tasks-page right-rail "Cost Breakdown" card. The rollup carries only sums + a per-step breakdown; heavy per-event payloads stay on the event bus and are never inlined here.
type TaskCostStep ¶
type TaskCostStep struct {
// StepIndex is the 0-based planner-step index.
StepIndex int `json:"step_index"`
// Tokens is the total token count attributed to the step.
Tokens int64 `json:"tokens"`
// USD is the dollar cost attributed to the step.
USD float64 `json:"usd"`
}
TaskCostStep is one planner-step entry in a TaskCostRollup — the aggregated cost of a single planner step within the task.
type TaskDetail ¶
type TaskDetail struct {
// Task is the compact row projection (same shape `tasks.list`
// returns).
Task TaskRow `json:"task"`
// ParentSession is the parent-session reference card.
ParentSession TaskParentSessionRef `json:"parent_session"`
// ParentTask is the parent-task reference; nil when the task is not
// a child of a SpawnTask group.
ParentTask *TaskParentTaskRef `json:"parent_task,omitempty"`
// Cost is the per-task cost rollup aggregated from
// `llm.cost.recorded` events scoped to the task.
Cost TaskCostRollup `json:"cost"`
// PlannerSnapshot is the planner-checkpoint reference at spawn time;
// nil when no checkpoint exists.
PlannerSnapshot *TaskPlannerSnapshotRef `json:"planner_snapshot,omitempty"`
// ResultRef references the task's result payload by artifact stub
// when the result exceeds the heavy-content threshold; nil
// when the task has no result or the result is inlined small.
ResultRef *ArtifactRef `json:"result_ref,omitempty"`
// ResultInline carries the task's result payload directly when it is
// below the heavy-content threshold ("" when absent or referenced).
ResultInline string `json:"result_inline,omitempty"`
// Trajectory is the projected planner reasoning-trace snapshot;
// nil when the trajectory is unavailable (evicted or not captured).
Trajectory *TaskTrajectoryRef `json:"trajectory,omitempty"`
// InputArtifacts lists the operator-attached input artifacts with
// their per-attachment disposition hints, in
// the order the `start` request supplied them. Empty for
// text-only tasks.
InputArtifacts []TaskInputArtifact `json:"input_artifacts,omitempty"`
}
TaskDetail is the enriched payload `tasks.get` returns. It carries the compact TaskRow projection plus the four enrichment fields the Console Tasks-page detail tabs + right-rail cards render. Heavy payload content is referenced via ArtifactRef — `tasks.get` MUST NOT inline bytes that exceed the heavy-content threshold.
type TaskFilter ¶
type TaskFilter struct {
// Statuses restricts to tasks whose Status is in this set.
Statuses []TaskStatus `json:"statuses,omitempty"`
// Kinds restricts to tasks whose Kind is in this set; empty matches
// both foreground and background.
Kinds []TaskKind `json:"kinds,omitempty"`
// ParentTaskID drills into a SpawnTask group — restricts to tasks
// whose ParentTaskID equals this value ("" = no parent-task filter).
ParentTaskID string `json:"parent_task_id,omitempty"`
// Identities scopes the query. A query naming more than one distinct
// tenant is a cross-tenant fan-in and requires the `auth.ScopeAdmin`
// claim. Empty = the caller's own identity scope.
Identities []IdentityScope `json:"identities,omitempty"`
// TenantIDs is the admin-widened FLEET-enumeration selector: when
// non-empty, `tasks.list` enumerates every task across ALL sessions of
// the named tenants (a coordinator control plane rendering a
// fleet-wide Tasks board), not just the caller's own triple. It
// mirrors `SessionFilter.TenantIDs`. Widening requires the verified
// `auth.ScopeAdmin` claim — a non-empty TenantIDs without the claim
// fails closed with the scope-mismatch error, never a silent narrowing
// to own scope. Empty (the default) is byte-compatible with the
// session-scoped read. Unlike `Identities` (a post-projection row
// facet), TenantIDs selects the enumeration SCOPE.
TenantIDs []string `json:"tenant_ids,omitempty"`
// Since is an optional lower bound on StartedAt (zero = unbounded).
Since time.Time `json:"since,omitempty"`
// Until is an optional upper bound on StartedAt (zero = unbounded).
Until time.Time `json:"until,omitempty"`
// ErrorClasses facets on TaskRow.ErrorClass for Failed tasks.
ErrorClasses []string `json:"error_classes,omitempty"`
// LatencyAboveMS facets on DurationMS — restricts to tasks whose
// DurationMS is at or above this value (0 = no latency filter).
LatencyAboveMS int64 `json:"latency_above_ms,omitempty"`
// Search is a free-text substring filter over the task's
// description + query, routed to the runtime search.tasks index.
Search string `json:"search,omitempty"`
// GroupID drills into one `TaskGroup` — restricts to tasks whose
// GroupID equals this value ("" = no group filter). The Background
// Jobs page's per-job right-rail "Related Sessions" tab issues a
// `tasks.list` with this facet set to surface the sibling tasks
// (foreground + background) under the same group. Identity scope is
// still enforced — a cross-tenant `group_id` lookup never widens
// visibility.
GroupID string `json:"group_id,omitempty"`
// HasPendingApproval, when non-nil, restricts to tasks whose
// HasPendingApproval row field equals the pointee. nil = no
// approval filter; *true = only tasks with an open approval gate;
// *false = only tasks with none. The Background Jobs page's `Has
// pending approval` facet chip binds this.
HasPendingApproval *bool `json:"has_pending_approval,omitempty"`
}
TaskFilter is the server-enforced facet filter on `tasks.list`. An empty facet slice matches every value on that axis. The filter is applied AFTER the identity-scope predicate — it never widens visibility.
type TaskGetRequest ¶
type TaskGetRequest struct {
// Identity is the (tenant, user, session) scope. Mandatory.
Identity IdentityScope `json:"identity"`
// ID is the task identifier to project.
ID string `json:"id"`
}
TaskGetRequest is the `tasks.get` request body.
type TaskInputArtifact ¶ added in v1.4.0
type TaskInputArtifact struct {
// ID is the content-addressed artifact identifier.
ID string `json:"id"`
// Disposition is the per-attachment caller hint persisted at
// spawn (`ref` / `inline` / `provider_native` / `tool:<name>`).
// Empty means the caller declared none — the agent's
// `multimodal.disposition` policy map or the runtime default
// (`image/*` → inline, everything else → ref) decides at run
// time; the resolved value is observable on the
// `task.input_disposition.resolved` event stream.
Disposition string `json:"disposition,omitempty"`
}
TaskInputArtifact is one operator-attached input artifact on the `tasks.get` projection. It pairs the artifact id with the per-attachment disposition hint the `start` request declared, so a client can verify its hint round-tripped onto the task.
type TaskKind ¶
type TaskKind string
TaskKind is the wire enum discriminating a foreground task (a run inside a session's primary turn) from a background task (a spawned-without-blocking task). The Protocol projection of the runtime-internal `tasks.TaskKind`.
type TaskListAggregates ¶
type TaskListAggregates struct {
// Pending is the count of filtered tasks in the Pending column.
Pending int64 `json:"pending"`
// Running is the count of filtered tasks in the Running column.
Running int64 `json:"running"`
// Paused is the count of filtered tasks in the Paused column.
Paused int64 `json:"paused"`
// Failed is the count of filtered tasks in the Failed column.
Failed int64 `json:"failed"`
// Complete is the count of filtered tasks in the Done column.
Complete int64 `json:"complete"`
// Cancelled is the count of filtered tasks that were cancelled.
Cancelled int64 `json:"cancelled"`
}
TaskListAggregates carries the per-status counters the kanban renders at each column header, computed over the FILTERED view.
type TaskListCursor ¶
type TaskListCursor struct {
// NextPageToken is the opaque continuation token; empty when there
// are no more pages.
NextPageToken string `json:"next_page_token,omitempty"`
}
TaskListCursor is the opaque pagination cursor for `tasks.list`.
type TaskListRequest ¶
type TaskListRequest struct {
// Identity is the (tenant, user, session) scope the task list is
// projected for. Mandatory — an incomplete triple fails closed.
Identity IdentityScope `json:"identity"`
// Filter is the optional facet filter; the zero value lists every
// visible task.
Filter TaskFilter `json:"filter"`
// PageSize is the rows-per-page; a non-positive value applies
// DefaultTaskListPageSize. A value above MaxTaskListPageSize is a
// 400 (CodeInvalidRequest) — never a silent clamp.
PageSize int `json:"page_size,omitempty"`
// Cursor is the pagination cursor; the zero value requests the
// first page.
Cursor TaskListCursor `json:"cursor"`
// IncludeStatusCounterStrip opts the response into carrying the
// TasksListStatusCounterStrip aggregate. It is
// off by default — the Console Live Runtime page sets it on its
// initial-load `tasks.list` call and then maintains the strip live
// from the `task.*` SSE stream (the aggregate is the initial-load
// shape only; see the phase plan's "tasks.list aggregate cost"
// risk). The Tasks page (73d) never sets it — its kanban renders
// the filtered-view TaskListAggregates instead.
IncludeStatusCounterStrip bool `json:"include_status_counter_strip,omitempty"`
}
TaskListRequest is the `tasks.list` request body.
type TaskListResponse ¶
type TaskListResponse struct {
// Rows is the page of task rows, sorted by StartedAt descending
// (newest first).
Rows []TaskRow `json:"rows"`
// Cursor carries the continuation token for the next page.
Cursor TaskListCursor `json:"cursor"`
// Aggregates carries the per-status counters for the filtered view.
Aggregates TaskListAggregates `json:"aggregates"`
// StatusCounterStrip carries the header-strip
// aggregate — non-nil ONLY when the request set
// IncludeStatusCounterStrip. It is computed over the FULL identity-
// scoped task set (not the filtered view) and is the Console Live
// Runtime page's header five-chip strip. nil on a request that did
// not opt in (the Tasks page never opts in).
StatusCounterStrip *TasksListStatusCounterStrip `json:"status_counter_strip,omitempty"`
}
TaskListResponse is the `tasks.list` reply: a paginated slice of task rows, the continuation cursor, and the filtered-view per-status aggregates.
type TaskParentSessionRef ¶
type TaskParentSessionRef struct {
// SessionID is the parent session's identifier.
SessionID string `json:"session_id"`
// AgentName is the agent the session runs.
AgentName string `json:"agent_name"`
// Status is the parent session's lifecycle status.
Status string `json:"status"`
// StartedAt is the parent session's start timestamp.
StartedAt time.Time `json:"started_at"`
// LatestEventAt is the timestamp of the most recent event on the
// parent session.
LatestEventAt time.Time `json:"latest_event_at"`
}
TaskParentSessionRef is the parent-session reference card `tasks.get` returns — the Console Tasks-page right-rail "Parent Session" card.
type TaskParentTaskRef ¶
type TaskParentTaskRef struct {
// TaskID is the spawning task's identifier.
TaskID string `json:"task_id"`
// Kind is the spawning task's kind.
Kind TaskKind `json:"kind"`
// Status is the spawning task's lifecycle status.
Status TaskStatus `json:"status"`
}
TaskParentTaskRef is the parent-task reference `tasks.get` returns when the task is a child spawned by a planner `SpawnTask`.
type TaskPlannerSnapshotRef ¶
type TaskPlannerSnapshotRef struct {
// CheckpointID is the planner-checkpoint identifier (resolvable via
// state.load_planner_checkpoint).
CheckpointID string `json:"checkpoint_id"`
// Summary is the pre-truncated checkpoint summary.
Summary string `json:"summary"`
}
TaskPlannerSnapshotRef is the planner-checkpoint reference `tasks.get` returns — it points at the planner checkpoint that existed at task spawn time. Heavy checkpoint content is fetched on demand via the existing `state.load_planner_checkpoint` method, never inlined in the `tasks.get` response.
type TaskRow ¶
type TaskRow struct {
// ID is the unified task identifier (foreground run or background
// task; one TaskID namespace).
ID string `json:"id"`
// Kind discriminates foreground vs background.
Kind TaskKind `json:"kind"`
// Status is the task's lifecycle state.
Status TaskStatus `json:"status"`
// Priority is the TASK-level priority (the `prioritize`
// control method). NEVER a session-level priority (carve-out).
Priority int `json:"priority"`
// Identity is the (tenant, user, session) triple the task runs
// within — the Console truncates it for display on the card.
Identity IdentityScope `json:"identity"`
// ParentSessionID is the session the task belongs to.
ParentSessionID string `json:"parent_session_id"`
// ParentTaskID is set when the task was spawned by a planner
// `SpawnTask` — it names the spawning task ("" when not a child).
ParentTaskID string `json:"parent_task_id,omitempty"`
// Description is the planner-facing task summary.
Description string `json:"description"`
// Query is the originating query / prompt text.
Query string `json:"query"`
// StartedAt is the task's creation timestamp.
StartedAt time.Time `json:"started_at"`
// UpdatedAt is the timestamp of the most recent lifecycle transition.
UpdatedAt time.Time `json:"updated_at"`
// DurationMS is the elapsed wall-clock time in milliseconds
// (StartedAt → UpdatedAt).
DurationMS int64 `json:"duration_ms"`
// ErrorClass is the short failure-class string; set only when
// Status is "failed" ("" otherwise).
ErrorClass string `json:"error_class,omitempty"`
// ToolCount is the running count of tool invocations the task's run
// successfully dispatched: a single tool call counts once, a
// parallel tool call counts once per branch, and spawned/awaited
// child tasks are NOT counted (spawning or joining a task is not a
// tool invocation). Failed dispatches are not counted either — the
// counter advances only when the executor returns without error.
ToolCount int `json:"tool_count"`
// BackgroundAcknowledged latches true once a completed background
// task has been acknowledged (the `task.background_acknowledged`
// event). No `tasks.list` facet operates over it, and the task
// registry record does not yet carry the latch, so it is represented
// honestly by omission (`omitempty`): a false value is elided from the
// wire rather than shipped as a fabricated-known `false` (the projection-completeness gate). When
// the latch lands on the record it populates here without a wire-shape
// break.
BackgroundAcknowledged bool `json:"background_acknowledged,omitempty"`
// GroupID is the TaskGroup the task is a member of ("" when the
// task is not a group member).
GroupID string `json:"group_id,omitempty"`
// Progress is the planner-emitted numeric progress hint in the
// [0,1] range. It is a pointer so the wire shape distinguishes "the
// planner emitted progress 0.0" from "the planner emitted no
// progress at all" — nil ⇒ no hint, and the Console renders an
// indeterminate Progress mini-bar rather than a 0% bar. Note:
// the Background Jobs page's Progress column.
Progress *float64 `json:"progress,omitempty"`
// Tags is the slice of short labels the Background Jobs page renders
// in its Tags column — the parent task type plus any planner-emitted
// labels. Empty slice ⇒ no tags.
Tags []string `json:"tags,omitempty"`
// LastActivityAt is the timestamp of the most recent activity on the
// task — the max of UpdatedAt and any event on the run's stream. The
// Background Jobs page's `Stuck > 1h` saved-filter chip derives off
// this field (a Console-local rule).
LastActivityAt time.Time `json:"last_activity_at"`
// IsBackground mirrors `Kind == "background"` — a convenience
// boolean so a Console row-renderer branches without re-comparing
// the enum. The Background Jobs queue is the
// `IsBackground == true` projection of the unified task set.
IsBackground bool `json:"is_background"`
// HasPendingApproval is true when the task's run has at least one
// open HITL approval / tool-approval gate. The Background Jobs
// page's `Has pending approval` facet filters on it, and the
// per-job right-rail's Pending-approvals tab is populated when it is
// true.
HasPendingApproval bool `json:"has_pending_approval"`
}
TaskRow is the compact projection returned by `tasks.list`. It is the row shape the Console Tasks-page kanban card + list-mode table render. Wire-only — never the internal `tasks.Task` struct (CLAUDE.md §8 — the Console never reads internal runtime objects). Heavy fields (the result / error payloads) stay on TaskDetail; the row is compact for kanban + table density.
NO session-level priority field appears here — a deliberate carve-out. Only Priority (the task-level priority shipped via the `prioritize` method) is rendered.
type TaskStatus ¶
type TaskStatus string
TaskStatus is the wire enum for a task's lifecycle state. It is the Protocol projection of the runtime-internal `tasks.TaskStatus`.
const ( TaskStatusPending TaskStatus = "pending" TaskStatusRunning TaskStatus = "running" TaskStatusPaused TaskStatus = "paused" TaskStatusComplete TaskStatus = "complete" TaskStatusFailed TaskStatus = "failed" TaskStatusCancelled TaskStatus = "cancelled" )
Canonical task statuses — the closed lifecycle set the kanban board and list-mode table render.
type TaskTrajectoryRef ¶ added in v1.2.0
type TaskTrajectoryRef struct {
Steps []TaskTrajectoryStep `json:"steps"`
}
TaskTrajectoryRef is the projected reasoning-trace snapshot from the planner's in-memory trajectory, carried on TaskDetail.Trajectory. The projection is narrow — per-step index + reasoning-trace string only; full action / observation projection is a later expansion.
type TaskTrajectoryStep ¶ added in v1.2.0
type TaskTrajectoryStep struct {
Index int `json:"index"`
ReasoningTrace string `json:"reasoning_trace"`
}
TaskTrajectoryStep maps one planner trajectory step to the wire. Steps with an empty ReasoningTrace are filtered out before the wire — the Console never sees a box that says "no reasoning here."
type TasksListStatusCounterStrip ¶
type TasksListStatusCounterStrip struct {
// Pending is the count of identity-scoped tasks in the Pending state.
Pending int `json:"pending"`
// Running is the count of identity-scoped tasks in the Running state.
Running int `json:"running"`
// Completed is the count of identity-scoped tasks in the Complete
// state (the strip's `completed` chip — see the type godoc on the
// `complete` → `completed` vocabulary choice).
Completed int `json:"completed"`
// Paused is the count of identity-scoped tasks in the Paused state.
Paused int `json:"paused"`
// Failed is the count of identity-scoped tasks in the Failed state.
Failed int `json:"failed"`
}
TasksListStatusCounterStrip is the status-counter-strip aggregate the Console Live Runtime page renders as its header-level five-chip strip (`pending / running / completed / paused / failed`). It is an OPT-IN projection on the `tasks.list` response — a caller requests it via TaskListRequest.IncludeStatusCounterStrip.
The strip is distinct from TaskListAggregates in two deliberate ways:
- It is computed over the FULL identity-scoped task set, NOT the filtered view. The Live Runtime header strip reports session-wide posture ("how many tasks are running in this session right now"), so it never narrows with the page's facet filter.
- It keys on the canonical lifecycle vocabulary the Live Runtime page-spec mockup uses (`completed` rather than `complete`); the `cancelled` status is folded out — the strip is a five-chip present-tense posture, not the six-status kanban tally.
The aggregate is identity-scoped and computed server-side per request (CLAUDE.md §6 rule 2): the counter NEVER crosses the isolation boundary — a second session never sees the first's counts.
type TimeRange ¶
type TimeRange struct {
// After, when non-zero, excludes artifacts created strictly before
// it.
After time.Time `json:"after,omitempty"`
// Before, when non-zero, excludes artifacts created strictly after
// it.
Before time.Time `json:"before,omitempty"`
}
TimeRange is an optional created-at filter for artifacts.list. Both bounds are inclusive; a zero bound is unbounded on that side.
type Tool ¶
type Tool struct {
// ID is the stable catalog key (the tool's registered name).
ID string `json:"id"`
// Name is the planner-facing display name (equal to ID in V1).
Name string `json:"name"`
// Version is the tool descriptor version string ("" when unset).
Version string `json:"version"`
// Description is the planner-facing summary.
Description string `json:"description"`
// Scope is the tool's visibility scope: "tenant" | "agent" | "session".
Scope string `json:"scope"`
// Transport discriminates the tool's source.
Transport ToolTransport `json:"transport"`
// OAuthStatus is the tool's OAuth binding status.
OAuthStatus ToolOAuthStatus `json:"oauth_status"`
// ApprovalPolicy is the tool's HITL approval gate.
ApprovalPolicy ToolApprovalPolicy `json:"approval_policy"`
// ReliabilityTier is the operator-facing reliability label
// (derived from the tool's side-effect class / cost hint).
ReliabilityTier string `json:"reliability_tier"`
// Owner is the configured owner / source identifier ("" when unset).
Owner string `json:"owner"`
// LastUsedAt is the timestamp of the most recent invocation; the
// zero value means "never used".
LastUsedAt time.Time `json:"last_used_at"`
}
Tool is the catalog-row projection of a registered tool descriptor. It is the row shape the Console Tools-page catalog table renders and the payload `tools.get` returns. Flat, low-cardinality strings — the Console branches on the enum fields.
type ToolAggregates ¶
type ToolAggregates struct {
// Total is the count of tools matching the filter.
Total int64 `json:"total"`
// Active is the count of tools with a non-zero LastUsedAt.
Active int64 `json:"active"`
// PendingApproval is the count of tools whose ApprovalPolicy is
// "gated".
PendingApproval int64 `json:"pending_approval"`
// AwaitingOAuth is the count of tools whose OAuthStatus is
// "Required" or "Expired".
AwaitingOAuth int64 `json:"awaiting_oauth"`
}
ToolAggregates carries the four catalog counters the Tools-page right-rail overview card renders, computed over the FILTERED view.
type ToolApprovalPolicy ¶
type ToolApprovalPolicy string
ToolApprovalPolicy is the wire enum for a tool's approval gate.
const ( // ToolApprovalAuto — the tool runs without a HITL gate. ToolApprovalAuto ToolApprovalPolicy = "auto" // ToolApprovalGated — every invocation pauses for HITL approval. ToolApprovalGated ToolApprovalPolicy = "gated" // ToolApprovalDenied — the tool is administratively denied. ToolApprovalDenied ToolApprovalPolicy = "denied" )
Canonical approval policies — the closed set `tools.set_approval_policy` accepts and the catalog table renders.
type ToolContentBucket ¶
type ToolContentBucket struct {
// MaxBytes is the inclusive upper bound of this bucket in bytes.
MaxBytes int64 `json:"max_bytes"`
// Count is the number of recent results that fell in this bucket.
Count int64 `json:"count"`
}
ToolContentBucket is one power-of-two size bucket in the per-tool result-size histogram.
type ToolContentStats ¶
type ToolContentStats struct {
// ID echoes the requested tool ID.
ID string `json:"id"`
// Histogram is the result-size distribution, one bucket per
// power-of-two byte range, ascending.
Histogram []ToolContentBucket `json:"histogram"`
// HeavyThresholdBytes is the configured heavy-content threshold
// results at or above this size route through the
// ArtifactStore by-reference.
HeavyThresholdBytes int64 `json:"heavy_threshold_bytes"`
// HeavyCount is the number of recent results at or above the
// heavy-content threshold.
HeavyCount int64 `json:"heavy_count"`
// NegotiatedDisplay maps a MIME type to its negotiated MCP-Apps
// DisplayMode; empty for non-MCP tools.
NegotiatedDisplay map[string]string `json:"negotiated_display"`
}
ToolContentStats is the `tools.content_stats` reply — the per-tool distribution of recent result sizes vs the heavy-content threshold (RFC §6.5) plus the negotiated DisplayMode snapshot.
type ToolContentStatsRequest ¶
type ToolContentStatsRequest struct {
// Identity is the (tenant, user, session) scope. Mandatory.
Identity IdentityScope `json:"identity"`
// ID is the catalog key of the tool to report content stats for.
ID string `json:"id"`
}
ToolContentStatsRequest is the `tools.content_stats` request body.
type ToolContextPayload ¶ added in v1.4.1
type ToolContextPayload struct {
// Content is the inline JSON, populated ONLY when the payload was
// captured below the heavy-content threshold. Empty when ArtifactRef
// is set.
Content json.RawMessage `json:"content,omitempty"`
// ArtifactRef is the by-reference stub, populated when the payload met
// or exceeded the heavy-content threshold at capture. Nil when Content
// is set.
ArtifactRef *MCPResourceArtifactRef `json:"artifact_ref,omitempty"`
}
ToolContextPayload is one half (input or result) of a tool context. EXACTLY ONE of Content / ArtifactRef is set: Content carries the inline JSON when the payload is below the heavy-content threshold; ArtifactRef carries the by-reference stub when it met or exceeded the threshold at capture time (the Console fetches the bytes via the artifacts surface).
type ToolContextRequest ¶ added in v1.4.1
type ToolContextRequest struct {
// Identity is the (tenant, user, session) scope the read runs under.
// Mandatory — an incomplete triple fails closed.
Identity IdentityScope `json:"identity"`
// ServerID is the MCP server (source id) the tool belongs to — the
// value carried on the `mcp.app_available` discovery event.
ServerID string `json:"server_id"`
// ToolCallID is the stable per-invocation id of the tool call that
// declared the app — also carried on the discovery event.
ToolCallID string `json:"tool_call_id"`
}
ToolContextRequest is the `mcp.apps.tool_context` request body — a rendered MCP App asking the host for the tool context (input arguments + lowered result) that produced it. The request carries the identity triple from the Protocol context; the runtime resolves the captured context scoped to that triple, so an app can never read a context captured under a different identity (a cross-identity id fails with CodeNotFound). Identity is mandatory.
type ToolContextResponse ¶ added in v1.4.1
type ToolContextResponse struct {
// Tool echoes the server-side tool name that declared the app.
Tool string `json:"tool"`
// Input is the tool's input arguments (inline JSON or by reference).
Input ToolContextPayload `json:"input"`
// Result is the tool's lowered result (inline JSON or by reference).
Result ToolContextPayload `json:"result"`
// IsError reports whether the tool returned a server-side error result.
IsError bool `json:"is_error"`
// ProtocolVersion echoes the Protocol version the Runtime answered
// under so a client can detect a version skew.
ProtocolVersion string `json:"protocol_version"`
}
ToolContextResponse is the `mcp.apps.tool_context` reply — the captured input + lowered result that produced the rendered app. Each of Input / Result is inline-or-by-reference (the heavy-content discipline matches ReadMCPResourceResponse): a large result rides by reference, never inline. An unknown or cross-identity (server_id, tool_call_id) fails with CodeNotFound rather than returning an empty response.
type ToolDescribeRequest ¶
type ToolDescribeRequest struct {
// Identity is the (tenant, user, session) scope. Mandatory.
Identity IdentityScope `json:"identity"`
// ID is the catalog key of the tool to describe.
ID string `json:"id"`
// AgentID, when set, projects the reported loading_mode through the
// named agent's active tool-exposure config (the EFFECTIVE mode).
// Optional — absent reports the boot-effective mode, byte-compatible
// with the surface before this projection existed.
AgentID string `json:"agent_id,omitempty"`
}
ToolDescribeRequest is the `tools.describe` request body.
type ToolFilter ¶
type ToolFilter struct {
// Scopes restricts to tools whose Scope is in this set.
Scopes []string `json:"scopes,omitempty"`
// Transports restricts to tools whose Transport is in this set.
Transports []ToolTransport `json:"transports,omitempty"`
// OAuthStatuses restricts to tools whose OAuthStatus is in this set.
OAuthStatuses []ToolOAuthStatus `json:"oauth_statuses,omitempty"`
// ApprovalPolicies restricts to tools whose ApprovalPolicy is in this set.
ApprovalPolicies []ToolApprovalPolicy `json:"approval_policies,omitempty"`
// ReliabilityTiers restricts to tools whose ReliabilityTier is in this set.
ReliabilityTiers []string `json:"reliability_tiers,omitempty"`
// Search is a free-text substring filter over tool name + version.
Search string `json:"search,omitempty"`
}
ToolFilter is the server-enforced facet filter on `tools.list`. An empty facet slice matches every value on that axis. The filter is applied AFTER the identity-scope predicate — it never widens visibility.
type ToolGetRequest ¶
type ToolGetRequest struct {
// Identity is the (tenant, user, session) scope. Mandatory.
Identity IdentityScope `json:"identity"`
// ID is the catalog key of the tool to project.
ID string `json:"id"`
}
ToolGetRequest is the `tools.get` request body.
type ToolListRequest ¶
type ToolListRequest struct {
// Identity is the (tenant, user, session) scope the catalog is
// projected for. Mandatory — an incomplete triple fails closed.
Identity IdentityScope `json:"identity"`
// Filter is the optional facet filter; the zero value lists every
// visible tool.
Filter ToolFilter `json:"filter"`
// Page is the 1-based page index; a non-positive value means page 1.
Page int `json:"page,omitempty"`
// PageSize is the rows-per-page; a non-positive value applies
// DefaultToolListPageSize. A value above MaxToolListPageSize is a
// 400 (CodeInvalidRequest) — never a silent clamp.
PageSize int `json:"page_size,omitempty"`
}
ToolListRequest is the `tools.list` request body.
type ToolListResponse ¶
type ToolListResponse struct {
// Tools is the page of catalog rows, sorted by Name.
Tools []Tool `json:"tools"`
// Page is the 1-based page index this response covers.
Page int `json:"page"`
// PageSize is the rows-per-page applied.
PageSize int `json:"page_size"`
// PageCount is the total number of pages for the filtered view.
PageCount int `json:"page_count"`
// TotalRows is the total row count for the filtered view.
TotalRows int64 `json:"total_rows"`
// Aggregates carries the four catalog counters for the filtered view.
// Active / PendingApproval / AwaitingOAuth ride the per-tool annotator
// (OAuth / approval / last-used). When AggregatesPartial is true they
// are UNAVAILABLE, not zero — see AggregatesPartial.
Aggregates ToolAggregates `json:"aggregates"`
// AggregatesPartial reports that the annotator-backed catalog aggregates
// (Active / PendingApproval / AwaitingOAuth) are UNAVAILABLE because no
// per-tool annotator is wired on this runtime (the concrete lands in
// the tools annotator follow-up). Only `Aggregates.Total` is authoritative; the Console
// renders the other three as "unavailable," NEVER a real-looking 0 — the
// fabricated zero the silent-absence class kills (the projection-completeness gate). Additive and
// omitempty: a wired build (a wired build) omits it and ships real
// aggregates.
AggregatesPartial bool `json:"aggregates_partial,omitempty"`
}
ToolListResponse is the `tools.list` reply: a paginated slice of catalog rows plus the filtered-view aggregates.
type ToolManifest ¶
type ToolManifest struct {
// Tool is the catalog-row projection (same shape as `tools.get`).
Tool Tool `json:"tool"`
// SideEffect is the declared side-effect class
// ("pure" | "read" | "write" | "external" | "stateful").
SideEffect string `json:"side_effect"`
// ArgsSchema is the raw JSON-Schema (object) for the tool's
// argument shape, as a JSON string ("" when the tool declares none).
ArgsSchema string `json:"args_schema"`
// OutSchema is the raw JSON-Schema (object) for the tool's result
// shape, as a JSON string ("" when the tool declares none).
OutSchema string `json:"out_schema"`
// Examples carries the canonical argument-shape examples, each a
// JSON string.
Examples []string `json:"examples"`
// AuthScopes lists the scopes a planner step's identity must carry
// for the tool to be visible.
AuthScopes []string `json:"auth_scopes"`
// OAuthBindingScope is the tool's OAuth binding scope
// ("user" | "agent" | "" when the tool requires no OAuth).
OAuthBindingScope string `json:"oauth_binding_scope"`
// RetryAttempts is the reliability shell's configured retry budget.
RetryAttempts int `json:"retry_attempts"`
// TimeoutMS is the reliability shell's per-attempt timeout in
// milliseconds (0 when the policy applies its default).
TimeoutMS int64 `json:"timeout_ms"`
// LoadingMode is the prompt-time loading mode ("always" | "deferred").
LoadingMode string `json:"loading_mode"`
// DisplayModes maps a MIME type to its negotiated MCP-Apps
// DisplayMode; empty for non-MCP tools.
DisplayModes map[string]string `json:"display_modes"`
}
ToolManifest is the full descriptor projection `tools.describe` returns — the read-only manifest the Tools-page Manifest / Inputs / Outputs tabs render.
type ToolMetrics ¶
type ToolMetrics struct {
// ID echoes the requested tool ID.
ID string `json:"id"`
// Window echoes the resolved observation window.
Window ToolMetricsWindow `json:"window"`
// ErrorRate1h is the fraction of failed invocations over the last 1h.
ErrorRate1h float64 `json:"error_rate_1h"`
// ErrorRate24h is the fraction of failed invocations over the last 24h.
ErrorRate24h float64 `json:"error_rate_24h"`
// ErrorRate7d is the fraction of failed invocations over the last 7d.
ErrorRate7d float64 `json:"error_rate_7d"`
// Invocations is the total invocation count over the selected window.
Invocations int64 `json:"invocations"`
// Failures is the failed-invocation count over the selected window.
Failures int64 `json:"failures"`
// Status is the health pill for the selected window.
Status ToolStatus `json:"status"`
}
ToolMetrics is the `tools.metrics` reply — per-tool error-rate gauges over the three fixed windows plus a status pill for the selected window.
type ToolMetricsRequest ¶
type ToolMetricsRequest struct {
// Identity is the (tenant, user, session) scope. Mandatory.
Identity IdentityScope `json:"identity"`
// ID is the catalog key of the tool to report metrics for.
ID string `json:"id"`
// Window selects the observation window; an empty value applies
// ToolWindow1h.
Window ToolMetricsWindow `json:"window,omitempty"`
}
ToolMetricsRequest is the `tools.metrics` request body.
type ToolMetricsWindow ¶
type ToolMetricsWindow string
ToolMetricsWindow is the wire enum for the `tools.metrics` selectable observation window.
const ( ToolWindow1h ToolMetricsWindow = "1h" ToolWindow24h ToolMetricsWindow = "24h" ToolWindow7d ToolMetricsWindow = "7d" )
Canonical metrics windows — the 1h / 24h / 7d toggle in the mockup.
type ToolOAuthStatus ¶
type ToolOAuthStatus string
ToolOAuthStatus is the wire enum for a tool's OAuth binding status.
const ( // ToolOAuthBound — the tool requires OAuth and a live binding exists. ToolOAuthBound ToolOAuthStatus = "Bound" // ToolOAuthRequired — the tool requires OAuth but no binding exists. ToolOAuthRequired ToolOAuthStatus = "Required" // ToolOAuthExpired — the tool requires OAuth and the binding lapsed. ToolOAuthExpired ToolOAuthStatus = "Expired" // ToolOAuthNotApplicable — the tool does not require OAuth. ToolOAuthNotApplicable ToolOAuthStatus = "n/a" )
Canonical OAuth statuses surfaced in the catalog table.
type ToolRevokeOAuthRequest ¶
type ToolRevokeOAuthRequest struct {
// Identity is the (tenant, user, session) scope. Mandatory.
Identity IdentityScope `json:"identity"`
// ID is the catalog key of the tool whose OAuth bindings to revoke.
ID string `json:"id"`
}
ToolRevokeOAuthRequest is the `tools.revoke_oauth` request body. ADMIN method — requires the verified `auth.ScopeAdmin` claim.
type ToolRevokeOAuthResponse ¶
type ToolRevokeOAuthResponse struct {
// ID echoes the tool ID whose bindings were revoked.
ID string `json:"id"`
// RevokedCount is the number of OAuth bindings revoked.
RevokedCount int64 `json:"revoked_count"`
}
ToolRevokeOAuthResponse is the `tools.revoke_oauth` reply.
type ToolSetApprovalPolicyRequest ¶
type ToolSetApprovalPolicyRequest struct {
// Identity is the (tenant, user, session) scope. Mandatory.
Identity IdentityScope `json:"identity"`
// ID is the catalog key of the tool to update.
ID string `json:"id"`
// Policy is the new approval policy; must be a valid
// ToolApprovalPolicy or the request is rejected with
// CodeInvalidRequest.
Policy ToolApprovalPolicy `json:"policy"`
}
ToolSetApprovalPolicyRequest is the `tools.set_approval_policy` request body. ADMIN method — requires the verified `auth.ScopeAdmin` claim.
type ToolSetApprovalPolicyResponse ¶
type ToolSetApprovalPolicyResponse struct {
// ID echoes the updated tool ID.
ID string `json:"id"`
// Policy echoes the applied approval policy.
Policy ToolApprovalPolicy `json:"policy"`
}
ToolSetApprovalPolicyResponse is the `tools.set_approval_policy` reply.
type ToolStatus ¶
type ToolStatus string
ToolStatus is the wire enum for a tool's health pill.
const ( ToolStatusHealthy ToolStatus = "Healthy" ToolStatusDegraded ToolStatus = "Degraded" ToolStatusOffline ToolStatus = "Offline" )
Canonical tool health statuses surfaced by `tools.metrics`.
type ToolTransport ¶
type ToolTransport string
ToolTransport is the wire enum for a tool's transport. It is the Protocol projection of the runtime-internal `tools.TransportKind`.
const ( ToolTransportInProc ToolTransport = "in-proc" ToolTransportHTTP ToolTransport = "HTTP" ToolTransportMCP ToolTransport = "MCP" ToolTransportA2A ToolTransport = "A2A" ToolTransportFlow ToolTransport = "flow" )
Canonical tool transports — the closed set the catalog supports.
type TopologyEdge ¶
type TopologyEdge struct {
// From is the upstream node's Name.
From string `json:"from"`
// To is the downstream node's Name.
To string `json:"to"`
// QueueDepth is the number of envelopes currently buffered on the
// (From → To) channel — len(channel) at projection time.
QueueDepth int `json:"queue_depth"`
// QueueCapacity is the bounded buffer size of the (From → To)
// channel — cap(channel). A consumer renders QueueDepth /
// QueueCapacity as a saturation indicator.
QueueCapacity int `json:"queue_capacity"`
}
TopologyEdge is one directed edge of the projected graph plus its live bounded-channel state. QueueDepth / QueueCapacity are the liveness fields the Live Runtime canvas renders as a fill bar.
type TopologyNode ¶
type TopologyNode struct {
// Name is the node's unique identifier within the engine.
Name string `json:"name"`
// Kind is the node's role tag — inlet / node / outlet.
Kind TopologyNodeKind `json:"kind"`
}
TopologyNode is one vertex of the projected graph — a name plus a role tag. Status / latency / selection are deliberately absent: they are per-run overlays the consumer composes from the event stream.
type TopologyNodeKind ¶
type TopologyNodeKind string
TopologyNodeKind tags a node's role in the graph. The V1 set is closed — inlet (no parent), node (intermediate), outlet (no child).
const ( // NodeKindInlet tags a node with no incoming edge — an entry point // where an external Emit lands. NodeKindInlet TopologyNodeKind = "inlet" // NodeKindNode tags an intermediate node — it has both a parent and // a child. NodeKindNode TopologyNodeKind = "node" // NodeKindOutlet tags a node with no outgoing edge — an exit point // that writes to the engine's egress. NodeKindOutlet TopologyNodeKind = "outlet" )
The V1 node-kind constants. A node with no parent is an inlet; a node with no child is an outlet; every other node is a plain node.
type TopologyProjection ¶
type TopologyProjection struct {
// EngineID identifies the engine the projection describes. In V1
// (one engine per Runtime process) it is the Runtime's engine id;
// the field exists so a post-V1 multi-engine Runtime can scope a
// projection without a wire-shape break.
EngineID string `json:"engine_id"`
// OccurredAt is the wall-clock instant the projection was built.
// On the `topology.changed` event it is the construction / edge-
// change time; on a `topology.snapshot` reply it is the snapshot
// time.
OccurredAt time.Time `json:"occurred_at"`
// Nodes is the engine's node set, sorted lexicographically by Name
// for byte-stability across snapshots of the same engine.
Nodes []TopologyNode `json:"nodes"`
// Edges is the engine's directed edge set, sorted lexicographically
// by (From, To) for byte-stability.
Edges []TopologyEdge `json:"edges"`
}
TopologyProjection is the canonical Protocol wire shape of an engine's node graph. It is the projection a Protocol client the Live Runtime topology canvas, the Playground trace toggle, a third-party Console — renders the engine's static graph + live per-edge queue depth from. It is NOT a re-export of any internal Runtime type: the Runtime constructs a TopologyProjection from its private adjacency list + per-edge channel state at request / emit time, and the consumer never sees those internals (CLAUDE.md §8; RFC §5.1 — a Protocol type that mapped 1:1 onto an internal Go struct would be the reject-on-sight smell).
The projection is engine-scoped, not run-scoped: it carries the static graph plus the live channel depth, both byte-stable across runs of the same engine. Per-run overlays (node status, latency, selection state) are NOT here — the consumer composes those from the existing event taxonomy (`tool.invoked`, `task.spawned`, `pause.requested`,...).
TopologyProjection is the wire shape on BOTH surfaces: the `topology.snapshot` Protocol method (request → reply) returns one, and the `topology.changed` canonical event carries one in its payload.
func (*TopologyProjection) SortDeterministic ¶
func (p *TopologyProjection) SortDeterministic()
SortDeterministic sorts the projection's Nodes (by Name) and Edges (by From then To) in place so two projections of the same engine marshal to byte-identical JSON. The Runtime calls this before returning a projection on either surface; callers constructing a projection by hand (tests) call it to get the canonical ordering.
type TopologySnapshotRequest ¶
type TopologySnapshotRequest struct {
// Identity is the mandatory caller identity scope. An incomplete
// triple fails the request closed with CodeIdentityRequired.
Identity IdentityScope `json:"identity"`
}
TopologySnapshotRequest is the wire request for the `topology.snapshot` Protocol method. It carries the flat identity scope the runtime-side surface translates into the runtime's identity triple at the edge — identity is mandatory (RFC §5.5). The request targets the Runtime's engine; a cross-tenant snapshot (Identity.Tenant ≠ the engine's tenant) requires the verified `auth.ScopeAdmin` claim.
type Version ¶
type Version struct {
// Major is bumped on a breaking Protocol change. Two versions are
// Compatible iff their Major components are equal.
Major int
// Minor is bumped on a backward-compatible surface addition (a new
// method, a new capability, a new optional wire field).
Minor int
// Patch is bumped on a backward-compatible fix with no surface
// change.
Patch int
}
Version is the parsed, comparable form of a Harbor Protocol version: a `MAJOR.MINOR.PATCH` triple of non-negative integers. The string ProtocolVersion is the pinned source of truth and the RFC-change trip-wire; Version is what a client uses to *reason* about a version — to detect skew (Compatible) or order two versions (Compare).
Version is an immutable value type — safe to copy, compare, and share across goroutines without synchronisation.
func ParseVersion ¶
ParseVersion parses a `MAJOR.MINOR.PATCH` string into a Version. Each component must be a non-negative base-10 integer; anything else (empty input, wrong arity, a non-numeric or negative component, surrounding whitespace) fails loudly with a wrapped ErrInvalidVersion.
func (Version) Compare ¶
Compare orders two versions component-wise (Major, then Minor, then Patch). It returns -1 if v sorts before o, +1 if after, 0 if equal.
func (Version) Compatible ¶
Compatible reports whether a client speaking version o can talk to a Runtime speaking version v. The rule is same-Major: a Major bump is a breaking change (which is why bumping it is an RFC change, RFC §5.3), so a client and a Runtime are compatible iff their Major components match — Minor / Patch differences are backward-compatible by construction. Compatible is symmetric: v.Compatible(o) == o.Compatible(v).
type VersionHandshake ¶
type VersionHandshake struct {
// ProtocolVersion is the version string the Runtime speaks — the
// ProtocolVersion constant. A client parses it (ParseVersion) and
// checks Compatible against its own.
ProtocolVersion string `json:"protocol_version"`
// Capabilities is the set of Protocol surfaces the Runtime
// advertises as live — deterministically sorted (Capabilities()).
Capabilities []Capability `json:"capabilities"`
}
VersionHandshake is the capability-negotiation wire shape: the Protocol version the Runtime speaks plus the set of surfaces it advertises. A Protocol client compares the handshake's version against its own (Version.Compatible) to detect skew, and checks Accepts(cap) before exercising a surface — so a third-party Console built against an older Protocol negotiates explicitly instead of discovering a missing surface by a 404.
VersionHandshake is a wire type — it round-trips through JSON; a transport adapter serves CurrentHandshake() at the negotiation entry point.
func CurrentHandshake ¶
func CurrentHandshake() VersionHandshake
CurrentHandshake builds the Runtime's VersionHandshake from the pinned ProtocolVersion and the advertised Capabilities() set. It is the value a negotiation entry point returns to a connecting client.
func (VersionHandshake) Accepts ¶
func (h VersionHandshake) Accepts(c Capability) bool
Accepts reports whether the handshake advertises capability c — i.e. whether the Runtime that produced this handshake has the corresponding Protocol surface live.
type Window ¶
type Window struct {
// From is the inclusive lower bound; nil ⇒ unbounded below.
From *time.Time `json:"from,omitempty"`
// To is the inclusive upper bound; nil ⇒ unbounded above.
To *time.Time `json:"to,omitempty"`
}
Window is a half-open time range filter. Both bounds are optional; a nil bound means "unbounded on that side". A non-nil From / To filters sessions whose StartedAt falls inside [From, To].