dino

package
v1.10.0 Latest Latest
Warning

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

Go to latest
Published: Aug 30, 2026 License: MIT Imports: 29 Imported by: 0

README

Dino - Cortex Advanced Orchestration

English | 简体中文

Dino is the advanced orchestration component of the Cortex framework. It provides enterprise-grade session management, resource budgeting, loop detection, and tool orchestration capabilities for building production-ready AI agents.


Overview

Dino extends the core Cortex agent capabilities with advanced features designed for production environments:

  • Multi-Session Management: Handle multiple concurrent user sessions with isolated context
  • Resource Budgeting: Prevent runaway costs with token, tool call, and time limits
  • Loop Detection: Automatically detect and prevent repetitive action loops
  • Tool Approval Workflows: Require human approval for dangerous operations
  • Task Queue: Built-in priority queue for batch processing
  • Planner Mode: Break down complex tasks into executable plans

Features

Session Management
  • Channel-based input/output for non-blocking communication
  • Observer pattern for real-time event subscription
  • Automatic session cleanup and resource management
Budget Control
  • Configurable token limits per session
  • Tool call count restrictions
  • Time-based budget enforcement
Loop Detection
  • Semantic similarity detection for action patterns
  • Configurable threshold and max repeat counts
  • Automatic loop prevention with user notifications
Tool System
  • Built-in tools: read_file, write_file, edit_file, bash, glob, grep, list_directory
  • Extensible tool registry
  • Dangerous tool approval workflows
  • MCP (Model Context Protocol) support
Planner Mode
  • Step-by-step plan generation before execution
  • Auto-approval option for trusted workflows
  • Plan visualization through events
Long-running tasks & harness (dino/task, dino/runner)
  • dino/task: neutral types (Task, TaskConfig, StopReason, checkpoint TaskSession, SessionSwapper, …)
  • dino/runner: DefaultTaskEngine wired to dino/harness (verify, stall, multi-outer iterations), shell/text/LLM verifiers, in-memory and blob-backed SessionStore implementations
Chat history vs structured memory (naming)
  • dino/chatstore: per-session chat transcript Provider for the factory (OpenSharedChatStore, SQLite / in-memory backends)
  • pkg/memkit: preferences, knowledge, index, PageIndex — structured memory; complements chatstore, different role
Embedding Dino in a host app (hostconfig, mem, pkg)
  • dino/hostconfig: mapstructure-friendly types for a typical host YAML (HostAppConfig, cortex/tool/MCP slices), CoalesceDinoFromHost (merge into dino.Config), ExpandConfigPath, MCP entries → dino.MCP (MergeMCPServersIntoDino), and ListMCPTools / ListMCPToolsFromToolConfigs for capability discovery. No goclaw import.
  • dino/mem: optional memory ingest loop and memory tool wiring over shared chat SQLite + memkit; host supplies LLM factory, paths, and logging via options.
  • dino/pkg: small non-config helpers only, e.g. user-echo skip (MarkPendingUserEcho / TakePendingUserEchoMatch) and scheduler tools bound to a chat session id.

Installation

go get github.com/xichan96/cortex/dino

Quick Start

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/xichan96/cortex/dino"
)

func main() {
    // 1. Create configuration
    cfg := dino.DefaultConfig()
    cfg.Provider.APIKey = "your-api-key"
    cfg.WorkspaceRoot = "/path/to/workspace"

    // 2. Create factory
    factory, err := dino.NewDinoFactory(cfg)
    if err != nil {
        log.Fatal(err)
    }
    defer factory.Shutdown(context.Background())

    // 3. Create client
    client := dino.NewClient(factory)

    // 4. Create session
    session, err := client.CreateSession(context.Background(), "session-1")
    if err != nil {
        log.Fatal(err)
    }

    // 5. Send message and get response
    ctx := context.Background()
    event, err := session.SendAndWait(ctx, "List files in the current directory")
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("Response:", event.Content)
}

Configuration

# dino.yaml
default_model: gpt-4o-mini
default_provider: openai
temperature: 0.7
max_tokens: 4096
timeout: 30s
max_iterations: 10

workspace_root: "."

# Tool configuration
tools:
  allowed:
    - read_file
    - write_file
    - edit_file
    - glob
    - grep
    - bash
    - list_directory
  approval_required:
    - bash
    - write_file
    - edit_file

# Loop detection
loop_detection:
  enabled: true
  max_repeats: 3
  similarity_threshold: 0.8

# Budget control
budget:
  enabled: true
  max_tokens: 100000
  max_tool_calls: 50
  max_time_ms: 300000

# Planner mode
planner_mode:
  enabled: false
  prompt_plan: "First, analyze the task and create a step-by-step plan."
  auto_approve: false

Advanced Usage

With Stream Events
type StreamHandler struct{}

func (h *StreamHandler) SendStreamEvent(sessionID string, event interface{}) {
    // Handle stream events
}

factory, _ := dino.NewDinoFactory(cfg, dino.WithStreamEventSender(handler))
With Task Queue
import "github.com/xichan96/cortex/dino/queue"

