auto

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Jul 14, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

Package auto - Cache control support for classifier API calls.

This module provides cache control header support for the classifier API, enabling prompt caching to reduce latency and costs. Cache control allows the API to cache the system prompt and transcript prefix across calls.

TTL Values:

  • ephemeral-1-hour: 1 hour cache TTL (default for auto mode)
  • ephemeral-5-minutes: 5 minute cache TTL (shorter)

Package auto implements the auto mode permission classifier for Seshat. This aligns with OpenClaude's two-stage security classification system.

Two-Stage Classifier Design: - Stage 1 (Fast): Quick yes/no decision with small token budget (64 tokens) - Stage 2 (Thinking): Full reasoning when stage 1 blocks, with extended analysis

Key Features: - XML-based output parsing (<block>/<reason>/<thinking>) - Transcript building from conversation history - SESHAT.md integration for user preferences - Feature flags for runtime configuration

Package auto - Classifier API client.

This module provides the API client interface for making classification requests to the LLM provider. It wraps the Seshat providers.Client to provide a classifier-specific interface with proper request/response handling.

The ClassifierAPI interface defines the contract for classifier API clients, allowing for different implementations (e.g., mock for testing, real for production).

Package auto - Configuration types for auto mode.

This file defines configuration structures used throughout the auto mode package, including mode-level configuration, denial limits, and defaults.

Package auto - Debug utilities for classifier diagnostics.

This module provides debug utilities for dumping classifier requests, responses, and transcripts for troubleshooting. Aligned with OpenClaude's yoloClassifier.ts debug functions.

Package auto - Feature flags for runtime configuration.

This module provides feature flag support for the auto mode classifier, allowing runtime configuration via environment variables. This aligns with OpenClaude's GrowthBook-based feature flag system, but uses env vars for simpler deployment in Seshat.

Environment Variables:

  • CLAUDE_CODE_TWO_STAGE_CLASSIFIER: Enable two-stage classifier (true/fast/thinking)
  • CLAUDE_CODE_JSONL_TRANSCRIPT: Use JSONL format for transcript
  • CLAUDE_CODE_CACHE_CONTROL: Enable cache control headers
  • CLAUDE_CODE_THINKING: Enable thinking mode
  • CLAUDE_CODE_MAX_TRANSCRIPT_CHARS: Maximum transcript characters

Package auto - Prompt templates for the security classifier.

This module contains the system prompt templates used by the auto mode classifier. These templates define the security policy and classification guidelines.

Alignment: These templates align with OpenClaude's yolo-classifier-prompts system, which includes base system prompt, external permissions template, and Anthropic internal template.

Template Types:

  • BaseSystemPrompt: Core classifier instructions
  • ExternalPermissionsTemplate: User-customizable permissions
  • AnthropicPermissionsTemplate: Internal Anthropic build template

Package auto - SESHAT.md integration for classifier.

This module handles integration with the user's SESHAT.md configuration file, which contains user-defined instructions for the agent. These instructions are treated as part of the user's intent when evaluating tool actions.

This is the Seshat equivalent of OpenClaude's CLAUDE.md integration. The content is wrapped in <user_seshat_md> tags and prepended to classifier prompts.

Usage:

auto.SetSeshatMdProvider(func() string {
    return readFile("SESHAT.md")
})

Package auto - State management for auto mode classifier.

This module provides state tracking for the auto mode classifier, including session state, circuit breaking, and transcript caching. Aligned with OpenClaude's autoModeState.ts.

Package auto - Telemetry and logging for auto mode.

This module provides telemetry and logging support for the classifier, tracking classification outcomes, errors, and performance metrics. Currently outputs to standard log; can be extended for external telemetry.

Package auto - Transcript building for classifier.

This module handles building the conversation transcript that gets sent to the classifier. It converts Seshat messages into a compact format that includes user messages and tool use blocks, while respecting character limits.

Key Features: - Converts Message[] to TranscriptEntry[] - Supports JSONL and text format for transcript - Tool input encoding via Tool interface - Character limit truncation for context management

Package auto - XML Parser for classifier responses.

This module provides XML parsing for the two-stage classifier output. The classifier returns responses in XML format with <block>, <reason>, and optional <thinking> tags. This parser handles extraction of these values from the raw response text.

Response Format:

  • <block>yes</block> or <block>no</block> for decision
  • <reason>explanation</reason> for decision rationale
  • <thinking>chain-of-thought</thinking> for reasoning (stage 2 only)

