domain

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Aug 16, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package domain holds the Anthropic-native core types that are the single source of truth for the platform. Nothing in this package may depend on adk-go, genai, or any provider SDK — the wire schema of Anthropic Managed Agents is authoritative here.

Index

Constants

View Source
const (
	PrefixAgent         = "agent"
	PrefixEnvironment   = "env"
	PrefixSession       = "sesn"
	PrefixEvent         = "sevt"
	PrefixWork          = "work"
	PrefixVault         = "vlt"
	PrefixCredential    = "vcrd"
	PrefixResource      = "sesrsc"
	PrefixDeployment    = "depl"
	PrefixDeploymentRun = "drun"
	PrefixFile          = "file"
	PrefixSkill         = "skill"
	PrefixSkillVersion  = "skillver"
	PrefixOutcome       = "outc"
	// PrefixEnvironmentKey names an issued worker credential's row. It is
	// internal-only — never on the /v1 wire, and the reference identifies its
	// own environment keys by bare UUID on its console's private API — so it
	// stays out of knownPrefixes, following the apikey_/gtk_ precedent. That
	// set is what every /v1 path accepts as an id shape, and widening it for a
	// private identifier would widen all of them (checkID validates shape, not
	// which resource the prefix names).
	PrefixEnvironmentKey = "envkey"
	// PrefixPrincipal names an authenticated human's identity-bookkeeping row
	// (#56, plan 31). It joins the same private family for the same reason:
	// a principal id never appears on a /v1 path — it is written to
	// sessions.created_by for audit and never rendered — so admitting it to
	// knownPrefixes would widen the id shape every wire path accepts in order
	// to validate something no wire path ever receives.
	PrefixPrincipal = "principal"
	// PrefixAPIKey names a management credential's row. The reference uses the
	// same spelling — its console addressed a probe key as
	// `apikey_013EepdgX96Ux6op9hfWqjqJ` (#378) — but on its console's private API,
	// not on the wire, so this joins the private family too. It was a bare string
	// literal in internal/api until plan 32 gave the console a route that has to
	// validate one on a path; the two spellings are the same constant now.
	PrefixAPIKey = "apikey"
)

Resource ID prefixes, matching the Anthropic Managed Agents wire format.

View Source
const (
	OutcomeResultPending              = "pending"
	OutcomeResultRunning              = "running"
	OutcomeResultEvaluating           = "evaluating"
	OutcomeResultSatisfied            = "satisfied"
	OutcomeResultMaxIterationsReached = "max_iterations_reached"
	OutcomeResultFailed               = "failed"
	OutcomeResultInterrupted          = "interrupted"
)

Outcome-evaluation results, mirroring BetaManagedAgentsOutcomeEvaluationResource (anthropic-sdk-go v1.61.0 betasession.go): pending before the agent begins work, running while producing or revising, evaluating while the grader scores; the other four are terminal.

Variables

This section is empty.

Functions

func OutcomeResultTerminal added in v0.2.0

func OutcomeResultTerminal(result string) bool

OutcomeResultTerminal reports whether an evaluation result ends the outcome: no further evaluation cycles follow and a new user.define_outcome may be accepted.

func ValidWithPrefix added in v0.3.0

func ValidWithPrefix(id, prefix string) bool

ValidWithPrefix is Valid for an identifier this platform mints but never puts on the /v1 wire — envkey_ and its kin, which stay out of knownPrefixes so that admitting one cannot widen the id shape every wire path accepts. It answers the same question against a prefix the caller names: the exact shape NewID emits. Callers off the wire use it to reject a malformed id before it binds into a query, which is the whole reason Valid exists.

Types

type Agent

type Agent struct {
	Scope
	AgentSpec

	ID         ID                `json:"id"` // agent_…
	Type       string            `json:"type"`
	Name       string            `json:"name"`
	Version    int               `json:"version"` // starts at 1
	Metadata   map[string]string `json:"metadata,omitempty"`
	CreatedAt  time.Time         `json:"created_at"`
	UpdatedAt  time.Time         `json:"updated_at"`
	ArchivedAt *time.Time        `json:"archived_at"`
}

Agent is a versioned, reusable configuration. Updates use optimistic locking on Version (mismatch → 409); each change bumps Version and snapshots an AgentVersion.

type AgentSpec