session, _ := client.CreateSession(ctx, "queue-session", dino.WithQueueEnabled(100, 10))
resultChan, _ := session.Enqueue("task 1", queue.PriorityNormal)
result := <-resultChan
With Event Observers
session.SubscribeFunc(func(event *dino.Event) {
    switch event.Type {
    case dino.EventTypeMessage:
        fmt.Println("Message:", event.Content)
    case dino.EventTypeThinking:
        fmt.Println("Thinking:", event.Thinking)
    case dino.EventTypeToolCall:
        fmt.Println("Tool:", event.ToolName)
    case dino.EventTypeDone:
        fmt.Println("Done")
    }
})

Core Types

Type Description
Client Main entry point for session management
Session Represents a single user conversation
Config Configuration for Dino factory
Event Real-time event during execution
Skill Custom prompt template for specific tasks
Budget Resource usage tracking and limits

Architecture

dino/
├── client.go        # Client and session management
├── factory.go       # Session factory, tool registry, budget
├── config.go        # Configuration types
├── defined_tool.go  # DefinedTool, ToolContext, ApprovalStore
├── types.go         # Core type definitions
├── bus.go           # Event bus
├── session/         # Session implementation
│   ├── session.go   # Core session logic
│   ├── event.go     # Event definitions
│   ├── info.go      # Session info
│   └── planner.go   # Planner helper
├── queue/           # Task queue
├── task/            # Long-task types (Task, StopReason, SessionStore)
├── runner/          # Outer-loop engine, verifiers, checkpoint stores
├── chatstore/       # Session chat transcript Provider (SQLite / in-memory)
├── hostconfig/      # Host YAML shapes + CoalesceDinoFromHost + MCP listing helpers
├── mem/             # Memory ingest loop + memory tools (host-injected deps)
├── pkg/             # Echo-skip + scheduler session tool wrappers
├── permission/      # Tool permission
├── agent/           # Subagent and prompts
└── tools/           # Registry, builtin, skill, MCP

License

MIT License - see LICENSE for details.

Documentation

Index

Constants

View Source
const (
	EventSessionCreated = "session.created"
	EventSessionUpdated = "session.updated"
	EventSessionDeleted = "session.deleted"
	EventSessionError   = "session.error"

	EventMessageCreated = "message.created"
	EventMessageUpdated = "message.updated"
	EventMessageDeleted = "message.deleted"

	EventToolInvoked = "tool.invoked"
	EventToolResult  = "tool.result"
	EventToolError   = "tool.error"

	EventUsageUpdated = "usage.updated"

	EventApprovalRequired = "approval.required"
	EventApprovalGiven    = "approval.given"
	EventApprovalDenied   = "approval.denied"

	EventPermissionAsked = "permission.asked"
	EventPermissionReply = "permission.reply"
)
View Source
const (
	EventTypeMessage    = session.EventTypeMessage
	EventTypeThinking   = session.EventTypeThinking
	EventTypeToolCall   = session.EventTypeToolCall
	EventTypeToolResult = session.EventTypeToolResult
	EventTypeToolStart  = session.EventTypeToolStart
	EventTypeTokenUsage = session.EventTypeTokenUsage
	EventTypeError      = session.EventTypeError
	EventTypeDone       = session.EventTypeDone
	EventTypeApproved   = session.EventTypeApproved
	EventTypeApproval   = session.EventTypeApproval
	EventTypePlan       = session.EventTypePlan
	EventTypePlanStep   = session.EventTypePlanStep
	EventTypeQuestion   = session.EventTypeQuestion

	StreamEventContent    = session.EventTypeMessage
	StreamEventReasoning  = session.EventTypeThinking
	StreamEventToolCall   = session.EventTypeToolCall
	StreamEventToolResult = session.EventTypeToolResult
	StreamEventError      = session.EventTypeError
	StreamEventDone       = session.EventTypeDone
	StreamEventApproval   = session.EventTypeApproval

	EventSourceUser     = session.EventSourceUser
	EventSourceSubagent = session.EventSourceSubagent
)

Variables

This section is empty.

Functions

func ClearProviderRegistry

func ClearProviderRegistry()

func ConfigurePromptCache added in v1.10.0

func ConfigurePromptCache(provider types.LLMProvider, opts types.PromptCacheOptions)

ConfigurePromptCache applies prompt caching to a provider that supports it. It is a no-op for providers that don't implement types.PromptCacheConfigurer (OpenAI/DeepSeek/Volce — no cache_control protocol).

func GetRegisteredProviders

func GetRegisteredProviders() []string

func HasSubscribers

func HasSubscribers(eventType string) bool

func NewAgentInput

func NewAgentInput(text string) types.AgentInput

func Publish

func Publish(eventType string, sessionID string, data interface{})

func RegisterLLMProvider

func RegisterLLMProvider(name string, factory LLMProviderFactory)

func SetGlobalBus

func SetGlobalBus(bus *Bus)

func Subscribe

func Subscribe(eventType string, handler func(BusEvent))

func SubscribeAsync

func SubscribeAsync(eventType string, handler func(BusEvent), transactional bool)

func SubscribeOnce

func SubscribeOnce(eventType string, handler func(BusEvent))

func SubscribeOnceAsync

func SubscribeOnceAsync(eventType string, handler func(BusEvent))

func Unsubscribe

func Unsubscribe(eventType string, handler func(BusEvent)) bool

func ValidateConfig added in v1.10.0

func ValidateConfig(cfg *Config) error

ValidateConfig 在构造 DinoFactory 前做配置校验,让配置错误尽早、清晰暴露 (而不是等到 createLLMProvider 时才报笼统的 provider not found)。

func WaitAsync

