agentharness

package
v0.3.35 Latest Latest
Warning

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

Go to latest
Published: Jun 26, 2026 License: MIT Imports: 27 Imported by: 0

Documentation

Overview

Package agentharness exposes the host/UI durable conversation API.

AgentHarness owns durable threads backed by sessiontree.Repo. Thread.Run, Thread.Retry, Thread.MoveTo, and Thread.Compact are safe to call concurrently across different ThreadIDs, including source and forked threads. A single durable ThreadID admits at most one active turn or mutation at a time; callers that race the same thread receive ErrActiveTurn before new turn entries are appended. This serialization is enforced through the repository turn lease contract when the repo implements sessiontree.TurnLeaseRepo, so two harnesses sharing one durable repo observe the same active-turn invariant.

The lower-level engine remains a turn executor. Harness callers configure engine behavior through TurnPolicy and LoopLimits rather than raw engine.Options so run identity, provider/model identity, and control tool definitions are generated by the harness for the active durable thread.

Thread.Read returns the host-facing snapshot: lifecycle status, appendability, retry availability, and display messages. Thread.Journal is the explicit raw session-tree inspection API for tests, debug consoles, and admin tooling.

Index

Constants

View Source
const (
	DefaultSubAgentWaitTimeout = 5 * time.Minute
	MaxSubAgentWaitTimeout     = 20 * time.Minute
	DefaultSubAgentRunTimeout  = 20 * time.Minute
	MaxSubAgentRunTimeout      = 20 * time.Minute
	DefaultSubAgentDetailLimit = 200
	MaxSubAgentDetailLimit     = 500
)
View Source
const ThreadTitleLogicalRequestID = "thread_title"

Variables

View Source
var (
	ErrActiveTurn    = errors.New("thread already has an active turn")
	ErrNoRetryTarget = errors.New("thread has no retryable turn")
)
View Source
var (
	ErrSubAgentNotFound = errors.New("subagent not found")
	ErrSubAgentClosed   = errors.New("subagent is closed")
)

Functions

This section is empty.

Types

type AgentHarness

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

func New

func New(options Options) *AgentHarness

func (*AgentHarness) CloseSubAgent added in v0.3.17

func (h *AgentHarness) CloseSubAgent(ctx context.Context, opts CloseSubAgentOptions) (SubAgentSnapshot, error)

func (*AgentHarness) ForkThread

func (h *AgentHarness) ForkThread(ctx context.Context, opts ForkOptions) (*Thread, error)

func (*AgentHarness) ListSubAgents added in v0.3.17

func (h *AgentHarness) ListSubAgents(ctx context.Context, parentThreadID string) ([]SubAgentSnapshot, error)

func (*AgentHarness) ReadSubAgentDetail added in v0.3.21

func (h *AgentHarness) ReadSubAgentDetail(ctx context.Context, opts ReadSubAgentDetailOptions) (SubAgentDetail, error)

func (*AgentHarness) ResumeThread

func (h *AgentHarness) ResumeThread(ctx context.Context, id string, _ ResumeOptions) (*Thread, error)

func (*AgentHarness) SendSubAgentInput added in v0.3.17

func (h *AgentHarness) SendSubAgentInput(ctx context.Context, opts SendSubAgentInputOptions) (SubAgentSnapshot, error)

func (*AgentHarness) SpawnSubAgent added in v0.3.17

func (h *AgentHarness) SpawnSubAgent(ctx context.Context, opts SpawnSubAgentOptions) (SubAgentSnapshot, error)

func (*AgentHarness) StartThread

func (h *AgentHarness) StartThread(ctx context.Context, opts StartThreadOptions) (*Thread, error)

func (*AgentHarness) WaitSubAgents added in v0.3.17

type CloseSubAgentOptions added in v0.3.17

type CloseSubAgentOptions struct {
	ParentThreadID string
	ChildThreadID  string
}

type ForkOptions

type ForkOptions struct {
	SourceThreadID string
	EntryID        string
	Position       sessiontree.ForkPosition
	NewThreadID    string
}

type HarnessEvent

type HarnessEvent struct {
	Type      HarnessEventType  `json:"type"`
	ThreadID  string            `json:"thread_id,omitempty"`
	TurnID    string            `json:"turn_id,omitempty"`
	EntryID   string            `json:"entry_id,omitempty"`
	ParentID  string            `json:"parent_id,omitempty"`
	Message   string            `json:"message,omitempty"`
	Status    string            `json:"status,omitempty"`
	Metadata  map[string]string `json:"metadata,omitempty"`
	Timestamp time.Time         `json:"timestamp"`
}