type AgentSpec struct {
	Model       Model             `json:"model"`
	System      string            `json:"system"`
	Description string            `json:"description"`
	Tools       []json.RawMessage `json:"tools"`
	MCPServers  []json.RawMessage `json:"mcp_servers"`
	Skills      []json.RawMessage `json:"skills"`
	Multiagent  json.RawMessage   `json:"multiagent"` // reserved seam: always null in v1
}

AgentSpec is the mutable configuration of an agent, shared by the stored Agent resource and the per-session ResolvedAgent snapshot. This is the wire shape: every field is always present (the surface is api:"required"), and tools/mcp_servers/skills entries stay raw wire JSON so they pass through byte-for-byte — validation happens at the API boundary.

func (*AgentSpec) Normalize

func (s *AgentSpec) Normalize()

Normalize guarantees non-nil collections so JSON renders [] rather than null.

type CacheCreation

type CacheCreation struct {
	Ephemeral1h int64 `json:"ephemeral_1h_input_tokens"`
	Ephemeral5m int64 `json:"ephemeral_5m_input_tokens"`
}

CacheCreation splits cache-creation input tokens by cache TTL.

type ContentBlock

type ContentBlock struct {
	Type string `json:"type"` // "text", …
	Text string `json:"text,omitempty"`
}

ContentBlock is a single block of message content. v1 handles text; other block types (image, etc.) are added as the toolset grows.

type Environment

type Environment struct {
	Scope

	ID          ID                `json:"id"` // env_…
	Type        string            `json:"type"`
	Name        string            `json:"name"`
	Kind        EnvironmentKind   `json:"kind"`
	State       string            `json:"state"`
	Config      EnvironmentConfig `json:"config"`
	Description string            `json:"description,omitempty"`
	Metadata    map[string]string `json:"metadata,omitempty"`
	CreatedAt   time.Time         `json:"created_at"`
	UpdatedAt   time.Time         `json:"updated_at"`
	ArchivedAt  *time.Time        `json:"archived_at"`
}

Environment is a sandbox configuration referenced by sessions. It is not versioned; it persists until archived/deleted.

type EnvironmentConfig

type EnvironmentConfig struct {
	Type       EnvironmentKind     `json:"type"`
	Packages   map[string][]string `json:"packages,omitempty"`
	Networking Networking          `json:"networking,omitempty"`
}

EnvironmentConfig is the sandbox spec. Packages maps a package manager ("apt","cargo","gem","go","npm","pip") to a list of packages (optionally version-pinned).

type EnvironmentKind

type EnvironmentKind string

EnvironmentKind is where sessions in this environment run.

const (
	// EnvCloud: the platform provisions and drives the sandbox (Docker/K8s).
	EnvCloud EnvironmentKind = "cloud"
	// EnvSelfHosted: the environment is a work queue; a customer-run worker
	// pulls work and executes tools (BYOC). Same pull protocol as cloud.
	EnvSelfHosted EnvironmentKind = "self_hosted"
)

type EvaluatedPermission

type EvaluatedPermission string

EvaluatedPermission is the resolved permission the brain stamps on an agent.tool_use / agent.mcp_tool_use event: the platform ran the tool automatically (allow), paused it for human confirmation (ask), or blocked it (deny — reserved; no configurable permission_policy produces it yet).

const (
	EvalPermAllow EvaluatedPermission = "allow"
	EvalPermAsk   EvaluatedPermission = "ask"
	EvalPermDeny  EvaluatedPermission = "deny"
)

type Event

type Event struct {
	ID          ID         // sevt_…
	SessionID   ID         // sesn_…
	ThreadID    ID         // optional (multi-agent), zero if none
	Seq         int64      // monotonic per session; (SessionID, Seq) is unique
	Type        EventType  //
	Body        []byte     // type-specific JSON (flattened at the wire boundary)
	ProcessedAt *time.Time // nil = queued, awaiting in-order processing
	CreatedAt   time.Time  //
}

Event is the stored envelope. Type-specific fields live in Body and are flattened onto the wire object (alongside id/type/processed_at) at the API boundary — the persisted JSON is a flat object keyed by "type".

type EventType

type EventType string

EventType is a "{domain}.{action}" event name, wire-compatible with Anthropic Managed Agents. The full taxonomy is authoritative here; the event log stores these verbatim and the SSE stream replays them.