func WaitAsync()

Types

type ApprovalError

type ApprovalError string
const (
	ErrApprovalTimeout      ApprovalError = "approval timeout"
	ErrApprovalNotAvailable ApprovalError = "approval not available in this context"
)

func (ApprovalError) Error

func (e ApprovalError) Error() string

type ApprovalRejectedError added in v1.10.0

type ApprovalRejectedError = dinoTools.ApprovalRejectedError

ApprovalRejectedError marks a user denial of a tool approval. It is an unrecoverable user veto: feeding it back to the model as a recoverable {ok:false} result would make the model retry the very tool the user just refused, looping until the doom detector fires. Wrappers (nonFatalTool) must pass it through as a real error so the engine surfaces the veto instead of resuming the loop. Defined in dino/tools so both the approval wrappers here and nonFatalTool (in dino/tools) can share it without an import cycle.

type ApprovalSender

type ApprovalSender interface {
	SendToolApprovalRequest(sessionID, requestID, toolName, arguments string)
	SendToolApprovalResponse(sessionID, requestID, toolName string, approved bool)
}

type ApprovalStore

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

ApprovalStore gates tool execution on user approval via ApprovalSender. Call SetSender before any tool that uses ActionAsk runs; if sender is nil, RequestApproval returns ErrApprovalNotAvailable immediately.

func NewApprovalStore

func NewApprovalStore(timeout time.Duration) *ApprovalStore

func (*ApprovalStore) Clear

func (s *ApprovalStore) Clear()

func (*ApprovalStore) RequestApproval

func (s *ApprovalStore) RequestApproval(
	ctx context.Context,
	sessionID,
	toolName,
	arguments string,
) (approved bool, err error)

func (*ApprovalStore) Respond

func (s *ApprovalStore) Respond(requestID string, approved bool) bool

Respond delivers an approval decision to the pending RequestApproval waiter. It returns true if the decision was delivered, false if the requestID is unknown/cleaned up or the delivery timed out. Unlike the previous select-default drop, it blocks (up to approvalRespondTimeout) so a response is never silently lost while the waiter is still alive.

func (*ApprovalStore) SetSender

func (s *ApprovalStore) SetSender(sender ApprovalSender)

type ApprovalTool

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

func NewApprovalTool

func NewApprovalTool(inner types.Tool, sessionID string, store *ApprovalStore, dangerous map[string]bool) *ApprovalTool

func (*ApprovalTool) Description

func (a *ApprovalTool) Description() string

func (*ApprovalTool) Execute

func (a *ApprovalTool) Execute(ctx context.Context, input map[string]interface{}) (interface{}, error)

func (*ApprovalTool) Metadata

func (a *ApprovalTool) Metadata() types.ToolMetadata

func (*ApprovalTool) Name

func (a *ApprovalTool) Name() string

func (*ApprovalTool) RequiresApproval

func (a *ApprovalTool) RequiresApproval() bool

func (*ApprovalTool) Schema

func (a *ApprovalTool) Schema() map[string]interface{}

type AssistantMeta

type AssistantMeta struct {
	System   []string      `json:"system"`
	ModelID  string        `json:"model_id"`
	Provider string        `json:"provider"`
	Path     AssistantPath `json:"path"`
	Cost     float64       `json:"cost"`
	Summary  bool          `json:"summary,omitempty"`
	Tokens   TokenInfo     `json:"tokens"`
}

type AssistantPath

type AssistantPath struct {
	CWD  string `json:"cwd"`
	Root string `json:"root"`
}

type Budget

type Budget = agentutils.Budget

func NewBudget

func NewBudget(cfg *BudgetConfig) Budget

type BudgetConfig

type BudgetConfig struct {
	Enabled      bool  `yaml:"enabled"`
	MaxTokens    int   `yaml:"max_tokens"`
	MaxToolCalls int   `yaml:"max_tool_calls"`
	MaxTimeMs    int64 `yaml:"max_time_ms"`
}

type BudgetRequest

type BudgetRequest = agentutils.BudgetRequest

type BudgetResult

type BudgetResult = agentutils.BudgetResult

type BudgetState

type BudgetState = agentutils.BudgetState

type Bus

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

func GetGlobalBus

func GetGlobalBus() *Bus

func NewBus

func NewBus() *Bus

func (*Bus) HasSubscribers

func (b *Bus) HasSubscribers(eventType string) bool

func (*Bus) Publish

func (b *Bus) Publish(eventType string, sessionID string, data interface{})

func (*Bus) Subscribe

func (b *Bus) Subscribe(eventType string, handler func(BusEvent))

func (*Bus) SubscribeAsync

func (b *Bus) SubscribeAsync(eventType string, handler func(BusEvent), transactional bool)

func (*Bus) SubscribeOnce

func (b *Bus) SubscribeOnce(eventType string, handler func(BusEvent))

func (*Bus) SubscribeOnceAsync

func (b *Bus) SubscribeOnceAsync(eventType string, handler func(BusEvent))

func (*Bus) Unsubscribe

func (b *Bus) Unsubscribe(eventType string, handler func(BusEvent)) bool

func (*Bus) WaitAsync

func (b *Bus) WaitAsync()

type BusEvent

type BusEvent struct {
	Type      string      `json:"type"`
	SessionID string      `json:"session_id"`
	Data      interface{} `json:"data,omitempty"`
}

