Documentation
¶
Overview ¶
Package subagent defines the contract for delegating a bounded sub-task to a nested agent. The in-process implementation (internal/turn) runs an ephemeral turn; the interface is intentionally backend-agnostic so a future Aether-task implementation (spawning a separate sandbox/agent) can satisfy the same contract without changing the spawn tool.
Index ¶
- Constants
- Variables
- func Depth(ctx context.Context) int
- func MarshalExecutionEnvelope(envelope ExecutionEnvelope) ([]byte, error)
- func StructuredDigest(raw json.RawMessage) string
- func WithDepth(ctx context.Context, depth int) context.Context
- type AgentName
- type AgentType
- type AssignedExecutionResolver
- type AssignedExecutionResolverFunc
- type AssignedExecutionResources
- type AssignedRunner
- type BackgroundRunner
- type CASRegistry
- func (r *CASRegistry) ListSubagents(ctx context.Context, workspaceID, parentSessionID string) ([]spec.SessionSubagentRecord, error)
- func (r *CASRegistry) ObserveSubagent(ctx context.Context, event LifecycleEvent) error
- func (r *CASRegistry) RecoverInterrupted(ctx context.Context, at time.Time) error
- func (r *CASRegistry) RecoverInterruptedWithTasks(ctx context.Context, at time.Time, tasks TaskBackend) error
- type CASRegistryConfig
- type Catalog
- type Definition
- type ExecutionArtifactRef
- type ExecutionEnvelope
- func (e ExecutionEnvelope) ExecutionScopeDigest() string
- func (e ExecutionEnvelope) ResolveInput(messages []protocol.ChatMessage) (protocol.ChatMessage, string, error)
- func (e ExecutionEnvelope) ResolveResult(messages []protocol.ChatMessage) (protocol.ChatMessage, error)
- func (e ExecutionEnvelope) Validate() error
- func (e ExecutionEnvelope) VerifyPolicy(req Request) error
- type ExecutionOwnership
- type ExecutionPolicy
- type ExecutionScopeAuthorizationRequest
- type ExecutionScopeAuthorizer
- type FileCatalog
- type FileRegistry
- func (r *FileRegistry) ListSubagents(ctx context.Context, workspaceID, parentSessionID string) ([]spec.SessionSubagentRecord, error)
- func (r *FileRegistry) ObserveSubagent(ctx context.Context, event LifecycleEvent) error
- func (r *FileRegistry) RecoverInterrupted(ctx context.Context, at time.Time) error
- type LifecycleEvent
- type LifecycleObserver
- type OutputContract
- type PermissionMode
- type ProviderCatalog
- func (c *ProviderCatalog) Get(ctx context.Context, typ AgentType) (Definition, error)
- func (c *ProviderCatalog) GetWorkspace(ctx context.Context, workspaceID string, typ AgentType) (Definition, error)
- func (c *ProviderCatalog) List(ctx context.Context) ([]Definition, error)
- func (c *ProviderCatalog) ListWorkspace(ctx context.Context, workspaceID string) ([]Definition, error)
- type Ref
- type Registry
- type Request
- type Result
- type Runner
- type TaskAdmission
- type TaskAwaiter
- type TaskBackend
- type TaskOutcome
- type TaskRecovery
- type TaskRecoveryRegistry
- type ValidationError
- type WorkspaceCatalog
- type WorkspaceDefinitionProvider
Constants ¶
const ( // ExecutionEnvelopeSchema identifies the OSS child-execution descriptor // carried by a durable task backend. It is an execution-plane contract, not // part of the ecosystem session-message protocol. ExecutionEnvelopeSchema = "agent-harness.subagent.execution" // Revision 1 includes the exact workspace execution scope. This contract is // still unreleased, so iterative local shapes are not retained as separate // compatibility revisions. ExecutionEnvelopeSchemaRevision = 1 ExecutionBackendHistory = "history" ExecutionBackendTaskCheckpoint = "task_checkpoint" ExecutionArtifactMessage = "message" ExecutionArtifactAssistantAfter = "assistant_after_input" ExecutionArtifactCheckpoint = "checkpoint" ExecutionAuthorityDurableTask = "durable_task" ExecutionUncertainInterrupt = "interrupt_without_replay" )
const (
MaxOutputSchemaBytes = 64 << 10
)
Variables ¶
var ( ErrInvalidDefinition = errors.New("subagent: invalid agent definition") ErrInvalidPermissionMode = errors.New("subagent: invalid permission mode") ErrToolDenied = errors.New("subagent: tool denied") )
var ( ErrCorruptRegistry = errors.New("subagent: corrupt lifecycle registry") ErrDeletedLifecycle = errors.New("subagent: deleted lifecycle cannot be resumed") )
var ( ErrTaskOutcomeUncertain = errors.New("subagent: execution task outcome is uncertain") // ErrParentCheckpointUncertain means child admission may already be durable, // but the parent turn could not confirm its own recovery checkpoint. The // parent must stop immediately and must not turn this into an ordinary tool // error that lets the model request another child. ErrParentCheckpointUncertain = errors.New("subagent: parent admission checkpoint is uncertain") )
ErrTaskOutcomeUncertain means child execution ended locally but the durable task backend could not confirm its terminal transition. Callers must not automatically replay the child: its transcript or tool side effects may have committed even though the task still appears non-terminal.
var ErrBackgroundUnsupported = errors.New("subagent: background execution not supported")
ErrBackgroundUnsupported is returned when a background spawn is requested but the installed runner does not implement BackgroundRunner (e.g. a backend without a detached-execution seam). The spawn tool treats it as a signal to fall back to a synchronous run rather than failing the call.
var ErrCASRetryLimit = errors.New("subagent: distributed lifecycle update retry limit exceeded")
var ErrNoRunner = errors.New("subagent: no runner configured")
ErrNoRunner is returned when a sub-agent is requested but no runner is wired.
var ErrUnknownAgent = errors.New("subagent: unknown agent")
Functions ¶
func MarshalExecutionEnvelope ¶ added in v0.0.2
func MarshalExecutionEnvelope(envelope ExecutionEnvelope) ([]byte, error)
MarshalExecutionEnvelope validates and deterministically encodes a descriptor for a durable task payload.
func StructuredDigest ¶ added in v0.0.2
func StructuredDigest(raw json.RawMessage) string
StructuredDigest identifies the exact validated JSON bytes returned by a child. Callers should trim surrounding whitespace before computing it.
Types ¶
type AssignedExecutionResolver ¶ added in v0.0.2
type AssignedExecutionResolver interface {
ResolveAssignedExecution(ctx context.Context, workspaceID string) (AssignedExecutionResources, error)
}
AssignedExecutionResolver selects workspace-scoped execution resources for an externally assigned child. Implementations must not fall back across workspace boundaries: a resolution failure prevents model/tool execution and is recorded as a terminal rejection before the task is claimed.
type AssignedExecutionResolverFunc ¶ added in v0.0.2
type AssignedExecutionResolverFunc func(context.Context, string) (AssignedExecutionResources, error)
AssignedExecutionResolverFunc adapts a function to AssignedExecutionResolver.
func (AssignedExecutionResolverFunc) ResolveAssignedExecution ¶ added in v0.0.2
func (f AssignedExecutionResolverFunc) ResolveAssignedExecution(ctx context.Context, workspaceID string) (AssignedExecutionResources, error)
type AssignedExecutionResources ¶ added in v0.0.2
type AssignedExecutionResources struct {
Runner AssignedRunner
Catalog Catalog
}
AssignedExecutionResources are resolved after the executor has validated an envelope's workspace identity and typed task authority, but before it claims the task. A multi-workspace host uses this seam to select a runner and catalog built exclusively for that logical workspace.
type AssignedRunner ¶ added in v0.0.2
type AssignedRunner interface {
ExecuteAssignedSubagent(ctx context.Context, taskID string, envelope ExecutionEnvelope, req Request) (Result, error)
}
AssignedRunner consumes an already-admitted execution. The caller owns the durable task claim and terminal transition; implementations must not admit a second task for the same envelope.
type BackgroundRunner ¶
type BackgroundRunner interface {
Runner
StartBackground(ctx context.Context, req Request) (threadID string, err error)
}
BackgroundRunner is a Runner that can additionally start a sub-agent DETACHED: StartBackground mints (or resumes) the child thread, launches the run asynchronously, and returns the child thread id — the re-addressable handle — immediately, without waiting for the child to finish. The backend delivers the child's completion out-of-band (the in-process backend pushes a notice back to the parent thread that wakes a fresh parent turn). A backend that cannot detach need not implement this; the spawn tool falls back to a synchronous RunSubagent.
type CASRegistry ¶ added in v0.0.2
type CASRegistry struct {
// contains filtered or unexported fields
}
CASRegistry persists one bounded-by-parent lifecycle projection per workspace/session. A small CAS-maintained identity index supports startup interruption recovery without requiring backend-specific key scans.
func NewCASRegistry ¶ added in v0.0.2
func NewCASRegistry(config CASRegistryConfig) (*CASRegistry, error)
func (*CASRegistry) ListSubagents ¶ added in v0.0.2
func (r *CASRegistry) ListSubagents(ctx context.Context, workspaceID, parentSessionID string) ([]spec.SessionSubagentRecord, error)
func (*CASRegistry) ObserveSubagent ¶ added in v0.0.2
func (r *CASRegistry) ObserveSubagent(ctx context.Context, event LifecycleEvent) error
func (*CASRegistry) RecoverInterrupted ¶ added in v0.0.2
func (*CASRegistry) RecoverInterruptedWithTasks ¶ added in v0.0.2
func (r *CASRegistry) RecoverInterruptedWithTasks(ctx context.Context, at time.Time, tasks TaskBackend) error
RecoverInterruptedWithTasks reconciles unfinished projections against the durable execution task state. In deferred Aether mode the backend is retained with the timestamp and used by the first post-connect registry operation.
type CASRegistryConfig ¶ added in v0.0.2
type CASRegistryConfig struct {
Blobs casblob.Store
Prefix string
MaxRetries int
// DeferRecovery makes RecoverInterrupted record the requested recovery and
// apply it on the first later read/write. Aether workers use this because KV
// becomes available only after Start; successful connection of their stable
// agent identity proves the prior duplicate is no longer active.
DeferRecovery bool
}
type Catalog ¶
type Catalog interface {
List(ctx context.Context) ([]Definition, error)
Get(ctx context.Context, typ AgentType) (Definition, error)
}
type Definition ¶
type Definition struct {
Name AgentName `json:"name"`
Type AgentType `json:"type"`
Description string `json:"description"`
Prompt string `json:"prompt,omitempty"`
PromptPath string `json:"prompt_path,omitempty"`
Model string `json:"model,omitempty"`
MaxTurns int `json:"max_turns,omitempty"`
AllowedTools []string `json:"tool_allow,omitempty"`
DeniedTools []string `json:"tool_deny,omitempty"`
Skills []string `json:"skills,omitempty"`
MCPServers []string `json:"mcp_servers,omitempty"`
PermissionMode PermissionMode `json:"permission_mode,omitempty"`
ExecPolicyHint string `json:"exec_policy_hint,omitempty"`
Background bool `json:"background,omitempty"`
}
func (Definition) AllowsTool ¶
func (d Definition) AllowsTool(tool string) error
func (Definition) Validate ¶
func (d Definition) Validate() error
type ExecutionArtifactRef ¶ added in v0.0.2
type ExecutionArtifactRef struct {
Backend string `json:"backend"`
Kind string `json:"kind"`
WorkspaceID string `json:"workspace_id,omitempty"`
SessionID string `json:"session_id,omitempty"`
RecordID string `json:"record_id"`
Digest string `json:"digest,omitempty"`
}
ExecutionArtifactRef names durable child input, output, or checkpoint state without embedding model-visible text in the task payload. History references are resolved within the explicit workspace/session pair. A checkpoint key is task-scoped by the durable backend.
type ExecutionEnvelope ¶ added in v0.0.2
type ExecutionEnvelope struct {
SchemaRevision uint32 `json:"schema_revision"`
Schema string `json:"schema"`
ExecutionID string `json:"execution_id"`
WorkspaceID string `json:"workspace_id"`
CatalogRevision string `json:"catalog_revision,omitempty"`
OutputSchema json.RawMessage `json:"output_schema,omitempty"`
OutputSchemaDigest string `json:"output_schema_digest,omitempty"`
ParentSessionID string `json:"parent_session_id"`
ChildSessionID string `json:"child_session_id"`
ParentTaskID string `json:"parent_task_id,omitempty"`
ParentMessageID string `json:"parent_message_id,omitempty"`
InvocationID string `json:"invocation_id,omitempty"`
Depth int `json:"depth"`
Background bool `json:"background,omitempty"`
ExecutionScope *workspacepkg.ExecutionScope `json:"execution_scope,omitempty"`
Input ExecutionArtifactRef `json:"input"`
Result ExecutionArtifactRef `json:"result"`
Checkpoint ExecutionArtifactRef `json:"checkpoint"`
Policy ExecutionPolicy `json:"policy"`
Ownership ExecutionOwnership `json:"ownership"`
}
ExecutionEnvelope is the immutable descriptor for one child invocation. It contains references and hashes, never the delegated task text, catalog instructions, or authority credentials. A backend may carry the encoded envelope as its task payload while retaining ordinary metadata for indexing.
func NewExecutionEnvelope ¶ added in v0.0.2
func NewExecutionEnvelope(req Request, workspaceID, childSessionID string, background bool) (ExecutionEnvelope, error)
NewExecutionEnvelope builds the immutable descriptor used by both the local in-process executor and optional durable task backends.
func ParseExecutionEnvelope ¶ added in v0.0.2
func ParseExecutionEnvelope(data []byte) (ExecutionEnvelope, error)
ParseExecutionEnvelope strictly decodes one descriptor. Unknown fields and trailing JSON are rejected so executors cannot silently disagree on policy.
func (ExecutionEnvelope) ExecutionScopeDigest ¶ added in v0.0.2
func (e ExecutionEnvelope) ExecutionScopeDigest() string
ExecutionScopeDigest is a stable, credential-free correlation value for task metadata. The complete scope remains in the versioned payload.
func (ExecutionEnvelope) ResolveInput ¶ added in v0.0.2
func (e ExecutionEnvelope) ResolveInput(messages []protocol.ChatMessage) (protocol.ChatMessage, string, error)
ResolveInput finds and verifies the referenced user message, returning the exact task text an executor should run. Duplicate record IDs fail closed.
func (ExecutionEnvelope) ResolveResult ¶ added in v0.0.2
func (e ExecutionEnvelope) ResolveResult(messages []protocol.ChatMessage) (protocol.ChatMessage, error)
ResolveResult returns the first terminal assistant message after the exact referenced input. Assistant messages that contain tool calls are intermediate execution state and are skipped. A later execution input bounds the search so resuming the same child session cannot replace an earlier result.
func (ExecutionEnvelope) Validate ¶ added in v0.0.2
func (e ExecutionEnvelope) Validate() error
Validate checks identity, workspace isolation, artifact shape, and ownership invariants without resolving any referenced content.
func (ExecutionEnvelope) VerifyPolicy ¶ added in v0.0.2
func (e ExecutionEnvelope) VerifyPolicy(req Request) error
VerifyPolicy proves that req is the same immutable policy snapshot described by the envelope. It includes catalog instructions in the digest even though those instructions are not serialized into the envelope.
type ExecutionOwnership ¶ added in v0.0.2
type ExecutionOwnership struct {
Authority string `json:"authority"`
ClaimRequired bool `json:"claim_required"`
MaxAttempts uint32 `json:"max_attempts"`
UncertainPolicy string `json:"uncertain_policy"`
}
ExecutionOwnership makes the task/executor boundary explicit. The first successful durable-task claim owns execution. One attempt is allowed; an uncertain outcome is interrupted and inspected rather than replayed.
type ExecutionPolicy ¶ added in v0.0.2
type ExecutionPolicy struct {
AgentName string `json:"agent_name,omitempty"`
AgentType string `json:"agent_type,omitempty"`
Model string `json:"model,omitempty"`
MaxTurns int `json:"max_turns,omitempty"`
AllowedTools []string `json:"allowed_tools,omitempty"`
DeniedTools []string `json:"denied_tools,omitempty"`
Skills []string `json:"skills,omitempty"`
MCPServers []string `json:"mcp_servers,omitempty"`
PermissionMode string `json:"permission_mode,omitempty"`
ExecPolicyHint string `json:"exec_policy_hint,omitempty"`
SnapshotDigest string `json:"snapshot_digest"`
}
ExecutionPolicy is the non-secret, deterministic execution surface an assignee must reproduce. SnapshotDigest also covers catalog instructions, so an external executor can fail closed if its local catalog has changed without putting those instructions in Aether task metadata or payload.
type ExecutionScopeAuthorizationRequest ¶ added in v0.0.2
type ExecutionScopeAuthorizationRequest struct {
Parent *workspacepkg.ExecutionScope
Requested *workspacepkg.ExecutionScope
Request Request
Reason string
}
ExecutionScopeAuthorizationRequest is emitted only when a child attempts to select a different view, broaden write access, or resume a thread under a scope that is not a monotonic narrowing of its previous scope. Exact inheritance and read-only narrowing require no adapter.
type ExecutionScopeAuthorizer ¶ added in v0.0.2
type ExecutionScopeAuthorizer interface {
AuthorizeSubagentExecutionScope(context.Context, ExecutionScopeAuthorizationRequest) error
}
ExecutionScopeAuthorizer is the enterprise/embedding seam for explicit view overrides. Nil is fail-closed: only exact inheritance and read-only narrowing are accepted.
type FileCatalog ¶
type FileCatalog struct {
// contains filtered or unexported fields
}
func NewFileCatalog ¶
func NewFileCatalog(dir string) *FileCatalog
func (*FileCatalog) Get ¶
func (c *FileCatalog) Get(ctx context.Context, typ AgentType) (Definition, error)
func (*FileCatalog) List ¶
func (c *FileCatalog) List(ctx context.Context) ([]Definition, error)
type FileRegistry ¶ added in v0.0.2
type FileRegistry struct {
// contains filtered or unexported fields
}
FileRegistry stores one parent-scoped registry per workspace. It is safe for concurrent use in one process; a state directory has one writing process.
func NewFileRegistry ¶ added in v0.0.2
func NewFileRegistry(stateDir string) (*FileRegistry, error)
func (*FileRegistry) ListSubagents ¶ added in v0.0.2
func (r *FileRegistry) ListSubagents(ctx context.Context, workspaceID, parentSessionID string) ([]spec.SessionSubagentRecord, error)
ListSubagents returns a deterministic deep copy for snapshot projection.
func (*FileRegistry) ObserveSubagent ¶ added in v0.0.2
func (r *FileRegistry) ObserveSubagent(ctx context.Context, event LifecycleEvent) error
ObserveSubagent atomically merges one lifecycle transition.
func (*FileRegistry) RecoverInterrupted ¶ added in v0.0.2
RecoverInterrupted marks children left admitted/running by a prior process as interrupted. It validates the complete registry set before writing any file, so corrupt state fails startup without silently skipping another session.
type LifecycleEvent ¶ added in v0.0.2
type LifecycleEvent struct {
WorkspaceID string
Record spec.SessionSubagentRecord
}
LifecycleEvent is an authoritative child-session registry update. The record uses the shared session protocol shape so local files, MemoryLayer adapters, Aether checkpoints, and remote clients project the same lifecycle fields.
type LifecycleObserver ¶ added in v0.0.2
type LifecycleObserver interface {
ObserveSubagent(ctx context.Context, event LifecycleEvent) error
}
LifecycleObserver records subagent admission/running/terminal transitions. Runner execution treats observation as best-effort; recovery surfaces fail closed when a configured registry cannot be read or validated.
type OutputContract ¶ added in v0.0.2
type OutputContract struct {
// contains filtered or unexported fields
}
OutputContract is a compiled, fail-closed subset of JSON Schema suitable for delegated result contracts. Unsupported assertion keywords are rejected at admission instead of being silently ignored.
func CompileOutputSchema ¶ added in v0.0.2
func CompileOutputSchema(raw json.RawMessage) (*OutputContract, error)
func (*OutputContract) Digest ¶ added in v0.0.2
func (c *OutputContract) Digest() string
func (*OutputContract) Raw ¶ added in v0.0.2
func (c *OutputContract) Raw() json.RawMessage
func (*OutputContract) Validate ¶ added in v0.0.2
func (c *OutputContract) Validate(raw json.RawMessage) []ValidationError
type PermissionMode ¶
type PermissionMode string
const ( PermissionModeInherit PermissionMode = "inherit" PermissionModeAsk PermissionMode = "ask" PermissionModeAllow PermissionMode = "allow" PermissionModeReadOnly PermissionMode = "read_only" )
type ProviderCatalog ¶ added in v0.0.2
type ProviderCatalog struct {
// contains filtered or unexported fields
}
ProviderCatalog adapts a workspace provider to the existing subagent Catalog. A selected logical workspace may be bound to a different backend workspace; explicitly addressed other workspaces pass through unchanged.
func NewProviderCatalog ¶ added in v0.0.2
func NewProviderCatalog(provider WorkspaceDefinitionProvider, logicalWorkspace, backendWorkspaceID string) (*ProviderCatalog, error)
func (*ProviderCatalog) Get ¶ added in v0.0.2
func (c *ProviderCatalog) Get(ctx context.Context, typ AgentType) (Definition, error)
func (*ProviderCatalog) GetWorkspace ¶ added in v0.0.2
func (c *ProviderCatalog) GetWorkspace(ctx context.Context, workspaceID string, typ AgentType) (Definition, error)
func (*ProviderCatalog) List ¶ added in v0.0.2
func (c *ProviderCatalog) List(ctx context.Context) ([]Definition, error)
func (*ProviderCatalog) ListWorkspace ¶ added in v0.0.2
func (c *ProviderCatalog) ListWorkspace(ctx context.Context, workspaceID string) ([]Definition, error)
type Ref ¶
type Ref struct {
// contains filtered or unexported fields
}
Ref is a late-bound Runner: the spawn tool can be registered (and thus surfaced to the model in the tool list) before the concrete runner exists, then wired via Set. RunSubagent returns ErrNoRunner until Set is called.
func (*Ref) RunSubagent ¶
RunSubagent delegates to the installed runner.
func (*Ref) StartBackground ¶
StartBackground forwards to the installed runner when it is a BackgroundRunner. It returns ErrNoRunner before Set is called and ErrBackgroundUnsupported when the installed runner lacks the detached-execution seam — so *Ref satisfies BackgroundRunner (a spawn tool holding the ref can attempt a background spawn) while still degrading cleanly on a backend that doesn't support it.
type Registry ¶ added in v0.0.2
type Registry interface {
LifecycleObserver
ListSubagents(ctx context.Context, workspaceID, parentSessionID string) ([]spec.SessionSubagentRecord, error)
RecoverInterrupted(ctx context.Context, at time.Time) error
}
Registry is the durable lifecycle surface used by the runner and session snapshot projection.
type Request ¶
type Request struct {
Task string
Depth int
Parent protocol.MessageAddress
// InvocationID identifies this spawn invocation independently from the child
// thread. The reference tool supplies its stable tool-call ID so a durable
// task backend can deduplicate an admission retry without collapsing later
// follow-ups that resume the same child thread.
InvocationID string
GrantID string
SubjectType string
SubjectID string
// ExecutionScope pins the child to the parent's exact workspace view and
// write ceiling. The spawn tool supplies it from trusted turn context; it is
// never accepted as a model-authored absolute path or bearer grant.
ExecutionScope *workspacepkg.ExecutionScope
// CatalogRevision pins the immutable workspace catalog admitted by the
// parent session so durable/external execution cannot silently use a newer
// skill, MCP, or agent surface.
CatalogRevision string
// OutputSchema is an optional, admission-validated JSON Schema contract for
// the child's final answer. The child receives it once in its bootstrap.
OutputSchema json.RawMessage
// Model optionally pins the sub-agent to a specific model (validated against
// the registry by the runner; empty → the runner's normal per-turn selection).
Model string
// ResumeThreadID, when set, CONTINUES an existing child sub-agent thread
// (used verbatim as the child thread id) instead of minting a new
// "<parentThread>::sub::<seq>" thread. It is the handle returned as
// Result.ThreadID from a prior spawn; empty → create a new child thread.
ResumeThreadID string
// ParentMessageID is the id of the spawning parent message, recorded on the
// child thread's task message as MessageRef.ParentMessageID (the cross-thread
// back-ref). Empty is acceptable (the back-ref still carries the parent
// thread id).
ParentMessageID string
// Agent fields are populated when a file-backed catalog definition is used.
// The OSS in-process runner applies Instructions, MaxTurns, AllowedTools,
// DeniedTools, and Model. Skills, MCPServers, PermissionMode,
// ExecPolicyHint, and Background are retained for catalog-compatible
// backends until OSS has concrete runtime seams for them.
AgentName AgentName
AgentType AgentType
Instructions string
MaxTurns int
AllowedTools []string
DeniedTools []string
Skills []string
MCPServers []string
PermissionMode PermissionMode
ExecPolicyHint string
Background bool
}
Request is a sub-task delegation. Authority fields carry the parent turn's OBO grant (as primitives to avoid importing the tools package and creating a cycle) so the sub-agent acts on behalf of the same principal.
func ReconstructExecutionRequest ¶ added in v0.0.2
func ReconstructExecutionRequest( ctx context.Context, envelope ExecutionEnvelope, catalog Catalog, grantID, subjectType, subjectID string, ) (Request, error)
ReconstructExecutionRequest rebuilds the private Request policy an assigned executor must use. Named agent policies are loaded from the executor's local catalog and verified against the envelope digest; generic policies can be reconstructed only when they carried no private instructions. The delegated task text is intentionally left empty and must be resolved from Input by the execution runner after the durable task has been claimed.
func (Request) AllowsTool ¶
type Result ¶
type Result struct {
Text string
// StructuredPayload is set when OutputSchema was supplied and the final JSON
// passed host-side validation. StructuredDigest identifies those exact bytes.
StructuredPayload json.RawMessage
StructuredDigest string
// ThreadID is the child sub-agent thread's id — the re-addressable handle.
// Pass it back as Request.ResumeThreadID to continue the same sub-agent.
ThreadID string
// Summary is a compact one-line digest of the answer (first line / first
// ~200 chars), suitable for the parent to keep as a reference.
Summary string
}
Result is the sub-agent's final answer.
type TaskAdmission ¶ added in v0.0.2
type TaskAdmission struct {
WorkspaceID string
ParentSessionID string
ChildSessionID string
ParentTaskID string
ParentMessageID string
InvocationID string
Name string
Kind string
Model string
Depth int
Background bool
GrantID string
SubjectType string
SubjectID string
// Execution is the immutable, non-secret payload descriptor for an eventual
// assignee. It references durable input/result/checkpoint state and records
// claim/replay ownership without embedding prompt text or credentials.
Execution ExecutionEnvelope
}
TaskAdmission is the non-secret identity and policy projection used to admit one subagent invocation to an optional durable task backend. Task is deliberately absent: prompts and OBO credentials do not belong in task metadata. InvocationID should be stable for a retried tool invocation (the spawn tool uses its tool-call ID), allowing a backend to deduplicate admission.
type TaskAwaiter ¶ added in v0.0.2
type TaskAwaiter interface {
TaskBackend
ExecutesExternally() bool
Await(ctx context.Context, taskID string, observe func(TaskRecovery)) (TaskRecovery, error)
}
TaskAwaiter marks a backend whose admitted work is executed by another assignee. The parent must not call Start or Finish in this mode. Await reports authoritative state changes until a terminal state is reached; callbacks may repeat and must be cheap and concurrency-safe.
type TaskBackend ¶ added in v0.0.2
type TaskBackend interface {
Admit(ctx context.Context, admission TaskAdmission) (taskID string, err error)
Start(ctx context.Context, taskID string) error
Finish(ctx context.Context, taskID string, outcome TaskOutcome, reason string) error
Recover(ctx context.Context, taskID string) (TaskRecovery, error)
}
TaskBackend makes a durable task system the execution authority while the SubagentRegistry remains a parent-session snapshot projection. Implementations must make Admit idempotent for a non-empty InvocationID. Finish must return nil only when the requested terminal state is confirmed; after an ambiguous mutation it should query, not blindly repeat the mutation. Recover must return a terminal projection, terminating orphaned non-terminal work before returning TaskRecoveryInterrupted.
type TaskOutcome ¶ added in v0.0.2
type TaskOutcome string
TaskOutcome is the requested durable terminal state for one execution task.
const ( TaskOutcomeCompleted TaskOutcome = "completed" TaskOutcomeFailed TaskOutcome = "failed" TaskOutcomeCancelled TaskOutcome = "cancelled" )
type TaskRecovery ¶ added in v0.0.2
type TaskRecovery string
TaskRecovery is the authoritative task state projected during owner restart. Interrupted means the backend found non-terminal work whose in-process execution was lost and durably terminated it; it must not be replayed.
const ( TaskRecoveryAdmitted TaskRecovery = "admitted" TaskRecoveryRunning TaskRecovery = "running" TaskRecoveryCompleted TaskRecovery = "completed" TaskRecoveryFailed TaskRecovery = "failed" TaskRecoveryCancelled TaskRecovery = "cancelled" TaskRecoveryInterrupted TaskRecovery = "interrupted" )
type TaskRecoveryRegistry ¶ added in v0.0.2
type TaskRecoveryRegistry interface {
Registry
RecoverInterruptedWithTasks(ctx context.Context, at time.Time, tasks TaskBackend) error
}
TaskRecoveryRegistry is implemented by distributed registries that can reconcile incomplete projections with their execution authority during owner restart. Local registries deliberately retain process-owner interruption recovery and do not need this extension.
type ValidationError ¶ added in v0.0.2
ValidationError is a deterministic, compact error returned to the child for its single correction attempt.
type WorkspaceCatalog ¶ added in v0.0.2
type WorkspaceCatalog interface {
Catalog
ListWorkspace(ctx context.Context, workspaceID string) ([]Definition, error)
GetWorkspace(ctx context.Context, workspaceID string, typ AgentType) (Definition, error)
}
WorkspaceCatalog is the additive multi-workspace catalog capability. Legacy Catalog callers use the configured default; turn-aware callers address the resolved logical workspace explicitly.
type WorkspaceDefinitionProvider ¶ added in v0.0.2
type WorkspaceDefinitionProvider interface {
LoadWorkspace(ctx context.Context, workspaceID string) ([]Definition, error)
}
WorkspaceDefinitionProvider loads the authoritative agent definitions for one logical workspace. Implementations must not silently fall back to another authority when a load fails.