Documentation
¶
Index ¶
- Constants
- Variables
- func IsMemoOverlay(id string) bool
- func MemoPutRequest(memo string) steering.PutRequest
- func RenderMemoPayload(memo string) string
- func ResolveInstructions(baseDir string, path string, inline string) (string, error)
- func ShapeExecutorCall(ctx context.Context, call lipapi.Call, store MemoStore, scope Scope, ...) (lipapi.Call, bool, *PendingMemoUpdate, MemoOutcome, error)
- func ShapeThinkerCall(call lipapi.Call, instructions string) (lipapi.Call, error)
- func StripResidualMemoTags(text string) string
- type Config
- type InMemoryMemoStore
- func (s *InMemoryMemoStore) Delete(ctx context.Context, scope Scope, ref state.MemoRef) error
- func (s *InMemoryMemoStore) Get(ctx context.Context, scope Scope, ref state.MemoRef) (state.MemoState, bool, error)
- func (s *InMemoryMemoStore) Latest(ctx context.Context, scope Scope) (state.MemoState, bool, error)
- func (s *InMemoryMemoStore) LatestEntry(ctx context.Context, scope Scope) (state.MemoState, state.MemoRef, bool, error)
- func (s *InMemoryMemoStore) Put(ctx context.Context, scope Scope, st state.MemoState) (state.MemoRef, error)
- func (s *InMemoryMemoStore) Update(ctx context.Context, scope Scope, ref state.MemoRef, st state.MemoState) (state.MemoRef, error)
- type MemoOutcome
- type MemoRef
- type MemoResult
- type MemoState
- type MemoStore
- type PendingMemoUpdate
- type Processor
- type Recorder
- type Scope
- type Turn
- type TurnInput
Constants ¶
const ( DefaultStreamToClient = "hidden" DefaultRegularTurns = 2 DefaultMaxMemoBytes = 16 * 1024 DefaultMaxInstructionsBytes = 64 * 1024 )
Default values for interleaved thinking configuration.
const ( MemoOpenTag = "<proxy_thinker_memo>" MemoCloseTag = "</proxy_thinker_memo>" // ExtractionSourceFull marks a memo captured as the full bounded thinker // output. Whole-output capture is the only extraction path since memo // wrapper tags were removed from the thinker prompt. ExtractionSourceFull = "full" )
Memo wrapper tags are no longer required or prompted for. They are tolerated defensively: complete wrapper tags are stripped from the stored memo and from the visible stream in case a model still emits them from cached prompts.
const DefaultInstructions = `` /* 2226-byte string literal not displayed */
DefaultInstructions is the built-in thinker prompt used when instructions_file is empty.
const ID = "interleaved-thinking"
ID is the canonical feature identifier in plugins.features.
const MemoInjectionModeConversationView = "conversation_view_overlay"
MemoInjectionModeConversationView identifies the memo injection mode in diagnostics.
const MemoOverlayID = "interleaved-thinking-memo"
MemoOverlayID is the stable conversation-view overlay ID that carries the latest thinker memo for an A-leg. Each capture replaces the payload and re-resolves the anchor to the current ingress tail.
const MemoSteeringReason = "interleaved_thinking_memo"
MemoSteeringReason is the bounded content-free reason recorded on the memo steering overlay and its diagnostics.
const SessionSteeringGuidanceHeader = "[Session Steering Guidance]"
SessionSteeringGuidanceHeader is the plain-text header that introduces the steering block. It is used when persisting the thinker memo as a conversation-view steering overlay.
Variables ¶
var ( // ErrMemoNotFound is returned when a memo reference does not exist under // the requested scope. Cross-scope access must surface this error so // session isolation is enforced by the store contract. ErrMemoNotFound = errors.New("interleavedthinking: memo not found") // ErrMemoTooLarge is returned when a put or update would store memo content // exceeding the configured byte limit. ErrMemoTooLarge = errors.New("interleavedthinking: memo too large") // ErrEmptyScope is returned when a mutating or lookup operation is called // with an empty scope. An empty scope cannot own a memo. ErrEmptyScope = errors.New("interleavedthinking: empty scope") // ErrEmptyMemoRef is returned when a mutating or lookup operation is called // with a memo reference whose key is empty. Lookup is keyed by ref.Key, so // an empty key cannot identify a memo. ErrEmptyMemoRef = errors.New("interleavedthinking: empty memo ref") )
Sentinel errors for the memo store contract.
var ErrThinkerInstructionsMissing = errors.New("interleavedthinking: thinker instructions required but missing")
ErrThinkerInstructionsMissing is returned when a thinker candidate is shaped without resolved thinker instructions.
Functions ¶
func IsMemoOverlay ¶
IsMemoOverlay reports whether id identifies the thinker-memo steering overlay, so generic orchestration can filter it without knowing the policy.
func MemoPutRequest ¶
func MemoPutRequest(memo string) steering.PutRequest
MemoPutRequest builds the trusted steering mutation that persists or replaces the thinker memo overlay for an A-leg. Placement resolves after_ingress_tail against the accepted ingress trajectory frozen at turn preparation; the anchor therefore stays fixed while later history appends behind it (cache-stable).
func RenderMemoPayload ¶
RenderMemoPayload renders the model-visible user-message text persisted for a captured memo. The header keeps prior injections unambiguous without any protocol-specific markers.
func ResolveInstructions ¶
ResolveInstructions returns the thinker instructions text. When path is non-empty, it validates the path and reads the file bounded by maxBytes. When path is empty, inline is returned if non-empty, otherwise DefaultInstructions is returned.
func ShapeExecutorCall ¶
func ShapeExecutorCall( ctx context.Context, call lipapi.Call, store MemoStore, scope Scope, ref *state.MemoRef, suppressVisibleMemo bool, ) (lipapi.Call, bool, *PendingMemoUpdate, MemoOutcome, error)
ShapeExecutorCall classifies the latest valid memo for an executor candidate, applies budget decrements, and validates the call.
func ShapeThinkerCall ¶
ShapeThinkerCall shapes a thinker candidate call by prepending thinker instructions to Instructions, clearing Tools and ToolChoice, and validating.
func StripResidualMemoTags ¶
StripResidualMemoTags removes complete <proxy_thinker_memo> and </proxy_thinker_memo> wrapper tags from text. It is a defensive cleanup for models that still emit wrapper tags from cached prompts; the tags are never required or prompted for. Matching is case-insensitive, treats a tag name followed by a boundary (whitespace, '/' or '>') as a tag, and preserves incomplete tag fragments as literal content.
Types ¶
type Config ¶
type Config struct {
Enabled bool `yaml:"enabled"`
InstructionsFile string `yaml:"instructions_file"`
Instructions string `yaml:"instructions"`
StreamToClient string `yaml:"stream_to_client"`
RegularTurnsRemaining int `yaml:"regular_turns_remaining"`
MaxMemoBytes int `yaml:"max_memo_bytes"`
}
Config carries operator-supplied settings for interleaved thinking.
func DecodeConfig ¶
DecodeConfig decodes a feature-private YAML subtree into Config.
func (Config) EffectiveMaxMemoBytes ¶
EffectiveMaxMemoBytes returns the configured memo size limit or default when <= 0.
func (Config) EffectiveRegularTurnsRemaining ¶
EffectiveRegularTurnsRemaining returns the configured budget or default when <= 0.
func (Config) EffectiveStreamToClient ¶
EffectiveStreamToClient returns the visibility mode, defaulting to hidden when unset.
type InMemoryMemoStore ¶
type InMemoryMemoStore struct {
// contains filtered or unexported fields
}
InMemoryMemoStore is a process-local, bounded MemoStore keyed by scope and memo reference. It is safe for concurrent use.
func NewMemoStore ¶
func NewMemoStore(maxBytes int) *InMemoryMemoStore
NewMemoStore returns an in-memory memo store that rejects memo content larger than maxBytes. A non-positive maxBytes disables size enforcement.
func (*InMemoryMemoStore) Get ¶
func (s *InMemoryMemoStore) Get(ctx context.Context, scope Scope, ref state.MemoRef) (state.MemoState, bool, error)
Get returns the memo state stored under scope for ref.Key.
func (*InMemoryMemoStore) Latest ¶
Latest returns the most recent memo state stored under scope, if any.
func (*InMemoryMemoStore) LatestEntry ¶
func (s *InMemoryMemoStore) LatestEntry(ctx context.Context, scope Scope) (state.MemoState, state.MemoRef, bool, error)
LatestEntry returns the most recent memo state and reference stored under scope, if any.
type MemoOutcome ¶
type MemoOutcome string
MemoOutcome classifies executor memo shaping for bounded diagnostics.
const ( MemoOutcomeNone MemoOutcome = "" MemoOutcomeInjected MemoOutcome = "injected" MemoOutcomeExpired MemoOutcome = "expired" MemoOutcomeSkippedVisible MemoOutcome = "skipped_visible" MemoOutcomeSkippedMissing MemoOutcome = "skipped_missing" MemoOutcomeSkippedEmpty MemoOutcome = "skipped_empty" )
type MemoResult ¶
MemoResult carries minimal evidence of captured thinker output.
type MemoStore ¶
type MemoStore interface {
Put(ctx context.Context, scope Scope, st state.MemoState) (state.MemoRef, error)
Get(ctx context.Context, scope Scope, ref state.MemoRef) (state.MemoState, bool, error)
Update(ctx context.Context, scope Scope, ref state.MemoRef, st state.MemoState) (state.MemoRef, error)
Delete(ctx context.Context, scope Scope, ref state.MemoRef) error
LatestEntry(ctx context.Context, scope Scope) (state.MemoState, state.MemoRef, bool, error)
}
MemoStore is the bounded memo store contract keyed by memo reference under an authoritative scope.
type PendingMemoUpdate ¶
PendingMemoUpdate is the memo-store mutation that should be committed once a shaped executor attempt becomes authoritative.
type Processor ¶
type Processor interface {
BeginTurn(ctx context.Context, in TurnInput) (Turn, error)
IsMemoVisibleToClient(ctx context.Context, aLegID string) bool
}
Processor is the feature-owned entry point for interleaved thinking per turn.
type Recorder ¶
type Recorder struct {
MaxMemoBytes int
// Identity metadata copied into the resulting MemoState.
SourceSelector string
Backend string
Model string
RequestID string
RegularTurnsRemaining int
// contains filtered or unexported fields
}
Recorder observes canonical thinker stream events, captures the entire thinker output as a bounded memo, and produces a bounded MemoState at stream completion.
Observe also sanitizes the visible stream: residual memo wrapper tags are stripped (including across delta boundaries) and thinker content is emitted as canonical EventReasoningDelta so wrapper tags never surface as ordinary assistant text. The stored memo is bounded by MaxMemoBytes; a zero MaxMemoBytes disables bounding, matching the memo store convention.
Identity metadata fields are set by the caller before Finish and copied into the resulting MemoState. Injection metadata (InjectedCount, VisibleToClient) is left zero at capture time.
func (*Recorder) Finish ¶
Finish returns the captured MemoState. The memo is the complete bounded thinker output with residual wrapper tags stripped, trimmed of surrounding whitespace. interrupted marks the stored memo as captured from an interrupted stream.
func (*Recorder) FlushVisibleSanitizer ¶
FlushVisibleSanitizer returns any buffered partial-tag visible content and should be called once at stream end before Finish when surfacing thinker output.
func (*Recorder) HadContent ¶
HadContent reports whether any non-empty content delta was observed. It lets callers distinguish an empty memo (content observed, nothing extractable after normalization) from a stream that never produced content at all.
func (*Recorder) Observe ¶
Observe processes one canonical event: it feeds text/reasoning deltas to memo capture and returns sanitized visible events. Returned content deltas are always EventReasoningDelta with residual memo wrapper tags stripped. Non-content events pass through unchanged; call FlushVisibleSanitizer at stream end to emit any buffered partial-tag visible content.
type Scope ¶
type Scope string
Scope identifies the authoritative session or A-leg that owns a memo. Memos
type Turn ¶
type Turn interface {
ShapeThinker(call lipapi.Call) (lipapi.Call, error)
ObserveThinkerEvent(ev lipapi.Event) ([]lipapi.Event, error)
FinalizeThinker(ctx context.Context) (MemoResult, error)
FinalizeThinkerStatus(ctx context.Context, interrupted bool, visibleCommitted bool) (MemoResult, error)
ShapeExecutor(ctx context.Context, call lipapi.Call, memo MemoResult) (lipapi.Call, error)
Visible() bool
CanContinue() bool
ShapeDiagnostics() (outcome string, turnsRemaining int)
CommitExecutor(ctx context.Context) (int, error)
FlushVisible() []lipapi.Event
}
Turn is the feature-owned lifecycle contract for a single turn.