codingagent

package
v0.2.4 Latest Latest
Warning

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

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

Documentation

Index

Constants

View Source
const (
	// ExecutionModeInteractive keeps stdin open for mid-task user responses.
	ExecutionModeInteractive = "interactive"
	// ExecutionModeSingleShot closes stdin after the initial prompt (legacy behavior).
	ExecutionModeSingleShot = "single_shot"
)
View Source
const (
	ErrorCodeUpstreamOverloaded = "upstream_overloaded"
	ErrorCodeUpstreamError      = "upstream_error"
)
View Source
const (
	// DefaultMaxAttempts is the default maximum number of retry attempts.
	DefaultMaxAttempts = 10
	// DefaultRetryInterval is the default interval between retry attempts.
	DefaultRetryInterval = 3 * time.Second
)
View Source
const (
	StatusActive    = "active"
	StatusSuspended = "suspended"
	StatusCompleted = "completed"
	StatusError     = "error"
	StatusClosed    = "closed"
)

Session status constants.

View Source
const (
	// DefaultMaxSSEDataLineBytes is the max JSON size for a single SSE data line.
	DefaultMaxSSEDataLineBytes = 64 * 1024 // 64 KiB
	// DefaultSSEChunkContentBytes is the max content bytes per tool_result_part chunk.
	DefaultSSEChunkContentBytes = 48 * 1024 // 48 KiB
)
View Source
const (
	// DefaultScannerMaxTokenSize is the default max JSONL line size for agent stdout scanners.
	DefaultScannerMaxTokenSize = 4 * 1024 * 1024 // 4MB
	// DefaultMaxToolResultBytes is the default max EventToolResult content size for SSE relay.
	DefaultMaxToolResultBytes = 256 * 1024 // 256KB
)

Variables

View Source
var ErrMultimodalNotSupported = errors.New("multimodal inputs are not supported by this agent")

ErrMultimodalNotSupported is returned by agents that do not support non-text content (e.g., images).

Functions

func ApplyDefaults

func ApplyDefaults(cfg *SessionConfig, ac *AdapterConfig)

ApplyDefaults applies AdapterConfig default values to SessionConfig. Fields explicitly set by SessionOption are not overwritten. Priority: SessionOption > AdapterConfig.Default* > zero value

func ClassifiedErrorContent added in v0.1.14

func ClassifiedErrorContent(msg string, retryable bool) string

ClassifiedErrorContent appends a stable error code tag for SSE EventError content.

func ConvertToLinuxPath added in v0.1.1

func ConvertToLinuxPath(path string) string

ConvertToLinuxPath converts a Windows path (which may be a WSL path) to a Linux-style path. If it is not a WSL path, it returns the input unchanged.

func EscapeShellArg added in v0.1.1

func EscapeShellArg(arg string) string

EscapeShellArg escapes a string to be safe as a shell argument inside sh -c.

func ExtractText added in v0.1.1

func ExtractText(parts []ContentPart) string

ExtractText concatenates all text blocks from a []ContentPart. Non-text blocks are ignored. Returns empty string if no text blocks exist.

func HasNonTextContent added in v0.1.1

func HasNonTextContent(parts []ContentPart) bool

HasNonTextContent returns true if any ContentPart has a type other than "text".

func IsNonRetryableError added in v0.1.15

func IsNonRetryableError(msg string) bool

IsNonRetryableError reports a fatal Codex CLI / auth / argv failure that must not trigger process re-exec.

func IsRetryableError

func IsRetryableError(err error) bool

IsRetryableError checks whether the error is retryable. EOF, connection reset, broken pipe, connection refused, connectex are retryable.

func IsRetryableUpstream added in v0.1.14

func IsRetryableUpstream(msg string) bool

IsRetryableUpstream reports whether a log, stderr, or API message is a transient upstream stream failure.

func IsSandboxRejection added in v0.2.3

func IsSandboxRejection(msg string) bool

IsSandboxRejection reports Codex sandbox/policy rejection in stderr or log text.

func NewLargeLineScanner added in v0.1.5

func NewLargeLineScanner(r io.Reader, maxTokenSize int) *bufio.Scanner

NewLargeLineScanner returns a Scanner with configurable max token size. maxTokenSize <= 0 uses DefaultScannerMaxTokenSize.

func NormalizeExecutionMode added in v0.1.2

func NormalizeExecutionMode(mode string) string