Alignment: This aligns with OpenClaude's classifierShared.ts parsing.

Index

Constants

View Source
const (
	CacheControlTTL1Hour = "ephemeral-1-hour"
	CacheControlTTL5Min  = "ephemeral-5-minutes"
)

Cache control TTL constants

View Source
const (
	// MaxTranscriptChars is the maximum character length for transcript context.
	// This includes user messages and tool uses sent to the classifier.
	MaxTranscriptChars = 200000

	// MaxBlockValueChars is the maximum characters per block value.
	// Used to truncate long tool inputs in the transcript.
	MaxBlockValueChars = 32000

	// Stage1MaxTokens is the token budget for stage 1 (fast) classification.
	// Small budget encourages quick yes/no decisions.
	Stage1MaxTokens = 64

	// Stage1MaxTokensFast is the token budget for fast-only mode.
	// Allows space for <reason> tag in response.
	Stage1MaxTokensFast = 256

	// Stage2MaxTokens is the token budget for stage 2 (thinking) classification.
	// Larger budget allows for chain-of-thought reasoning.
	Stage2MaxTokens = 4096

	// ThinkingPadding is extra tokens reserved for models with always-on thinking.
	// Prevents max_tokens exhaustion on extended thinking models.
	ThinkingPadding = 2048
)
View Source
const (
	// Stage1Suffix nudges the model for immediate <block> decision.
	Stage1Suffix = "\nErr on the side of blocking. <block> immediately."

	// Stage2Suffix encourages chain-of-thought reasoning before decision.
	Stage2Suffix = "" /* 263-byte string literal not displayed */
)

Stage suffixes appended to classifier prompts to guide response format. These match OpenClaude's classifier.py stage suffixes.

View Source
const (
	OutcomeSuccess           = "success"
	OutcomeParseFailure      = "parse_failure"
	OutcomeInterrupted       = "interrupted"
	OutcomeTranscriptTooLong = "transcript_too_long"
	OutcomeError             = "error"
)
View Source
const AnthropicPermissionsTemplate = `` /* 952-byte string literal not displayed */

AnthropicPermissionsTemplate is the internal Anthropic-specific template. This is used for internal builds with specific guidelines.

View Source
const (
	// AutoModeDumpDir is the directory for classifier debug dumps.
	AutoModeDumpDir = "auto-mode"
)
View Source
const BaseSystemPrompt = `` /* 2801-byte string literal not displayed */

BaseSystemPrompt is the main system prompt for the security classifier. This is the core prompt that defines how the classifier evaluates tool uses. It includes instructions about allowed actions, blocked actions, and guidelines for making classification decisions. The prompt uses XML format for responses.

View Source
const BlockedByFastClassifier = "Blocked by fast classifier"

BlockedByFastClassifier is the reason when fast stage blocks.

View Source
const ExternalPermissionsTemplate = `` /* 1525-byte string literal not displayed */

ExternalPermissionsTemplate is the external-facing permissions template. This template includes user-customizable sections wrapped in <user_*_to_replace> tags. Users can override these sections via settings.autoMode configuration.

View Source
const NoReasonProvided = "No reason provided"

NoReasonProvided is the default reason when classifier doesn't provide one.

View Source
const SeshatMdDelimiter = "<user_seshat_md>"
View Source
const SeshatMdDelimiterEnd = "</user_seshat_md>"

Variables

View Source
var DefaultModeConfig = &ModeConfig{
	FailClosed: true,
}

DefaultModeConfig is the default configuration for auto mode. FailClosed is true by default for security.