type Client

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

func NewClient

func NewClient(factory DinoFactory, opts ...ClientOption) *Client

func (*Client) CloseAll

func (c *Client) CloseAll()

func (*Client) CloseSession

func (c *Client) CloseSession(sessionID string)

func (*Client) CreateSession

func (c *Client) CreateSession(ctx context.Context, sessionID string) (*ClientSession, error)

func (*Client) GetSession

func (c *Client) GetSession(sessionID string) *ClientSession

func (*Client) ListSessions

func (c *Client) ListSessions() []string

type ClientOption

type ClientOption func(*clientConfig)

func WithSessionBufferSize

func WithSessionBufferSize(size int) ClientOption

func WithSessionQueueEnabled

func WithSessionQueueEnabled(maxSize, maxPending int) ClientOption

type ClientSession

type ClientSession struct {
	*Session
	// contains filtered or unexported fields
}

func (*ClientSession) Close

func (cs *ClientSession) Close()

func (*ClientSession) Done

func (cs *ClientSession) Done() <-chan struct{}

func (*ClientSession) Err

func (cs *ClientSession) Err() <-chan error

func (*ClientSession) Handler

func (cs *ClientSession) Handler() *HandlerBuilder

func (*ClientSession) Input

func (cs *ClientSession) Input() chan<- interface{}

func (*ClientSession) Output

func (cs *ClientSession) Output() <-chan *Event

func (*ClientSession) Send

func (cs *ClientSession) Send(ctx context.Context, input types.AgentInput) error

func (*ClientSession) SendAndWait

func (cs *ClientSession) SendAndWait(ctx context.Context, input types.AgentInput) (*Event, error)

func (*ClientSession) Subscribe

func (cs *ClientSession) Subscribe(observer Observer) string

func (*ClientSession) SubscribeFunc

func (cs *ClientSession) SubscribeFunc(fn func(*Event)) string

func (*ClientSession) Unsubscribe

func (cs *ClientSession) Unsubscribe(id string)

type Config

type Config struct {
	DefaultModel          string                                                            `yaml:"default_model"`
	DefaultProvider       string                                                            `yaml:"default_provider"`
	Temperature           float32                                                           `yaml:"temperature"`
	MaxTokens             int                                                               `yaml:"max_tokens"`
	TopP                  float32                                                           `yaml:"top_p"`
	Timeout               time.Duration                                                     `yaml:"timeout"`
	SystemPrompt          string                                                            `yaml:"system_prompt"`
	MaxIterations         int                                                               `yaml:"max_iterations"`
	MaxSessions           int                                                               `yaml:"max_sessions"`
	ToolExecutionTimeout  time.Duration                                                     `yaml:"tool_execution_timeout"`
	ToolTimeouts          map[string]time.Duration                                          `yaml:"tool_timeouts"`
	ToolTimeoutCalculator func(toolName string, input map[string]interface{}) time.Duration `json:"-" yaml:"-"`
	LoopDetection         LoopDetectionConfig                                               `yaml:"loop_detection"`
	Budget                BudgetConfig                                                      `yaml:"budget"`
	Tools                 ToolConfig                                                        `yaml:"tools"`
	Permission            map[string]interface{}                                            `yaml:"permission"`
	WorkspaceRoot         string                                                            `yaml:"workspace_root"`
	Skills                SkillsConfig                                                      `yaml:"skills"`
	Provider              ProviderConfig                                                    `yaml:"provider"`
	PlannerMode           PlannerModeConfig                                                 `yaml:"planner_mode"`
	Memory                MemoryConfig                                                      `yaml:"memory"`
	PromptCaching         PromptCachingConfig                                               `yaml:"prompt_caching"`
	LongTermMemory        MemLongTermConfig                                                 `yaml:"long_term_memory"`
	Subagent              agent.SubagentConfig                                              `yaml:"subagent"`
	MCP                   MCPConfig                                                         `yaml:"mcp"`
	Trace                 TraceConfig                                                       `yaml:"trace"`
}

func CloneConfig added in v1.9.1

func CloneConfig(cfg *Config) (*Config, error)

func DefaultConfig

func DefaultConfig() *Config

func (*Config) PromptCacheOptions added in v1.10.0

func (c *Config) PromptCacheOptions() types.PromptCacheOptions

PromptCacheOptions maps dino's PromptCachingConfig onto the shared types.PromptCacheOptions, starting from provider defaults so partial YAML overrides don't zero unrelated toggles.

type Cost

type Cost = agentutils.Cost

type DefinedTool

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

func DefinedToolFromAgent

func DefinedToolFromAgent(agentTool types.Tool) *DefinedTool

func DefinedToolFromJSON

func DefinedToolFromJSON(jsonStr string) (*DefinedTool, error)

func NewDefinedTool

func NewDefinedTool(id, name, description string, executor ToolExecutor) *DefinedTool

func (*DefinedTool) Description

func (t *DefinedTool) Description() string

func (*DefinedTool) Execute

func (t *DefinedTool) Execute(ctx context.Context, input map[string]interface{}) (interface{}, error)

func (*DefinedTool) Metadata

func (t *DefinedTool) Metadata() types.ToolMetadata

func (*DefinedTool) Name

func (t *DefinedTool) Name() string

func (*DefinedTool) Schema

func (t *DefinedTool) Schema() map[string]interface{}

func (*DefinedTool) ToAgentTool

