native

package
v0.20.0 Latest Latest
Warning

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

Go to latest
Published: Sep 15, 2026 License: AGPL-3.0 Imports: 39 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DefaultToolOutputMaxBytes  = 64 * 1024
	DefaultToolOutputMaxLines  = 2000
	DefaultSystemFilesMaxBytes = 32 * 1024
)
View Source
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.

View Source
const (
	EventAgentStart          = event.AgentStart
	EventStart               = event.AgentStart
	EventTextStart           = event.TextStart
	EventTextDelta           = event.TextDelta
	EventTextEnd             = event.TextEnd
	EventReasoningStart      = event.ReasoningStart
	EventReasoningDelta      = event.ReasoningDelta
	EventReasoningEnd        = event.ReasoningEnd
	EventToolCallInputStart  = event.ToolCallInputStart
	EventToolCallStart       = event.ToolCallStart
	EventToolCallMetadata    = event.ToolCallMetadata
	EventToolCallProgress    = event.ToolCallProgress
	EventToolCallEnd         = event.ToolCallEnd
	EventToolApprovalRequest = event.ToolApprovalRequest
	EventUserInputRequest    = event.UserInputRequest
	EventAttachment          = event.Attachment
	EventReaction            = event.Reaction
	EventSpeech              = event.Speech
	EventAgentEnd            = event.AgentEnd
	EventEnd                 = event.AgentEnd
	EventAgentAbort          = event.AgentAbort
	EventAbort               = event.AgentAbort
	EventRetry               = event.Retry
	EventStepEnd             = event.StepEnd
	EventProgress            = event.Progress
	EventError               = event.Error
)

Variables

View Source
var (
	ErrTextLoopDetected = errors.New(LoopDetectedAbortMessage)
	ErrToolLoopDetected = errors.New(ToolLoopDetectedAbortMessage)
)

Functions

func ContextWithHookForcedApproval

func ContextWithHookForcedApproval(ctx context.Context, reason string) context.Context

func GenerateSchedulePrompt

func GenerateSchedulePrompt(s Schedule) string

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 HookForcedApprovalReason

func HookForcedApprovalReason(ctx context.Context) (string, bool)

func SpawnContextSourceFrags

func SpawnContextSourceFrags(rc RunConfig) []contextfrag.ContextFrag

SpawnContextSourceFrags uses typed system sections only when they reproduce the caller-supplied System exactly. Custom spawn prompts deliberately stay on the legacy collector fallback so PR1 cannot replace or normalize them.

func SpawnSystemPrompt

func SpawnSystemPrompt(sessionType string) string

SpawnSystemPrompt returns the system prompt for a given session type.

func SystemSectionFrags

func SystemSectionFrags(sections []SystemSection, scope contextfrag.Scope) []contextfrag.ContextFrag

SystemSectionFrags converts typed system prompt sections into context fragments, mirroring contextview.ToolUsageFrag's construction so a caller building ContextSourceFrags directly from GenerateSystemSections produces fragments indistinguishable in shape from the rest of the pipeline.

Types

type Agent

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

Agent is the core agent that handles LLM interactions.

func New

func New(deps Deps) *Agent

New creates a new Agent with the given dependencies.

func (*Agent) BridgeProvider

func (a *Agent) BridgeProvider() bridge.Provider

BridgeProvider returns the underlying bridge provider (workspace manager).

func (*Agent) ExecuteTool

func (a *Agent) ExecuteTool(ctx context.Context, cfg RunConfig, call sdk.ToolCall) (sdk.ToolResultPart, error)

func (*Agent) ExecuteToolWithUIMetadata added in v0.20.0

func (a *Agent) ExecuteToolWithUIMetadata(ctx context.Context, cfg RunConfig, call sdk.ToolCall) (sdk.ToolResultPart, map[string]any, error)

ExecuteToolWithUIMetadata runs one tool outside a stream (deferred approval, hook tests) and returns the UI-only payloads stripped from its output alongside the model-facing result, so callers can persist them on harness-side channels (row metadata) instead of leaking them to the model.

func (*Agent) Generate

func (a *Agent) Generate(ctx context.Context, cfg RunConfig) (*GenerateResult, error)

Generate runs the agent in non-streaming mode, returning the complete result.

func (*Agent) Limits

func (a *Agent) Limits() Limits

func (*Agent) LoopReselectMode