View Source
var DefaultToolRegistry = []Tool{
	NewDefaultTool("Read", []string{}, func(input map[string]any) string {
		path := input["path"]
		return fmt.Sprintf("Read %v", path)
	}),
	NewDefaultTool("Edit", []string{}, func(input map[string]any) string {
		oldString := input["old_string"]
		newString := input["new_string"]
		return fmt.Sprintf("Edit: replace %v with %v", oldString, newString)
	}),
	NewDefaultTool("Write", []string{}, func(input map[string]any) string {
		path := input["path"]
		content := input["content"]
		return fmt.Sprintf("Write %v (length=%d)", path, len(fmt.Sprintf("%v", content)))
	}),
	NewDefaultTool("bash", []string{"Shell", "Command"}, func(input map[string]any) string {
		command := input["command"]
		return fmt.Sprintf("Bash %v", command)
	}),
	NewDefaultTool("Glob", []string{}, func(input map[string]any) string {
		pattern := input["pattern"]
		return fmt.Sprintf("Glob %v", pattern)
	}),
	NewDefaultTool("Grep", []string{}, func(input map[string]any) string {
		pattern := input["pattern"]
		path := input["path"]
		return fmt.Sprintf("Grep %v in %v", pattern, path)
	}),
	NewDefaultTool("LS", []string{}, func(input map[string]any) string {
		path := input["path"]
		return fmt.Sprintf("LS %v", path)
	}),
	NewDefaultTool("web_fetch", []string{"fetch"}, func(input map[string]any) string {
		url := input["url"]
		return fmt.Sprintf("WebFetch %v", url)
	}),
	NewDefaultTool("TodoRead", []string{}, func(input map[string]any) string {
		return "TodoRead"
	}),
	NewDefaultTool("todo_write", []string{}, func(input map[string]any) string {
		content := input["content"]
		return fmt.Sprintf("TodoWrite %v", content)
	}),
}
View Source
var POWERSHELL_TOOL_NAME = "powershell"

PowerShell tool name constant.

View Source
var SafeToolNames = []string{
	"read_file", "grep", "glob",
	"ask_user_question", "web_search", "web_fetch",
}

SafeToolNames is the allowlist of tool names that are safe and don't need classifier checking. These are read-only tools or tools that only affect internal metadata and don't modify the filesystem or system state. Aligned with OpenClaude's safe tool allowlist.

Functions

func BuildSeshatMdMessage

func BuildSeshatMdMessage() *types.Message

func BuildSystemPrompt

func BuildSystemPrompt() string

BuildSystemPrompt returns the complete system prompt for the classifier. This uses the default template configuration with external template support. For customization, use BuildSystemPromptWithConfig() with a custom TemplateConfig.

func BuildSystemPromptWithConfig

func BuildSystemPromptWithConfig(config *TemplateConfig) string

BuildSystemPrompt builds the complete system prompt using the template configuration. It combines the base prompt with the appropriate permissions template and applies any user-defined rules. The function returns a complete system prompt string ready for the classifier.

Parameters:

  • config: Template configuration containing rules and template selection

Returns: Complete system prompt string for the classifier

func BuildSystemPromptWithSeshatMd

func BuildSystemPromptWithSeshatMd() string

func BuildTranscriptForClassifier

func BuildTranscriptForClassifier(messages []types.Message, tools []Tool, maxChars int) string

func DumpClassifierRequest

func DumpClassifierRequest(reqID string, content string) error

DumpClassifierRequest dumps a classifier request for debugging.

func DumpClassifierResponse

func DumpClassifierResponse(reqID string, content string) error

DumpClassifierResponse dumps a classifier response for debugging.

func EnsureAutoModeDumpDir

func EnsureAutoModeDumpDir() error

EnsureAutoModeDumpDir ensures the auto mode dump directory exists.

func ExtractDefaultAllowRules

func ExtractDefaultAllowRules() []string

ExtractDefaultAllowRules extracts the default allow rules from the external template. This is used to show users the default rules and allow them to customize.

Returns: Slice of default allow rule strings

func ExtractDefaultDenyRules

func ExtractDefaultDenyRules() []string

ExtractDefaultDenyRules extracts the default deny rules from the external template.

Returns: Slice of default deny rule strings

func ExtractDefaultEnvironmentRules

func ExtractDefaultEnvironmentRules() []string

ExtractDefaultEnvironmentRules extracts the default environment rules.

Returns: Slice of default environment rule strings

func ExtractSeshatMdRules

func ExtractSeshatMdRules(content string) string

func FormatToolUseCompact

func FormatToolUseCompact(toolName string, input map[string]any) string

FormatToolUseCompact creates a compact representation of a tool use for the classifier prompt.

func GetAnthropicTemplate

func GetAnthropicTemplate() string

GetAnthropicTemplate returns the Anthropic internal template string.

func GetAutoModeClassifierErrorDumpPath

func GetAutoModeClassifierErrorDumpPath() string

GetAutoModeClassifierErrorDumpPath returns the path for dumping classifier errors. Aligned with OpenClaude's getAutoModeClassifierErrorDumpPath (yoloClassifier.ts:189).

func GetAutoModeDumpDir

func GetAutoModeDumpDir() string