type HarnessEventType

type HarnessEventType string
const (
	EventThreadStarted     HarnessEventType = "thread_started"
	EventThreadResumed     HarnessEventType = "thread_resumed"
	EventThreadForked      HarnessEventType = "thread_forked"
	EventLeafMoved         HarnessEventType = "leaf_moved"
	EventTurnStarted       HarnessEventType = "turn_started"
	EventTurnCompleted     HarnessEventType = "turn_completed"
	EventTurnFailed        HarnessEventType = "turn_failed"
	EventTurnAborted       HarnessEventType = "turn_aborted"
	EventEntryAppended     HarnessEventType = "entry_appended"
	EventRetryStarted      HarnessEventType = "retry_started"
	EventTitleUpdated      HarnessEventType = "thread_title_updated"
	EventTitleFailed       HarnessEventType = "thread_title_failed"
	EventSubAgentSpawned   HarnessEventType = "subagent_spawned"
	EventSubAgentInput     HarnessEventType = "subagent_input"
	EventSubAgentClosed    HarnessEventType = "subagent_closed"
	EventSubAgentCompleted HarnessEventType = "subagent_completed"
)

type HarnessRecorder

type HarnessRecorder struct {
	Events []HarnessEvent
	// contains filtered or unexported fields
}

func (*HarnessRecorder) EmitHarness

func (r *HarnessRecorder) EmitHarness(ev HarnessEvent)

func (*HarnessRecorder) Snapshot

func (r *HarnessRecorder) Snapshot() []HarnessEvent

type HarnessSink

type HarnessSink interface {
	EmitHarness(HarnessEvent)
}

type LoopLimits

type LoopLimits struct {
	MaxEmptyProviderRetries  int
	NoProgressLimit          int
	DuplicateToolLimit       int
	WallTime                 time.Duration
	MaxTotalTokens           int64
	MaxCostUSD               float64
	MaxToolCalls             int
	MaxLengthContinuations   int
	MaxStopHookContinuations int
}

type MoveOptions

type MoveOptions struct {
	Summary string
}

type Options

type Options struct {
	Provider            provider.Provider
	ProviderName        string
	Model               string
	SystemPrompt        string
	Tools               *tools.Registry
	PromptStore         cache.Store
	Repo                sessiontree.Repo
	Sink                event.Sink
	SinkPolicy          event.SinkPolicy
	HarnessSink         HarnessSink
	Approver            tools.Approver
	StopHook            engine.StopHook
	CompactionGenerator compaction.SummaryGenerator
	CompactionPrompt    compaction.PromptOptions
	TitleGenerator      TitleGenerator
	Artifacts           artifact.Store
	Reasoning           provider.ReasoningCapability
	TurnPolicy          TurnPolicy
	LoopLimits          LoopLimits
	SubAgentRunTimeout  time.Duration
	NewID               func(string) string
	Now                 func() time.Time
}

type PendingToolCompletion added in v0.3.10

type PendingToolCompletion struct {
	TurnID     string
	RunID      string
	ToolCallID string
	ToolName   string
	Handle     string
	Status     PendingToolCompletionStatus
	Summary    string
	Output     string
	Labels     engine.RunLabels
}

type PendingToolCompletionStatus added in v0.3.10

type PendingToolCompletionStatus string
const (
	PendingToolCompleted PendingToolCompletionStatus = "completed"
	PendingToolFailed    PendingToolCompletionStatus = "failed"
	PendingToolCanceled  PendingToolCompletionStatus = "canceled"
)

type ProviderTitleGenerator

type ProviderTitleGenerator struct {
	Provider        provider.Provider
	ProviderName    string
	Model           string
	Reasoning       provider.ReasoningCapability
	MaxRunes        int
	MaxOutputTokens int64
}

func (ProviderTitleGenerator) GenerateTitle

func (g ProviderTitleGenerator) GenerateTitle(ctx context.Context, req TitleRequest) (TitleResult, error)

type ReadSubAgentDetailOptions added in v0.3.21

type ReadSubAgentDetailOptions struct {
	ParentThreadID string
	ChildThreadID  string
	AfterOrdinal   int64
	Limit          int
	IncludeRaw     bool
}

type ResumeOptions