NormalizeExecutionMode returns a valid execution mode, defaulting to interactive.

func OverlayConfigDir added in v0.1.8

func OverlayConfigDir(sessionDir, configDir string, allowlist []string) error

OverlayConfigDir copies or symlinks allowlisted names from configDir into sessionDir. Only entries that exist under configDir are applied. Existing session-only data outside the allowlist is never removed. Protected names under sessionDir are never deleted even if listed in allowlist by mistake.

func ParseWSLPath added in v0.1.1

func ParseWSLPath(path string) (distro string, linuxPath string, isWSL bool)

ParseWSLPath parses a Windows path starting with a WSL prefix into (distro, linuxPath, isWSL). e.g. `\\wsl.localhost\Ubuntu\tmp` -> (`Ubuntu`, `/tmp`, true)

func PhysicalToHostPath

func PhysicalToHostPath(physical string) string

PhysicalToHostPath converts a "file://" URI to a native file path. "file:///home/user/project" -> "/home/user/project"

func ReassembleToolResultParts added in v0.1.6

func ReassembleToolResultParts(events []StreamEvent) (string, error)

ReassembleToolResultParts joins tool_result_part content in order.

func Register

func Register(name string, factory FactoryFunc)

Register registers a factory function for the given agent name. Typically called from init() in each adapter's package. Panics if name is already registered (programming error).

func Retry

func Retry(ctx context.Context, cfg *RetryConfig, fn func() error) error

Retry executes fn up to MaxAttempts times. Only retryable errors trigger a retry. If ContainerCheck returns false, retry is immediately aborted.

func SortVFSMounts

func SortVFSMounts(mounts []VFSMount)

SortVFSMounts sorts mounts by parent directory first (ascending VFSPath length).

func StripMarkdownCodeFence

func StripMarkdownCodeFence(text string) string

StripMarkdownCodeFence removes markdown code fences and returns the inner content. If no code fence is found, the original text is returned unchanged.

func TruncateToolResult added in v0.1.5

func TruncateToolResult(content string, maxBytes int) string

TruncateToolResult truncates content to maxBytes for SSE/TaskLog relay. Appends "\n... [truncated, N bytes total]" when truncated. maxBytes <= 0 uses DefaultMaxToolResultBytes.

func VFSMountsToDockerArgs

func VFSMountsToDockerArgs(mounts []VFSMount) []string

VFSMountsToDockerArgs generates Docker -v arguments from VFSMount list. Returns: ["-v", "/host/path:/container/path", "-v", ...]

func ValidateContentParts added in v0.1.1

func ValidateContentParts(parts []ContentPart) error

ValidateContentParts validates a []ContentPart for correctness. Returns an error if any part is invalid.

func VerifyWSLRuntime added in v0.1.1

func VerifyWSLRuntime(ctx context.Context, distro string, cmdName string) error

VerifyWSLRuntime checks if the target CLI exists in WSL.

func VfsToContainerPath

func VfsToContainerPath(vfsPath string) string

VfsToContainerPath converts a VFS URI to a container path. "vfs://workspace/" -> "/workspace" "vfs://workspace/data/" -> "/workspace/data"

Types

type AdapterConfig

type AdapterConfig struct {
	// AgentName is the agent name used for directory naming (e.g., "claudecode", "codex").
	AgentName string

	// GatewayURL is the LLM Gateway Proxy URL.
	GatewayURL string

	// Logger is the logger instance.
	Logger logger.Logger

	// DefaultWorkDir is the default working directory (CWD).
	// Can be overridden per-session via WithWorkDir.
	DefaultWorkDir string

	// DefaultModel is the default model name.
	// Can be overridden per-session via WithModel.
	DefaultModel string

	// DefaultEnvVars is the default additional environment variables.
	// Can be overridden per-session via WithEnvVars.
	DefaultEnvVars map[string]string

	// DefaultSessionDir is the default session data storage directory.
	// Can be overridden per-session via WithSessionDir.
	// Falls back to WorkDir if not set.
	DefaultSessionDir string

	// DisableSandbox disables the CLI internal sandbox (for container execution).
	// When true, CLAUDE_CODE_SKIP_SANDBOX=1 is set.
	DisableSandbox bool

	// ToolCallFallback enables text-to-tool-call conversion in the Gateway.
	// When true, the ANTHROPIC_API_KEY includes ";fallback=true" metadata
	// so the gateway proxy can apply fallback logic for models that
	// sometimes emit tool calls as text instead of proper function_call.
	ToolCallFallback bool

	// ModelMode is the wire API mode for the adapter ("chat" or "responses").
	// Used by Codex to determine config.toml wire_api value.
	// Empty string defaults to "chat".
	ModelMode string

	// GatewayToken is the internal authentication token for LLMGP.
	// Injected by server.Server on startup.
	GatewayToken string

	// EnableSubagent enables subagent delegation for WBS node execution.
	// When true, each WBS node runs in an independent child session.
	EnableSubagent bool

	// MaxPromptBytes is the maximum allowed prompt size in bytes.
	MaxPromptBytes int
	// ExecutionMode controls stdin behavior: "interactive" or "single_shot".
	ExecutionMode string
	// IdleTimeoutSeconds is the max idle time without stdout/stderr output.
	IdleTimeoutSeconds int
	// MaxExecutionSeconds is the max wall-clock execution time.
	MaxExecutionSeconds int
	// ScannerMaxTokenBytes is the max JSONL line size for agent stdout scanners.
	ScannerMaxTokenBytes int
	// MaxToolResultBytes is the max EventToolResult content size for SSE relay.
	MaxToolResultBytes int
}