GetAutoModeDumpDir returns the base directory for auto mode dumps. Aligned with OpenClaude's getAutoModeDumpDir (yoloClassifier.ts:147).

func GetAutoModeFlagCli

func GetAutoModeFlagCli() bool

GetAutoModeFlagCli returns whether auto mode was requested via CLI.

func GetBasePrompt

func GetBasePrompt() string

GetBasePrompt returns the base system prompt.

func GetExternalTemplate

func GetExternalTemplate() string

GetExternalTemplate returns the external permissions template string. This is used for tools like "seshat auto-mode defaults" to show default rules.

func GetLastClassifierTranscript

func GetLastClassifierTranscript() string

GetLastClassifierTranscript returns the last classifier transcript.

func GetSeshatMdContent

func GetSeshatMdContent() string

func GetSessionID

func GetSessionID() types.SessionID

GetSessionID returns the current session ID.

func HandleDenialLimitExceeded

func HandleDenialLimitExceeded(
	state *types.DenialTrackingState,
	config *DenialLimitConfig,
	isHeadless bool,
	classifierReason string,
) *types.PermissionResult

HandleDenialLimitExceeded checks if denial limits have been exceeded and returns an appropriate permission result. Aligned with OpenClaude's handleDenialLimitExceeded.

Parameters:

  • state: The current denial tracking state
  • config: The denial limit configuration
  • isHeadless: Whether running in headless mode
  • classifierReason: The reason from the classifier denial

Returns a PermissionResult with fallback behavior, or nil if limits not exceeded.

func HasSeshatMdContent

func HasSeshatMdContent() bool

func IsAutoModeActive

func IsAutoModeActive() bool

IsAutoModeActive returns whether auto mode is currently active.

func IsAutoModeCircuitBroken

func IsAutoModeCircuitBroken() bool

IsAutoModeCircuitBroken returns whether auto mode circuit is broken.

func IsJSONLTranscriptEnabled

func IsJSONLTranscriptEnabled() bool

func IsTwoStageClassifierEnabled

func IsTwoStageClassifierEnabled() bool

func LogAutoModeOutcome

func LogAutoModeOutcome(outcome string, model string, metadata map[string]any)

func LogError

func LogError(model string, err error, tooLong bool)

func LogParseFailure

func LogParseFailure(model string, failureKind string)

func LogSuccess

func LogSuccess(model string, durationMs int64)

func ReplaceOutputFormatWithXml

func ReplaceOutputFormatWithXml(systemPrompt string) string

func ResetForTesting

func ResetForTesting()

ResetForTesting resets all state for testing.

func SerializeTranscript

func SerializeTranscript(transcript []TranscriptEntry) []string

func SetAutoModeActive

func SetAutoModeActive(active bool)

SetAutoModeActive sets whether auto mode is currently active.

func SetAutoModeCircuitBroken

func SetAutoModeCircuitBroken(broken bool)

SetAutoModeCircuitBroken sets whether auto mode circuit is broken. When circuit is broken, auto mode cannot be re-enabled.

func SetAutoModeFlagCli

func SetAutoModeFlagCli(passed bool)

SetAutoModeFlagCli sets whether auto mode was requested via CLI.

func SetLastClassifierTranscript

func SetLastClassifierTranscript(transcript string)

SetLastClassifierTranscript stores the last classifier transcript for debugging.

func SetSeshatMdProvider

func SetSeshatMdProvider(provider SeshatMdProvider)

SetSeshatMdProvider sets the global SESHAT.md content provider. Should be called during application initialization.

func SetSessionID

func SetSessionID(id types.SessionID)

SetSessionID sets the current session ID.

func TruncateString

func TruncateString(s string, maxLen int) string

func WrapWithTranscriptTags

func WrapWithTranscriptTags(blocks []string) []string

Types

type AdvancedClassifierInterface

type AdvancedClassifierInterface interface {
	// ClassifyWithTranscript predicts if a tool use should be allowed, using conversation context.
	// The messages parameter provides transcript context for better classification.
	// Returns ClassifierResult with detailed stage information.
	ClassifyWithTranscript(ctx context.Context, toolName string, toolInput map[string]any, messages []types.Message, toolUseID string) (*ClassifierResult, error)
}

AdvancedClassifierInterface extends Classifier with transcript support. This enables the two-stage classifier with context awareness.

type AdvancedConfig