const (
	EventUserMessage       EventType = "user.message"
	EventUserInterrupt     EventType = "user.interrupt"
	EventUserToolConfirm   EventType = "user.tool_confirmation"
	EventUserCustomToolRes EventType = "user.custom_tool_result"
	EventUserToolResult    EventType = "user.tool_result" // self_hosted: worker returns agent_toolset results
	EventUserDefineOutcome EventType = "user.define_outcome"
	EventSystemMessage     EventType = "system.message"
)

Inbound events — the client/harness sends these into a session.

const (
	EventAgentMessage       EventType = "agent.message"
	EventAgentThinking      EventType = "agent.thinking"
	EventAgentToolUse       EventType = "agent.tool_use"
	EventAgentToolResult    EventType = "agent.tool_result"
	EventAgentMCPToolUse    EventType = "agent.mcp_tool_use"
	EventAgentMCPToolResult EventType = "agent.mcp_tool_result"
	EventAgentCustomToolUse EventType = "agent.custom_tool_use"
)

Outbound agent events — produced by the brain during a turn.

const (
	EventSessionStatusRunning     EventType = "session.status_running"
	EventSessionStatusIdle        EventType = "session.status_idle" // carries stop_reason
	EventSessionStatusRescheduled EventType = "session.status_rescheduled"
	EventSessionStatusTerminated  EventType = "session.status_terminated"
	EventSessionError             EventType = "session.error"
	EventSessionUpdated           EventType = "session.updated"
	EventSessionDeleted           EventType = "session.deleted"
)

Session lifecycle events.

const (
	EventSpanModelRequestStart EventType = "span.model_request_start"
	EventSpanModelRequestEnd   EventType = "span.model_request_end" // carries model_usage

	// The outcome-evaluation cycle trio (plan 21). _end carries the verdict
	// and the grader call's usage; _ongoing is the liveness heartbeat.
	EventSpanOutcomeEvalStart   EventType = "span.outcome_evaluation_start"
	EventSpanOutcomeEvalOngoing EventType = "span.outcome_evaluation_ongoing"
	EventSpanOutcomeEvalEnd     EventType = "span.outcome_evaluation_end"
)

Span (observability) events. These are emitted from the same instrumentation point as the OTel spans so the two never drift.

const (
	EventStart EventType = "event_start"
	EventDelta EventType = "event_delta"
)

Stream-only preview frames. These are NOT persisted and never carry their own id/processed_at — their only identity is the previewed event's id.

func (EventType) Domain

func (t EventType) Domain() string

Domain returns the part before the ".", e.g. "agent" for "agent.tool_use".

func (EventType) Inbound

func (t EventType) Inbound() bool

Inbound reports whether this event type is sent into the session by a client or worker (user.* / system.*) as opposed to produced by the platform.

func (EventType) Persisted

func (t EventType) Persisted() bool

Persisted reports whether the event is durably stored in the log. The stream-only preview frames (event_start/event_delta) are not.

type ID

type ID string

ID is an opaque, prefixed identifier, e.g. "agent_9m3k…". The prefix is wire-compatible with Anthropic Managed Agents so the real `ant` CLI and Anthropic SDKs recognize our resources. Clients must treat the part after the prefix as opaque.

func NewID

func NewID(prefix string) ID

NewID returns a fresh ID with the given prefix (use the Prefix* constants). It panics only if the system CSPRNG fails, which is not a recoverable condition for a server that must mint identifiers.

func (ID) HasPrefix

func (id ID) HasPrefix(prefix string) bool

HasPrefix reports whether id carries the given resource prefix. The Session prefix additionally accepts the alternate "session_" form for wire compat.

func (ID) IsZero

func (id ID) IsZero() bool

IsZero reports whether the ID is empty.

func (ID) Prefix

func (id ID) Prefix() string

Prefix returns the portion before the first underscore, or "" if there is none.

func (ID) String

func (id ID) String() string

func (ID) Valid added in v0.2.0

func (id ID) Valid() bool