func (a *Agent) LoopReselectMode() LoopReselectMode

LoopReselectMode returns the normalized rollout mode for in-loop context reselection. A nil Agent defaults to active.

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.

func (*Agent) Stream

func (a *Agent) Stream(ctx context.Context, cfg RunConfig) <-chan StreamEvent

Stream runs the agent in streaming mode, emitting events to the returned channel.

type BotInfo

type BotInfo struct {
	ID          string `json:"id,omitempty"`
	Name        string `json:"name,omitempty"`
	DisplayName string `json:"display_name,omitempty"`
	Timezone    string `json:"timezone,omitempty"`
}

BotInfo is service-owned bot metadata injected into the system prompt.

type ContextStepSelectionInput

type ContextStepSelectionInput struct {
	Scope               contextfrag.Scope
	InitialMessageCount int
	Messages            []sdk.Message
	BudgetMaxTokens     int
	// ProviderSystem, ProviderTools, and ProviderInputAllowanceTokens carry
	// the complete provider envelope into step reselection. A zero allowance
	// keeps the unlimited-window contract and disables serialized enforcement.
	ProviderSystem               string
	ProviderTools                []sdk.Tool
	ProviderInputAllowanceTokens int
	// RecentProtectTokens carries the run's recent-protection window override
	// so step reselection resolves the same window as the provider view. Nil
	// uses the view default; a pointer to zero disables the window.
	RecentProtectTokens *int
	// KeepRecentToolResults keeps the newest N complete tool cycles intact
	// and truncates older bulky tool results to a size summary; <= 0 disables
	// content truncation.
	KeepRecentToolResults int
	// MinMessages gates content truncation on total provider message count.
	MinMessages int
}

type ContextStepSelectionResult

type ContextStepSelectionResult struct {
	Messages []sdk.Message
	// MessageSourceIndexes maps each returned message to its absolute index in
	// ContextStepSelectionInput.Messages. Synthetic messages use -1. A
	// normalized byte-identical unchanged output can inherit every input
	// origin. Otherwise a missing or invalid vector preserves only verified
	// protected-prefix origins and treats every suffix origin as unknown.
	// Custom reselectors that need dynamic carriers to become durable must
	// return a complete, exact source-index vector.
	MessageSourceIndexes      []int
	MessageSourceIndexesKnown bool
	Dropped                   int
	Truncated                 int
	// ProtectedPruned counts the subset of Truncated stubbed to resolve a
	// protected-budget overflow that would otherwise fail the run.
	ProtectedPruned int
	DropReasons     map[string]int
	FatalError      error
}

type ContextViewApplier

type ContextViewApplier func(context.Context, RunConfig) (RunConfig, error)

ContextViewApplier rebuilds provider-facing fields from the authoritative context fragments immediately before generate options are assembled.

type Deps

type Deps struct {
	BridgeProvider     bridge.Provider
	HookService        *hooks.Service
	Logger             *slog.Logger
	Limits             Limits
	ContextViewApplier ContextViewApplier
	LoopReselectMode   LoopReselectMode
}

Deps holds all service dependencies for the Agent.

type FSClient

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

FSClient provides file operations against a bot's container filesystem.

func NewFSClient

func NewFSClient(provider bridge.Provider, botID string, now func() time.Time) *FSClient

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.

func (*FSClient) ReadText

func (f *FSClient) ReadText(ctx context.Context, path string) (string, error)

ReadText reads a text file from the container, returning its content as a string. Returns an empty string if the file does not exist or cannot be read.

func (*FSClient) ReadTextSafe

func (f *FSClient) ReadTextSafe(ctx context.Context, path string) string

ReadTextSafe reads a text file, returning empty string on any error.

type FileAttachment

type FileAttachment = event.FileAttachment

FileAttachment, ReactionItem and SpeechItem live in the event leaf package (they ride on StreamEvent); aliased here for source compatibility.

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

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 Limits

type Limits struct {
	ToolOutputMaxBytes  int
	ToolOutputMaxLines  int
	SystemFilesMaxBytes int
}

func DefaultLimits

func DefaultLimits() Limits

func LimitsFromValues

func LimitsFromValues(toolOutputMaxBytes, toolOutputMaxLines, systemFilesMaxBytes int) Limits

func (Limits) Normalize

func (l Limits) Normalize() Limits

func (Limits) ToolOutputLimit

func (l Limits) ToolOutputLimit() agenttools.ToolOutputLimit