type AdvancedConfig struct {
	// TwoStageClassifier is the model name for the second-stage thinking classifier.
	// If empty, two-stage classification is disabled.
	TwoStageClassifier string

	// MaxTranscriptChars is the maximum characters to include in the transcript.
	MaxTranscriptChars int

	// UseCacheControl enables cache control headers for classifier calls.
	UseCacheControl bool

	// EnableThinking enables the thinking/reasoning token output.
	EnableThinking bool
}

AdvancedConfig holds configuration for the two-stage (advanced) classifier.

func DefaultAdvancedConfig

func DefaultAdvancedConfig() AdvancedConfig

DefaultAdvancedConfig returns the default configuration for advanced classification.

type AutoModeOutcome

type AutoModeOutcome struct {
	Outcome    string         `json:"outcome"`     // Outcome type (success/error/parse_failure)
	Model      string         `json:"model"`       // Model used for classification
	DurationMs int64          `json:"duration_ms"` // Time taken for classification
	Metadata   map[string]any `json:"metadata"`    // Additional outcome metadata
}

AutoModeOutcome represents a single classification outcome for telemetry. Tracks the result of each classification request for monitoring and debugging.

type CacheControl

type CacheControl struct {
	Type string // Cache type (typically "ephemeral")
	TTL  string // Cache TTL (e.g., "ephemeral-1-hour")
}

CacheControl represents cache control metadata for API requests. Used to enable prompt caching on classifier calls.

func GetCacheControl

func GetCacheControl(querySource string) *CacheControl

func (*CacheControl) ToAPIString

func (c *CacheControl) ToAPIString() string

type Classification

type Classification struct {
	Allowed    bool    // Whether the tool use is predicted to be safe
	Confidence float64 // Confidence level (0-1) for the prediction
	Reason     string  // Human-readable explanation for the classification
}

Classification represents the classifier's prediction.

type Classifier

type Classifier interface {
	// Classify predicts if a tool use should be allowed.
	// Returns the classification result with allowed flag, confidence, and reason.
	Classify(ctx context.Context, toolName string, input map[string]any) (Classification, error)
}

Classifier is the interface for permission classification in auto mode. The classifier predicts whether a tool use should be allowed or denied.

type ClassifierAPI

type ClassifierAPI interface {
	Classify(ctx context.Context, req *ClassifierAPIRequest) (*ClassifierAPIResponse, error)
}

ClassifierAPI interface defines the contract for classifier API clients. Implementations must provide a Classify method that processes classification requests.

type ClassifierAPIClient

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

func NewClassifierAPIClient

func NewClassifierAPIClient(client *providers.Client) *ClassifierAPIClient

func (*ClassifierAPIClient) Classify

type ClassifierAPIRequest

type ClassifierAPIRequest struct {
	Model         string
	MaxTokens     int
	System        string
	Temperature   float64
	Messages      []types.Message
	StopSequences []string
	Thinking      bool
}

type ClassifierAPIResponse

type ClassifierAPIResponse struct {
	Text       string
	Usage      *ClassifierUsage
	MessageID  string
	RequestID  string
	StopReason string
}

type ClassifierContext

type ClassifierContext struct {
	ToolName                     string
	ToolInput                    map[string]any
	Mode                         types.PermissionMode
	SessionID                    types.SessionID
	TurnID                       types.TurnID
	ToolUseID                    string
	Messages                     []types.Message
	ShouldAvoidPermissionPrompts bool // Whether to avoid permission prompts (headless mode)
	Additional                   map[string]any
	DenialTracking               *types.DenialTrackingState
}

ClassifierContext provides context for auto mode classification. This mirrors the PermissionContext structure used by the permissions engine.

type ClassifierResult

type ClassifierResult struct {
	ShouldBlock       bool             `json:"should_block"`                  // Whether action should be blocked
	Reason            string           `json:"reason"`                        // Human-readable reason
	Thinking          string           `json:"thinking,omitempty"`            // Chain-of-thought reasoning
	Model             string           `json:"model"`                         // Model used for classification
	Usage             *ClassifierUsage `json:"usage,omitempty"`               // Token usage statistics
	DurationMs        int64            `json:"duration_ms"`                   // Total classification time
	Stage             string           `json:"stage,omitempty"`               // Which stage produced result (fast/thinking)
	Unavailable       bool             `json:"unavailable,omitempty"`         // Classifier API was unavailable
	TranscriptTooLong bool             `json:"transcript_too_long,omitempty"` // Transcript exceeded context limit
	PromptLengths     PromptLengths    `json:"prompt_lengths,omitempty"`      // Prompt component lengths
	Stage1Usage       *ClassifierUsage `json:"stage1_usage,omitempty"`        // Stage 1 usage (for two-stage)
	Stage1DurationMs  int64            `json:"stage1_duration_ms,omitempty"`  // Stage 1 timing
	Stage2Usage       *ClassifierUsage `json:"stage2_usage,omitempty"`        // Stage 2 usage (for two-stage)
	Stage2DurationMs  int64            `json:"stage2_duration_ms,omitempty"`  // Stage 2 timing
}