Valid reports whether id is a well-formed resource identifier: a known prefix, an underscore, and a non-empty token drawn only from idAlphabet — the exact shape NewID emits, plus the session_ wire spelling. Clients only ever hold ids the server minted, so a value failing this cannot name a stored row. The API rejects such an id on shape (a 404 on a path, a 400 on a query filter) before it reaches a bind parameter, where an unstorable byte (U+0000, invalid UTF-8) — or any non-alphabet byte — would otherwise fail as a 500 (Postgres SQLSTATE 22021) rather than the status the wire expects.

type Model

type Model struct {
	ID    string `json:"id"`
	Speed string `json:"speed,omitempty"` // "standard" | "fast"
}

Model is an agent's model selection. On the wire it is either a bare string ("claude-opus-4-8") or an object ({"id":…,"speed":"standard|fast"}); we normalize to this struct and round-trip both forms.

func (*Model) UnmarshalJSON

func (m *Model) UnmarshalJSON(b []byte) error

UnmarshalJSON accepts either a bare string or the object form.

type ModelUsage

type ModelUsage struct {
	CacheCreationInputTokens int64   `json:"cache_creation_input_tokens"`
	CacheReadInputTokens     int64   `json:"cache_read_input_tokens"`
	InputTokens              int64   `json:"input_tokens"`
	OutputTokens             int64   `json:"output_tokens"`
	Speed                    *string `json:"speed"`
}

ModelUsage is the token accounting attached to a span.model_request_end event (wire field model_usage). All counters are always present on the wire; speed is nullable ("standard" | "fast").

type Networking

type Networking struct {
	Type                 NetworkingType `json:"type"`
	AllowedHosts         []string       `json:"allowed_hosts,omitempty"`
	AllowMCPServers      bool           `json:"allow_mcp_servers,omitempty"`
	AllowPackageManagers bool           `json:"allow_package_managers,omitempty"`
}

Networking is the sandbox egress policy. For "limited", AllowedHosts is a list of bare hostnames or "*.example.com" wildcards (no scheme/port/path).

type NetworkingType

type NetworkingType string

NetworkingType controls sandbox egress.

const (
	NetUnrestricted NetworkingType = "unrestricted" // default; all egress except a safety blocklist
	NetLimited      NetworkingType = "limited"      // only AllowedHosts
)

type OutcomeEvaluation added in v0.2.0

type OutcomeEvaluation struct {
	Type        string     `json:"type"` // "outcome_evaluation"
	OutcomeID   ID         `json:"outcome_id"`
	Description string     `json:"description"`
	Explanation string     `json:"explanation"`
	Iteration   int64      `json:"iteration"`
	Result      string     `json:"result"`
	CompletedAt *time.Time `json:"completed_at"`
}

OutcomeEvaluation is one entry of the session's outcome_evaluations list — the wire shape of BetaManagedAgentsOutcomeEvaluationResource, stored verbatim as jsonb on the sessions row and mutated in place per evaluation cycle (one entry per define_outcome event, `explanation` from the most recent evaluation). CompletedAt is null until the result is terminal (ours, INFERRED — docs/DIVERGENCES.md).

type PermissionPolicy

type PermissionPolicy struct {
	Type PermissionPolicyType `json:"type"`
}

PermissionPolicy wraps the policy type in the wire's {"type":…} object.

type PermissionPolicyType

type PermissionPolicyType string

PermissionPolicyType controls whether a tool runs automatically or pauses for confirmation. Defaults per the reference: agent toolset = always_allow, mcp toolset = always_ask.

const (
	PolicyAlwaysAllow PermissionPolicyType = "always_allow"
	PolicyAlwaysAsk   PermissionPolicyType = "always_ask"
)

type ResolvedAgent

type ResolvedAgent struct {
	Type    string `json:"type"` // "agent"
	ID      ID     `json:"id"`
	Version int64  `json:"version"`
	Name    string `json:"name"`

	AgentSpec
}

ResolvedAgent is the agent config actually applied to a session, after any per-session overrides (BetaManagedAgentsSessionAgent). ID/Version still reference the base agent. Stored verbatim in sessions.resolved_agent; rendering is a passthrough except for the toolset configuration inside tools[], which the API resolves for the echo.

type Scope

type Scope struct {
	OrgID       string `json:"-"`
	WorkspaceID string `json:"-"`
	ProjectID   string `json:"-"`
}

Scope is the reserved multi-tenant scoping carried by every core resource. v1 is single-tenant and fills these with default values; the columns exist from day 1 so multi-tenancy can land without a migration of meaning.

