Help us shape the future of Go! Take the 2026 Go Developer Survey

domain

package
v0.5.1 Latest Latest
Warning

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

Go to latest
Published: Oct 4, 2026 License: Apache-2.0 Imports: 8 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  = "skver"
	PrefixOutcome       = "outc"
	PrefixSessionThread = "sthr"
	// The memory family (plan 36 decision 2).
	PrefixMemoryStore   = "memstore"
	PrefixMemory        = "mem"
	PrefixMemoryVersion = "memver"
	// PrefixDream names a memory-consolidation job over a store and a set of
	// session transcripts (plan 41).
	PrefixDream = "drm"
	// 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 (
	MCPModelNamePrefix    = "mcp__"
	MCPModelNameSeparator = "__"
)

The frame of the name an MCP tool is offered to the model under. The reference composes the name it shows the model and decomposes it on the event it commits, which carries the server and the bare tool in fields of their own (docs/DIVERGENCES.md, "Offering an MCP tool to the model").

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

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

View Source
const ScheduleCron = "cron"

ScheduleCron is the only schedule type the reference defines. It is spelled out rather than assumed because the wire field is a discriminator: a second kind would arrive as a new value here, not as a new schema.

Variables

ConsumedInputs are the inputs a model request consumes when it starts (#793), and the one list every set built on that fact derives from: the consumption rule (events.ConsumedInput), what a request's start stamps (events.RequestInputTypes), what may be written unprocessed (StampedOnConsumption) and what chains a thread's next turn (the brain's pendingInputTypes). The start stamps each 1 µs before its span.model_request_start, as the reference stamps it, and one that lands while a request is in flight is the next request's.

View Source
var ErrInferenceGeoValue = errors.New(`model.inference_geo must be "us" or "global"`)

ErrInferenceGeoValue is ModelInferenceGeo's refusal of a string outside the supported values. Its text is this platform's own; the agent create and update routes recognize it and answer in the reference's recorded words instead (internal/api parseAgentModel, #540).

Functions

func MCPModelName added in v0.5.0

func MCPModelName(server, tool string) string

MCPModelName composes the name an MCP tool is offered to the model under: the tool named by the event's mcp_server_name and name. Anything that shows the model a call it made — replay rebuilding the assistant block, a denial's text — names it this way, so the model reads the name it called.

Bytes outside the Messages tool-name class [a-zA-Z0-9_-] become '_', one for one, so the name is exactly as long as its parts and frame — the length a caller bounding it can settle before composing. Mangling rather than dropping is what keeps a whole server's tools from vanishing over a naming convention: internal/mcp admits the SDK's own tool-name class, which includes '.', so a server publishing `github.create_issue` would otherwise offer nothing at all. A mangled name costs nothing a reader of the log can see, since the event keeps the pair; two tools that mangle to one name contest it exactly as two that composed to one do.

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 ValidPackageEntry added in v0.4.0

func ValidPackageEntry(entry string) bool

ValidPackageEntry reports whether entry may be handed to its package manager as one argument. Two shapes are refused, and only two: the empty string, which no manager can install, and one beginning with '-', which every manager reads as an option rather than a package — `--index-url=…` passed to `pip install` would redirect the whole install, and no quoting can stop it, because the entry is a single argument either way. Everything else (a pin, `@`, `:`, whitespace) is the manager's own syntax and passes through verbatim. A NUL is not this predicate's concern: the API's rejectNULBody (wire.go) refuses it anywhere in the request body before this runs, and jsonb could not store it, so no stored row ever carries one to the executor. The API applies this at create and update; the executor applies it again before building a command, so a row stored before the rule is refused at install rather than passed (docs/plan/40_environment-packages.md decision 6).

func WellFormedID added in v0.5.0

func WellFormedID(id, prefix string) bool

WellFormedID reports whether id is shaped like an id of the resource prefix names, on the surfaces where the reference was recorded telling a malformed id from an absent one: prefix_, then a non-empty token of ASCII letters and digits other than I, O and l. That set is the union of the alphabet NewID mints and the base58 the reference's own ids carry after their "01" (base58 has no 0, I, O or l; idAlphabet needs the 0), so every id either side mints is well-formed — the fixed ones too, agent_dreamrunner among them — and the reference's recorded refusals still read as malformed: a missing or wrong prefix (`undefined`, `sth_…`) and an I in the token, which it refused as malformed in a thread id (`sthr_01UnknownThreadIdXXXXXXXXX`) and an agent id (`agent_01UnknownAgentIdXXXXXXXX`, 24 characters like every real one, so the character is what decides and not the length). Only ASCII letters and digits pass, so nothing unstorable reaches a bind parameter. The rule is inferred from those recordings (docs/DIVERGENCES.md); the I is the only excluded character any of them carries.

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 AgentReference added in v0.4.0

type AgentReference struct {
	Type    string `json:"type"` // "agent"
	ID      ID     `json:"id"`
	Version int    `json:"version"`
}

AgentReference is an agent pinned to a concrete version — "a resolved agent reference with a concrete version". A deployment stores one rather than a floating "latest" so that publishing a new agent version cannot change what tonight's scheduled fire runs; repinning is an explicit update.

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 is the coordinator roster, null for a single agent: on the
	// stored agent, pinned {id, type, version} references; on a session's
	// resolved agent, full member definitions (plan 35; internal/api/roster.go).
	Multiagent json.RawMessage `json:"multiagent"`
}

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 Deployment added in v0.4.0