ClassifierResult contains the complete classification result. Returned by TwoStageClassifier after processing.

type ClassifierUsage

type ClassifierUsage struct {
	InputTokens              int `json:"input_tokens"`                // Tokens in request
	OutputTokens             int `json:"output_tokens"`               // Tokens in response
	CacheReadInputTokens     int `json:"cache_read_input_tokens"`     // Tokens from cache read
	CacheCreationInputTokens int `json:"cache_creation_input_tokens"` // Tokens for cache creation
}

ClassifierUsage tracks token usage from classifier API calls. Used for telemetry and cost tracking.

func CombineUsage

func CombineUsage(a, b *ClassifierUsage) *ClassifierUsage

type Config

type Config struct {
	FailClosed bool // When true, classifier errors result in deny (fail-closed)
}

Config holds general configuration for auto mode. Note: ModeConfig in mode.go is used for the Mode struct itself. This Config is a separate type kept for potential future use.

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig returns the default auto mode configuration. FailClosed is true for security (deny on classifier errors).

type DefaultTool

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

func (DefaultTool) Aliases

func (t DefaultTool) Aliases() []string

func (DefaultTool) Name

func (t DefaultTool) Name() string

func (DefaultTool) ToAutoClassifierInput

func (t DefaultTool) ToAutoClassifierInput(input map[string]any) string

type DenialLimitConfig

type DenialLimitConfig struct {
	MaxConsecutiveDenials int // Maximum consecutive denials before fallback
	MaxTotalDenials       int // Maximum total denials before fallback
	WindowMinutes         int // Time window for tracking (currently unused)
}

DenialLimitConfig defines thresholds for auto mode fallback behavior. When these limits are exceeded, the system falls back from auto-approval to prompting the user for permission. Aligned with OpenClaude's denial tracking configuration.

func DefaultDenialLimitConfig

func DefaultDenialLimitConfig() DenialLimitConfig

DefaultDenialLimitConfig returns the default denial limit configuration. These values are aligned with OpenClaude:

  • MaxConsecutiveDenials: 3 - After 3 consecutive denials, fallback to prompting
  • MaxTotalDenials: 10 - After 10 total denials in session, fallback to prompting

func (*DenialLimitConfig) ShouldFallback

func (c *DenialLimitConfig) ShouldFallback(state *types.DenialTrackingState) bool

ShouldFallback checks if the denial limits have been exceeded. Returns true if the system should fall back from auto-approval to prompting.

type Fallback

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

Fallback handles the transition from auto-approval to prompting when denial limits are exceeded. This prevents infinite loops of classifier denials and ensures the user gets involved when the classifier is repeatedly blocking actions. Aligned with OpenClaude's fallback behavior.

func NewFallback

func NewFallback(config *DenialLimitConfig) *Fallback

NewFallback creates a new Fallback handler with the given config. If config is nil, DefaultDenialLimitConfig is used.

func (*Fallback) Apply

func (f *Fallback) Apply(state *types.DenialTrackingState, result types.PermissionResult, isHeadless bool) types.PermissionResult

Apply applies the fallback behavior to a permission result. It checks if denial limits have been exceeded and converts a denial to an ask (or deny in headless mode). Parameters:

  • state: The current denial tracking state
  • result: The original permission result
  • isHeadless: Whether running in headless mode (no UI available)

Returns the adjusted result with fallback behavior applied.

func (*Fallback) RecordSuccess

func (f *Fallback) RecordSuccess(state *types.DenialTrackingState)

RecordSuccess records a successful tool use, resetting consecutive denials. Called when a tool use is allowed to prevent false positives in the denial tracking.

type FeatureFlags

type FeatureFlags struct {
	TwoStageClassifier     bool         // Enable two-stage classifier
	TwoStageClassifierMode TwoStageMode // Which stages to run (both/fast/thinking)
	TranscriptJSONL        bool         // Use JSONL format for transcript
	CacheControl           bool         // Enable cache control headers
	ThinkingEnabled        bool         // Enable thinking/reasoning
	MaxTranscriptChars     int          // Maximum transcript character length
}