type LoopDetectionConfig

type LoopDetectionConfig struct {
	Enabled bool
}

LoopDetectionConfig controls loop detection behavior.

type LoopReselectMode

type LoopReselectMode string

LoopReselectMode is the server-level rollout mode for the in-loop context step reselector (cfg.ContextStepReselector).

const (
	LoopReselectActive LoopReselectMode = "active"
	LoopReselectShadow LoopReselectMode = "shadow"
	LoopReselectOff    LoopReselectMode = "off"
)

func (LoopReselectMode) Normalize

func (m LoopReselectMode) Normalize() LoopReselectMode

Normalize maps an unrecognized or empty mode to LoopReselectActive.

type ReactionItem

type ReactionItem = event.ReactionItem

FileAttachment, ReactionItem and SpeechItem live in the event leaf package (they ride on StreamEvent); aliased here for source compatibility.

type RetryConfig

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

func DefaultRetryConfig() RetryConfig

DefaultRetryConfig returns the default retry strategy: 5 attempts total. Only the first retry fires immediately — it absorbs network blips and instant upstream rejections. Later attempts back off 1s→8s with jitter, so a sustained overload window (typically tens of seconds) is ridden out without hammering the upstream with a burst of immediate retries.

type RunConfig

type RunConfig struct {
	// RunID is the stable identity allocated by durable admission for this
	// invocation. Direct callers without admission receive one at the
	// application creation boundary before the native runtime starts.
	RunID                       string
	Model                       *sdk.Model
	CurrentModelUUID            string
	CurrentModelID              string
	CurrentModelProvider        string
	ForkContext                 *tools.MessageSnapshot
	ForkContextSourceMessageIDs []string
	// ReasoningConfig is the resolved thinking decision, carried whole. It was
	// once five flat fields, which is how the subagent spawn path came to carry
	// one of them and silently drop the rest.
	ReasoningConfig *models.ReasoningConfig
	// ReasoningStoredEffort and ReasoningRequestedEffort retain the two inputs
	// behind ReasoningConfig. Tools that select a different model (notably
	// spawn_agent) must resolve those inputs against that model instead of copying
	// a decision made for the parent model.
	ReasoningStoredEffort          string
	ReasoningRequestedEffort       string
	ChatCompletionsCompat          string
	Messages                       []sdk.Message
	Query                          string
	System                         string
	ContextFrags                   []contextfrag.ContextFrag
	ContextSourceFrags             []contextfrag.ContextFrag
	ContextSourceWarnings          []contextfrag.ValidationWarning
	ContextManifest                contextfrag.Manifest
	ContextScope                   contextfrag.Scope
	ContextCurrentUserMessageIndex *int
	ContextMemoryMessageIndex      *int
	ContextQueryMaterialized       bool
	ContextToolUsage               string
	ContextToolUsageFrags          []contextfrag.ContextFrag
	ContextHookText                string
	ContextToolDefs                []contextfrag.ToolDefAccounting
	ContextToolDefsResolved        bool
	ContextToolExchangePolicy      *contextfrag.ToolExchangePolicy
	ContextBudgetMaxTokens         int
	ContextRecentProtectTokens     *int
	ContextHistoryTokenEstimates   []int
	ContextTrimmableMessages       int
	ContextCachePlan               contextfrag.CachePlan
	ContextMutations               *contextfrag.MutationLedger
	ContextDynamicMutators         []contextfrag.DynamicMutator
	ContextLifecycle               *contextfrag.LifecycleHolder
	ContextStepReselector          ContextStepReselector

	SessionType         string
	LiveToolStream      bool
	CanRequestUserInput bool
	SupportsImageInput  bool
	SupportsFileInput   bool
	SupportsToolCall    bool
	InlineImages        []sdk.ImagePart
	// InlineAttachments carries non-image native attachment parts (documents
	// as sdk.FilePart, small text files as wrapped sdk.TextPart) appended to
	// the current user message. Images stay in InlineImages, which also feeds
	// the context-frag view; these parts are materialized by prepareRunConfig
	// only.
	InlineAttachments []sdk.MessagePart
	Identity          SessionContext
	Bot               BotInfo
	Skills            []SkillEntry
	LoopDetection     LoopDetectionConfig
	Retry             RetryConfig
	// StepIndexOffset lets an application-owned continuation of the same run
	// keep durable step indexes monotonic when the SDK invocation is restarted
	// after a final step accepted a steer item.
	StepIndexOffset int
	// ContinueAfterFinal is set by the durable coordinator when a final model
	// step found steer input. Native runtime uses it to reopen the same run.
	ContinueAfterFinal *atomic.Bool
	NextModelInputs    *[]sdk.Message

	// SteerWake announces queue changes; PendingSteer rechecks the authoritative
	// queue. OnSteer checkpoints a stopped model attempt and claims its next input.
	// These callbacks retain the run context, unlike the cancelled invocation.
	SteerWake          <-chan struct{}
	PendingSteer       func(context.Context) (bool, error)
	OnSteer            func(context.Context, int, *sdk.StepResult) error
	SuppressAgentStart bool

	// 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

	// 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 during terminal delivery for each injected
	// message admitted by a provider attempt, recording the headerified text
	// and the number of SDK output messages that preceded the injection. Used
	// by the resolver to interleave injected messages in storeRound.
	InjectedRecorder func(headerifiedText string, insertAfter int)

	// OnProviderStreamEventObserved receives normalized provider parts before
	// Twilight buffers them or invokes the step commit barrier. Persistence uses
	// this production boundary to measure reasoning without putting timing on
	// the public event wire.
	OnProviderStreamEventObserved func(StreamEvent)

	// OnStepCommitted is a synchronous durability barrier. The callback sees
	// the complete step plus any user/read-media messages prepared immediately
	// before it, with persistence-only tool metadata already attached.
	OnStepCommitted func(ctx context.Context, stepIndex int, step *sdk.StepResult) error

	// OnStepInterrupted persists text/reasoning emitted by the current model
	// call when cancellation arrives before finish-step. Tool-call steps never
	// use this path. It retains the original run cancellation cause so the
	// persistence adapter can reject ownership loss before detaching for IO.
	OnStepInterrupted func(ctx context.Context, stepIndex int, step *sdk.StepResult) error

	// BackgroundManager provides access to the background task system.
	// When non-nil, the agent loop refreshes running task summaries at step
	// boundaries while tools handle waiting and result inspection.
	BackgroundManager *background.Manager

	ToolApprovalHandler func(ctx context.Context, call sdk.ToolCall) (sdk.ToolApprovalResult, error)
	// contains filtered or unexported fields
}