type Deployment struct {
	Scope

	ID   ID     `json:"id"` // depl_…
	Name string `json:"name"`
	// Description is nullable on the wire, and null is how the reference
	// spells "unset" — the key is required, so it is present either way.
	Description   *string           `json:"description"`
	Agent         AgentReference    `json:"agent"`
	EnvironmentID ID                `json:"environment_id"`
	VaultIDs      []ID              `json:"vault_ids"`
	InitialEvents []json.RawMessage `json:"initial_events"`
	// Resources "echoes the input minus write-only credentials" — raw wire
	// JSON, so it passes through byte-for-byte after the API has stripped
	// what must never be echoed.
	Resources []json.RawMessage `json:"resources"`
	Metadata  map[string]string `json:"metadata"`
	Schedule  *Schedule         `json:"schedule"`

	// The three stored pause columns. They are storage, not wire: emitting
	// them beside paused_reason would publish a second, unschema'd spelling of
	// the same fact.
	PausedAt        *time.Time `json:"-"`
	PausedKind      PausedKind `json:"-"`
	PausedErrorType string     `json:"-"`

	// CreatedBy is audit-only — which API key or principal created the
	// deployment — and never on the wire, sessions.created_by's rule. It
	// matters more here: a session a schedule fires has no creator, so this is
	// where the audit trail survives.
	CreatedBy *string `json:"-"`

	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
	// ArchivedAt is set once and never cleared. Archiving is one-way: this
	// platform serves no unarchive and no DELETE /v1/deployments.
	ArchivedAt *time.Time `json:"archived_at"`
}

Deployment binds an agent to everything needed to run it autonomously: an environment, credentials, initial events, and an optional schedule.

Two of its sixteen required wire members are not fields here. `type` is a constant, and `status`/`paused_reason` are computed from the three pause columns by MarshalJSON — the invariant "paused_reason is non-null exactly when status is paused" is one a single renderer can hold and two independently-written columns cannot. `budget` is the seventeenth property, outside the required list, and this platform never emits it (§8.1 entry 2).

func (Deployment) MarshalJSON added in v0.4.0

func (d Deployment) MarshalJSON() ([]byte, error)

MarshalJSON adds the three members nothing stores — the constant type and the computed status/paused_reason — and guarantees the collections render as [] and {} rather than null.

func (Deployment) Reason added in v0.4.0

func (d Deployment) Reason() *PausedReason

Reason renders paused_reason: "non-null exactly when status is paused; null otherwise". It reads the same two columns Status does, so the two cannot disagree.

func (Deployment) Status added in v0.4.0

func (d Deployment) Status() DeploymentStatus