AdapterConfig is the common configuration for all coding agent adapters.

type CodingAgent

type CodingAgent interface {
	// CreateSession starts a new agent session.
	// Internally launches a CLI subprocess.
	CreateSession(ctx context.Context, opts ...SessionOption) (Session, error)

	// Name returns the agent backend name ("claudecode", "codex").
	Name() string

	// Close releases agent resources.
	Close() error
}

CodingAgent is the common interface for coding agent backends. Both CLI wrapper types (Claude Code, Codex) and future direct API types can implement this interface.

func CreateAll

func CreateAll(cfg *AdapterConfig) []CodingAgent

CreateAll creates all registered agents using the given config. Agents whose factory returns (nil, nil) are silently skipped (CLI not found). Agents whose factory returns an error are logged and skipped. Returns the successfully created agents.

type ContentPart added in v0.1.1

type ContentPart struct {
	Type   string       `json:"type"`             // "text" or "image"
	Text   string       `json:"text,omitempty"`   // populated when type="text"
	Source *ImageSource `json:"source,omitempty"` // populated when type="image"
}

ContentPart represents a single block in a multimodal message. Supported types: "text" (plain text) and "image" (base64-encoded image).

func TextOnlyContent added in v0.1.1

func TextOnlyContent(text string) []ContentPart

TextOnlyContent creates a []ContentPart from a plain text string. Used by v1 handler to wrap legacy "message" field into content blocks.

type EventType

type EventType string

EventType represents the type of a streaming event from a coding agent.

const (
	// EventText is a text content event from the agent.
	EventText EventType = "text"
	// EventToolUse is a tool use event from the agent.
	EventToolUse EventType = "tool_use"
	// EventToolResult is a tool result event.
	EventToolResult EventType = "tool_result"
	// EventToolResultPart is a chunk of a large tool_result for SSE wire format.
	EventToolResultPart EventType = "tool_result_part"
	// EventResult is the final result event.
	EventResult EventType = "result"
	// EventError is an error event.
	EventError EventType = "error"
	// EventSystem is a system event (e.g., session init).
	EventSystem EventType = "system"
	// EventNodeStart indicates a WBS node has started execution.
	EventNodeStart EventType = "node_start"
	// EventNodeComplete indicates a WBS node has completed successfully.
	EventNodeComplete EventType = "node_complete"
	// EventNodeFailed indicates a WBS node execution failed.
	EventNodeFailed EventType = "node_failed"
	// EventProgress indicates WBS overall progress (e.g., "2/5").
	EventProgress EventType = "progress"
	// EventUserInputRequired indicates the agent is waiting for user input.
	EventUserInputRequired EventType = "user_input_required"
)

type FactoryFunc

type FactoryFunc func(cfg *AdapterConfig) (CodingAgent, error)

FactoryFunc creates a CodingAgent from config. Return (nil, nil) if the agent's CLI is not available (graceful skip). Return (nil, err) if initialization fails unexpectedly.

type FallbackToolCall

type FallbackToolCall struct {
	Name      string         `json:"name"`
	Arguments map[string]any `json:"arguments"`
}

FallbackToolCall is a tool call parsed from text output.

func ParseFallbackToolCalls