func (t *DefinedTool) ToAgentTool() types.Tool

func (*DefinedTool) ToJSON

func (t *DefinedTool) ToJSON() (string, error)

func (*DefinedTool) WithParameters

func (t *DefinedTool) WithParameters(params map[string]interface{}) *DefinedTool

type DinoFactory

type DinoFactory interface {
	CreateSession(ctx context.Context, sessionID string, opts ...session.Option) (*session.Session, error)
	GetSession(sessionID string) *session.Session
	CloseSession(sessionID string)
	CloseAll()
	GetTools() []types.Tool
	GetSkills() []*Skill
	Shutdown(ctx context.Context) error
	GetLLMProvider() types.LLMProvider
	GetPlannerConfig() *PlannerModeConfig
	Budget() Budget
	RespondToolApproval(requestID string, approved bool)
	SaveSessionSnapshot(ctx context.Context, sessionID string, dir string) (string, error)
	RestoreSessionSnapshot(ctx context.Context, sessionID string, snapPath string) error
}

func NewDinoFactory

func NewDinoFactory(cfg *Config, opts ...FactoryOption) (DinoFactory, error)

type Event

type Event = session.Event

type EventHandler

type EventHandler func(event *Event)

type EventSource added in v1.10.0

type EventSource = session.EventSource

type EventType

type EventType = session.EventType

type ExecuteRequest

type ExecuteRequest struct {
	SessionID         string
	Content           string
	Files             []FileAttachment
	ExtraSystemPrompt string
	Stream            bool
}

type ExecuteResponse

type ExecuteResponse = session.ExecuteResponse

type ExternalPathApprovalTool added in v1.8.10

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

func NewExternalPathApprovalTool added in v1.8.10

func NewExternalPathApprovalTool(inner types.Tool, workspace, sessionID string, store *ApprovalStore) *ExternalPathApprovalTool

func (*ExternalPathApprovalTool) Description added in v1.8.10

func (e *ExternalPathApprovalTool) Description() string

func (*ExternalPathApprovalTool) Execute added in v1.8.10

func (e *ExternalPathApprovalTool) Execute(ctx context.Context, input map[string]interface{}) (interface{}, error)

func (*ExternalPathApprovalTool) Metadata added in v1.8.10

func (*ExternalPathApprovalTool) Name added in v1.8.10

func (e *ExternalPathApprovalTool) Name() string

func (*ExternalPathApprovalTool) Schema added in v1.8.10

func (e *ExternalPathApprovalTool) Schema() map[string]interface{}

type FactoryOption

type FactoryOption func(*dinoFactory)

func WithApprovalSender added in v1.8.10

func WithApprovalSender(sender ApprovalSender) FactoryOption

func WithHooks added in v1.9.3

func WithHooks(h hooks.Hooks) FactoryOption

WithHooks sets lifecycle hooks that will be applied to every session created by this factory. This is a convenience alternative to calling session.GetAgent().SetHooks() after CreateSession.

func WithSessionTools added in v1.8.9

func WithSessionTools(fn func(sessionID string) []types.Tool) FactoryOption

func WithStreamEventSender

func WithStreamEventSender(sender StreamEventSender) FactoryOption

type FileAttachment

type FileAttachment struct {
	Path    string
	Name    string
	Content []byte
}

type FilePart

type FilePart struct {
	Type      string `json:"type"`
	MediaType string `json:"media_type"`
	Filename  string `json:"filename,omitempty"`
	URL       string `json:"url"`
}

type HandlerBuilder

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

func (*HandlerBuilder) Build

func (hb *HandlerBuilder) Build() string

func (*HandlerBuilder) OnApproval

func (hb *HandlerBuilder) OnApproval(fn func(toolName string, approved bool)) *HandlerBuilder

func (*HandlerBuilder) OnDone

func (hb *HandlerBuilder) OnDone(fn func()) *HandlerBuilder

func (*HandlerBuilder) OnError

func (hb *HandlerBuilder) OnError(fn func(err string)) *HandlerBuilder

func (*HandlerBuilder) OnMessage

func (hb *HandlerBuilder) OnMessage(fn func(content string)) *HandlerBuilder

func (*HandlerBuilder) OnQuestion added in v1.10.0

func (hb *HandlerBuilder) OnQuestion(fn func(question string, toolCallID string)) *HandlerBuilder

OnQuestion 注册 question 工具提问回调(P2.1)。question 工具被调用且返回 SentinelQuestionResult 时触发,调用方可把问题展示给用户。

func (*HandlerBuilder) OnSubagentMessage added in v1.10.0

func (hb *HandlerBuilder) OnSubagentMessage(fn func(content string)) *HandlerBuilder

OnSubagentMessage 注册子代理完成唤醒注入消息的回调(S4/B2)。不注册时这些 "幽灵消息"被折叠(默认不喷 UI);注册后由调用方决定如何展示。

func (*HandlerBuilder) OnThinking

func (hb *HandlerBuilder) OnThinking(fn func(thinking string)) *HandlerBuilder

func (*HandlerBuilder) OnToolCall

func (hb *HandlerBuilder) OnToolCall(fn func(toolName string, input map[string]interface{})) *HandlerBuilder

func (*HandlerBuilder) OnToolResult

func (hb *HandlerBuilder) OnToolResult(fn func(toolName string, output interface{})) *HandlerBuilder