Status is "active" or "paused", and an archived deployment reports "active" with archived_at set. Archive leaves the pause columns exactly as it found them, so without that last rule a deployment archived while paused would report paused forever on a row nothing can fire — and nothing unarchives, so nothing could observe it recover.

type DeploymentRun added in v0.4.0

type DeploymentRun struct {
	ID             ID             `json:"id"` // drun_…
	DeploymentID   ID             `json:"deployment_id"`
	TriggerContext TriggerContext `json:"trigger_context"`
	SessionID      *ID            `json:"session_id"`
	Error          *RunError      `json:"error"`
	Agent          AgentReference `json:"agent"`
	CreatedAt      time.Time      `json:"created_at"`
}

DeploymentRun is BetaManagedAgentsDeploymentRun: "a persistent, append-only record of a single deployment execution. Records session creation success or failure — no session lifecycle tracking." Exactly one of SessionID and Error is non-null on a settled row — the writers' construction, not a CHECK (0031). SessionID outlives its session, dangling, since migration 0042 (#663); on a run whose session was deleted before 0042 it reverted to null, which is why success is judged from the stored succeeded_at and never from this link (#520).

func (DeploymentRun) MarshalJSON added in v0.4.0

func (r DeploymentRun) MarshalJSON() ([]byte, error)

MarshalJSON adds the constant type and renders the timestamp in UTC, Deployment.MarshalJSON's rule.

type DeploymentStatus added in v0.4.0

type DeploymentStatus string

DeploymentStatus is the two-value computed status. It is never stored: see Deployment.Status.

const (
	DeploymentActive DeploymentStatus = "active"
	DeploymentPaused DeploymentStatus = "paused"
)

type EffortLevelError added in v0.5.0

type EffortLevelError struct{ Level string }

EffortLevelError is ModelEffort's refusal of a level string outside the five. Its text is this platform's own; Level is the value sent, which the agent create and update routes quote in the reference's recorded sentence instead (internal/api parseAgentModel, #540). The {type: level} form's bad level is a plain error: the reference's answer to it is unrecorded.

func (*EffortLevelError) Error added in v0.5.0

func (e *EffortLevelError) Error() string

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). It carries no slot for the wire's packages.type discriminator (#382): that key is a render-time-only concern the API layer stamps on and off (api.packagesTypeEcho) — this map must never store it, or internal/executor's and the gate config endpoint's decode of this same field breaks.

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         // the emitting child thread; zero on the primary thread's rows
	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"

	// The agent-to-agent message pair (plan 35 decision 6). _sent is the
	// observability event on the sender's own stream and _received the delivery
	// written to the target thread's input stream, so one message is two rows,
	// one per thread. Each names its peer thread in a field of its own —
	// to_session_thread_id and from_session_thread_id — rather than in the
	// envelope's session_thread_id, which neither carries. The agent name beside
	// it is asymmetric (#675): _received always names its sender in
	// from_agent_name, the coordinator included, while _sent carries
	// to_agent_name only when its target is a child and omits the key, rather
	// than writing a null, when the target is the primary. Rows a build before
	// #675 wrote hold a present null in either field when that peer is the
	// primary.
	EventAgentThreadMessageSent     EventType = "agent.thread_message_sent"
	EventAgentThreadMessageReceived EventType = "agent.thread_message_received"
)

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 (
	EventSessionThreadCreated           EventType = "session.thread_created"
	EventSessionThreadStatusRunning     EventType = "session.thread_status_running"
	EventSessionThreadStatusIdle        EventType = "session.thread_status_idle"
	EventSessionThreadStatusRescheduled EventType = "session.thread_status_rescheduled"
	EventSessionThreadStatusTerminated  EventType = "session.thread_status_terminated"
)

Session-thread lifecycle events (plan 35). The four status events mirror session.status_* per thread — emitted on the thread's own stream and, for a child, cross-posted to the primary's; every session.status_running/_idle/ _rescheduled a primary-thread transition emits has the primary's beside it, on every session (decision 12; events.TransitionThread orders the pair) — never _terminated, which the primary does not emit (a child terminates; the primary ends with its session). Each carries {session_thread_id, agent_name}; _idle adds stop_reason.

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.