func ParseFallbackToolCalls(text string) ([]FallbackToolCall, bool)

ParseFallbackToolCalls extracts tool calls from text output. Supported formats:

  • Single object: {"name": "Write", "arguments": {...}}
  • Array: [{"name": "Write", ...}, ...]
  • Markdown code fence: ```json\n{...}\n```

type ImageSource added in v0.1.1

type ImageSource struct {
	Type      string `json:"type"`       // "base64"
	MediaType string `json:"media_type"` // MIME type (e.g., "image/png", "image/jpeg")
	Data      string `json:"data"`       // Base64-encoded image data
}

ImageSource holds image data for a ContentPart of type "image".

type RetryConfig

type RetryConfig struct {
	MaxAttempts   int
	RetryInterval time.Duration
	// ContainerCheck is an optional container liveness check function.
	// If nil, no check is performed.
	// If it returns false, retry is immediately aborted.
	ContainerCheck func() bool
}

RetryConfig configures retry behavior.

func DefaultRetryConfig

func DefaultRetryConfig() *RetryConfig

DefaultRetryConfig returns the default retry configuration.

type Session

type Session interface {
	// Send sends a message and returns a streaming event channel.
	// The channel is closed when the agent response completes.
	Send(ctx context.Context, message string) (<-chan StreamEvent, error)

	// ID returns the session ID.
	ID() string

	// Close terminates the session and cleans up the subprocess.
	Close() error
}

Session is an active agent session. Corresponds to the lifecycle of a CLI subprocess.

type SessionConfig

type SessionConfig struct {
	// Request-level options (vary per request)
	Model        string   // Model name (e.g., "anthropic/claude-sonnet-4")
	Prompt       string   // Initial prompt (for single-shot sessions)
	AllowedTools []string // Allowed tool names

	// Environment-level options (fixed at process/container start)
	WorkDir string            // Working directory (CWD)
	EnvVars map[string]string // Additional environment variables

	// Session resume
	AgentSessionID string // Agent-managed session ID for context resume

	// Session data storage directory.
	// When set, the adapter maps this to the agent-specific env var
	// (e.g., CLAUDE_CONFIG_DIR, CODEX_HOME).
	// Falls back to WorkDir if not explicitly set.
	SessionDir string

	// ConfigDir is an optional source directory for agent config assets
	// (skills, rules, settings). When set, adapters overlay allowlisted
	// entries into SessionDir before launch. Empty means disabled
	// (backward compatible: no overlay).
	ConfigDir string

	// VFS mounts (container execution)
	VFSMounts []VFSMount // Host->container file mappings

	// MaxTurns limits the number of agent turns. 0 means CLI default.
	MaxTurns int

	// ExecutionMode controls stdin behavior: "interactive" or "single_shot".
	ExecutionMode string
	// IdleTimeoutSeconds is the max idle time without stdout/stderr output.
	IdleTimeoutSeconds int
	// MaxExecutionSeconds is the max wall-clock execution time.
	MaxExecutionSeconds int
	// ScannerMaxTokenBytes is the max JSONL line size for agent stdout scanners.
	ScannerMaxTokenBytes int
	// MaxToolResultBytes is the max EventToolResult content size for SSE relay.
	MaxToolResultBytes int
}

SessionConfig holds session creation parameters.

func NewSessionConfig

func NewSessionConfig(opts ...SessionOption) *SessionConfig

NewSessionConfig applies the given SessionOptions and returns a SessionConfig.

type SessionOption

type SessionOption func(*SessionConfig)

SessionOption configures a session at creation time.

func WithAgentSessionID

func WithAgentSessionID(id string) SessionOption

WithAgentSessionID sets the agent session ID for context resume.

func WithAllowedTools

func WithAllowedTools(tools []string) SessionOption

WithAllowedTools sets the allowed tool names.

func WithConfigDir added in v0.1.8

func WithConfigDir(dir string) SessionOption

WithConfigDir sets the optional agent config set directory.

func WithEnvVars

func WithEnvVars(vars map[string]string) SessionOption

WithEnvVars sets additional environment variables.

func WithExecutionMode added in v0.1.2

func WithExecutionMode(mode string) SessionOption

WithExecutionMode sets the execution mode for stdin handling.

func WithIdleTimeout added in v0.1.2

func WithIdleTimeout(seconds int) SessionOption

WithIdleTimeout sets the idle timeout in seconds.

func WithMaxExecution added in v0.1.2