type LLMProviderFactory

type LLMProviderFactory func(config *Config) (types.LLMProvider, error)

type LoopDetectionConfig

type LoopDetectionConfig struct {
	Enabled             bool    `yaml:"enabled"`
	MaxRepeats          int     `yaml:"max_repeats"`
	SimilarityThreshold float64 `yaml:"similarity_threshold"`
	InputMaxRepeats     int     `yaml:"input_max_repeats"`
}

type MCPConfig

type MCPConfig struct {
	Enabled bool                       `yaml:"enabled"`
	Servers map[string]MCPServerConfig `yaml:"servers"`
}

type MCPServerConfig

type MCPServerConfig struct {
	Type    string            `yaml:"type"` // "remote" | "stdio"
	URL     string            `yaml:"url,omitempty"`
	Command string            `yaml:"command,omitempty"`
	Args    []string          `yaml:"args,omitempty"`
	Env     map[string]string `yaml:"env,omitempty"`
	Headers map[string]string `yaml:"headers,omitempty"`
	Timeout time.Duration     `yaml:"timeout,omitempty"`
	OAuth   *OAuthConfig      `yaml:"oauth,omitempty"`
	Enabled bool              `yaml:"enabled"`
}

type MemLongTermConfig added in v1.10.0

type MemLongTermConfig = mem.MemLongTermConfig

MemLongTermConfig 长期记忆配置段。定义在 dino/mem 包(避免 import cycle), 这里按原样引用。

type MemoryConfig

type MemoryConfig struct {
	EnableCompress     bool   `yaml:"enable_compress"`
	EnableLLMCompress  bool   `yaml:"enable_llm_compress"` // 压缩是否走 LLM 摘要(Hybrid 包裹);false 退回 DeterministicCompact。与 EnableCompress(是否压缩)语义正交
	MaxHistoryMessages int    `yaml:"max_history_messages"`
	MaxBudgetTokens    int    `yaml:"max_budget_tokens"`
	CompactAfterTurns  int    `yaml:"compact_after_turns"`
	CompressThreshold  int    `yaml:"compress_threshold"` // message-count gate for async compress; if <=0, CreateSession uses budget.max_tool_calls/2 then agent default
	KeepRecentCount    int    `yaml:"keep_recent_count"`
	PersistDirectory   string `yaml:"persist_directory"`
	PersistFileName    string `yaml:"persist_file_name"`
	PersistEnabled     bool   `yaml:"persist_enabled"`
	Type               string `yaml:"type"` // "memory" or "sqlite"
	// CompactionPrefix enables prefix-preserving compaction (P3.1 · prompt
	// caching Step 4): trimHistoryToTokenBudget keeps a head cache anchor and
	// preserves the recent tail verbatim, replacing the middle with a summary,
	// so prompt-cache segments 1-2 (system+tools) survive compaction. Default
	// off (conservative): the trim output structure changes when on.
	CompactionPrefix bool `yaml:"compaction_prefix"`
	// CacheAnchorTokens caps the head-cache-anchor budget (tokens). 0 = no
	// anchor (the head is trimmed like today). Default 0. Suggest ≤30% of
	// MaxBudgetTokens so the tail keeps enough room to anchor segment 3 (R5).
	CacheAnchorTokens int `yaml:"cache_anchor_tokens"`
}

type Message

type Message struct {
	ID       string           `json:"id"`
	Role     MessageRole      `json:"role"`
	Parts    []Part           `json:"parts"`
	Metadata *MessageMetadata `json:"metadata,omitempty"`
}

func NewMessage

func NewMessage(id string, role MessageRole, sessionID string) *Message

func (*Message) AddReasoning

func (m *Message) AddReasoning(text string)

func (*Message) AddText

func (m *Message) AddText(text string)

func (*Message) AddToolCall

func (m *Message) AddToolCall(toolCallID, toolName string, args map[string]interface{})

func (*Message) AddToolResult

func (m *Message) AddToolResult(toolCallID, toolName, result string)

func (*Message) Complete

func (m *Message) Complete()

func (*Message) GetReasoning

func (m *Message) GetReasoning() string

func (*Message) GetText

func (m *Message) GetText() string

func (*Message) GetToolCalls

func (m *Message) GetToolCalls() []ToolInvocation

func (*Message) GetToolResults

func (m *Message) GetToolResults() []ToolInvocation

type MessageError

type MessageError struct {
	Name    string `json:"name"`
	Message string `json:"message"`
}

type MessageInfo

type MessageInfo struct {
	Role    string
	Content string
	Parts   []PartInfo
}

type MessageMetadata

type MessageMetadata struct {
	Time      MessageTime         `json:"time"`
	Error     *MessageError       `json:"error,omitempty"`
	SessionID string              `json:"session_id"`
	Tool      map[string]ToolMeta `json:"tool,omitempty"`
	Assistant *AssistantMeta      `json:"assistant,omitempty"`
	Snapshot  string              `json:"snapshot,omitempty"`
}

type MessageRole

type MessageRole string
const (
	RoleUser      MessageRole = "user"
	RoleAssistant MessageRole = "assistant"
)

type MessageTime

type MessageTime struct {
	Created   int64 `json:"created"`
	Completed int64 `json:"completed,omitempty"`
}

type OAuthConfig

type OAuthConfig struct {
	ClientID     string `yaml:"client_id"`
	ClientSecret string `yaml:"client_secret"`
	Scope        string `yaml:"scope"`
}