RunConfig holds everything needed for a single agent invocation.

func (RunConfig) GenerationLimits

func (cfg RunConfig) GenerationLimits() models.GenerationLimits

GenerationLimits resolves the turn's output allowance from the model the run dispatches to and the thinking decision it was constructed with. The context budget plan reserves exactly this value and, when requested, the provider request carries it as max_tokens.

func (RunConfig) RefreshContextFrag

func (cfg RunConfig) RefreshContextFrag() RunConfig

RefreshContextFrag rebuilds the typed context frag view from the legacy RunConfig fields. The SDK-facing fields remain the source of truth in phase 1.

func (RunConfig) RefreshContextFragWithDynamicMutators

func (cfg RunConfig) RefreshContextFragWithDynamicMutators(readMedia bool, beforeModelCallHook bool, injectCh bool) RunConfig

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.

func (*Sential) Reset

func (s *Sential) Reset()

Reset clears the detector state.

type SentialOptions

type SentialOptions struct {
	NgramSize        int
	WindowSize       int
	OverlapThreshold float64
}

SentialOptions configures the n-gram overlap detector.

type SentialResult

type SentialResult struct {
	Hit          bool
	Overlap      float64
	MatchedGrams int
	NewGrams     int
}

SentialResult is the output of an overlap inspection.

type SessionContext