func (EventType) StampedOnConsumption added in v0.5.0

func (t EventType) StampedOnConsumption() bool

StampedOnConsumption reports whether this event may be written unprocessed, its processed_at left null until whatever consumes it stamps it — every inbound event, and every consumed input the platform writes itself: a delivered agent-to-agent message, read by its target's next request (#793). What consumes each differs: an answer is stamped by its thread's ordered processor, and an input a model request reads by that request's start, 1 µs before it, as the reference stamps it (events.RequestInputTypes). Everything else the platform writes is processed on emission.

func (EventType) StartsNewWork added in v0.4.0

func (t EventType) StartsNewWork() bool

StartsNewWork reports whether this event is somebody outside the session asking it to do something new — the narrower sibling of Inbound, and the reset for the session delegation bound (#447).

Inbound cannot serve: it is true for user.tool_result, and on a self_hosted environment every single tool call comes back as a client POST, so a bound reset by Inbound would be zeroed continuously and bound nothing. The split is demand versus answer. A message, an outcome and an operator's system message are demands. A tool result answers a call the session itself made, so it carries the session's own work forward rather than starting new work.

user.tool_confirmation is a demand for a reason beyond "a human is present": it is absent from the brain's pendingInputTypes, so without it a human who has just approved a gated call would see the very next turn refused.

user.interrupt is excluded deliberately: a stop is not a demand, and counting it would let an operator's own stop action hand the session a fresh budget.

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 PrimaryThreadID added in v0.4.0

func PrimaryThreadID(sessionID ID) ID

PrimaryThreadID is the id of a session's primary thread: sthr_ plus the session id's own token (plan 35 decision 1) — deterministic, so any component can name it without a lookup, backfillable in SQL, valid in the id alphabet, and unique because session ids are. Clients treat it as opaque; the reference's derivation is unrecorded. The session_ wire spelling derives to the same id as its sesn_ form.

func (ID) HasPrefix

func (id ID) HasPrefix(prefix string) bool

HasPrefix reports whether id carries the given resource prefix. Two prefixes additionally accept an alternate form on input: Session takes "session_" for wire compat, and SkillVersion takes "skillver_", the spelling stored rows still carry.

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. A value failing this cannot name a row NewID wrote. The API rejects such an id on shape before it reaches a bind parameter, where an unstorable byte (U+0000, invalid UTF-8) would otherwise fail as a 500 (Postgres SQLSTATE 22021): with the 404 an absent id gets on most paths, and a 400 on a query filter. The surfaces where the reference tells a malformed id from an absent one read ids by WellFormedID instead, which admits the reference's own ids, and the fixed ones this platform writes, to the lookup.

type Model

type Model struct {
	ID     string      `json:"id"`
	Speed  string      `json:"speed,omitempty"` // "standard" | "fast"
	Effort ModelEffort `json:"effort,omitempty"`
	// InferenceGeo is compatibility metadata only; it does not constrain routing.
	// Checked against anthropic-sdk-go v1.70.1 — betaagent.go
	// BetaManagedAgentsModelConfigParams.InferenceGeo and BetaManagedAgentsModelConfig.InferenceGeo.
	InferenceGeo ModelInferenceGeo `json:"inference_geo,omitempty"`
}

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":…, "effort":…, "inference_geo":…}); 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 ModelEffort added in v0.5.0

type ModelEffort string

ModelEffort accepts the input union and renders the response's object form. Checked against anthropic-sdk-go v1.70.1 — betaagent.go BetaManagedAgentsModelConfigParams.Effort and BetaManagedAgentsModelConfigEffortUnion. The zero value leaves the choice to the configured upstream (DIVERGENCES).

func (ModelEffort) MarshalJSON added in v0.5.0

func (e ModelEffort) MarshalJSON() ([]byte, error)

func (*ModelEffort) UnmarshalJSON added in v0.5.0

func (e *ModelEffort) UnmarshalJSON(b []byte) error

type ModelInferenceGeo added in v0.5.0

type ModelInferenceGeo string

ModelInferenceGeo preserves the optional geo selection, without enforcing it. The supported values come from the public agent guide: https://platform.claude.com/docs/en/managed-agents/agent-setup#pin-the-inference-geo

func (*ModelInferenceGeo) UnmarshalJSON added in v0.5.0

func (g *ModelInferenceGeo) UnmarshalJSON(b []byte) error

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 PausedKind added in v0.4.0

type PausedKind string

PausedKind discriminates the two ways a deployment comes to be paused. It is the stored half of paused_reason, whose wire shape carries no timestamp — so the column pair, not the rendering, is what the platform writes.

const (
	// PausedManual: "the caller invoked the pause endpoint on the deployment".
	PausedManual PausedKind = "manual"
	// PausedError: "a scheduled fire recorded a failed run whose error
	// auto-pauses the deployment".
	PausedError PausedKind = "error"
)

type PausedReason added in v0.4.0

type PausedReason struct {
	Type  PausedKind         `json:"type"`
	Error *PausedReasonError `json:"error,omitempty"`
}

PausedReason is the rendering of a deployment's three pause columns: {"type":"manual"}, or {"type":"error","error":{"type":…}}.

type PausedReasonError added in v0.4.0

type PausedReasonError struct {
	Type string `json:"type"`
}

PausedReasonError names why an auto-pause happened. It carries a type and nothing else — no message — so the run row remains the only place the failure's detail survives.

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[] — the agent's own and each multiagent member's — which the API resolves for the echo.

type RunError added in v0.4.0

type RunError struct {
	Type    string `json:"type"`
	Message string `json:"message"`
}

RunError is the {type, message} a failed deployment run records — one of the sixteen members of the reference's run-error union (0031 spells them out).

type Schedule added in v0.4.0

type Schedule struct {
	Type       string `json:"type"` // ScheduleCron
	Expression string `json:"expression"`
	Timezone   string `json:"timezone"`

	// LastRunAt is "time the most recent scheduled run actually started. Null
	// until one completes; preserved after the deployment is archived. Manual
	// runs do not update this."
	LastRunAt *time.Time `json:"last_run_at"`
	// UpcomingRunsAt is "up to 5 timestamps of upcoming cron occurrences" —
	// non-empty for active and paused deployments, empty once archived.
	UpcomingRunsAt []time.Time `json:"upcoming_runs_at"`
}

Schedule is a deployment's recurring cron schedule together with the two timestamps the platform computes for it. Presence enables scheduled execution; a nil Schedule means manual-only.

Expression and Timezone are the stored pair — always both or neither. LastRunAt and UpcomingRunsAt are derived at read time from deployment_runs and internal/cron respectively, and are never stored: a stored copy would be a second answer to a question the run history already answers, free to drift from it.

func (Schedule) MarshalJSON added in v0.4.0

func (s Schedule) MarshalJSON() ([]byte, error)

MarshalJSON renders an unset UpcomingRunsAt as [] rather than null — the member is an array whenever it is present, and a client reading "is anything scheduled?" indexes into it — and stamps both timestamps in UTC.

The zone is not cosmetic. LastRunAt arrives from the database in whatever zone the connection is set to, and rendering it as +08:00 rather than Z is a different string for the same instant: a client diffing two reads, or an acceptance test comparing against a recorded response, sees a change that did not happen.

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 TriggerContext added in v0.4.0

type TriggerContext struct {
	Type        string     `json:"type"` // "schedule" | "manual"
	ScheduledAt *time.Time `json:"scheduled_at,omitempty"`
}

TriggerContext says what fired a run: {"type": "manual"} for POST /run, {"type": "schedule", "scheduled_at": …} for the cron scheduler. The manual context carries no scheduled_at at all — the reference closes both objects with additionalProperties: false — which is what omitempty renders. The same omitempty cuts the other way on the schedule variant, where the wire REQUIRES scheduled_at: a renderer that builds one must set the pointer, because a forgotten nil is silently omitted rather than failing loudly.

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