type Observer

type Observer = session.Observer

type ObserverFunc

type ObserverFunc = session.ObserverFunc

type OutputObserver added in v1.9.1

type OutputObserver = session.OutputObserver

type Part

type Part interface {
	// contains filtered or unexported methods
}

type PartInfo

type PartInfo struct {
	Type   string
	Text   string
	Tool   string
	CallID string
	State  ToolState
	Input  map[string]interface{}
	Output string
	Error  string
}

type PermissionRequest

type PermissionRequest struct {
	Permission string
	SessionID  string
	Input      map[string]interface{}
	Metadata   map[string]interface{}
}

type Plan

type Plan = session.Plan

type PlanStep

type PlanStep = session.PlanStep

type PlannerModeConfig

type PlannerModeConfig struct {
	Enabled     bool   `yaml:"enabled"`
	PromptPlan  string `yaml:"prompt_plan"`
	AutoApprove bool   `yaml:"auto_approve"`
}

type PromptCachingConfig added in v1.10.0

type PromptCachingConfig struct {
	Enabled          bool  `yaml:"enabled"` // default true (pure cost optimization)
	SystemBreakpoint *bool `yaml:"system_breakpoint,omitempty"`
	ToolsBreakpoint  *bool `yaml:"tools_breakpoint,omitempty"`
	HistoryEveryN    *int  `yaml:"history_every_n,omitempty"` // history breakpoint budget (≤ remaining of 4); 0 = none
	MinCacheTokens   *int  `yaml:"min_cache_tokens,omitempty"`
}

PromptCachingConfig controls provider prompt caching. nil sub-fields mean "use the provider default" (see types.DefaultPromptCacheOptions). This lets a partial YAML block (e.g. only `enabled: false`) override just that field instead of silently zeroing the other toggles.

type ProviderConfig

type ProviderConfig struct {
	Type    string            `yaml:"type"`
	APIKey  string            `yaml:"api_key"`
	BaseURL string            `yaml:"base_url"`
	Models  map[string]string `yaml:"models"`
	Headers map[string]string `yaml:"headers"`
}

type ProviderError

type ProviderError string
const ErrProviderNotFound ProviderError = "provider not found"

func (ProviderError) Error

func (e ProviderError) Error() string

type ReasoningPart

type ReasoningPart struct {
	Type             string                 `json:"type"`
	Text             string                 `json:"text"`
	ProviderMetadata map[string]interface{} `json:"provider_metadata,omitempty"`
}

type Session

type Session = session.Session

type SessionLister

type SessionLister interface {
	ListSessions() []string
}

type SessionOption

type SessionOption = session.Option

func WithInputBufferSize

func WithInputBufferSize(size int) SessionOption

func WithOutputBufferSize

func WithOutputBufferSize(size int) SessionOption

func WithPlannerEnabled

func WithPlannerEnabled(enabled bool, prompt string, autoApprove bool) SessionOption

func WithQueueEnabled

func WithQueueEnabled(maxSize, maxPending int) SessionOption

type Skill

type Skill struct {
	Name        string `json:"name"`
	Description string `json:"description"`
	Prompt      string `json:"prompt"`
}

type SkillsConfig

type SkillsConfig struct {
	Path     string `yaml:"path"`
	AutoLoad bool   `yaml:"auto_load"`
}

type SourceURLPart

type SourceURLPart struct {
	Type             string                 `json:"type"`
	SourceID         string                 `json:"source_id"`
	URL              string                 `json:"url"`
	Title            string                 `json:"title,omitempty"`
	ProviderMetadata map[string]interface{} `json:"provider_metadata,omitempty"`
}

type StepStartPart

type StepStartPart struct {
	Type string `json:"type"`
}

type StreamEvent

type StreamEvent = session.Event

type StreamEventSender

type StreamEventSender interface {
	SendStreamEvent(sessionID string, event interface{})
}

type TextPart

type TextPart struct {
	Type string `json:"type"`
	Text string `json:"text"`
}

type TokenCache

type TokenCache struct {
	Read  int `json:"read"`
	Write int `json:"write"`
}

type TokenInfo

type TokenInfo struct {
	Input     int        `json:"input"`
	Output    int        `json:"output"`
	Reasoning int        `json:"reasoning"`
	Cache     TokenCache `json:"cache"`
}

type ToolCallInfo

type ToolCallInfo = session.ToolCallInfo

type ToolConfig

type ToolConfig struct {
	Profile                     string   `yaml:"profile"`
	Allowed                     []string `yaml:"allowed"`
	ApprovalRequired            []string `yaml:"approval_required"`
	Denied                      []string `yaml:"denied"`
	MaxToolParallelism          int      `yaml:"max_tool_parallelism,omitempty"`            // 0=默认 max(4, GOMAXPROCS*2);>0 用该值
	StreamBufferSize            int      `yaml:"stream_buffer_size,omitempty"`              // 0=默认 50
	ResultLimiterMaxBytes       int      `yaml:"result_limiter_max_bytes,omitempty"`        // 0=默认 120_000
	ResultLimiterMaxStringBytes int      `yaml:"result_limiter_max_string_bytes,omitempty"` // 0=默认 60_000
	// ToolSearchEnabled 控制是否注入 tool_search 工具并启用 Deferred 工具的
	// 延迟发现(E2)。默认 true。
	ToolSearchEnabled bool `yaml:"tool_search_enabled,omitempty"`
	// MCPDeferred 为 true 时,所有 MCP 工具以 ExposureDeferred 注册(不进初始
	// 工具列表,靠 tool_search 发现)。默认 false 灰度,稳定后翻 true(§2.5)。
	MCPDeferred bool `yaml:"mcp_deferred,omitempty"`
	// MaxDiscoveredTools 每个 session 可通过 tool_search 发现/注入的 Deferred
	// 工具上限(R1)。0 = 默认 32;<0 = 不设上限。
	MaxDiscoveredTools int `yaml:"max_discovered_tools,omitempty"`
}