type SessionContext struct {
	BotID               string
	ChatID              string
	SessionID           string
	UserID              string
	ChannelIdentityID   string
	CurrentPlatform     string
	ReplyTarget         string
	ConversationType    string
	Timezone            string
	TimezoneLocation    *time.Location
	SessionToken        string //nolint:gosec // carries session credential material at runtime
	WorkspaceTargetID   string
	WorkspaceTargetKind string
	WorkspaceTargetName string
	// WorkdirPath is the session's immutable working directory, resolved
	// once per run from the session's workdir binding.
	WorkdirPath string
	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 (*SpawnAdapter) GenerateWithWatchdog

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.

func (*SpawnAdapter) SetRunObserverFactory

func (s *SpawnAdapter) SetRunObserverFactory(f SpawnRunObserverFactory)

SetRunObserverFactory installs live event publishing for spawned runs.

func (*SpawnAdapter) SetStepCommitFactory

func (s *SpawnAdapter) SetStepCommitFactory(f SpawnStepCommitFactory)

SetStepCommitFactory installs incremental step persistence for spawned runs.

type SpawnRunObservation

type SpawnRunObservation struct {
	TerminalResolved bool
	TerminalOutcome  tools.SpawnAttemptDisposition
}

SpawnRunObservation carries the terminal outcome selected by the session runtime that serialized terminal publication against routed controls.

type SpawnRunObserver

type SpawnRunObserver func(StreamEvent) SpawnRunObservation

SpawnRunObserver publishes one spawned-run event and reports a terminal outcome when the session runtime resolved one. Nonterminal events and observers without a session runtime return the zero observation.

type SpawnRunObserverFactory

type SpawnRunObserverFactory func(ctx context.Context) SpawnRunObserver

SpawnRunObserverFactory builds the per-event publisher for one spawned run. A nil return means nothing observes this run and events are not forwarded.

type SpawnStepCommitFactory

type SpawnStepCommitFactory func(
	ctx context.Context,
	botID, sessionID, modelUUID, turnRequestMessageID string,
	contextLifecycle *contextfrag.LifecycleHolder,
	onPersisted func(),
) (
	func(context.Context, int, *sdk.StepResult) error,
	func(context.Context, int, *sdk.StepResult) error,
)

SpawnStepCommitFactory builds the per-step persistence callback for one spawned run. It receives the run context (which carries the admitted run's identity) and returns nil when incremental persistence is unavailable, in which case the spawn provider keeps its terminal-snapshot persistence. turnRequestMessageID is the persisted task user message the step rows bind to, so every step lands in the turn admission allocated.

type SpeechItem

type SpeechItem = event.SpeechItem

FileAttachment, ReactionItem and SpeechItem live in the event leaf package (they ride on StreamEvent); aliased here for source compatibility.

type StreamEvent

type StreamEvent = event.StreamEvent

StreamEvent is emitted by the agent during streaming.

type StreamEventType

type StreamEventType = event.StreamEventType

StreamEventType identifies the kind of stream event.

type SystemFile

type SystemFile struct {
	Filename string
	Content  string
}

SystemFile is a file loaded from the bot container for prompt generation.

type SystemPromptItem

type SystemPromptItem struct {
	ID   string
	Text string
}

type SystemPromptParams

type SystemPromptParams struct {
	SessionType               string
	Bot                       BotInfo
	Skills                    []SkillEntry
	Files                     []SystemFile
	MaxFilesBytes             int
	Timezone                  string
	PlatformIdentitiesSection string
	PlatformIdentities        []SystemPromptItem
}

SystemPromptParams holds all inputs for system prompt generation.

type SystemSection

type SystemSection struct {
	ID                 string
	Kind               contextfrag.Kind
	Priority           int
	RetentionTier      contextfrag.RetentionTier
	DropPriority       contextfrag.DropPriority
	RequiredCapability string
	Render             contextfrag.RenderPolicy
	Text               string
}

SystemSection is one typed, priority-ordered piece of the system prompt.

func GenerateSystemSections

func GenerateSystemSections(params SystemPromptParams) []SystemSection

GenerateSystemSections builds the typed system prompt sections that renderSystemSections joins into the same string GenerateSystemPrompt used to build directly. Two sections (intro, bot identity) sit inside a single template's own placeholder gaps: they are always returned, even with empty Text, so the uniform join below reproduces that template's literal spacing. Sections folding in dynamic, possibly-absent content (platform identity, skills, workspace files) are omitted entirely when empty.

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.

func (*TextLoopGuard) Reset

func (g *TextLoopGuard) Reset()

Reset clears the guard state.

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.

func (*ToolLoopGuard) Reset

func (g *ToolLoopGuard) Reset()

Reset clears the guard state.

type ToolLoopInput

type ToolLoopInput struct {
	ToolName string
	Input    any
}

ToolLoopInput represents a tool call for loop detection.

type ToolLoopResult

type ToolLoopResult struct {
	Hash        string
	RepeatCount int
	BreachCount int
	Warn        bool
	Abort       bool
}

ToolLoopResult is the output of a tool loop inspection.

Jump to

Keyboard shortcuts

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