Documentation
¶
Index ¶
- func BuildNotesPrepareStep(baseSystem string, np NotesProvider, section string, logger *zap.Logger) fantasy.PrepareStepFunction
- func BuildSystemPrompt(root string, files []ContextFile) (string, error)
- func CreateAgent(ctx context.Context, cfg Config, systemPrompt string, ...) (fantasy.Agent, fantasy.LanguageModel, error)
- type ChatStreamOptions
- type Config
- type ContextFile
- type NotesProvider
- type Service
- func (s *Service) Chat(ctx context.Context, sessionID, prompt string) (string, error)
- func (s *Service) ChatStream(ctx context.Context, sessionID, prompt string, cb StreamCallback, ...) (string, error)
- func (s *Service) DeleteSession(ctx context.Context, sessionID string) error
- func (s *Service) ListSessionMessages(ctx context.Context, sessionID string, _ int) ([]SessionMessage, error)
- func (s *Service) ListSessions(ctx context.Context) ([]memory.SessionInfo, error)
- func (s *Service) PromptObject(ctx context.Context, prompt string, schemaJSON []byte, ...) ([]byte, string, error)
- type SessionMessage
- type StoredPart
- type StreamCallback
- type StreamEvent
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BuildNotesPrepareStep ¶
func BuildNotesPrepareStep( baseSystem string, np NotesProvider, section string, logger *zap.Logger, ) fantasy.PrepareStepFunction
BuildNotesPrepareStep returns a fantasy.PrepareStepFunction that re-renders the system prompt on every step with two optional blocks merged into the base:
- A preview table of ALL notes — only when section is "above" or "below"; "off" suppresses it. Controls global visibility.
- A pinned-notes section with full content — always rendered when there are notes flagged in_context, regardless of section. This is the per-note opt-in the model uses for facts it expects to lean on continuously.
baseSystem is captured at agent-creation time. The two note queries are issued fresh on every step so newly-saved or newly-pinned notes surface to the model from the very next step without any external state push.
section is "off" (default), "above", or "below". Anything else is treated as "below" for the table. The pinned block always appears immediately after the table when both exist; when the table is suppressed, the pinned block goes below the base.
Errors fetching notes are NOT fatal. They log a Warn and pass the base system prompt through unchanged — notes are decoration, never break the turn.
func BuildSystemPrompt ¶
func BuildSystemPrompt(root string, files []ContextFile) (string, error)
BuildSystemPrompt reads each context file and concatenates them into one markdown blob separated by horizontal rules. Each section is prefixed with `## <Name>` so the model sees a stable document title (AGENT, WORKSPACE, SOUL, …) rather than an absolute on-disk path. Missing files are silently skipped (the daemon may declare optional context); files that are present but blank contribute nothing.
Types ¶
type ChatStreamOptions ¶
type ChatStreamOptions struct {
// Regenerate signals the runtime to attach the produced parts
// as a new branch onto the most recent assistant turn for the
// session. Falls back to a fresh row if no prior assistant
// turn exists.
Regenerate bool
}
ChatStreamOptions modulates a ChatStream invocation.
type Config ¶
type Config struct {
Provider string
ModelName string
APIKey string
APIBase string
MaxTokens int
MaxIterations int
Temperature *float64
TopP *float64
TopK *int64
PresencePenalty *float64
FrequencyPenalty *float64
ExtraAgentOpts []fantasy.AgentOption
}
Config bundles the inputs CreateAgent needs to talk to a provider. MaxTokens / MaxIterations always apply (we have defaults in agent_config.go); the sampling pointers (Temperature, TopP, TopK, PresencePenalty, FrequencyPenalty) are optional — only forwarded to fantasy when non-nil, so an unset config leaves the provider's own defaults in place rather than zeroing them out.
ExtraAgentOpts is the escape hatch for fantasy AgentOptions the runtime composes outside this package — currently the notes PrepareStep callback. Kept as a slice (rather than a sequence of dedicated Config fields) so adding another optional hook doesn't require a new field on Config.
type ContextFile ¶
ContextFile pairs a context document's display name with the path to its source on disk. Name shows up as the markdown header inside the assembled system prompt; Path is resolved against the agent root by BuildSystemPrompt. Empty Name falls back to the basename of Path so the section still gets a readable header.
type NotesProvider ¶
type NotesProvider interface {
List(ctx context.Context) ([]notes.Note, error)
ListInContext(ctx context.Context) ([]notes.Note, error)
}
NotesProvider is the read-only surface BuildNotesPrepareStep needs. Declared here so callers can mock the store in tests without depending on a real sqlite database. Two queries — one for "every note" (preview-table rendering) and one for "only pinned notes" (full-content block rendering) — keep the PrepareStep callback from doing client-side filtering.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
func NewService ¶
func (*Service) ChatStream ¶
func (s *Service) ChatStream( ctx context.Context, sessionID, prompt string, cb StreamCallback, opts ChatStreamOptions, ) (string, error)
ChatStream runs one streamed turn against the configured model and persists the assistant's structured parts. When opts.Regenerate is true and a prior assistant turn exists for the session, the new parts get appended as a branch to that turn instead of inserting a new row, so refresh recovers all alternatives.
func (*Service) DeleteSession ¶
func (*Service) ListSessionMessages ¶
func (s *Service) ListSessionMessages(ctx context.Context, sessionID string, _ int) ([]SessionMessage, error)
ListSessionMessages returns the recent messages stored for sessionID in role/content form suitable for gRPC transport. limit <= 0 means "use the store default" (LIMIT 50 today).
func (*Service) ListSessions ¶
func (*Service) PromptObject ¶
func (s *Service) PromptObject( ctx context.Context, prompt string, schemaJSON []byte, schemaName, schemaDesc string, ) ([]byte, string, error)
PromptObject runs a one-shot, stateless structured-output query against the underlying LanguageModel. No session memory is loaded or saved, no tool loop is run — just prompt + schema in, parsed object out. Matches fantasy.LanguageModel.GenerateObject one-to-one and exists so the runtime's gRPC surface has a place to hang the call without exposing the model type through Service's public API.
schemaJSON must be a JSON Schema document that unmarshals into fantasy/schema.Schema (common subset: type, properties, required, items, enum, format, min/max). schemaName and schemaDesc surface in tool-mode providers as the synthetic tool's name/description.
ObjectMode (JSON / tool / text / auto) is provider-level — set when the LanguageModel is constructed via e.g. anthropic.WithObjectMode(...). This method doesn't override it per-call because fantasy.ObjectCall has no per-call mode field.
Returns (objectJSON, rawText). rawText is the model's unparsed reply — useful for debugging when repair was needed.
type SessionMessage ¶
type SessionMessage struct {
Role string
Content string
BranchesJSON string
ActiveBranch int32
CreatedAt int64
}
SessionMessage is the plain wire-ready view of a stored chat message: role, text, and its creation time. Compacted or summarised entries already flow through the store as role=assistant, so callers get a post-compaction view.
type StoredPart ¶
type StoredPart struct {
Kind string `json:"kind"` // "text" | "tool"
Text string `json:"text,omitempty"` // kind=text
ToolID string `json:"tool_id,omitempty"` // kind=tool, runtime-issued id
Name string `json:"name,omitempty"` // kind=tool
Input string `json:"input,omitempty"` // kind=tool, raw JSON the model produced
Output string `json:"output,omitempty"` // kind=tool
State string `json:"state,omitempty"` // "input-available" | "output-available"
}
StoredPart is the on-disk shape of one piece of an assistant response. The dashboard rendering layer mirrors this exactly — kind=text accumulates streamed text deltas; kind=tool captures one tool call + its result, parsed via the runtime's stream callbacks. Stored as an array of StoredPart inside the messages row's `content` column for assistant turns.
type StreamCallback ¶
type StreamCallback func(event StreamEvent)