Documentation
¶
Index ¶
- Constants
- Variables
- func CollectErrorCount(messages []StreamMessage) int
- func CollectModelUsage(messages []StreamMessage) map[string]int
- func CollectPRURLs(messages []StreamMessage) []string
- func CollectResultText(messages []StreamMessage) string
- func ExtractModel(msg StreamMessage) string
- func Float64Ptr(f float64) *float64
- func ResultStorePath() string
- func ToOpenAIMessages(msgs []StreamMessage) ([]OpenAIMessage, OpenAIMetadata)
- func Truncate(s string, maxLen int) string
- func ValidateEffort(effort string) error
- func ValidatePermissionMode(mode string) error
- type AgentConfig
- type MessageSubtype
- type MessageSummary
- type MessageType
- type MessagesInfo
- type OpenAIFunction
- type OpenAIHook
- type OpenAIMessage
- type OpenAIMessagesInfo
- type OpenAIMetadata
- type OpenAIPlugin
- type OpenAISubagent
- type OpenAIToolCall
- type Options
- type PersistedResult
- type PersistentProcess
- func (p *PersistentProcess) Done() <-chan struct{}
- func (p *PersistentProcess) MarshalStatus() ([]byte, error)
- func (p *PersistentProcess) Messages() MessagesInfo
- func (p *PersistentProcess) OpenAIMessages(offset int) OpenAIMessagesInfo
- func (p *PersistentProcess) RawMessages(offset int, types []string) RawMessagesInfo
- func (p *PersistentProcess) ResultDetail() ResultDetailInfo
- func (p *PersistentProcess) Run(ctx context.Context, prompt string) (<-chan StreamMessage, error)
- func (p *PersistentProcess) RunSyncWithOptions(ctx context.Context, prompt string, runOpts *RunOptions) (string, []StreamMessage, error)
- func (p *PersistentProcess) RunWithOptions(ctx context.Context, prompt string, runOpts *RunOptions) (<-chan StreamMessage, error)
- func (p *PersistentProcess) Start(ctx context.Context) error
- func (p *PersistentProcess) Status() StatusInfo
- func (p *PersistentProcess) Stop() error
- func (p *PersistentProcess) Submit(ctx context.Context, prompt string, opts *RunOptions) error
- type Process
- func (p *Process) Done() <-chan struct{}
- func (p *Process) MarshalStatus() ([]byte, error)
- func (p *Process) Messages() MessagesInfo
- func (p *Process) OpenAIMessages(offset int) OpenAIMessagesInfo
- func (p *Process) RawMessages(offset int, types []string) RawMessagesInfo
- func (p *Process) ResultDetail() ResultDetailInfo
- func (p *Process) Run(ctx context.Context, prompt string) (<-chan StreamMessage, error)
- func (p *Process) RunSync(ctx context.Context, prompt string) (string, []StreamMessage, error)
- func (p *Process) RunSyncWithOptions(ctx context.Context, prompt string, runOpts *RunOptions) (string, []StreamMessage, error)
- func (p *Process) RunWithOptions(ctx context.Context, prompt string, runOpts *RunOptions) (<-chan StreamMessage, error)
- func (p *Process) Status() StatusInfo
- func (p *Process) Stop() error
- func (p *Process) Submit(ctx context.Context, prompt string, opts *RunOptions) error
- type ProcessStatus
- type Prompter
- type RawMessagesInfo
- type ResultDetailInfo
- type ResultStore
- type RunOptions
- type StatusInfo
- type StopReason
- type StreamMessage
- type SubagentCall
- type ThinkingBlock
- type TokenUsage
- type ToolCallInfo
- type ToolResultBlock
- type ToolResultInfo
Constants ¶
const ( EventContentBlockStart = "content_block_start" EventContentBlockDelta = "content_block_delta" EventContentBlockStop = "content_block_stop" )
Stream event type names emitted by the Claude CLI inside stream_event envelopes.
const ( SubagentStatusRunning = "running" SubagentStatusCompleted = "completed" )
Subagent status values reported in SubagentCall.Status.
const ToolNameBash = "Bash"
Tool name for the bash command execution tool.
Variables ¶
var AllProcessStatuses = []ProcessStatus{ ProcessStatusStarting, ProcessStatusIdle, ProcessStatusBusy, ProcessStatusCompleted, ProcessStatusStopped, ProcessStatusError, }
AllProcessStatuses is the canonical list of all ProcessStatus values. Used by the metrics package to initialise the process_status gauge.
var ErrBusy = errors.New("claude process is already busy")
ErrBusy is returned when a prompt is submitted while the process is already handling another prompt.
var ValidEffortLevels = []string{
"low",
"medium",
"high",
}
ValidEffortLevels lists all valid effort level values for Claude Code.
var ValidPermissionModes = []string{
"default",
"acceptEdits",
"bypassPermissions",
"dontAsk",
"plan",
"delegate",
}
ValidPermissionModes lists all valid permission mode values for Claude Code.
Functions ¶
func CollectErrorCount ¶
func CollectErrorCount(messages []StreamMessage) int
CollectErrorCount counts tool_result blocks with is_error set to true.
func CollectModelUsage ¶
func CollectModelUsage(messages []StreamMessage) map[string]int
CollectModelUsage extracts model usage counts from a set of messages.
func CollectPRURLs ¶
func CollectPRURLs(messages []StreamMessage) []string
CollectPRURLs extracts unique GitHub PR URLs from tool_result content blocks that correspond to Bash/shell tool invocations. Tool results from file-reading tools (Read, Write, etc.) are skipped to avoid false positives from PR URLs embedded in source code or documentation.
func CollectResultText ¶
func CollectResultText(messages []StreamMessage) string
CollectResultText extracts the result text from a completed set of stream messages. It returns the text from the last result message, falling back to concatenated assistant text messages if no result message contains text.
func ExtractModel ¶
func ExtractModel(msg StreamMessage) string
ExtractModel parses the model field from a StreamMessage's raw Message JSON. Returns an empty string if the message has no model field or cannot be parsed.
func Float64Ptr ¶
Float64Ptr returns a pointer to the given float64 value.
func ResultStorePath ¶
func ResultStorePath() string
ResultStorePath returns the default result store directory based on the environment. It checks (in order):
- The KLAUS_RESULT_DIR environment variable (must be absolute)
- $HOME/.klaus/results/
- A UID-scoped directory under os.TempDir() as a last resort
Note: Options.ResultDir is handled by resultStoreDir, not this function.
func ToOpenAIMessages ¶
func ToOpenAIMessages(msgs []StreamMessage) ([]OpenAIMessage, OpenAIMetadata)
ToOpenAIMessages converts raw stream-json StreamMessages into OpenAI Chat Completions compatible format. System and result messages are excluded from the messages array and extracted into metadata. Consecutive assistant messages with the same message.id are consolidated into a single message.
func Truncate ¶
Truncate returns s truncated to maxLen runes with "..." appended if truncated. It operates on runes to ensure clean truncation of multi-byte UTF-8 strings.
func ValidateEffort ¶
ValidateEffort checks whether the given effort level is valid. An empty string is allowed (uses the CLI default).
func ValidatePermissionMode ¶
ValidatePermissionMode checks whether the given mode is a valid Claude Code permission mode.
Types ¶
type AgentConfig ¶
type AgentConfig struct {
Description string `json:"description"`
Prompt string `json:"prompt"`
Tools []string `json:"tools,omitempty"`
DisallowedTools []string `json:"disallowedTools,omitempty"`
Model string `json:"model,omitempty"`
PermissionMode string `json:"permissionMode,omitempty"`
MaxTurns int `json:"maxTurns,omitempty"`
Skills []string `json:"skills,omitempty"`
McpServers map[string]any `json:"mcpServers,omitempty"`
Hooks map[string]any `json:"hooks,omitempty"`
Memory string `json:"memory,omitempty"`
}
AgentConfig defines a custom subagent for Claude Code.
Subagents are specialized AI assistants that the main Claude Code agent can delegate work to via the built-in "Task" tool. Each subagent runs in its own context window with a custom system prompt (Prompt), specific tool access (Tools/DisallowedTools), and independent permissions. When the main agent encounters a task matching a subagent's Description, it delegates to that subagent, which works independently and returns results.
Subagent definitions are passed to the CLI via the --agents flag as a JSON map (highest priority, session-scoped). They can also be defined as markdown files in .claude/agents/ directories (loaded via --add-dir).
This is distinct from agent selection (--agent / ActiveAgent), which changes the top-level agent persona for the entire session. When running as the main agent via --agent, that agent can spawn subagents defined here via Task.
See https://code.claude.com/docs/en/sub-agents for full documentation.
The Description and Prompt fields are the minimum required.
type MessageSubtype ¶
type MessageSubtype string
MessageSubtype identifies the subtype of an assistant message.
const ( SubtypeText MessageSubtype = "text" SubtypeToolUse MessageSubtype = "tool_use" )
type MessageSummary ¶
type MessageSummary struct {
Role string `json:"role"`
Content string `json:"content"`
ToolCalls []ToolCallInfo `json:"tool_calls,omitempty"`
ToolCallID string `json:"tool_call_id,omitempty"`
Timestamp string `json:"timestamp,omitempty"`
}
MessageSummary is a simplified representation of a StreamMessage with only role and content, suitable for external consumers.
func SummarizeMessages ¶
func SummarizeMessages(msgs []StreamMessage) []MessageSummary
SummarizeMessages converts a slice of StreamMessages to simplified MessageSummary entries for external consumption. System messages are deduplicated by content.
type MessageType ¶
type MessageType string
MessageType identifies the kind of message in the stream-json protocol.
const ( MessageTypeSystem MessageType = "system" MessageTypeAssistant MessageType = "assistant" MessageTypeUser MessageType = "user" MessageTypeResult MessageType = "result" MessageTypeStreamEvent MessageType = "stream_event" )
type MessagesInfo ¶
type MessagesInfo struct {
Status ProcessStatus `json:"status"`
Messages []MessageSummary `json:"messages"`
}
MessagesInfo holds the current conversation messages along with the process status. Used by the messages MCP tool for real-time access.
type OpenAIFunction ¶
OpenAIFunction holds the function name and stringified arguments.
type OpenAIHook ¶
type OpenAIHook struct {
HookName string `json:"hook_name"`
Output string `json:"output,omitempty"`
ExitCode int `json:"exit_code,omitempty"`
}
OpenAIHook holds hook execution metadata from system/hook_response messages.
type OpenAIMessage ¶
type OpenAIMessage struct {
Role string `json:"role"`
Content *string `json:"content"`
ToolCalls []OpenAIToolCall `json:"tool_calls,omitempty"`
ToolCallID string `json:"tool_call_id,omitempty"`
ReasoningContent string `json:"reasoning_content,omitempty"`
ThinkingBlocks []ThinkingBlock `json:"thinking_blocks,omitempty"`
}
OpenAIMessage represents a message in OpenAI Chat Completions compatible format.
type OpenAIMessagesInfo ¶
type OpenAIMessagesInfo struct {
Messages []OpenAIMessage `json:"messages"`
Metadata OpenAIMetadata `json:"metadata"`
Total int `json:"total"`
}
OpenAIMessagesInfo is the response envelope for the MCP messages tool, containing OpenAI-compatible messages, metadata, and pagination info.
type OpenAIMetadata ¶
type OpenAIMetadata struct {
SessionID string `json:"session_id,omitempty"`
Model string `json:"model,omitempty"`
ClaudeCodeVersion string `json:"claude_code_version,omitempty"`
Tools []string `json:"tools,omitempty"`
Plugins []OpenAIPlugin `json:"plugins,omitempty"`
Hooks []OpenAIHook `json:"hooks,omitempty"`
Subagents []OpenAISubagent `json:"subagents,omitempty"`
CostUSD float64 `json:"cost_usd,omitempty"`
DurationMS float64 `json:"duration_ms,omitempty"`
NumTurns int `json:"num_turns,omitempty"`
Usage *TokenUsage `json:"usage,omitempty"`
}
OpenAIMetadata holds infrastructure metadata extracted from system and result messages, excluded from the messages array.
type OpenAIPlugin ¶
OpenAIPlugin holds plugin metadata from system/init messages.
type OpenAISubagent ¶
type OpenAISubagent struct {
TaskID string `json:"task_id"`
Description string `json:"description,omitempty"`
TaskType string `json:"task_type,omitempty"`
}
OpenAISubagent holds subagent dispatch metadata from system/task_started messages.
type OpenAIToolCall ¶
type OpenAIToolCall struct {
ID string `json:"id"`
Type string `json:"type"`
Function OpenAIFunction `json:"function"`
}
OpenAIToolCall represents a tool call in OpenAI function calling format.
type Options ¶
type Options struct {
// Model selects the Claude model (e.g. "claude-sonnet-4-20250514", "sonnet", "opus").
Model string
// SystemPrompt overrides the default system prompt entirely.
SystemPrompt string
// AppendSystemPrompt is appended to the default system prompt.
AppendSystemPrompt string
// AllowedTools restricts tool access; empty means all allowed.
// Supports patterns like "Bash(git:*)" and "Edit".
AllowedTools []string
// DisallowedTools explicitly blocks specific tools.
DisallowedTools []string
// Tools controls the base set of built-in tools available.
// Use "default" for all tools, "" to disable all, or specific names like "Bash,Edit,Read".
Tools []string
// MaxTurns limits agentic turns per prompt; 0 means unlimited.
MaxTurns int
// MCPConfigPath is a path to an MCP servers configuration file.
MCPConfigPath string
// StrictMCPConfig when true only uses MCP servers from MCPConfigPath,
// ignoring user, project, and local MCP configurations.
StrictMCPConfig bool
// WorkDir is the working directory for the Claude subprocess.
WorkDir string
// PermissionMode controls how Claude handles tool permissions.
// Valid values: "default", "acceptEdits", "bypassPermissions", "dontAsk", "plan", "delegate".
PermissionMode string
// MaxBudgetUSD caps the maximum dollar spend per invocation; 0 means no limit.
MaxBudgetUSD float64
// Effort controls the effort level: "low", "medium", "high"; empty means default.
Effort string
// FallbackModel specifies a model to use when the primary is overloaded.
FallbackModel string
// SessionID uses a specific UUID for the conversation.
SessionID string
// Resume resumes a previous conversation by session ID.
Resume string
// ContinueSession continues the most recent conversation in the working directory.
ContinueSession bool
// ForkSession creates a new session ID when resuming.
ForkSession bool
// NoSessionPersistence disables saving sessions to disk.
NoSessionPersistence bool
// Agents defines custom subagents that the main agent can delegate to via
// the "Task" tool. Passed to the CLI as --agents JSON. Each subagent runs
// in its own context with its own prompt, tools, and model.
// See https://code.claude.com/docs/en/sub-agents
Agents map[string]AgentConfig
// ActiveAgent selects which agent runs as the top-level agent for the
// session (--agent flag). This changes who handles the prompt, not which
// subagents are available. The selected agent can still spawn subagents
// defined in Agents or discovered via AddDirs.
ActiveAgent string
// JSONSchema constrains the output to conform to a JSON Schema.
JSONSchema string
// SettingsFile is a path to a settings JSON file or inline JSON string.
SettingsFile string
// SettingSources controls which setting sources are loaded (comma-separated: "user,project,local").
SettingSources string
// ResultDir overrides the directory where session results are persisted.
// When empty, ResultStorePath determines the default location outside
// the workspace (e.g. $HOME/.klaus/results/).
ResultDir string
// PluginDirs are directories to load plugins from.
PluginDirs []string
// AddDirs are directories to search for .claude/ subdirectories containing
// skills (.claude/skills/) and subagent definitions (.claude/agents/).
// Subagents found via AddDirs have lower priority than those in Agents (--agents).
// See https://code.claude.com/docs/en/sub-agents#choose-the-subagent-scope
AddDirs []string
}
Options configures how a Claude CLI subprocess is spawned.
func DefaultOptions ¶
func DefaultOptions() Options
DefaultOptions returns sensible defaults for headless operation.
func (Options) PersistentArgs ¶
PersistentArgs builds the CLI argument list for persistent (bidirectional stream-json) mode. It shares the base arguments with single-shot mode but adds --input-format stream-json and --replay-user-messages, and omits session management flags since the persistent subprocess maintains a single long-running session.
type PersistedResult ¶
type PersistedResult struct {
ResultText string `json:"result_text"`
Messages []StreamMessage `json:"messages,omitempty"`
MessageCount int `json:"message_count"`
ToolCalls map[string]int `json:"tool_calls,omitempty"`
SubagentCalls []SubagentCall `json:"subagent_calls,omitempty"`
ModelUsage map[string]int `json:"model_usage,omitempty"`
PRURLs []string `json:"pr_urls,omitempty"`
ErrorCount int `json:"error_count,omitempty"`
TokenUsage *TokenUsage `json:"token_usage,omitempty"`
TotalCost *float64 `json:"total_cost_usd"`
SessionID string `json:"session_id,omitempty"`
Status ProcessStatus `json:"status"`
ErrorMessage string `json:"error,omitempty"`
StopReason StopReason `json:"stop_reason,omitempty"`
Timestamp time.Time `json:"timestamp"`
}
PersistedResult is the on-disk representation of a session result. It extends ResultDetailInfo with metadata for post-mortem retrieval.
func (*PersistedResult) ToResultDetailInfo ¶
func (pr *PersistedResult) ToResultDetailInfo() ResultDetailInfo
ToResultDetailInfo converts a PersistedResult back to a ResultDetailInfo.
type PersistentProcess ¶
type PersistentProcess struct {
// contains filtered or unexported fields
}
PersistentProcess maintains a long-running Claude subprocess for multi-turn conversations using bidirectional stream-json. Instead of spawning a new subprocess per prompt, it writes user messages to stdin and reads responses from stdout, providing conversation continuity and lower latency.
func NewPersistentProcess ¶
func NewPersistentProcess(opts Options) *PersistentProcess
NewPersistentProcess returns a PersistentProcess. Call Start() to launch the subprocess before sending prompts. The process includes a background watchdog that automatically restarts the subprocess if it crashes.
func (*PersistentProcess) Done ¶
func (p *PersistentProcess) Done() <-chan struct{}
Done returns a channel closed when the current prompt response is complete.
func (*PersistentProcess) MarshalStatus ¶
func (p *PersistentProcess) MarshalStatus() ([]byte, error)
MarshalStatus returns the status as JSON.
func (*PersistentProcess) Messages ¶
func (p *PersistentProcess) Messages() MessagesInfo
Messages returns the current conversation messages. liveMessages accumulates across turns, so it is preferred over result.messages (which only contains the last Submit run). Falls back to persisted state on disk when empty.
func (*PersistentProcess) OpenAIMessages ¶
func (p *PersistentProcess) OpenAIMessages(offset int) OpenAIMessagesInfo
OpenAIMessages returns conversation messages in OpenAI Chat Completions compatible format. System and result messages are extracted into metadata. offset skips the first N converted messages (after consolidation).
func (*PersistentProcess) RawMessages ¶
func (p *PersistentProcess) RawMessages(offset int, types []string) RawMessagesInfo
RawMessages returns the raw stream-json messages from the current or last completed run. offset skips the first N messages; types filters by message type (empty means all types). The Total field always reflects the full unfiltered message count. liveMessages is preferred as it accumulates across turns (#171).
func (*PersistentProcess) ResultDetail ¶
func (p *PersistentProcess) ResultDetail() ResultDetailInfo
ResultDetail returns the full untruncated result and detailed metadata from the last completed Submit run. Falls back to the persisted result on disk when the in-memory state is empty.
func (*PersistentProcess) Run ¶
func (p *PersistentProcess) Run(ctx context.Context, prompt string) (<-chan StreamMessage, error)
Run sends a prompt to the persistent subprocess and returns a channel of response messages. RunOptions are partially supported -- only fields relevant to multi-turn conversation (like ActiveAgent) take effect; subprocess-level flags (Model, PermissionMode, etc.) are set at Start time.
func (*PersistentProcess) RunSyncWithOptions ¶
func (p *PersistentProcess) RunSyncWithOptions(ctx context.Context, prompt string, runOpts *RunOptions) (string, []StreamMessage, error)
RunSyncWithOptions sends a prompt and blocks until the response is complete.
func (*PersistentProcess) RunWithOptions ¶
func (p *PersistentProcess) RunWithOptions(ctx context.Context, prompt string, runOpts *RunOptions) (<-chan StreamMessage, error)
RunWithOptions sends a prompt with optional per-invocation overrides. In persistent mode, per-invocation overrides cannot be applied since the subprocess flags were set at Start time. If non-empty overrides are provided, a warning is logged listing which fields were ignored.
func (*PersistentProcess) Start ¶
func (p *PersistentProcess) Start(ctx context.Context) error
Start launches the persistent Claude subprocess. It must be called before sending prompts. The subprocess runs until Stop() is called or it exits.
func (*PersistentProcess) Status ¶
func (p *PersistentProcess) Status() StatusInfo
Status returns the current status information.
func (*PersistentProcess) Stop ¶
func (p *PersistentProcess) Stop() error
Stop sends SIGTERM to the persistent subprocess and waits for it to exit. It also cancels the background watchdog to prevent auto-restart.
func (*PersistentProcess) Submit ¶
func (p *PersistentProcess) Submit(ctx context.Context, prompt string, opts *RunOptions) error
Submit starts a prompt non-blocking. It calls RunWithOptions, spawns a background goroutine to drain the message channel and store results, then returns immediately. The ctx should be a server-scoped context so the drain goroutine outlives the MCP request. Previous results are preserved if the run fails to start (e.g. process is already busy).
type Process ¶
type Process struct {
// contains filtered or unexported fields
}
Process manages a Claude CLI subprocess lifecycle and streams its output.
func NewProcess ¶
NewProcess returns a Process ready to run. The Done channel is pre-closed to indicate no subprocess is active.
func (*Process) Done ¶
func (p *Process) Done() <-chan struct{}
Done returns a channel closed when the current run completes.
func (*Process) MarshalStatus ¶
func (*Process) Messages ¶
func (p *Process) Messages() MessagesInfo
Messages returns the current conversation messages. liveMessages accumulates across turns, so it is preferred over result.messages (which only contains the last Submit run). Falls back to persisted state on disk when empty.
func (*Process) OpenAIMessages ¶
func (p *Process) OpenAIMessages(offset int) OpenAIMessagesInfo
OpenAIMessages returns conversation messages in OpenAI Chat Completions compatible format. System and result messages are extracted into metadata. offset skips the first N converted messages (after consolidation).
func (*Process) RawMessages ¶
func (p *Process) RawMessages(offset int, types []string) RawMessagesInfo
RawMessages returns the raw stream-json messages from the current or last completed run. offset skips the first N messages; types filters by message type (empty means all types). The Total field always reflects the full unfiltered message count. liveMessages is preferred as it accumulates across turns (#171).
func (*Process) ResultDetail ¶
func (p *Process) ResultDetail() ResultDetailInfo
ResultDetail returns the full untruncated result and detailed metadata from the last completed Submit run. Intended for debugging and troubleshooting. Falls back to the persisted result on disk when the in-memory state is empty.
func (*Process) Run ¶
Run spawns a claude subprocess for the given prompt and returns a channel of stream-json messages. The channel is closed when the process exits.
func (*Process) RunSync ¶
RunSync runs a prompt and blocks until completion, returning the result text and all messages. It respects context cancellation.
func (*Process) RunSyncWithOptions ¶
func (p *Process) RunSyncWithOptions(ctx context.Context, prompt string, runOpts *RunOptions) (string, []StreamMessage, error)
RunSyncWithOptions runs a prompt with per-run overrides and blocks until completion.
func (*Process) RunWithOptions ¶
func (p *Process) RunWithOptions(ctx context.Context, prompt string, runOpts *RunOptions) (<-chan StreamMessage, error)
RunWithOptions spawns a claude subprocess with per-run option overrides.
func (*Process) Status ¶
func (p *Process) Status() StatusInfo
func (*Process) Submit ¶
Submit starts a prompt non-blocking. It calls RunWithOptions, spawns a background goroutine to drain the message channel and store results, then returns immediately. The ctx should be a server-scoped context so the drain goroutine outlives the MCP request. Previous results are preserved if the run fails to start (e.g. process is already busy).
type ProcessStatus ¶
type ProcessStatus string
const ( ProcessStatusStarting ProcessStatus = "starting" ProcessStatusIdle ProcessStatus = "idle" ProcessStatusBusy ProcessStatus = "busy" ProcessStatusCompleted ProcessStatus = "completed" ProcessStatusStopped ProcessStatus = "stopped" ProcessStatusError ProcessStatus = "error" )
type Prompter ¶
type Prompter interface {
// Run spawns or sends a prompt and returns a channel of stream-json messages.
// The channel is closed when the response is complete.
Run(ctx context.Context, prompt string) (<-chan StreamMessage, error)
// RunWithOptions is like Run but accepts per-invocation overrides.
RunWithOptions(ctx context.Context, prompt string, opts *RunOptions) (<-chan StreamMessage, error)
// RunSyncWithOptions sends a prompt with per-run overrides and blocks until completion.
RunSyncWithOptions(ctx context.Context, prompt string, opts *RunOptions) (string, []StreamMessage, error)
// Submit starts a prompt non-blocking: it calls RunWithOptions, spawns a
// background goroutine to drain the message channel and store results,
// then returns immediately. The ctx should be a server-scoped context
// (not an MCP request context) so the drain goroutine outlives the caller.
// When the drain completes, the status transitions to "completed" and the
// result is available via Status() and ResultDetail(). The result persists
// until the next Submit call clears it.
Submit(ctx context.Context, prompt string, opts *RunOptions) error
// Status returns the current status information. When the status is
// "completed" (after a non-blocking Submit finishes), the Result field
// contains the agent's truncated output. Use ResultDetail() for the
// full untruncated text.
Status() StatusInfo
// Stop stops the current operation or subprocess.
Stop() error
// Done returns a channel that is closed when the current run completes.
Done() <-chan struct{}
// ResultDetail returns the full untruncated result and detailed metadata
// from the last completed run. Intended for debugging and troubleshooting.
ResultDetail() ResultDetailInfo
// Messages returns the current conversation messages. While the agent
// is busy, it returns the live-accumulated messages; when completed,
// it falls back to the stored result messages or persisted state.
Messages() MessagesInfo
// RawMessages returns the raw stream-json messages from the current or
// last completed run. Unlike Messages(), it preserves the original JSON
// bytes without lossy summarization. offset skips the first N messages;
// types filters by message type (empty means all types).
RawMessages(offset int, types []string) RawMessagesInfo
// OpenAIMessages returns conversation messages in OpenAI Chat Completions
// compatible format, with metadata extracted from system/result messages.
// offset skips the first N converted messages (after consolidation).
OpenAIMessages(offset int) OpenAIMessagesInfo
// MarshalStatus returns the status as JSON.
MarshalStatus() ([]byte, error)
}
Prompter defines the interface for sending prompts to a Claude agent. Both single-shot (Process) and persistent (PersistentProcess) modes implement this interface.
type RawMessagesInfo ¶
type RawMessagesInfo struct {
Status ProcessStatus `json:"status"`
Total int `json:"total"`
Messages []json.RawMessage `json:"messages"`
}
RawMessagesInfo holds raw stream-json messages along with the process status and total message count. Used by the messages MCP tool to return lossless message data for external consumers.
type ResultDetailInfo ¶
type ResultDetailInfo struct {
ResultText string `json:"result_text"`
Messages []StreamMessage `json:"messages,omitempty"`
MessageCount int `json:"message_count"`
ToolCalls map[string]int `json:"tool_calls,omitempty"`
SubagentCalls []SubagentCall `json:"subagent_calls,omitempty"`
ModelUsage map[string]int `json:"model_usage,omitempty"`
PRURLs []string `json:"pr_urls,omitempty"`
ErrorCount int `json:"error_count,omitempty"`
TokenUsage *TokenUsage `json:"token_usage,omitempty"`
TotalCost *float64 `json:"total_cost_usd"`
SessionID string `json:"session_id,omitempty"`
Status ProcessStatus `json:"status"`
ErrorMessage string `json:"error,omitempty"`
}
ResultDetailInfo contains the full untruncated result and detailed metadata from the last completed run. Intended for debugging and troubleshooting. Unlike StatusInfo.Result, ResultText is never truncated.
type ResultStore ¶
type ResultStore struct {
// contains filtered or unexported fields
}
ResultStore persists session results to disk so they survive process restarts. It writes JSON files to a well-known directory.
func NewResultStore ¶
func NewResultStore(dir string) *ResultStore
NewResultStore creates a ResultStore that writes to the given directory. The directory is created on first Save if it doesn't exist.
func (*ResultStore) Load ¶
func (s *ResultStore) Load() (*PersistedResult, error)
Load reads the persisted result from disk. Returns nil if no persisted result exists. Returns an error for I/O or parse failures.
func (*ResultStore) Save ¶
func (s *ResultStore) Save(result PersistedResult) error
Save persists a result to disk. It creates the directory if needed. Save is not safe for concurrent use; callers must ensure single-writer semantics (which is naturally provided by the drain goroutine pattern).
type RunOptions ¶
type RunOptions struct {
// SessionID overrides Options.SessionID for this run.
SessionID string
// Resume overrides Options.Resume for this run.
Resume string
// ContinueSession overrides Options.ContinueSession for this run.
ContinueSession bool
// ForkSession overrides Options.ForkSession for this run.
ForkSession bool
// ActiveAgent overrides Options.ActiveAgent for this run.
ActiveAgent string
// JSONSchema overrides Options.JSONSchema for this run.
JSONSchema string
// MaxBudgetUSD overrides Options.MaxBudgetUSD for this run.
MaxBudgetUSD float64
// Effort overrides Options.Effort for this run.
Effort string
}
RunOptions allows overriding base Options on a per-invocation basis. Zero values are ignored (the base Options value is used instead).
type StatusInfo ¶
type StatusInfo struct {
Status ProcessStatus `json:"status"`
SessionID string `json:"session_id,omitempty"`
ErrorMessage string `json:"error,omitempty"`
PreviousError string `json:"previous_error,omitempty"`
TotalCost *float64 `json:"total_cost_usd"`
MessageCount int `json:"message_count,omitempty"`
ToolCallCount int `json:"tool_call_count,omitempty"`
ToolCalls map[string]int `json:"tool_calls,omitempty"`
TokenUsage *TokenUsage `json:"token_usage,omitempty"`
LastMessage string `json:"last_message,omitempty"`
LastToolName string `json:"last_tool_name,omitempty"`
// SubagentCalls tracks subagent dispatches via the Task/Agent tool.
SubagentCalls []SubagentCall `json:"subagent_calls,omitempty"`
ModelUsage map[string]int `json:"model_usage,omitempty"`
ErrorCount int `json:"error_count,omitempty"`
// Result contains the agent's final output text from the last completed
// non-blocking Submit run, truncated to maxStatusResultLen runes. It is
// populated when the status is "completed". Use the result debug tool
// for the full untruncated text.
//
// The result persists until the next Submit call clears it (along with
// resetting the status to "busy"). There is no explicit "consumed"
// acknowledgement; callers should track whether they have already
// processed a given result.
Result string `json:"result,omitempty"`
}
type StopReason ¶
type StopReason string
StopReason indicates why the agent stopped.
const ( StopReasonCompleted StopReason = "completed" StopReasonBudget StopReason = "budget" StopReasonError StopReason = "error" StopReasonStopped StopReason = "stopped" )
type StreamMessage ¶
type StreamMessage struct {
Type MessageType `json:"type"`
Subtype MessageSubtype `json:"subtype,omitempty"`
Timestamp string `json:"timestamp,omitempty"`
Message json.RawMessage `json:"message,omitempty"`
// Fields present on "system" messages.
SessionID string `json:"session_id,omitempty"`
// Fields present on "assistant" messages with subtype "text".
Text string `json:"text,omitempty"`
// Fields present on "assistant" messages with subtype "tool_use".
ToolName string `json:"tool_name,omitempty"`
ToolID string `json:"tool_id,omitempty"`
ToolArgs json.RawMessage `json:"tool_args,omitempty"`
// Usage holds token counts from the Claude API, present on "assistant" messages.
Usage *TokenUsage `json:"usage,omitempty"`
// Fields present on "result" messages.
Result string `json:"result,omitempty"`
Duration float64 `json:"duration_ms,omitempty"`
Cost float64 `json:"cost_usd,omitempty"`
IsError bool `json:"is_error,omitempty"`
// TotalCost tracks the running total cost of the session.
TotalCost float64 `json:"total_cost_usd,omitempty"`
// Fields present on "stream_event" messages (--include-partial-messages).
EventType string `json:"-"`
DeltaText string `json:"-"`
ToolUseName string `json:"-"` // tool name from content_block_start with type "tool_use"
ToolUseBlockID string `json:"-"` // tool use ID from content_block_start with type "tool_use"
InputJSONDelta string `json:"-"` // partial JSON from content_block_delta with input_json_delta
// Raw holds the original JSON for messages we don't fully parse.
Raw json.RawMessage `json:"-"`
}
StreamMessage is the top-level envelope for all stream-json messages emitted by the Claude CLI on stdout.
func ParseStreamMessage ¶
func ParseStreamMessage(data []byte) (StreamMessage, error)
ParseStreamMessage unmarshals a single line of stream-json output. It stamps each message with the current UTC time in RFC3339 format.
Claude Code 2.1+ nests assistant message content inside message.content[] instead of using top-level fields. When top-level subtype is empty and msg.Message is populated, this function extracts content from the nested structure to populate Subtype, Text, ToolName, ToolID, ToolArgs, and Usage.
type SubagentCall ¶
type SubagentCall struct {
Type string `json:"type"`
Description string `json:"description,omitempty"`
ToolID string `json:"tool_id,omitempty"`
ToolCalls int `json:"tool_calls,omitempty"`
Tokens int `json:"tokens,omitempty"`
DurationMS float64 `json:"duration_ms,omitempty"`
Status string `json:"status,omitempty"`
}
SubagentCall tracks a single subagent dispatch via the Task/Agent tool.
type ThinkingBlock ¶
type ThinkingBlock struct {
Type string `json:"type"`
Thinking string `json:"thinking"`
Signature string `json:"signature,omitempty"`
}
ThinkingBlock preserves Anthropic thinking blocks with signatures, following the LiteLLM/DeepSeek convention.
type TokenUsage ¶
type TokenUsage struct {
InputTokens int64 `json:"input_tokens,omitempty"`
OutputTokens int64 `json:"output_tokens,omitempty"`
CacheCreationInputTokens int64 `json:"cache_creation_input_tokens,omitempty"`
CacheReadInputTokens int64 `json:"cache_read_input_tokens,omitempty"`
}
TokenUsage holds per-message token counts from the Claude API usage object.
type ToolCallInfo ¶
type ToolCallInfo struct {
ID string `json:"id"`
Name string `json:"name"`
Args json.RawMessage `json:"args,omitempty"`
}
ToolCallInfo holds structured tool call data for external consumers.
type ToolResultBlock ¶
type ToolResultBlock struct {
Type string `json:"type"`
ToolUseID string `json:"tool_use_id,omitempty"`
Content string `json:"content"`
IsError bool `json:"is_error"`
}
ToolResultBlock represents a single content block from a user message (tool result).
func ExtractToolResults ¶
func ExtractToolResults(msg StreamMessage) []ToolResultBlock
ExtractToolResults parses tool_result content blocks from a StreamMessage's raw Message JSON. Returns nil if the message has no content blocks or cannot be parsed.
type ToolResultInfo ¶
type ToolResultInfo struct {
ToolCallID string `json:"tool_call_id"`
Content string `json:"content"`
IsError bool `json:"is_error,omitempty"`
}
ToolResultInfo holds structured tool result data for external consumers.