func WithMaxExecution(seconds int) SessionOption

WithMaxExecution sets the max execution time in seconds.

func WithMaxToolResultBytes added in v0.1.5

func WithMaxToolResultBytes(n int) SessionOption

WithMaxToolResultBytes sets the max EventToolResult content size for SSE relay.

func WithMaxTurns

func WithMaxTurns(n int) SessionOption

WithMaxTurns sets the maximum number of agent turns.

func WithModel

func WithModel(model string) SessionOption

WithModel sets the model name.

func WithPrompt

func WithPrompt(prompt string) SessionOption

WithPrompt sets the initial prompt.

func WithScannerMaxTokenBytes added in v0.1.5

func WithScannerMaxTokenBytes(n int) SessionOption

WithScannerMaxTokenBytes sets the max JSONL line size for stdout scanners.

func WithSessionDir

func WithSessionDir(dir string) SessionOption

WithSessionDir sets the session data storage directory.

func WithVFSMounts

func WithVFSMounts(mounts []VFSMount) SessionOption

WithVFSMounts sets the VFS mount mappings.

func WithWorkDir

func WithWorkDir(dir string) SessionOption

WithWorkDir sets the working directory.

type SessionRecord

type SessionRecord struct {
	ID             string    `json:"id"`
	AgentName      string    `json:"agent_name"`
	Model          string    `json:"model"`
	Status         string    `json:"status"`
	Error          string    `json:"error,omitempty"`
	WorkDir        string    `json:"work_dir"`
	StorageRoot    string    `json:"storage_root,omitempty"`
	AgentSessionID string    `json:"agent_session_id"`
	SessionDir     string    `json:"session_dir"`
	ConfigDir      string    `json:"config_dir,omitempty"`
	CreatedAt      time.Time `json:"created_at"`
	UpdatedAt      time.Time `json:"updated_at"`
}

SessionRecord is a persisted session record.

type SessionStore

type SessionStore interface {
	Create(session *SessionRecord) error
	Get(id string) (*SessionRecord, error)
	Update(session *SessionRecord) error
	List() ([]*SessionRecord, error)
	Delete(id string) error
}

SessionStore is the abstract interface for session persistence.

type StdinWriter added in v0.1.2

type StdinWriter interface {
	WriteStdin(text string) error
}

StdinWriter allows writing additional input to a running CLI session.

type StreamEvent

type StreamEvent struct {
	Type          EventType              `json:"type"`
	Content       string                 `json:"content,omitempty"`
	PromptID      string                 `json:"prompt_id,omitempty"`
	Choices       []string               `json:"choices,omitempty"`
	ToolName      string                 `json:"tool_name,omitempty"`
	ToolInput     map[string]interface{} `json:"tool_input,omitempty"`
	SessionID     string                 `json:"session_id,omitempty"`
	TurnID        string                 `json:"turn_id,omitempty"`
	CorrelationID string                 `json:"correlation_id,omitempty"`
	ChunkID       string                 `json:"chunk_id,omitempty"`
	ChunkIndex    int                    `json:"index,omitempty"`
	ChunkTotal    int                    `json:"total,omitempty"`
	Error         error                  `json:"-"`
	Retryable     bool                   `json:"-"`
}

StreamEvent is a streaming event from a coding agent.

func SplitStreamEventForSSE added in v0.1.6

func SplitStreamEventForSSE(ev StreamEvent, maxLineBytes int) ([]StreamEvent, error)

SplitStreamEventForSSE splits oversized EventToolResult into wire-safe events. Non-EventToolResult events are returned unchanged as a single-element slice. maxLineBytes <= 0 uses DefaultMaxSSEDataLineBytes.

type VFSMount

type VFSMount struct {
	VFSPath      string // Logical path (e.g., "vfs://workspace/")
	PhysicalPath string // Host physical path (e.g., "file:///home/user/project")
}

VFSMount defines a host path <-> container path mapping.

type WSLCommandBuilder added in v0.1.1

type WSLCommandBuilder struct {
	Distro         string
	WorkDir        string
	Command        string
	Args           []string
	Env            []string
	DisableSandbox bool
}

WSLCommandBuilder builds a wsl.exe command execution structure.

func (*WSLCommandBuilder) BuildCmd added in v0.1.1

func (b *WSLCommandBuilder) BuildCmd(ctx context.Context) *exec.Cmd

BuildCmd returns the *exec.Cmd to execute.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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