Documentation
¶
Index ¶
- Constants
- Variables
- func GenerateHeartbeatPrompt(interval int, checklist string, now time.Time, lastHeartbeatAt string) string
- func GenerateSchedulePrompt(s Schedule) string
- func GenerateSystemPrompt(params SystemPromptParams) string
- func SpawnModelCreatorFunc() tools.ModelCreator
- func SpawnSystemPrompt(sessionType string) string
- type Agent
- func (a *Agent) BridgeProvider() bridge.Provider
- func (a *Agent) ExecuteTool(ctx context.Context, cfg RunConfig, call sdk.ToolCall) (sdk.ToolResultPart, error)
- func (a *Agent) Generate(ctx context.Context, cfg RunConfig) (*GenerateResult, error)
- func (a *Agent) SetToolProviders(providers []tools.ToolProvider)
- func (a *Agent) Stream(ctx context.Context, cfg RunConfig) <-chan StreamEvent
- type Deps
- type FSClient
- type FileAttachment
- type GenerateResult
- type InjectMessage
- type LoopDetectionConfig
- type ModelConfig
- type ReactionItem
- type ReasoningConfig
- type RetryConfig
- type RunConfig
- type Schedule
- type Sential
- type SentialOptions
- type SentialResult
- type SessionContext
- type SkillEntry
- type SpawnAdapter
- type SpeechItem
- type StreamEvent
- type StreamEventType
- type SystemFile
- type SystemPromptParams
- type TextLoopGuard
- type TextLoopGuardResult
- type TextLoopProbeBuffer
- type ToolLoopGuard
- type ToolLoopInput
- type ToolLoopResult
Constants ¶
const ( // MidTaskPruneKeepStepsDefault is the number of recent tool-call steps to keep // intact when pruning older tool results during a multi-step agent run. MidTaskPruneKeepStepsDefault = 4 // MidTaskPruneThresholdDefault is the minimum number of messages before pruning activates. MidTaskPruneThresholdDefault = 20 )
const ( LoopDetectedAbortMessage = "loop detected, stream aborted" LoopDetectedStreakThreshold = 3 LoopDetectedMinNewGramsPerChunk = 8 LoopDetectedProbeChars = 256 ToolLoopDetectedAbortMessage = "tool loop detected, stream aborted" ToolLoopRepeatThreshold = 5 ToolLoopWarningsBeforeAbort = 1 ToolLoopWarningKey = "__memoh_tool_loop_warning" //nolint:gosec // internal warning key, not a credential ToolLoopWarningText = "" //nolint:gosec // human-readable warning text, not a credential /* 196-byte string literal not displayed */ )
Loop detection constants matching the TypeScript implementation.
Variables ¶
var ( MemoryExtractPrompt string MemoryUpdatePrompt string )
var ( ErrTextLoopDetected = errors.New(LoopDetectedAbortMessage) ErrToolLoopDetected = errors.New(ToolLoopDetectedAbortMessage) )
var TimeNow = time.Now
TimeNow is a hook for testing. Defaults to time.Now.
Functions ¶
func GenerateHeartbeatPrompt ¶
func GenerateHeartbeatPrompt(interval int, checklist string, now time.Time, lastHeartbeatAt string) string
GenerateHeartbeatPrompt builds the user message for a heartbeat trigger.
func GenerateSchedulePrompt ¶
GenerateSchedulePrompt builds the user message for a scheduled task trigger.
func GenerateSystemPrompt ¶
func GenerateSystemPrompt(params SystemPromptParams) string
GenerateSystemPrompt builds the complete system prompt from files, skills, and context.
func SpawnModelCreatorFunc ¶
func SpawnModelCreatorFunc() tools.ModelCreator
SpawnModelCreatorFunc returns a tools.ModelCreator backed by the shared SDK model factory. This keeps subagent model creation aligned with the shared SDK model factory.
func SpawnSystemPrompt ¶
SpawnSystemPrompt returns the system prompt for a given session type.
Types ¶
type Agent ¶
type Agent struct {
// contains filtered or unexported fields
}
Agent is the core agent that handles LLM interactions.
func (*Agent) BridgeProvider ¶
BridgeProvider returns the underlying bridge provider (workspace manager).
func (*Agent) ExecuteTool ¶ added in v0.8.0
func (*Agent) Generate ¶
Generate runs the agent in non-streaming mode, returning the complete result.
func (*Agent) SetToolProviders ¶
func (a *Agent) SetToolProviders(providers []tools.ToolProvider)
SetToolProviders sets the tool providers after construction. This allows breaking dependency cycles in the DI graph.
type FSClient ¶
type FSClient struct {
// contains filtered or unexported fields
}
FSClient provides file operations against a bot's container filesystem.
func NewFSClient ¶
NewFSClient creates a new container filesystem client.
func (*FSClient) LoadSystemFiles ¶
func (f *FSClient) LoadSystemFiles(ctx context.Context) []SystemFile
LoadSystemFiles loads the standard set of system files from the bot container.
type FileAttachment ¶
type FileAttachment struct {
Type string `json:"type"`
Base64 string `json:"base64,omitempty"`
Path string `json:"path,omitempty"`
URL string `json:"url,omitempty"`
PlatformKey string `json:"platform_key,omitempty"`
Mime string `json:"mime,omitempty"`
Name string `json:"name,omitempty"`
ContentHash string `json:"content_hash,omitempty"`
Size int64 `json:"size,omitempty"`
Metadata map[string]any `json:"metadata,omitempty"`
}
FileAttachment represents a file reference extracted from agent output.
type GenerateResult ¶
type GenerateResult struct {
Messages []sdk.Message
Text string
Attachments []FileAttachment
Reactions []ReactionItem
Speeches []SpeechItem
Usage *sdk.Usage
}
GenerateResult holds the result of a non-streaming agent invocation.
type InjectMessage ¶ added in v0.7.0
type InjectMessage struct {
Text string
HeaderifiedText string
// ImageParts carries inline images (data URL or public URL) to attach
// alongside the injected text when the model supports vision input.
ImageParts []sdk.ImagePart
}
InjectMessage carries a user message to be injected into a running agent stream between tool rounds via the PrepareStep hook.
type LoopDetectionConfig ¶
type LoopDetectionConfig struct {
Enabled bool
}
LoopDetectionConfig controls loop detection behavior.
type ModelConfig ¶
type ModelConfig struct {
ModelID string
ClientType string
APIKey string //nolint:gosec // carries provider credential material at runtime
CodexAccountID string
BaseURL string
HTTPClient *http.Client
ReasoningConfig *ReasoningConfig
}
ModelConfig holds provider and model information resolved from DB.
type ReactionItem ¶
type ReactionItem struct {
Emoji string `json:"emoji"`
}
ReactionItem represents an emoji reaction extracted from agent output.
type ReasoningConfig ¶
ReasoningConfig controls extended thinking/reasoning behavior.
type RetryConfig ¶ added in v0.7.0
type RetryConfig struct {
MaxAttempts int // total retry attempts
FastAttempts int // first N attempts with no delay
BaseDelay time.Duration // backoff base for non-fast attempts
MaxDelay time.Duration // backoff cap
}
RetryConfig controls retry behavior for stream failures.
func DefaultRetryConfig ¶ added in v0.7.0
func DefaultRetryConfig() RetryConfig
DefaultRetryConfig returns the default retry strategy: 10 attempts total, first 5 fast (no delay), last 5 with exponential backoff.
type RunConfig ¶
type RunConfig struct {
Model *sdk.Model
ReasoningEffort string
Messages []sdk.Message
Query string
System string
SessionType string
SupportsImageInput bool
SupportsToolCall bool
InlineImages []sdk.ImagePart
Identity SessionContext
Skills []SkillEntry
LoopDetection LoopDetectionConfig
Retry RetryConfig
// PromptCacheTTL controls prompt caching for this run. Empty or
// unrecognized values default to 5m. Use "1h" for the long-cache tier
// or "off" to disable caching entirely. The TTL is honored only when
// the resolved model's vendor implements prompt caching (currently
// Anthropic Messages); for other vendors the value is ignored.
PromptCacheTTL string
// MidTaskPruneThreshold is the minimum number of messages before mid-task
// pruning kicks in. When the accumulated message count reaches this
// threshold, older tool-result pairs are pruned to keep the context
// within budget. Defaults to MidTaskPruneThresholdDefault (20).
MidTaskPruneThreshold int
// MidTaskPruneKeepSteps is the number of recent tool-call cycles to
// preserve when mid-task pruning is triggered. Defaults to
// MidTaskPruneKeepStepsDefault (4).
MidTaskPruneKeepSteps int
// InjectCh receives user messages to inject between tool rounds.
// When non-nil, a PrepareStep hook drains this channel and appends
// user messages to the conversation before the next LLM call.
InjectCh <-chan InjectMessage
// InjectedRecorder is called each time a message is injected via
// PrepareStep, recording the headerified text and the number of SDK
// output messages that preceded the injection. Used by the resolver
// to interleave injected messages at the correct position in storeRound.
InjectedRecorder func(headerifiedText string, insertAfter int)
// BackgroundManager provides access to the background task system.
// When non-nil, the agent loop drains pending notifications at step
// boundaries and injects them as user messages so the model learns
// about completed background work.
BackgroundManager *background.Manager
ToolApprovalHandler func(ctx context.Context, call sdk.ToolCall) (sdk.ToolApprovalResult, error)
}
RunConfig holds everything needed for a single agent invocation.
type Schedule ¶
type Schedule struct {
ID string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Pattern string `json:"pattern"`
MaxCalls *int `json:"maxCalls,omitempty"`
Command string `json:"command"`
}
Schedule represents a scheduled task definition.
type Sential ¶
type Sential struct {
// contains filtered or unexported fields
}
Sential detects text repetition via n-gram overlap.
func NewSential ¶
func NewSential(opts SentialOptions) *Sential
NewSential creates a new n-gram overlap detector.
func (*Sential) Inspect ¶
func (s *Sential) Inspect(text string) SentialResult
Inspect checks a chunk of text for n-gram overlap with the sliding window.
type SentialOptions ¶
SentialOptions configures the n-gram overlap detector.
type SentialResult ¶
SentialResult is the output of an overlap inspection.
type SessionContext ¶
type SessionContext struct {
BotID string
ChatID string
SessionID string
ChannelIdentityID string
CurrentPlatform string
ReplyTarget string
ConversationType string
Timezone string
TimezoneLocation *time.Location
SessionToken string //nolint:gosec // carries session credential material at runtime
IsSubagent bool
}
SessionContext carries request-scoped identity and routing information.
type SkillEntry ¶
type SkillEntry struct {
Name string
Description string
Content string
Path string
Metadata map[string]any
}
SkillEntry represents a skill loaded from the bot container.
type SpawnAdapter ¶
type SpawnAdapter struct {
// contains filtered or unexported fields
}
SpawnAdapter wraps *Agent to satisfy tools.SpawnAgent without creating an import cycle (tools -> agent).
func NewSpawnAdapter ¶
func NewSpawnAdapter(a *Agent) *SpawnAdapter
NewSpawnAdapter creates a SpawnAdapter from the given Agent.
func (*SpawnAdapter) Generate ¶
func (s *SpawnAdapter) Generate(ctx context.Context, cfg tools.SpawnRunConfig) (*tools.SpawnResult, error)
func (*SpawnAdapter) GenerateWithWatchdog ¶ added in v0.7.0
func (s *SpawnAdapter) GenerateWithWatchdog(ctx context.Context, cfg tools.SpawnRunConfig, touchFn func()) (*tools.SpawnResult, error)
GenerateWithWatchdog runs the agent in streaming mode, touching the provided touchFn on every stream event (token, tool progress, etc.). It collects the full result and returns it in the same shape as Generate. This enables activity-based watchdog monitoring for subagent execution.
type SpeechItem ¶
type SpeechItem struct {
Text string `json:"text"`
}
SpeechItem represents a TTS request extracted from agent output.
type StreamEvent ¶
type StreamEvent struct {
Type StreamEventType `json:"type"`
Delta string `json:"delta,omitempty"`
ToolName string `json:"toolName,omitempty"`
ToolCallID string `json:"toolCallId,omitempty"`
ApprovalID string `json:"approvalId,omitempty"`
ShortID int `json:"shortId,omitempty"`
Status string `json:"status,omitempty"`
Input any `json:"input,omitempty"`
Metadata map[string]any `json:"metadata,omitempty"`
Progress any `json:"progress,omitempty"`
Result any `json:"result,omitempty"`
Attachments []FileAttachment `json:"attachments,omitempty"`
Reactions []ReactionItem `json:"reactions,omitempty"`
Speeches []SpeechItem `json:"speeches,omitempty"`
Messages json.RawMessage `json:"messages,omitempty"`
Usage json.RawMessage `json:"usage,omitempty"`
Reasoning []string `json:"reasoning,omitempty"`
Error string `json:"error,omitempty"`
Attempt int `json:"attempt,omitempty"`
MaxAttempt int `json:"maxAttempt,omitempty"`
RetryError string `json:"retryError,omitempty"`
StepNumber int `json:"stepNumber,omitempty"`
TotalSteps int `json:"totalSteps,omitempty"`
ProgressStatus string `json:"progressStatus,omitempty"`
}
StreamEvent is emitted by the agent during streaming.
func (StreamEvent) IsTerminal ¶
func (e StreamEvent) IsTerminal() bool
IsTerminal returns true for events that signal end of stream.
type StreamEventType ¶
type StreamEventType string
StreamEventType identifies the kind of stream event.
const ( EventAgentStart StreamEventType = "agent_start" EventTextStart StreamEventType = "text_start" EventTextDelta StreamEventType = "text_delta" EventTextEnd StreamEventType = "text_end" EventReasoningStart StreamEventType = "reasoning_start" EventReasoningDelta StreamEventType = "reasoning_delta" EventReasoningEnd StreamEventType = "reasoning_end" EventToolCallStart StreamEventType = "tool_call_start" EventToolCallProgress StreamEventType = "tool_call_progress" EventToolCallEnd StreamEventType = "tool_call_end" EventToolApprovalRequest StreamEventType = "tool_approval_request" EventAttachment StreamEventType = "attachment_delta" EventReaction StreamEventType = "reaction_delta" EventSpeech StreamEventType = "speech_delta" EventAgentEnd StreamEventType = "agent_end" EventAgentAbort StreamEventType = "agent_abort" EventRetry StreamEventType = "retry" EventProgress StreamEventType = "progress" EventError StreamEventType = "error" )
type SystemFile ¶
SystemFile is a file loaded from the bot container for prompt generation.
type SystemPromptParams ¶
type SystemPromptParams struct {
SessionType string
Skills []SkillEntry
Files []SystemFile
Now time.Time
Timezone string
SupportsImageInput bool
PlatformIdentitiesSection string
}
SystemPromptParams holds all inputs for system prompt generation.
type TextLoopGuard ¶
type TextLoopGuard struct {
// contains filtered or unexported fields
}
TextLoopGuard wraps Sential with consecutive-hit tracking.
func NewTextLoopGuard ¶
func NewTextLoopGuard(consecutiveHits, minNewGrams int, opts SentialOptions) *TextLoopGuard
NewTextLoopGuard creates a text loop guard.
func (*TextLoopGuard) Inspect ¶
func (g *TextLoopGuard) Inspect(text string) TextLoopGuardResult
Inspect checks text and tracks consecutive overlap streaks.
type TextLoopGuardResult ¶
type TextLoopGuardResult struct {
SentialResult
Streak int
Abort bool
}
TextLoopGuardResult extends SentialResult with streak and abort tracking.
type TextLoopProbeBuffer ¶
type TextLoopProbeBuffer struct {
// contains filtered or unexported fields
}
TextLoopProbeBuffer batches text into chunks before passing to an inspector.
func NewTextLoopProbeBuffer ¶
func NewTextLoopProbeBuffer(chunkSize int, inspect func(string)) *TextLoopProbeBuffer
NewTextLoopProbeBuffer creates a probe buffer.
func (*TextLoopProbeBuffer) Flush ¶
func (b *TextLoopProbeBuffer) Flush()
Flush emits any remaining content to the inspector.
func (*TextLoopProbeBuffer) Push ¶
func (b *TextLoopProbeBuffer) Push(text string)
Push adds text to the buffer, emitting full chunks to the inspector.
type ToolLoopGuard ¶
type ToolLoopGuard struct {
// contains filtered or unexported fields
}
ToolLoopGuard detects repeated identical tool calls.
func NewToolLoopGuard ¶
func NewToolLoopGuard(repeatThreshold, warningsBeforeAbort int) *ToolLoopGuard
NewToolLoopGuard creates a tool loop guard.
func (*ToolLoopGuard) Guard ¶
func (g *ToolLoopGuard) Guard(toolName string, input any) (warn bool, abort bool)
Guard wraps tools with tool loop detection. Returns a wrapper execute function.
func (*ToolLoopGuard) Inspect ¶
func (g *ToolLoopGuard) Inspect(input ToolLoopInput) ToolLoopResult
Inspect checks a tool call for repetition.
type ToolLoopInput ¶
ToolLoopInput represents a tool call for loop detection.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package background implements a background task manager for long-running commands executed inside bot containers.
|
Package background implements a background task manager for long-running commands executed inside bot containers. |