type ResumeOptions struct{}

type RetryOptions

type RetryOptions struct {
	Reason string
	Labels engine.RunLabels
}

type RunOptions

type RunOptions struct {
	TurnID           string
	Labels           engine.RunLabels
	TerminalMetadata map[string]string
	DeadlineMetadata map[string]string
}

type SendSubAgentInputOptions added in v0.3.17

type SendSubAgentInputOptions struct {
	ParentThreadID string
	ChildThreadID  string
	Message        string
	Interrupt      bool
	Labels         engine.RunLabels
}

type SpawnSubAgentOptions added in v0.3.17

type SpawnSubAgentOptions struct {
	ParentThreadID string
	ParentTurnID   string
	ThreadID       string
	TaskName       string
	Message        string
	HostProfileRef string
	ForkMode       SubAgentForkMode
	Labels         engine.RunLabels
}

type StartThreadOptions

type StartThreadOptions struct {
	ThreadID string
}

type SubAgentDetail added in v0.3.21

type SubAgentDetail struct {
	Snapshot     SubAgentSnapshot      `json:"snapshot"`
	Events       []SubAgentDetailEvent `json:"events"`
	NextOrdinal  int64                 `json:"next_ordinal,omitempty"`
	HasMore      bool                  `json:"has_more,omitempty"`
	RetainedFrom int64                 `json:"retained_from,omitempty"`
	GeneratedAt  time.Time             `json:"generated_at"`
}

type SubAgentDetailApproval added in v0.3.21

type SubAgentDetailApproval struct {
	State    string            `json:"state,omitempty"`
	ToolID   string            `json:"tool_id,omitempty"`
	ToolName string            `json:"tool_name,omitempty"`
	ToolKind string            `json:"tool_kind,omitempty"`
	ArgsHash string            `json:"args_hash,omitempty"`
	Reason   string            `json:"reason,omitempty"`
	Metadata map[string]string `json:"metadata,omitempty"`
}

type SubAgentDetailCompaction added in v0.3.21

type SubAgentDetailCompaction struct {
	CompactionID            string            `json:"compaction_id,omitempty"`
	PreviousCompactionID    string            `json:"previous_compaction_id,omitempty"`
	CompactedThroughEntryID string            `json:"compacted_through_entry_id,omitempty"`
	SummarySchemaVersion    string            `json:"summary_schema_version,omitempty"`
	CompactionGeneration    int               `json:"compaction_generation,omitempty"`
	CompactionWindowID      string            `json:"compaction_window_id,omitempty"`
	FirstKeptEntryID        string            `json:"first_kept_entry_id,omitempty"`
	KeptUserEntryIDs        []string          `json:"kept_user_entry_ids,omitempty"`
	Summary                 string            `json:"summary,omitempty"`
	Trigger                 string            `json:"trigger,omitempty"`
	Reason                  string            `json:"reason,omitempty"`
	Phase                   string            `json:"phase,omitempty"`
	TokensBefore            int64             `json:"tokens_before,omitempty"`
	TokensAfterEstimate     int64             `json:"tokens_after_estimate,omitempty"`
	Metadata                map[string]string `json:"metadata,omitempty"`
}

type SubAgentDetailEvent added in v0.3.21

type SubAgentDetailEvent struct {
	ID        string                  `json:"id"`
	Ordinal   int64                   `json:"ordinal"`
	ParentID  string                  `json:"parent_id,omitempty"`
	ThreadID  string                  `json:"thread_id"`
	TurnID    string                  `json:"turn_id,omitempty"`
	Kind      SubAgentDetailEventKind `json:"kind"`
	Type      string                  `json:"type,omitempty"`
	CreatedAt time.Time               `json:"created_at"`

	Message    *SubAgentDetailMessage    `json:"message,omitempty"`
	ToolCall   *SubAgentDetailToolCall   `json:"tool_call,omitempty"`
	ToolResult *SubAgentDetailToolResult `json:"tool_result,omitempty"`
	Approval   *SubAgentDetailApproval   `json:"approval,omitempty"`
	TurnMarker *SubAgentDetailTurnMarker `json:"turn_marker,omitempty"`
	Compaction *SubAgentDetailCompaction `json:"compaction,omitempty"`
	Error      string                    `json:"error,omitempty"`
	Metadata   map[string]string         `json:"metadata,omitempty"`
}

type SubAgentDetailEventKind added in v0.3.21