FeatureFlags holds all configurable feature flags for auto mode. These values are determined at startup from environment variables.

func GetFeatureFlags

func GetFeatureFlags() FeatureFlags

type Mode

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

Mode handles auto mode permission classification. It integrates with the permissions engine to provide classifier-based permission decisions for auto mode.

func NewMode

func NewMode(classifier Classifier, config *ModeConfig) *Mode

NewMode creates a new auto mode handler with the given classifier and config. If config is nil, DefaultModeConfig is used.

func NewModeWithAdvancedClassifier

func NewModeWithAdvancedClassifier(
	classifier Classifier,
	advancedClassifier AdvancedClassifierInterface,
	config *ModeConfig,
	advancedConfig AdvancedConfig,
) *Mode

NewModeWithAdvancedClassifier creates a new auto mode handler with both basic and advanced classifier support.

func (*Mode) Classify

func (m *Mode) Classify(ctx context.Context, pctx *ClassifierContext) (types.PermissionResult, error)

Classify determines the permission decision for a tool use in auto mode. It implements several fast-paths aligned with OpenClaude:

  • PowerShell special handling: always requires explicit permission
  • Safe-tool allowlist: read-only tools skip the classifier
  • Classifier fallback: handles classifier errors based on FailClosed
  • Denial tracking: tracks consecutive/total denials for fallback

Returns a PermissionResult indicating allow/deny/ask behavior.

func (*Mode) SetAdvancedClassifier

func (m *Mode) SetAdvancedClassifier(classifier AdvancedClassifierInterface)

SetAdvancedClassifier sets the advanced two-stage classifier.

func (*Mode) SetClassifier

func (m *Mode) SetClassifier(classifier Classifier)

SetClassifier updates the classifier used for auto mode decisions.

type ModeConfig

type ModeConfig struct {
	FailClosed bool // When true, classifier errors result in deny (fail-closed)
}

ModeConfig holds configuration for auto mode behavior.

type PromptLengths

type PromptLengths struct {
	SystemPrompt int `json:"system_prompt"` // System prompt length
	ToolCalls    int `json:"tool_calls"`    // Tool calls/transcript length
	UserPrompts  int `json:"user_prompts"`  // User messages length
}

PromptLengths tracks the character length of each prompt component. Used for debugging and context size tracking.

type SeshatMdProvider

type SeshatMdProvider func() string

SeshatMdProvider is a function type that returns the SESHAT.md content. This allows flexible integration with different file reading strategies.

type TemplateConfig

type TemplateConfig struct {
	UseExternalTemplate  bool     // Use external vs internal template
	UseAnthropicTemplate bool     // Use Anthropic internal template
	AllowRules           []string // User-defined allow rules
	DenyRules            []string // User-defined deny rules
	EnvironmentRules     []string // Environment-specific rules
}

TemplateConfig holds configuration for which template to use.

func DefaultTemplateConfig

func DefaultTemplateConfig() *TemplateConfig

DefaultTemplateConfig returns the default template configuration. By default, uses the external template (user-customizable).

type Tool

type Tool interface {
	Name() string                                      // Tool name (e.g., "Read", "Edit")
	Aliases() []string                                 // Alternative names for the tool
	ToAutoClassifierInput(input map[string]any) string // Encode input for classifier
}

Tool interface defines the contract for tool input encoding. Each tool implements ToAutoClassifierInput to provide a compact representation of its input for the classifier.

func NewDefaultTool

func NewDefaultTool(name string, aliases []string, inputFn func(map[string]any) string) Tool

type ToolRegistry

type ToolRegistry map[string]Tool

func BuildToolLookup

func BuildToolLookup(tools []Tool) ToolRegistry

func (ToolRegistry) Get

func (r ToolRegistry) Get(name string) Tool

type TranscriptBlock

type TranscriptBlock struct {
	Type  string `json:"type"`            // "text" or "tool_use"
	Text  string `json:"text,omitempty"`  // For text blocks
	Name  string `json:"name,omitempty"`  // For tool_use blocks (tool name)
	Input any    `json:"input,omitempty"` // For tool_use blocks (tool input)
}

TranscriptBlock represents a single content block within a transcript entry. Can be either user text or tool use.

type TranscriptBuilder

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