type ToolContext

type ToolContext struct {
	SessionID string
	MessageID string
	Agent     string
	Abort     <-chan struct{}
	CallID    string
	Extra     map[string]interface{}
	Messages  []MessageInfo
	Metadata  func(title string, metadata map[string]interface{})
	Ask       func(request PermissionRequest) error
}

type ToolDefinition

type ToolDefinition struct {
	ID          string
	Name        string
	Description string
	Parameters  map[string]interface{}
	Metadata    ToolMetadataExt
}

type ToolExecutor

type ToolExecutor func(args map[string]interface{}, ctx ToolContext) (*ToolResult, error)

type ToolInvocation

type ToolInvocation struct {
	State      ToolInvocationState    `json:"state"`
	Step       int                    `json:"step,omitempty"`
	ToolCallID string                 `json:"tool_call_id"`
	ToolName   string                 `json:"tool_name"`
	Args       map[string]interface{} `json:"args,omitempty"`
	Result     string                 `json:"result,omitempty"`
}

type ToolInvocationPart

type ToolInvocationPart struct {
	Type           string         `json:"type"`
	ToolInvocation ToolInvocation `json:"tool_invocation"`
}

type ToolInvocationState

type ToolInvocationState string
const (
	ToolStateCall        ToolInvocationState = "call"
	ToolStatePartialCall ToolInvocationState = "partial-call"
	ToolStateResult      ToolInvocationState = "result"
)

type ToolMeta

type ToolMeta struct {
	Title    string                 `json:"title"`
	Snapshot string                 `json:"snapshot,omitempty"`
	Time     ToolMetaTime           `json:"time"`
	Extra    map[string]interface{} `json:"extra,omitempty"`
}

type ToolMetaTime

type ToolMetaTime struct {
	Start int64 `json:"start"`
	End   int64 `json:"end,omitempty"`
}

type ToolMetadataExt

type ToolMetadataExt struct {
	Title       string                 `json:"title,omitempty"`
	Snapshot    string                 `json:"snapshot,omitempty"`
	Truncated   bool                   `json:"truncated,omitempty"`
	OutputPath  string                 `json:"output_path,omitempty"`
	Attachments []FileAttachment       `json:"attachments,omitempty"`
	Extra       map[string]interface{} `json:"extra,omitempty"`
}

type ToolResult

type ToolResult struct {
	Title       string                 `json:"title"`
	Metadata    map[string]interface{} `json:"metadata"`
	Output      string                 `json:"output"`
	Attachments []FileAttachment       `json:"attachments,omitempty"`
}

type ToolState

type ToolState struct {
	Status   string                 `json:"status"`
	Input    map[string]interface{} `json:"input,omitempty"`
	Output   string                 `json:"output,omitempty"`
	Metadata map[string]interface{} `json:"metadata,omitempty"`
	Title    string                 `json:"title,omitempty"`
	Time     *ToolTime              `json:"time,omitempty"`
}

type ToolTime

type ToolTime struct {
	Start int64 `json:"start"`
	End   int64 `json:"end,omitempty"`
}

type TraceConfig added in v1.10.0

type TraceConfig struct {
	Enabled               bool   `yaml:"enabled"`
	Dir                   string `yaml:"dir,omitempty"` // default "./dino_sessions/traces"
	QueueSize             int    `yaml:"queue_size,omitempty"`
	FlushIntervalMs       int    `yaml:"flush_interval_ms,omitempty"`
	CaptureFullMessages   bool   `yaml:"capture_full_messages,omitempty"`
	CaptureFullToolOutput bool   `yaml:"capture_full_tool_output,omitempty"`
	CaptureChunks         bool   `yaml:"capture_chunks,omitempty"`
}

TraceConfig controls the context-trace event log (docs/design/context-trace.md). Enabled=false (default) means no recorder is constructed at all — the engine's tracer stays nil (zero overhead).

type TurnCanceledError added in v1.9.0

type TurnCanceledError = session.TurnCanceledError

type TurnObservation added in v1.9.0

type TurnObservation = session.TurnObservation

func ObserveOneUserTurn added in v1.9.0

func ObserveOneUserTurn(ctx context.Context, s *Session, in types.AgentInput) (*TurnObservation, bool, error)

type TurnSessionClosedError added in v1.9.0

type TurnSessionClosedError = session.TurnSessionClosedError

type Usage

type Usage = session.Usage

Directories

Path Synopsis
Package trace implements the context-trace event log: an append-only JSONL record of everything that happened during an agent session, separate from the chatstore state layer.
Package trace implements the context-trace event log: an append-only JSONL record of everything that happened during an agent session, separate from the chatstore state layer.

Jump to

Keyboard shortcuts

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