type SubAgentDetailEventKind string
const (
	SubAgentDetailEventUserMessage      SubAgentDetailEventKind = "user_message"
	SubAgentDetailEventAssistantMessage SubAgentDetailEventKind = "assistant_message"
	SubAgentDetailEventToolCall         SubAgentDetailEventKind = "tool_call"
	SubAgentDetailEventToolResult       SubAgentDetailEventKind = "tool_result"
	SubAgentDetailEventTurnMarker       SubAgentDetailEventKind = "turn_marker"
	SubAgentDetailEventCompaction       SubAgentDetailEventKind = "compaction"
	SubAgentDetailEventError            SubAgentDetailEventKind = "error"
	SubAgentDetailEventApproval         SubAgentDetailEventKind = "approval"
	SubAgentDetailEventInput            SubAgentDetailEventKind = "input"
	SubAgentDetailEventCustom           SubAgentDetailEventKind = "custom"
)

type SubAgentDetailMessage added in v0.3.21

type SubAgentDetailMessage struct {
	Role      string `json:"role,omitempty"`
	Preview   string `json:"preview,omitempty"`
	Content   string `json:"content,omitempty"`
	Reasoning string `json:"reasoning,omitempty"`
}

type SubAgentDetailToolCall added in v0.3.21

type SubAgentDetailToolCall struct {
	ID          string `json:"id,omitempty"`
	Name        string `json:"name,omitempty"`
	ArgsPreview string `json:"args_preview,omitempty"`
	ArgsJSON    string `json:"args_json,omitempty"`
	ArgsHash    string `json:"args_hash,omitempty"`
}

type SubAgentDetailToolResult added in v0.3.21

type SubAgentDetailToolResult struct {
	CallID        string        `json:"call_id,omitempty"`
	ToolName      string        `json:"tool_name,omitempty"`
	Preview       string        `json:"preview,omitempty"`
	Content       string        `json:"content,omitempty"`
	Truncated     bool          `json:"truncated,omitempty"`
	OriginalBytes int           `json:"original_bytes,omitempty"`
	VisibleBytes  int           `json:"visible_bytes,omitempty"`
	OriginalLines int           `json:"original_lines,omitempty"`
	VisibleLines  int           `json:"visible_lines,omitempty"`
	Strategy      string        `json:"strategy,omitempty"`
	ContentSHA256 string        `json:"content_sha256,omitempty"`
	FullOutput    *artifact.Ref `json:"full_output,omitempty"`
}

type SubAgentDetailTurnMarker added in v0.3.21

type SubAgentDetailTurnMarker struct {
	Status   string            `json:"status,omitempty"`
	Metadata map[string]string `json:"metadata,omitempty"`
}

type SubAgentForkMode added in v0.3.17

type SubAgentForkMode string
const (
	SubAgentForkNone     SubAgentForkMode = "none"
	SubAgentForkFullPath SubAgentForkMode = "full_path"
)

type SubAgentSnapshot added in v0.3.17

type SubAgentSnapshot struct {
	ThreadID       string         `json:"thread_id"`
	Path           string         `json:"path"`
	TaskName       string         `json:"task_name"`
	ParentThreadID string         `json:"parent_thread_id"`
	ParentTurnID   string         `json:"parent_turn_id,omitempty"`
	HostProfileRef string         `json:"host_profile_ref,omitempty"`
	Status         SubAgentStatus `json:"status"`
	LatestTurnID   string         `json:"latest_turn_id,omitempty"`
	LastMessage    string         `json:"last_message,omitempty"`
	WaitingPrompt  string         `json:"waiting_prompt,omitempty"`
	QueuedInputs   int            `json:"queued_inputs,omitempty"`
	CreatedAt      time.Time      `json:"created_at"`
	UpdatedAt      time.Time      `json:"updated_at"`
	Closed         bool           `json:"closed,omitempty"`
	CanSendInput   bool           `json:"can_send_input"`
	CanInterrupt   bool           `json:"can_interrupt"`
	CanClose       bool           `json:"can_close"`
}

type SubAgentStatus added in v0.3.17

type SubAgentStatus string
const (
	SubAgentStatusIdle        SubAgentStatus = "idle"
	SubAgentStatusRunning     SubAgentStatus = "running"
	SubAgentStatusWaiting     SubAgentStatus = "waiting"
	SubAgentStatusCompleted   SubAgentStatus = "completed"
	SubAgentStatusFailed      SubAgentStatus = "failed"
	SubAgentStatusCancelled   SubAgentStatus = "cancelled"
	SubAgentStatusInterrupted SubAgentStatus = "interrupted"
	SubAgentStatusClosed      SubAgentStatus = "closed"
)