func NewTranscriptBuilder

func NewTranscriptBuilder(tools []Tool, maxChars int, jsonlEnabled bool) *TranscriptBuilder

func (*TranscriptBuilder) Build

func (tb *TranscriptBuilder) Build(messages []types.Message, action *TranscriptEntry) string

type TranscriptEntry

type TranscriptEntry struct {
	Role    string            `json:"role"`    // "user" or "assistant"
	Content []TranscriptBlock `json:"content"` // Content blocks in this entry
}

TranscriptEntry represents a single turn in the classifier transcript. Either user message or assistant tool use.

func BuildTranscriptFromMessages

func BuildTranscriptFromMessages(messages []types.Message) []TranscriptEntry

type TwoStageClassifier

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

TwoStageClassifier is the main classifier implementation. It handles both fast (stage 1) and thinking (stage 2) classification stages.

func NewTwoStageClassifier

func NewTwoStageClassifier(config *TwoStageConfig) *TwoStageClassifier

func NewTwoStageClassifierWithAPI

func NewTwoStageClassifierWithAPI(config *TwoStageConfig, apiClient ClassifierAPI) *TwoStageClassifier

func (*TwoStageClassifier) Classify

func (c *TwoStageClassifier) Classify(ctx context.Context, toolName string, toolInput map[string]any) (*Classification, error)

func (*TwoStageClassifier) ClassifyWithTranscript

func (c *TwoStageClassifier) ClassifyWithTranscript(ctx context.Context, toolName string, toolInput map[string]any, messages []types.Message, toolUseID string) (*ClassifierResult, error)

type TwoStageConfig

type TwoStageConfig struct {
	Model              string
	TwoStageMode       TwoStageMode
	MaxTranscriptChars int
	UseCacheControl    bool
	EnableThinking     bool
}

func DefaultTwoStageConfig

func DefaultTwoStageConfig() *TwoStageConfig

type TwoStageMode

type TwoStageMode string

TwoStageMode defines which stages of the classifier to run. Aligned with OpenClaude's classifier modes.

const (
	// TwoStageModeBoth runs both stage 1 and stage 2 (default).
	// Fast stage runs first; if blocked, escalates to thinking stage.
	TwoStageModeBoth TwoStageMode = "both"

	// TwoStageModeFast runs only stage 1 (fast) classifier.
	// Stage 1 verdict is final; allows <reason> in response.
	TwoStageModeFast TwoStageMode = "fast"

	// TwoStageModeThinking runs only stage 2 (thinking) classifier.
	// Skips fast stage entirely for complex decisions.
	TwoStageModeThinking TwoStageMode = "thinking"
)

type XMLParser

type XMLParser struct{}

XMLParser parses XML responses from the two-stage classifier. Aligned with OpenClaude's classifierShared.ts.

func NewXMLParser

func NewXMLParser() *XMLParser

NewXMLParser creates a new XML parser instance. Returns a pointer to a fresh XMLParser ready for use.

func (*XMLParser) ExtractToolUse

func (p *XMLParser) ExtractToolUse(toolUseID, toolName string, toolInput map[string]any) string

ExtractToolUse extracts the tool use block from the classifier prompt response. This is used to identify which tool use is being classified.

func (*XMLParser) IsParseFailure

func (p *XMLParser) IsParseFailure(response string) bool

IsParseFailure checks if the response indicates a parsing failure (response too short, malformed XML, etc.).

func (*XMLParser) ParseBlock

func (p *XMLParser) ParseBlock(response string) *bool

ParseBlock parses the <block> tag from classifier response. Returns: true (blocked), false (allowed), nil (parse error / not found).

func (*XMLParser) ParseBlockWithReason

func (p *XMLParser) ParseBlockWithReason(response string) (blocked *bool, reason string)

ParseBlockWithReason parses both block and reason from response. Returns the parsed values and whether parsing succeeded.

func (*XMLParser) ParseFullResponse

func (p *XMLParser) ParseFullResponse(response string) (blocked *bool, reason, thinking string)

ParseFullResponse parses a complete classifier response including block, reason, and thinking tags.

func (*XMLParser) ParseReason

func (p *XMLParser) ParseReason(response string) string

ParseReason extracts the <reason> tag from classifier response.

func (*XMLParser) ParseThinking

func (p *XMLParser) ParseThinking(response string) string

ParseThinking extracts the <thinking> tag from classifier response (thinking mode).

Jump to

Keyboard shortcuts

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