NOTE: scoping is org/workspace/project — NEVER user. Sessions are not bound to an end-user (a deliberate divergence from adk's AppName+UserID). End-user ↔ session ownership is an application-layer concern.

type SearchResultBlock added in v0.2.0

type SearchResultBlock struct {
	Type      string                `json:"type"` // always "search_result"
	Citations SearchResultCitations `json:"citations"`
	Content   []ContentBlock        `json:"content"`
	Source    string                `json:"source"`
	Title     string                `json:"title"`
}

SearchResultBlock is one web_search hit as an agent.tool_result carries it — the SDK's BetaManagedAgentsSearchResultBlock, field for field: the citation settings, the hit's text content, the source URL, the page title, and type "search_result". Every field is required on the wire, so none is omitempty.

type SearchResultCitations added in v0.2.0

type SearchResultCitations struct {
	Enabled bool `json:"enabled"`
}

SearchResultCitations mirrors BetaManagedAgentsSearchResultCitations.

type Session

type Session struct {
	Scope

	ID            ID            `json:"id"` // sesn_…
	Type          string        `json:"type"`
	Title         string        `json:"title,omitempty"`
	Status        SessionStatus `json:"status"`
	EnvironmentID ID            `json:"environment_id"`

	// Agent is the resolved agent snapshot applied to this session (after any
	// per-session overrides). Its embedded id/version still point at the base
	// agent for traceability.
	Agent ResolvedAgent `json:"agent"`

	VaultIDs  []ID              `json:"vault_ids,omitempty"`
	Resources []SessionResource `json:"resources,omitempty"`
	Metadata  map[string]string `json:"metadata,omitempty"`
	Usage     Usage             `json:"usage"`

	// CreatedBy is audit-only: which API key / principal created the session.
	// It does NOT participate in isolation/partitioning and is not part of the
	// wire schema — it exists purely for on-prem audit. Nil when unknown.
	CreatedBy *string `json:"-"`

	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

Session is a running instance of an agent in an environment. It references a resolved snapshot of the agent config (so agent updates don't retroactively change a live session) and an environment.

type SessionResource

type SessionResource struct {
	ID   ID     `json:"id"` // sesrsc_…
	Type string `json:"type"`
	Raw  []byte `json:"-"`
}

SessionResource is a mounted resource (github_repository, file, …). Modeled as a raw envelope in v1; typed variants land with the resource-mount slice.

type SessionStatus

type SessionStatus string

SessionStatus is the session state-machine value, wire-compatible with Anthropic Managed Agents.

const (
	SessionIdle         SessionStatus = "idle"         // waiting for input; new sessions start here
	SessionRunning      SessionStatus = "running"      // executing
	SessionRescheduling SessionStatus = "rescheduling" // transient error, auto-retrying
	SessionTerminated   SessionStatus = "terminated"   // unrecoverable, ended
)

type StopReason

type StopReason struct {
	Type     StopReasonType `json:"type"`
	EventIDs []ID           `json:"event_ids,omitempty"`
}

StopReason accompanies a session.status_idle event. EventIDs lists the blocking tool_use/custom_tool_use events when Type is requires_action.

type StopReasonType

type StopReasonType string

StopReasonType enumerates why a session went idle.

const (
	StopRequiresAction   StopReasonType = "requires_action"
	StopEndTurn          StopReasonType = "end_turn"
	StopRetriesExhausted StopReasonType = "retries_exhausted"
)

type Usage

type Usage struct {
	InputTokens          int64         `json:"input_tokens"`
	OutputTokens         int64         `json:"output_tokens"`
	CacheReadInputTokens int64         `json:"cache_read_input_tokens"`
	CacheCreation        CacheCreation `json:"cache_creation"`
}

Usage accumulates token counts over the session — the session-resource wire shape, with cache-creation tokens nested per TTL bucket (unlike the flat event-level ModelUsage on span.model_request_end). Stored verbatim in sessions.usage.

func (*Usage) Add

func (u *Usage) Add(m ModelUsage)

Add folds one model turn's usage into the session totals. The flat cache_creation_input_tokens counter lands in the 5-minute bucket: providers don't report a TTL split, and 5m is the protocol's default cache TTL.

Jump to

Keyboard shortcuts

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