type Thread

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

func (*Thread) Compact

func (t *Thread) Compact(ctx context.Context, summary, firstKeptEntryID string) (sessiontree.Entry, error)

func (*Thread) CompletePendingTool added in v0.3.10

func (t *Thread) CompletePendingTool(ctx context.Context, completion PendingToolCompletion) (TurnResult, error)

func (*Thread) ID

func (t *Thread) ID() string

func (*Thread) Journal

func (t *Thread) Journal(ctx context.Context) (ThreadJournalSnapshot, error)

func (*Thread) MoveTo

func (t *Thread) MoveTo(ctx context.Context, entryID string, opts MoveOptions) error

func (*Thread) Read

func (t *Thread) Read(ctx context.Context) (ThreadSnapshot, error)

func (*Thread) Retry

func (t *Thread) Retry(ctx context.Context, opts RetryOptions) (TurnResult, error)

func (*Thread) Run

func (t *Thread) Run(ctx context.Context, input string, opts RunOptions) (TurnResult, error)

type ThreadJournalSnapshot

type ThreadJournalSnapshot struct {
	Meta    sessiontree.ThreadMeta `json:"meta"`
	Path    []sessiontree.Entry    `json:"path"`
	Entries []sessiontree.Entry    `json:"entries"`
	Context []session.Message      `json:"context"`
	Phase   string                 `json:"phase"`
}

type ThreadMessage

type ThreadMessage struct {
	Role      session.Role `json:"role"`
	Content   string       `json:"content"`
	TurnID    string       `json:"turn_id,omitempty"`
	CreatedAt time.Time    `json:"created_at"`
}

type ThreadSnapshot

type ThreadSnapshot struct {
	ID               string          `json:"id"`
	Title            string          `json:"title,omitempty"`
	TitleStatus      string          `json:"title_status,omitempty"`
	TitleSource      string          `json:"title_source,omitempty"`
	TitleUpdatedAt   time.Time       `json:"title_updated_at,omitempty"`
	TitleError       string          `json:"title_error,omitempty"`
	CreatedAt        time.Time       `json:"created_at"`
	UpdatedAt        time.Time       `json:"updated_at"`
	Phase            string          `json:"phase"`
	Status           string          `json:"status"`
	LatestTurnID     string          `json:"latest_turn_id,omitempty"`
	WaitingPrompt    string          `json:"waiting_prompt,omitempty"`
	Recoverable      bool            `json:"recoverable"`
	CanAppendMessage bool            `json:"can_append_message"`
	CanRetry         bool            `json:"can_retry"`
	Messages         []ThreadMessage `json:"messages"`
}

type TitleGenerator

type TitleGenerator interface {
	GenerateTitle(context.Context, TitleRequest) (TitleResult, error)
}

type TitleRequest

type TitleRequest struct {
	ThreadID string
	TurnID   string
	Messages []session.Message
}

type TitleResult

type TitleResult struct {
	Title  string
	Source sessiontree.ThreadTitleSource
}

type TurnPolicy

type TurnPolicy struct {
	ContextPolicy         contextpolicy.Policy
	Reasoning             provider.ReasoningSelection
	CacheRetention        cache.Retention
	HostedToolDefinitions []provider.HostedToolDefinition
	CompletionPolicy      engine.CompletionPolicy
}

type TurnResult

type TurnResult struct {
	ID                 string
	Status             engine.Status
	Output             string
	Err                error
	Diagnostics        map[string]string
	Metrics            engine.RunMetrics
	CompletionReason   engine.CompletionReason
	ContinuationReason engine.ContinuationReason
	FinishReason       provider.FinishReason
	RawFinishReason    string
	FinishInferred     bool
}

type WaitSubAgentsOptions added in v0.3.17

type WaitSubAgentsOptions struct {
	ParentThreadID string
	ChildThreadIDs []string
	Timeout        time.Duration
}

type WaitSubAgentsResult added in v0.3.17

type WaitSubAgentsResult struct {
	Snapshots []SubAgentSnapshot `json:"snapshots"`
	TimedOut  bool               `json:"timed_out,omitempty"`
}

Jump to

Keyboard shortcuts

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