Documentation
¶
Index ¶
- Constants
- Variables
- func AgentContextSearchDirs(cwd string) []string
- func AgentsProjectDir(cwd string) string
- func AgentsUserDir() string
- func AppendToolResultText(resp map[string]any, extra string) map[string]any
- func AppendTouchedFile(files []string, toolName string, input map[string]any) []string
- func AsADKTool(t Tool) (tool.Tool, error)
- func AsADKTools(tools []Tool) ([]tool.Tool, error)
- func BuildInstructionProvider(opts PromptOptions) func(ctx agent.ReadonlyContext) (string, error)
- func BuildSystemPrompt(opts PromptOptions) string
- func BumpSkillsGeneration()
- func CloseMemoryExtractor()
- func CloseModel(m model.LLM) error
- func ContextFileRealPath(path string) string
- func ContextLinksPromptBlock(docs []LoadedContextDoc) string
- func DefaultPlugins() []*plugin.Plugin
- func DeleteAgent(cwd, name string, scope OriginScope) error
- func DeleteSkill(cwd, name string, scope OriginScope) error
- func EncodeProjectDir(path string) string
- func EnqueueMemoryTurn(turn MemoryTurn) bool
- func ExpandBraces(s string) []string
- func ExpandSkillInvocation(cwd, text string) (string, bool)
- func ExtractContextLinks(body string) []string
- func GitStatusSnapshot(ctx context.Context, cwd string) string
- func GlobMatch(pattern, rel string) bool
- func IngestWorkflowMemory(ctx context.Context, sessSvc session.Service, sessionID, cwd string)
- func IsConfirmationCall(fc *genai.FunctionCall) bool
- func MemoryExtractContent(turn MemoryTurn, nearest []memory.Concept, topics []string) string
- func MemoryExtractModel(cfg config.Config, sessionProvider string) (string, string)
- func NewRetryAndReflectPlugin(maxRetries int) (*plugin.Plugin, error)
- func NewSkillSource(cwd string) skill.Source
- func NewSkillToolset(ctx context.Context, cwd string) (*skilltoolset.SkillToolset, error)
- func NewStandaloneAgentContext(ctx context.Context) agent.Context
- func ParseFrontmatterBytes(data []byte) (fields map[string]string, body string, ok bool)
- func ParseMarkdownFrontmatter(path string) (fields map[string]string, body string, ok bool)
- func ParseMemoryExtraction(raw string) (memoryExtraction, error)
- func ParsePathsField(fm string) []string
- func ParseRuleFrontmatter(s string) (paths []string, body string)
- func RegisterToolFactory(factory ToolFactory)
- func RenderAgentFile(spec AgentSpec) ([]byte, error)
- func RenderSkillFile(spec SkillSpec) ([]byte, error)
- func ResolveContextLink(repoRoot, link string) (string, bool)
- func RulesPromptBlock(rules []Rule) string
- func RunADKTool(ctx agent.Context, t tool.Tool, args any) (map[string]any, error)
- func SessionPreview(messages []Message) string
- func SessionPreviewFromEvents(events []*session.Event) string
- func SetMemoryExtractor(e *MemoryExtractor)
- func SkillBody(s Skill) string
- func SkillSearchDirs(cwd string) []string
- func SkillsProjectDir(cwd string) string
- func SkillsPromptBlock(skills []Skill) string
- func SkillsUserDir() string
- func StripFencedCodeBlocks(s string) string
- func SubagentSearchDirs(cwd string) []string
- func SubagentToolNames(def SubagentDef) []string
- func SubagentsPromptBlock(defs []SubagentDef) string
- func ToolResultText(resp map[string]any) (string, bool)
- func TruncateInstructionDoc(path, body string, limit int) string
- func UnquoteYAML(s string) string
- func UnwrapConfirmationCall(fc *genai.FunctionCall) (*genai.FunctionCall, error)
- func WorkflowCompileConfig(e *Engine, cwd string, tabID int, def workflow.Def, src workflow.Source) workflow.WorkflowAgentConfig
- func WorkflowGraphAgent(name string, compiled *workflow.Compiled) (agent.Agent, error)
- type ADKRunnable
- type AgentPatch
- type AgentSpec
- type ApprovalRequest
- type ApprovalResponse
- type AssistantTextEvent
- type BaseEvent
- type BgTaskEndedEvent
- type BgTaskStartedEvent
- type ContextAwareTool
- func (ct *ContextAwareTool) Declaration() *genai.FunctionDeclaration
- func (ct *ContextAwareTool) Description() string
- func (ct *ContextAwareTool) Info() ToolInfo
- func (ct *ContextAwareTool) IsLongRunning() bool
- func (ct *ContextAwareTool) Name() string
- func (ct *ContextAwareTool) ProcessRequest(ctx agent.Context, req *model.LLMRequest) error
- func (ct *ContextAwareTool) RelPath(p string) string
- func (ct *ContextAwareTool) Run(ctx agent.Context, args any) (map[string]any, error)
- type ContextScope
- type Coordinator
- func (c *Coordinator) CancelWorkflow(tabID int)
- func (c *Coordinator) Dispatch(tabID int, text string) error
- func (c *Coordinator) GetSession(tabID int) *Session
- func (c *Coordinator) HasSession(tabID int) bool
- func (c *Coordinator) InterruptSession(tabID int) bool
- func (c *Coordinator) IsBusy(tabID int) bool
- func (c *Coordinator) RemoveSession(tabID int)
- func (c *Coordinator) SetSession(tabID int, s *Session)
- type CostEvent
- type DoneEvent
- type Engine
- func (e *Engine) CompileWorkflow(ctx context.Context, cwd string, tabID int, def workflow.Def, ...) (*workflow.Compiled, error)
- func (e *Engine) Coordinator() *Coordinator
- func (e *Engine) Interaction() InteractionHandler
- func (e *Engine) Run(ctx context.Context, opts RunOptions) (*RunResult, error)
- func (e *Engine) RunWorkflow(ctx context.Context, cwd string, tabID int, def workflow.Def, ...) error
- func (e *Engine) SystemPrompt(cwd string, inWorkflow bool) string
- type EngineEvent
- type EventKind
- type EventListener
- type ExitedEvent
- type ExtensionsChangedEvent
- type FilePart
- type FileSessionService
- func (s *FileSessionService) AppendEvent(ctx context.Context, curSession session.Session, event *session.Event) error
- func (s *FileSessionService) Create(ctx context.Context, req *session.CreateRequest) (*session.CreateResponse, error)
- func (s *FileSessionService) Delete(ctx context.Context, req *session.DeleteRequest) error
- func (s *FileSessionService) DirFor(cwd string) (string, error)
- func (s *FileSessionService) Get(ctx context.Context, req *session.GetRequest) (*session.GetResponse, error)
- func (s *FileSessionService) List(ctx context.Context, req *session.ListRequest) (*session.ListResponse, error)
- func (s *FileSessionService) PathFor(id string) (string, error)
- func (s *FileSessionService) Root() (string, error)
- type GenerateStreamFunc
- type HeadlessInteractionHandler
- func (h HeadlessInteractionHandler) AskQuestion(ctx context.Context, tabID int, questions []Question) (QuestionResponse, error)
- func (h HeadlessInteractionHandler) ConfirmPlan(ctx context.Context, tabID int, req PlanRequest) (PlanResponse, error)
- func (h HeadlessInteractionHandler) RequestApproval(ctx context.Context, tabID int, req ApprovalRequest) (ApprovalResponse, error)
- func (h HeadlessInteractionHandler) RequestSudoPassword(ctx context.Context, tabID int, prompt string) (SudoPasswordResponse, error)
- type InteractionHandler
- type LoadedContextDoc
- type MCPStatusChangedEvent
- type MemoryExtractor
- type MemoryExtractorOptions
- type MemoryTurn
- type Message
- func MessageFromGenAIContent(c *genai.Content) Message
- func MessagesFromEvents(events []*session.Event) []Message
- func NewAssistantMessage(text string, thoughts []ThoughtPart, toolCalls []ToolCallPart) Message
- func NewToolResultMessage(toolResults ...ToolResultPart) Message
- func NewUserMessage(text string, files ...FilePart) Message
- type MessageRole
- type MidTurnDrainedEvent
- type MidTurnQueue
- type ModelInfoEvent
- type Options
- type Origin
- type OriginScope
- type PermissionRule
- type PlanRequest
- type PlanResponse
- type PromptOptions
- type Question
- type QuestionAnswer
- type QuestionOption
- type QuestionResponse
- type ResultSummary
- type Rule
- type RuleScope
- type RunOptions
- type RunResult
- type RunnerBuilderFunc
- type Session
- func (s *Session) Close()
- func (s *Session) Emit(event EngineEvent)
- func (s *Session) InterruptTurn() bool
- func (s *Session) IsBusy() bool
- func (s *Session) LastResponse() string
- func (s *Session) Messages() []Message
- func (s *Session) QueueMidTurn(text string)
- func (s *Session) QueueTurn(text string, files ...[]FilePart) error
- func (s *Session) QueueTurnSync(ctx context.Context, text string, files ...[]FilePart) error
- func (s *Session) SessionID() string
- type SessionArgs
- type SessionStore
- func (st *SessionStore) Delete(id string) error
- func (st *SessionStore) DirFor(cwd string) (string, error)
- func (st *SessionStore) List(cwd string) ([]SessionSummary, error)
- func (st *SessionStore) Load(id string) (StoredSessionFile, error)
- func (st *SessionStore) PathFor(id string) (string, error)
- func (st *SessionStore) Root() (string, error)
- func (st *SessionStore) Save(id, cwd string, messages []Message) error
- func (st *SessionStore) SaveEvents(id, cwd string, events []*session.Event) error
- type SessionSummary
- type Skill
- func CreateSkill(cwd string, scope OriginScope, spec SkillSpec) (Skill, error)
- func DiscoverSkills(cwd string) []Skill
- func FindSkill(cwd, name string) (Skill, bool)
- func ResolveEditableSkill(cwd, name string, scope OriginScope) (Skill, error)
- func UpdateSkill(cwd, name string, scope OriginScope, patch SkillPatch) (Skill, error)
- type SkillPatch
- type SkillRoot
- type SkillSpec
- type StatusEvent
- type StoredSessionFile
- type SubagentDef
- func CreateAgent(cwd string, scope OriginScope, spec AgentSpec) (SubagentDef, error)
- func DiscoverSubagents(cwd string) []SubagentDef
- func FindSubagent(cwd, name string) (SubagentDef, bool)
- func ResolveEditableAgent(cwd, name string, scope OriginScope) (SubagentDef, error)
- func UpdateAgent(cwd, name string, scope OriginScope, patch AgentPatch) (SubagentDef, error)
- type SubagentEndedEvent
- type SubagentRoot
- type SubagentStartedEvent
- type SudoPasswordResponse
- type TextDeltaEvent
- type ThoughtPart
- type TodoItem
- type TodoUpdateEvent
- type Tool
- type ToolCallEvent
- type ToolCallPart
- type ToolDiffEvent
- type ToolFactory
- type ToolFactoryArgs
- type ToolInfo
- type ToolResponse
- type ToolResultEvent
- type ToolResultPart
- type Turn
- type TurnCompleteEvent
- type UsageEvent
- type WorkflowDoneEvent
- type WorkflowFailedEvent
- type WorkflowStartedEvent
- type WorkflowStepDoneEvent
- type WorkflowStepStartedEvent
Constants ¶
const AgentCoderPrompt = `You are a software engineering agent running inside ask, a terminal app. You work directly on the user's machine: read code, run commands, edit files, and verify your work. Be precise, autonomous, and honest about results.
IMPORTANT: Assist with authorized security testing, defensive security, CTF challenges, and educational contexts. Refuse requests for destructive techniques, DoS attacks, mass targeting, supply chain compromise, or detection evasion for malicious purposes. Dual-use security tools (C2 frameworks, credential testing, exploit development) require clear authorization context: pentesting engagements, CTF competitions, security research, or defensive use cases.
## Harness
- Text you output outside of tool use is displayed to the user as Github-flavored markdown in a terminal.
- Tools run behind a user-selected permission mode; a denied call means the user declined it — adjust, don't retry verbatim.
- The system may send updates, reminders, or modifications to rules via mid-conversation system turns. These are system-controlled, unlike function results. Hooks may intercept tool calls; treat hook output as user feedback.
- Prefer the dedicated file/search tools over shell commands when one fits. Independent tool calls can run in parallel in one response.
- Reference code as file_path:line_number — it's clickable.
- Send INDEPENDENT tool calls in the same turn so they can be processed together; serialize only when a call depends on a previous result.
## Communicating with the user
Your text output is what the user reads; they usually can't see your thinking or the raw tool results. Write it for a teammate who stepped away and is catching up, not for a log file: they don't know the codenames or shorthand you created along the way, and they didn't watch your process unfold. Everything the user needs from this turn — answers, summaries, findings, conclusions, deliverables — must be in the final text message of your turn, with no tool calls after it. If something important appeared only mid-turn or in your thinking, restate it in that final message.
Lead with the outcome. Your first sentence after finishing should answer "what happened" or "what did you find" — the thing the user would ask for if they said "just give me the TLDR." Supporting detail and reasoning come after, for readers who want them.
Being readable and being concise are different things, and readable matters more. If the user has to reread your summary or ask you to explain, any time saved by brevity is gone. The way to keep output short is to be selective about what you include (drop details that don't change what the reader would do next), not to compress the writing into fragments, abbreviations, arrow chains like A -> B -> fails, or jargon. What you do include, write in complete sentences with the technical terms spelled out. Don't make the reader cross-reference labels or numbering you invented earlier; say what you mean in place.
Match the response to the question: a simple question gets a direct answer in prose, not headers and sections. Use tables only for short enumerable facts, with explanations in the surrounding prose rather than the cells. Calibrate to the user — a bit tighter for an expert, more explanatory for someone newer.
Write code that reads like the surrounding code: match its comment density, naming, and idiom.
Only write a code comment to state a constraint the code itself can't show — never to say where it came from, what the next line does, or why your change is correct; that's you talking to the reviewer, not the next reader, and it's noise the moment the PR merges.
When you use a pronoun for someone — the user or anyone else you mention — and their pronouns haven't been stated, use they/them. A name doesn't tell you someone's pronouns; a wrong guess misgenders a real person in a way the neutral default never does, so never infer pronouns from a name. This applies to all user-visible text, including visible thinking.
For actions that are hard to reverse or outward-facing, confirm first unless durably authorized or explicitly told to proceed without asking; approval in one context doesn't extend to the next. Sending content to an external service publishes it; it may be cached or indexed even if later deleted. Before deleting or overwriting, look at the target — if what you find contradicts how it was described, or you didn't create it, surface that instead of proceeding. Report outcomes faithfully: if tests fail, say so with the output; if a step was skipped, say that; when something is done and verified, state it plainly without hedging.
## Doing tasks
- The user will primarily request you to perform software engineering tasks. These may include solving bugs, adding new functionality, refactoring code, explaining code, and more. When given an unclear or generic instruction, consider it in the context of these software engineering tasks and the current working directory. For example, if the user asks you to change "methodName" to snake case, do not reply with just "method_name", instead find the method in the code and modify the code comprehensively.
- You are highly capable and often allow users to complete ambitious tasks that would otherwise be too complex or take too long. You should defer to user judgement about whether a task is too large to attempt.
- For exploratory questions ("what could we do about X?", "how should we approach this?", "what do you think?"), respond in 2-3 sentences with a recommendation and the main tradeoff. Present it as something the user can redirect, not a decided plan. Don't implement until the user agrees.
- Prefer editing existing files to creating new ones.
- Be careful not to introduce security vulnerabilities such as command injection, XSS, SQL injection, and other OWASP top 10 vulnerabilities. If you notice that you wrote insecure code, immediately fix it. Prioritize writing safe, secure, and correct code.
- Don't add features, refactor, or introduce abstractions beyond what the task requires. A bug fix doesn't need surrounding cleanup; a one-shot operation doesn't need a helper. Don't design for hypothetical future requirements. Three similar lines is better than a premature abstraction. No half-finished implementations either.
- Don't add error handling, fallbacks, or validation for scenarios that can't happen. Trust internal code and framework guarantees. Only validate at system boundaries (user input, external APIs). Don't use feature flags or backwards-compatibility shims when you can just change the code.
- For UI or frontend changes, start the dev server and use the feature in a browser before reporting the task as complete. Make sure to test the golden path and edge cases for the feature and monitor for regressions in other features. Type checking and test suites verify code correctness, not feature correctness - if you can't test the UI, say so explicitly rather than claiming success.
## Handling Failures and Blockers
- Root-Cause Rigor: When you encounter an obstacle, do not use destructive actions as a shortcut to simply make it go away. For instance, try to identify root causes and fix underlying issues rather than bypassing safety checks (e.g. --no-verify). If you discover unexpected state like unfamiliar files, branches, or configuration, investigate before deleting or overwriting, as it may represent the user's in-progress work.
- Graceful degradation: If you're unsure whether the user would want something kept, prefer a reversible step (move it aside, rename it, or stash it) over deleting. Files you created yourself this session (scratch outputs, experiment intermediates) are yours to clean up freely.
- Elevated privileges (` + "`" + `sudo` + "`" + `): When running commands with ` + "`" + `sudo` + "`" + `, you MUST include ` + "`" + `-A` + "`" + ` as the first argument (e.g., ` + "`" + `sudo -A <command>` + "`" + `). Plain ` + "`" + `sudo` + "`" + ` without ` + "`" + `-A` + "`" + ` will be rejected because ` + "`" + `-A` + "`" + ` is required to trigger ask's secure native password modal.
- Merge Conflicts: Typically resolve merge conflicts rather than discarding changes. If a lock file exists, investigate what process holds it rather than deleting it.
- Git Safety: In a git repository, run ` + "`" + `git status` + "`" + ` before any command that could discard uncommitted work (git checkout/restore/reset/clean, rm -rf on a repo path, restoring from a snapshot), and stash (with ` + "`" + `-u` + "`" + ` for untracked) or commit anything you find first.
- Secrets: When staging or committing, review what's included (` + "`" + `git status` + "`" + ` after a broad ` + "`" + `git add` + "`" + `), and if you see anything suspicious that might reveal secrets — even if the filename looks innocuous — double-check the file's contents before pushing.
- In short: only take risky actions carefully, and when in doubt, ask before acting. Follow both the spirit and letter of these instructions - measure twice, cut once.
## Context management
When the conversation grows long, some or all of the current context is summarized; the summary, along with any remaining unsummarized context, is provided in the next context window so work can continue — you don't need to wrap up early or hand off mid-task.
When you have enough information to act, act. Do not re-derive facts already established in the conversation, re-litigate a decision the user has already made, or narrate options you will not pursue. If you are weighing a choice, give a recommendation, not an exhaustive survey.
Exception: when the user is describing a problem, asking a question, or thinking out loud rather than requesting a change, the deliverable is your assessment. Report your findings and stop. Don't apply a fix until they ask for one.
Before ending your turn, check your last paragraph. If it is a plan, an analysis, a question, a list of next steps, or a promise about work you have not done ('I'll…', 'let me know when…'), do that work now with tool calls. That includes retrying after errors and gathering missing information yourself. Do not stop because the context or session is long. End your turn only when the task is complete or you are blocked on input only the user can provide.
Before running a command that changes system state — restarts, deletes, config edits — check that the evidence actually supports that specific action. A signal that pattern-matches to a known failure may have a different cause.
## Investigation and planning
- Investigate before you change: read the relevant code, docs, or web sources first, and build on what you have actually seen rather than on guesses.
- For a large or ambiguous request, scope it before writing code — read the key files, then break the work into small, reviewable chunks, verifying each (build, tests) before moving to the next.
- Delegate by default, keep inline by exception. Substantial or independent work — research, multi-file investigation, chasing cross-references, reading docs or the web, well-scoped implementation and code edits, and running builds or test suites — goes to sub-agents through the task tool, each in its own context window, fanned out in parallel or in the background when the pieces are independent. Delegation is how you conserve your own context, so reach for it first and keep work inline only when you can justify it. Give each sub-agent a complete, self-contained prompt, since it cannot see this conversation. Only genuinely trivial lookups stay in your hands — a single file read, or a couple of grep/glob calls you act on at once; once a task spans several files, a multi-step trace, or a non-trivial code edit, hand it off.
## Memory
You have a persistent long-term memory of concepts, each a one-line title with a full body, weighted by how useful it has proven. The strongest concepts for this project (plus global ones about the user) open every session under <project_memory>; each turn, the concepts relevant to the prompt arrive in a <memory> block on the user message; a file you read, edit, or write brings its own. Only the leading concepts carry bodies — call load_memory with an id (the #number) for any other body, or with a query to search.
After every turn a background pass extracts durable facts on its own, so you rarely need to store anything by hand. Do call memory_index when the user says "remember" or states a preference, decision, or constraint explicitly, with kind user (their role, expertise, preferences), feedback (how they want you to work, always with the why), project (goals, decisions, constraints not derivable from the code or git history; convert relative dates to absolute), or reference (where things live in external systems). Use scope global for facts about the user that hold in every project. Never store code, task state, or what the repository already records.
Shape the memory as you use it: memory_reinforce when a recalled concept was genuinely load-bearing for your answer, memory_demote when one was wrong or outdated. memory_forget only for misinformation that must go, secrets stored by mistake, or an explicit user request.
<tool_call_hygiene>
## Tool Call Hygiene
- Pass arguments as a single JSON object matching the tool schema exactly.
- OMIT optional parameters you do not need. Never pass null, "", {}, or [] as placeholder values.
- Never encode arrays or objects as JSON strings — pass them as real JSON values.
- Send INDEPENDENT tool calls in the same turn so they can be processed together. Serialize only when a call depends on a previous result.
</tool_call_hygiene>
`
AgentCoderPrompt is the static head of the harness system prompt. It must stay byte-stable across turns: provider prefix caches key on exact prefixes, so anything volatile (env, git status, context files) is appended AFTER this block, computed once per session.
const AgentContextFileCap = 128_000
AgentContextFileCap bounds one instruction document's contribution to the prompt — a context file, a rule, or an @-linked doc.
The cap is a backstop against a pathological file (generated markdown, a vendored dump, a stray log) eating the context window. It is NOT a budget for trimming hand-written instructions: an author who writes a long CLAUDE.md means all of it, so the cap sits well above any realistic one. At 48_000 a real 83KB CLAUDE.md silently lost ~42% of its body, including whole sections the agent was supposed to follow.
const ConfirmationFunctionCallName = toolconfirmation.FunctionCallName
ConfirmationFunctionCallName is the wire function call name used by ADK for HITL confirmations.
Variables ¶
var AgentContextFileNames = []string{
"CLAUDE.md",
"CLAUDE.local.md",
"AGENTS.md",
"agents.md",
"CRUSH.md",
".cursorrules",
".github/copilot-instructions.md",
}
AgentContextFileNames are the project instruction files inlined into the system prompt, in priority order. Within one directory they are deduped case-insensitively so AGENTS.md/agents.md don't double-inject on case-insensitive mounts; across directories they are deduped by resolved path so a symlink (the common AGENTS.md -> CLAUDE.md) loads its target exactly once.
var AgentGitStatus = func(cwd string) string { ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() out, err := exec.CommandContext(ctx, "git", "-C", cwd, "status", "--porcelain=v1", "--branch").Output() if err != nil { return "" } lines := strings.Split(strings.TrimSpace(string(out)), "\n") if len(lines) > 40 { lines = append(lines[:40], fmt.Sprintf("… (%d more entries)", len(lines)-40)) } return strings.Join(lines, "\n") }
AgentGitStatus captures a one-shot git snapshot for the env block. Swappable in tests so prompt assembly stays subprocess-free there.
var AllSubagentTools = []string{
"read", "glob", "grep", "ls", "write", "edit", "bash",
"job_output", "job_kill", "fetch", "todos", "search_tools", "invoke_tool", "web_search",
"workflow_list", "workflow_get", "workflow_create", "workflow_edit", "workflow_delete", "workflow_copy",
}
AllSubagentTools is the full list of tool names available to subagents.
var DebugLog = func(format string, args ...any) {}
DebugLog is the engine's debug sink; the TUI points it at its own ASK_DEBUG logger. A no-op by default.
var ModelBuilder = func(ctx context.Context, p providers.Provider, cfg config.Config, modelID string) (model.LLM, error) { if p == nil { return nil, errors.New("provider is nil") } ctx = providers.WithWebSearchAvailable(ctx, config.ResolveBraveAPIKey(cfg.WebSearch) != "") llm, err := p.BuildModel(ctx, cfg.ProviderConfig(p.ID()), modelID) if err != nil { return nil, err } _, initialDelay, backoff := config.AgentRetryOptions(cfg) return newRetryingModel(llm, initialDelay, backoff), nil }
ModelBuilder builds the ADK LLM for a provider and wraps it in the transient-error retry decorator. Swappable so tests can hand back a scripted model.
Functions ¶
func AgentContextSearchDirs ¶
AgentContextSearchDirs lists the directories searched for project instruction files, in load order: the user-global ~/.claude scope first, then every directory from the project root down to cwd, so general instructions load before the more specific ones that follow. Mirrors RuleSearchScopes / DiscoverSkills / DiscoverSubagents, which already walk to the project root and read the user-global scope.
func AgentsProjectDir ¶
AgentsProjectDir is where ask writes new project-scope agents.
func AgentsUserDir ¶
func AgentsUserDir() string
AgentsUserDir is where ask writes new user-scope agents.
func AppendToolResultText ¶
AppendToolResultText appends extra to a tool result's human-readable field, so a decorator can add context to a result without knowing which per-tool struct produced it. Falls back to a dedicated "notes" field when the result has no text field of its own.
func AppendTouchedFile ¶
AppendTouchedFile records the file_path of a read/write/edit call, once, up to memoryExtractMaxFiles.
func AsADKTool ¶
AsADKTool passes through an ADK Tool or adapts it to ensure llmagent compatibility.
func AsADKTools ¶
AsADKTools converts a slice of Tools into ADK Tools.
func BuildInstructionProvider ¶
func BuildInstructionProvider(opts PromptOptions) func(ctx agent.ReadonlyContext) (string, error)
BuildInstructionProvider creates an ADK agent.InstructionProvider that returns the base system prompt combined with any dynamic context or state deltas from ctx.ReadonlyState().
The returned text is deliberately NOT run through instructionutil.InjectSessionState. ask's instruction text is not a template — it is user-authored documentation (CLAUDE.md, .claude/rules, @-linked docs, skill and subagent bodies) inlined verbatim, and ADK's placeholder regex is `{+[^{}]*}+`, so every `{identifier}` in that prose is treated as a session-state lookup. Two ways that goes wrong:
- `{name}` that happens to match a state key ask sets (system_reminder, step_incomplete, extra_instructions) is silently replaced inside the user's own documentation.
- `{name?}` resolves to the empty string when the key is absent, so the text is silently deleted with no error to fall back on.
It never bought anything either: ask defines no `{placeholder}` anywhere, and every dynamic value it does need is appended explicitly as a tagged block below. ADK's own llmagent.Config docs make the same point — "if templating logic for {} chars is not desired, then InstructionProvider should be used". Using an InstructionProvider and then re-applying the interpolation by hand defeats that. Any agent built from user-authored text (workflow steps, subagents) must use an InstructionProvider for the same reason; a static llmagent.Config.Instruction is interpolated by ADK and hard-fails the invocation on the first brace.
func BuildSystemPrompt ¶
func BuildSystemPrompt(opts PromptOptions) string
BuildSystemPrompt assembles the full system prompt for one agent session: static coder head, env snapshot, <project_instructions> (CLAUDE.md/AGENTS.md context files), <project_rules> (eager rules), <included_docs> (markdown files @-linked from context files, rules, skills, or subagents — loaded transitively via BFS with cycle-safe dedup), <project_memory>, <available_skills>, <available_agents>, then the shared ask steering prompt (with its worktree pinning clause when args.Cwd is an ask-managed worktree). Called once per session — the result must be reused verbatim on every request so the provider's prefix caching can hit.
func BumpSkillsGeneration ¶
func BumpSkillsGeneration()
BumpSkillsGeneration invalidates every live skill source.
func CloseMemoryExtractor ¶
func CloseMemoryExtractor()
CloseMemoryExtractor stops the process-wide extractor. Call it before closing the memory service so no job races the database going away.
func CloseModel ¶
CloseModel releases any resources a model.LLM holds — a subprocess-backed provider (Claude Code) forks a child on first use and implements io.Closer to terminate it. Building a model through ModelBuilder wraps it in retryingModel, which forwards Close, so callers close whatever ModelBuilder returned. A no-op for in-process models.
func ContextFileRealPath ¶
ContextFileRealPath resolves path to its canonical on-disk identity so two names for one file (an AGENTS.md -> CLAUDE.md symlink, a case-insensitive mount) dedupe to a single entry. Falls back to the cleaned path when the file cannot be resolved.
func ContextLinksPromptBlock ¶
func ContextLinksPromptBlock(docs []LoadedContextDoc) string
ContextLinksPromptBlock renders the loaded @-linked docs into a single <included_docs> system-prompt block, sorted by path for deterministic output.
func DefaultPlugins ¶
DefaultPlugins returns the standard set of ADK plugins configured for ask.
functioncallmodifier is deliberately absent. It exists to inject synthetic arguments into tool declarations at request time; ask needed that for the required `description` phrase, which is now a real field on every native tool's params struct, so there is nothing left to inject. It was registered here with a predicate that always returned false ever since PR #132 disabled it to stop it clobbering ParametersJsonSchema — a plugin that could never fire.
Bridge tools (linear_*, workflow_*) still have `description` added to their input schema in pkg/tools/bridge.go, because their input types come from the MCP handler cores and do not carry the field. That is a one-time schema build at construction, not per-request AST surgery.
func DeleteAgent ¶
func DeleteAgent(cwd, name string, scope OriginScope) error
DeleteAgent removes a user/project agent definition.
func DeleteSkill ¶
func DeleteSkill(cwd, name string, scope OriginScope) error
DeleteSkill removes a user/project skill package.
func EncodeProjectDir ¶
EncodeProjectDir encodes a path into a filesystem-safe directory name.
func EnqueueMemoryTurn ¶
func EnqueueMemoryTurn(turn MemoryTurn) bool
EnqueueMemoryTurn hands a finished turn to the process-wide extractor.
func ExpandBraces ¶
ExpandBraces expands one level of {a,b,c} alternation.
func ExpandSkillInvocation ¶
ExpandSkillInvocation turns a "/skill-name optional args" user line into the full skill invocation message — the user-invocable side of the standard. Returns ok=false when the line is not a known user-invocable skill (the caller sends the text unchanged).
func ExtractContextLinks ¶
ExtractContextLinks finds all @path/to/file.md references in body.
func IngestWorkflowMemory ¶
IngestWorkflowMemory files a finished workflow run into memory: the run's source as the prompt, the model text it produced as the answer.
func IsConfirmationCall ¶
func IsConfirmationCall(fc *genai.FunctionCall) bool
IsConfirmationCall reports whether a function call is an ADK tool confirmation request.
func MemoryExtractContent ¶
func MemoryExtractContent(turn MemoryTurn, nearest []memory.Concept, topics []string) string
MemoryExtractContent renders the user half of the extraction request.
func MemoryExtractModel ¶
MemoryExtractModel resolves the provider and model for extraction: the config's memory block first, then the session's provider with its cheapest listed model.
func NewRetryAndReflectPlugin ¶
NewRetryAndReflectPlugin creates an ADK retryandreflect plugin with the specified max retries.
func NewSkillSource ¶
NewSkillSource constructs an ADK skill.Source across all discovery roots for cwd plus every enabled plugin. Later roots take precedence (project-overrides-global).
func NewSkillToolset ¶
func NewSkillToolset(ctx context.Context, cwd string) (*skilltoolset.SkillToolset, error)
NewSkillToolset creates an ADK SkillToolset backed by NewSkillSource(cwd).
func NewStandaloneAgentContext ¶
NewStandaloneAgentContext wraps a context.Context with a compliant agent.Context implementation.
func ParseFrontmatterBytes ¶
ParseFrontmatterBytes parses frontmatter and body from bytes.
func ParseMarkdownFrontmatter ¶
ParseMarkdownFrontmatter reads a markdown file with YAML frontmatter and returns the scalar fields plus the body after the closing delimiter.
func ParseMemoryExtraction ¶
ParseMemoryExtraction reads the model's JSON reply, tolerating fences and prose around the object.
func ParsePathsField ¶
func ParseRuleFrontmatter ¶
func RegisterToolFactory ¶
func RegisterToolFactory(factory ToolFactory)
RegisterToolFactory registers the global default tool factory.
func RenderAgentFile ¶
RenderAgentFile builds an agent definition from a spec.
func RenderSkillFile ¶
RenderSkillFile builds SKILL.md content from a spec.
func ResolveContextLink ¶
ResolveContextLink resolves a link (without the @) against repoRoot.
func RulesPromptBlock ¶
func RunADKTool ¶
RunADKTool executes an ADK tool.
It takes an agent.Context, not a context.Context. That is the whole point: a plain context has to be converted into a fake agent context, and the fake returns nil for Artifacts, Session, State, and ToolConfirmation, and hands out a throwaway Actions — so a tool that escalates or requests confirmation through it is silently ignored.
func SessionPreview ¶
SessionPreview extracts the first user prompt line from messages.
func SessionPreviewFromEvents ¶
SessionPreviewFromEvents extracts the first user prompt line to serve as a preview.
func SetMemoryExtractor ¶
func SetMemoryExtractor(e *MemoryExtractor)
SetMemoryExtractor replaces the process-wide extractor (tests).
func SkillSearchDirs ¶
SkillSearchDirs is SkillSearchRoots without the origin tags.
func SkillsProjectDir ¶
SkillsProjectDir is where ask writes new project-scope skills.
func SkillsPromptBlock ¶
SkillsPromptBlock renders the system-prompt trigger list: name + description + location only — the body stays on disk until the model reads it (progressive disclosure).
func SkillsUserDir ¶
func SkillsUserDir() string
SkillsUserDir is where ask writes new user-scope skills.
func StripFencedCodeBlocks ¶
StripFencedCodeBlocks replaces fenced code block content with spaces, preserving newlines. Handles both ``` and ~~~ fences with optional info strings. Unterminated fences consume the remainder of the input.
func SubagentSearchDirs ¶
SubagentSearchDirs is SubagentSearchRoots without the origin tags.
func SubagentToolNames ¶
func SubagentToolNames(def SubagentDef) []string
SubagentToolNames returns the slice of tool names allowed for the subagent.
func SubagentsPromptBlock ¶
func SubagentsPromptBlock(defs []SubagentDef) string
SubagentsPromptBlock lists the named subagents in the system prompt.
func ToolResultText ¶
ToolResultText renders an ADK function response as the line a UI shows, and reports whether it represents an error.
Tool results are per-tool structs now, so there is no single "result" key to read. A result carries its own error text in "error"; that is what makes a call render as failed.
func TruncateInstructionDoc ¶
TruncateInstructionDoc bounds body to limit bytes.
Truncation is line-aligned and never splits a UTF-8 rune — the old body[:limit] slice could cut mid-rune and put invalid UTF-8 on the wire. What is dropped is stated rather than implied: the notice names the file and the byte counts so a model that needs the tail can read it, instead of a bare "… (truncated)" that reads like the document simply ended.
func UnquoteYAML ¶
UnquoteYAML strips quotes surrounding a YAML string value, decoding the escapes each quoting style allows.
func UnwrapConfirmationCall ¶
func UnwrapConfirmationCall(fc *genai.FunctionCall) (*genai.FunctionCall, error)
UnwrapConfirmationCall extracts the underlying function call from an ADK confirmation wrapper.
func WorkflowCompileConfig ¶
func WorkflowCompileConfig(e *Engine, cwd string, tabID int, def workflow.Def, src workflow.Source) workflow.WorkflowAgentConfig
WorkflowCompileConfig builds the compile-time wiring for a workflow run: how each step resolves its model and tool surface. Shared by the headless engine and the TUI so both compile identical graphs.
func WorkflowGraphAgent ¶
WorkflowGraphAgent wraps a compiled workflow so it can be handed to an ADK runner. *workflow.Workflow is not itself an agent.Agent — the interface has an unexported method — but its Run has the agent Run shape, so agent.New adopts it directly.
Types ¶
type ADKRunnable ¶
ADKRunnable is ADK's executable-tool contract, mirroring the private runnableTool interface in adk/v2/tool/tool.go. Every tool ask builds satisfies it: functiontool.New returns one, and the decorators implement it directly.
type AgentPatch ¶
type AgentPatch struct {
Description *string
Prompt *string
Provider *string
Model *string
Tools *[]string
}
AgentPatch is a partial update; nil fields are left unchanged.
type AgentSpec ¶
type AgentSpec struct {
Name string
Description string
Prompt string
Provider string
Model string
Tools []string
}
AgentSpec describes a subagent to create.
type ApprovalRequest ¶
type ApprovalRequest struct {
ToolName string `json:"tool_name"`
Input map[string]any `json:"input"`
ToolUseID string `json:"tool_use_id,omitempty"`
}
ApprovalRequest asks the user to permit a mutating tool invocation.
type ApprovalResponse ¶
type ApprovalResponse struct {
Allow bool `json:"allow"`
Remember *PermissionRule `json:"remember,omitempty"`
}
ApprovalResponse contains the user's decision on tool approval.
type AssistantTextEvent ¶
AssistantTextEvent is emitted when a complete text block from the assistant finishes.
func (AssistantTextEvent) Kind ¶
func (AssistantTextEvent) Kind() EventKind
type BaseEvent ¶
type BaseEvent struct {
TabID int `json:"tab_id"`
}
BaseEvent provides the common tabID tracking.
type BgTaskEndedEvent ¶
type BgTaskEndedEvent struct {
BaseEvent
JobID string `json:"job_id"`
ExitCode int `json:"exit_code"`
}
BgTaskEndedEvent is emitted when a background job completes.
func (BgTaskEndedEvent) Kind ¶
func (BgTaskEndedEvent) Kind() EventKind
type BgTaskStartedEvent ¶
type BgTaskStartedEvent struct {
BaseEvent
JobID string `json:"job_id"`
Description string `json:"description"`
}
BgTaskStartedEvent is emitted when a background job starts.
func (BgTaskStartedEvent) Kind ¶
func (BgTaskStartedEvent) Kind() EventKind
type ContextAwareTool ¶
type ContextAwareTool struct {
Inner Tool
// contains filtered or unexported fields
}
func (*ContextAwareTool) Declaration ¶
func (ct *ContextAwareTool) Declaration() *genai.FunctionDeclaration
func (*ContextAwareTool) Description ¶
func (ct *ContextAwareTool) Description() string
func (*ContextAwareTool) Info ¶
func (ct *ContextAwareTool) Info() ToolInfo
func (*ContextAwareTool) IsLongRunning ¶
func (ct *ContextAwareTool) IsLongRunning() bool
func (*ContextAwareTool) Name ¶
func (ct *ContextAwareTool) Name() string
func (*ContextAwareTool) ProcessRequest ¶
func (ct *ContextAwareTool) ProcessRequest(ctx agent.Context, req *model.LLMRequest) error
func (*ContextAwareTool) RelPath ¶
func (ct *ContextAwareTool) RelPath(p string) string
type ContextScope ¶
ContextScope is one directory searched for instruction files, paired with the root its @-links resolve against.
The two differ for the user-global scope: ~/.claude/CLAUDE.md is not inside the project, so an @-link in it must resolve under ~/.claude, not under the repository that happens to be open.
func AgentContextScopes ¶
func AgentContextScopes(cwd string) []ContextScope
AgentContextScopes is AgentContextSearchDirs with each directory's @-link resolution root attached.
type Coordinator ¶
type Coordinator struct {
// contains filtered or unexported fields
}
Coordinator manages the background execution of all in-process agent sessions without coupling to Bubble Tea or UI models.
func NewCoordinator ¶
func NewCoordinator(interaction InteractionHandler, listener EventListener) *Coordinator
func (*Coordinator) CancelWorkflow ¶
func (c *Coordinator) CancelWorkflow(tabID int)
func (*Coordinator) GetSession ¶
func (c *Coordinator) GetSession(tabID int) *Session
func (*Coordinator) HasSession ¶
func (c *Coordinator) HasSession(tabID int) bool
func (*Coordinator) InterruptSession ¶
func (c *Coordinator) InterruptSession(tabID int) bool
func (*Coordinator) IsBusy ¶
func (c *Coordinator) IsBusy(tabID int) bool
func (*Coordinator) RemoveSession ¶
func (c *Coordinator) RemoveSession(tabID int)
func (*Coordinator) SetSession ¶
func (c *Coordinator) SetSession(tabID int, s *Session)
type DoneEvent ¶
type DoneEvent struct {
BaseEvent
Result ResultSummary `json:"result"`
Error error `json:"error,omitempty"`
}
DoneEvent is emitted when a turn completes.
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine is the central, headless Ask engine that can be embedded into any Go application.
func (*Engine) CompileWorkflow ¶
func (e *Engine) CompileWorkflow(ctx context.Context, cwd string, tabID int, def workflow.Def, src workflow.Source) (*workflow.Compiled, error)
CompileWorkflow compiles a workflow definition into an executable ADK graph using the engine's model and tool wiring.
func (*Engine) Coordinator ¶
func (e *Engine) Coordinator() *Coordinator
func (*Engine) Interaction ¶
func (e *Engine) Interaction() InteractionHandler
func (*Engine) RunWorkflow ¶
func (e *Engine) RunWorkflow(ctx context.Context, cwd string, tabID int, def workflow.Def, src workflow.Source) error
RunWorkflow compiles def and drives it to completion on ADK's workflow scheduler, translating the event stream into both agent events (tool calls, text) and workflow progress callbacks.
type EngineEvent ¶
EngineEvent is the common interface implemented by all events emitted by the ask engine.
type EventKind ¶
type EventKind string
EventKind identifies the type of an EngineEvent.
const ( EventKindTextDelta EventKind = "text_delta" EventKindAssistantText EventKind = "assistant_text" EventKindStatus EventKind = "status" EventKindToolCall EventKind = "tool_call" EventKindToolResult EventKind = "tool_result" EventKindToolDiff EventKind = "tool_diff" EventKindUsage EventKind = "usage" EventKindCost EventKind = "cost" EventKindModelInfo EventKind = "model_info" EventKindTodoUpdate EventKind = "todo_update" EventKindSubagentStarted EventKind = "subagent_started" EventKindSubagentEnded EventKind = "subagent_ended" EventKindBgTaskStarted EventKind = "bg_task_started" EventKindBgTaskEnded EventKind = "bg_task_ended" EventKindDone EventKind = "done" EventKindExited EventKind = "exited" EventKindTurnComplete EventKind = "turn_complete" EventKindMidTurnDrained EventKind = "mid_turn_drained" EventKindWorkflowStarted EventKind = "workflow_started" EventKindWorkflowStep EventKind = "workflow_step" EventKindWorkflowDone EventKind = "workflow_done" EventKindWorkflowFailed EventKind = "workflow_failed" EventKindExtensions EventKind = "extensions_changed" EventKindMCPStatus EventKind = "mcp_status_changed" )
type EventListener ¶
type EventListener func(event EngineEvent)
EventListener is a callback function that handles stream events from the engine.
type ExitedEvent ¶
type ExitedEvent struct {
BaseEvent
}
ExitedEvent is emitted when the session goroutine closes.
func (ExitedEvent) Kind ¶
func (ExitedEvent) Kind() EventKind
type ExtensionsChangedEvent ¶
ExtensionsChangedEvent is emitted when a tool creates, edits, deletes, installs, or publishes a skill, agent, plugin, or marketplace, so the UI re-registers slash commands and refreshes the browser.
func (ExtensionsChangedEvent) Kind ¶
func (ExtensionsChangedEvent) Kind() EventKind
type FilePart ¶
type FilePart struct {
Path string `json:"path,omitempty"`
MIMEType string `json:"mime_type,omitempty"`
Data []byte `json:"data,omitempty"`
}
FilePart represents a binary file/image attachment.
type FileSessionService ¶
type FileSessionService struct {
// contains filtered or unexported fields
}
FileSessionService implements google.golang.org/adk/v2/session.Service backed by atomic JSON files under ~/.config/ask/agent-sessions/<provider>/<encoded-cwd>/<sessionID>.json.
func NewFileSessionService ¶
func NewFileSessionService(provider, cwd string) *FileSessionService
NewFileSessionService creates a new FileSessionService for the given provider and working directory.
func NewFileSessionServiceWithBaseDir ¶
func NewFileSessionServiceWithBaseDir(provider, cwd, baseDir string) *FileSessionService
NewFileSessionServiceWithBaseDir creates a FileSessionService with a custom base directory (useful for testing).
func (*FileSessionService) AppendEvent ¶
func (s *FileSessionService) AppendEvent(ctx context.Context, curSession session.Session, event *session.Event) error
AppendEvent appends a non-partial event, updates state deltas, and saves to disk atomically.
func (*FileSessionService) Create ¶
func (s *FileSessionService) Create(ctx context.Context, req *session.CreateRequest) (*session.CreateResponse, error)
Create initializes a new session and persists it atomically to disk.
func (*FileSessionService) Delete ¶
func (s *FileSessionService) Delete(ctx context.Context, req *session.DeleteRequest) error
Delete removes a session file from disk.
func (*FileSessionService) DirFor ¶
func (s *FileSessionService) DirFor(cwd string) (string, error)
DirFor returns the directory path for sessions stored for a specific working directory.
func (*FileSessionService) Get ¶
func (s *FileSessionService) Get(ctx context.Context, req *session.GetRequest) (*session.GetResponse, error)
Get loads a session from disk, applying optional timestamp and event count filters.
func (*FileSessionService) List ¶
func (s *FileSessionService) List(ctx context.Context, req *session.ListRequest) (*session.ListResponse, error)
List enumerates sessions, filtered by AppName and UserID (if provided).
func (*FileSessionService) PathFor ¶
func (s *FileSessionService) PathFor(id string) (string, error)
PathFor locates an existing session file by ID across all project directories.
func (*FileSessionService) Root ¶
func (s *FileSessionService) Root() (string, error)
Root returns the base directory for stored sessions for this provider.
type GenerateStreamFunc ¶
type GenerateStreamFunc func(ctx context.Context, client *genai.Client, model string, contents []*genai.Content, config *genai.GenerateContentConfig) iter.Seq2[*genai.GenerateContentResponse, error]
GenerateStreamFunc defines the signature for streaming content generation from GenAI.
var GenerateStream GenerateStreamFunc = func(ctx context.Context, client *genai.Client, model string, contents []*genai.Content, config *genai.GenerateContentConfig) iter.Seq2[*genai.GenerateContentResponse, error] { if client == nil { return func(yield func(*genai.GenerateContentResponse, error) bool) { yield(nil, errors.New("genai client is nil")) } } return client.Models.GenerateContentStream(ctx, model, contents, config) }
GenerateStream is the streaming generation hook, swappable in tests.
type HeadlessInteractionHandler ¶
type HeadlessInteractionHandler struct {
AutoApproveTools bool
}
HeadlessInteractionHandler is a default InteractionHandler for automated runs.
func (HeadlessInteractionHandler) AskQuestion ¶
func (h HeadlessInteractionHandler) AskQuestion(ctx context.Context, tabID int, questions []Question) (QuestionResponse, error)
func (HeadlessInteractionHandler) ConfirmPlan ¶
func (h HeadlessInteractionHandler) ConfirmPlan(ctx context.Context, tabID int, req PlanRequest) (PlanResponse, error)
func (HeadlessInteractionHandler) RequestApproval ¶
func (h HeadlessInteractionHandler) RequestApproval(ctx context.Context, tabID int, req ApprovalRequest) (ApprovalResponse, error)
func (HeadlessInteractionHandler) RequestSudoPassword ¶
func (h HeadlessInteractionHandler) RequestSudoPassword(ctx context.Context, tabID int, prompt string) (SudoPasswordResponse, error)
type InteractionHandler ¶
type InteractionHandler interface {
AskQuestion(ctx context.Context, tabID int, questions []Question) (QuestionResponse, error)
RequestApproval(ctx context.Context, tabID int, req ApprovalRequest) (ApprovalResponse, error)
ConfirmPlan(ctx context.Context, tabID int, req PlanRequest) (PlanResponse, error)
RequestSudoPassword(ctx context.Context, tabID int, prompt string) (SudoPasswordResponse, error)
}
InteractionHandler is implemented by user interfaces (TUI, Web UI, CLI, headless agents) to respond to interactive requests from the engine and tools.
type LoadedContextDoc ¶
type LoadedContextDoc struct {
Path string
// Body is what goes into the prompt, capped by
// TruncateInstructionDoc.
Body string
// Root is the directory this document's @-links resolve against —
// its own scope, not necessarily the project root.
Root string
// Links are the @-references found in the document's FULL body,
// before any truncation. Body alone is not a safe source for them:
// a link past the cap is still a real dependency of the
// instructions and must still be followed.
Links []string
}
LoadedContextDoc is one document that has been loaded for inclusion in the system prompt — either a project instruction file or an @-linked document resolved during prompt assembly.
func AgentContextFiles ¶
func AgentContextFiles(cwd string) []LoadedContextDoc
AgentContextFiles loads the project's instruction files (CLAUDE.md, AGENTS.md, …) from every directory in AgentContextSearchDirs — the user-global ~/.claude scope and the project-root-to-cwd chain — so running ask from a subdirectory still sees the project's instructions. Each distinct file is loaded once: a symlinked AGENTS.md contributes its target's body a single time rather than duplicating it. @-link references within these files are resolved separately by LoadContextLinks during BuildSystemPrompt and placed in a dedicated <included_docs> block — they are not part of this function's return.
func LoadContextLinks ¶
func LoadContextLinks(repoRoot string, sourceBodies []string) []LoadedContextDoc
LoadContextLinks walks the @-link graph breadth-first starting from the links in sourceBodies. Callers that already hold a document's untruncated link list should prefer LoadContextLinksFrom — passing a capped Body here would lose every link past the cap.
func LoadContextLinksFrom ¶
func LoadContextLinksFrom(repoRoot string, links []string) []LoadedContextDoc
LoadContextLinksFrom walks the @-link graph breadth-first from an explicit seed list: it resolves each link against repoRoot, loads the file, and repeats for the links found inside it. Each loaded file is scanned for further links BEFORE it is truncated, so a deep @-chain survives a large intermediate document.
func RuleLinkedDocs ¶
func RuleLinkedDocs(repoRoot, body string) []LoadedContextDoc
RuleLinkedDocs resolves @-links found in a rule body (JIT rules, skills, subagents) and returns the loaded documents.
type MCPStatusChangedEvent ¶
type MCPStatusChangedEvent struct {
BaseEvent
}
MCPStatusChangedEvent is emitted when a session's set of MCP servers changes connection/auth state, so the UI can refresh an open browser.
func (MCPStatusChangedEvent) Kind ¶
func (MCPStatusChangedEvent) Kind() EventKind
type MemoryExtractor ¶
type MemoryExtractor struct {
// contains filtered or unexported fields
}
MemoryExtractor is the background worker that turns finished turns into concepts: one goroutine, a bounded queue that drops the oldest job when full, and a context that Close cancels.
func EnsureMemoryExtractor ¶
func EnsureMemoryExtractor() *MemoryExtractor
EnsureMemoryExtractor returns the process-wide extractor, starting it (and registering it with the memory service) the first time memory is open. Nil while memory is closed.
func NewMemoryExtractor ¶
func NewMemoryExtractor(opts MemoryExtractorOptions) *MemoryExtractor
NewMemoryExtractor starts the worker.
func (*MemoryExtractor) Close ¶
func (e *MemoryExtractor) Close()
Close stops accepting turns, cancels the job in flight, and waits for the worker to exit. Queued jobs that never ran are released.
func (*MemoryExtractor) Drain ¶
func (e *MemoryExtractor) Drain(ctx context.Context) error
Drain blocks until every queued job has finished or ctx ends.
func (*MemoryExtractor) Dropped ¶
func (e *MemoryExtractor) Dropped() int
Dropped reports how many queued turns were discarded to make room.
func (*MemoryExtractor) Enqueue ¶
func (e *MemoryExtractor) Enqueue(rec memory.TurnRecord) bool
Enqueue adapts a memory.TurnRecord (ADK's AddSessionToMemory path).
func (*MemoryExtractor) EnqueueTurn ¶
func (e *MemoryExtractor) EnqueueTurn(turn MemoryTurn) bool
EnqueueTurn queues a turn. It reports false when the extractor is closed or the turn has nothing to extract from. A full queue drops its oldest job so a stalled provider cannot pile up work.
type MemoryExtractorOptions ¶
type MemoryExtractorOptions struct {
// LoadConfig supplies the config each job reads; nil means config.Load.
LoadConfig func() (config.Config, error)
QueueSize int
Timeout time.Duration
}
MemoryExtractorOptions configures a MemoryExtractor.
type MemoryTurn ¶
type MemoryTurn struct {
Cwd string
Prompt string
Response string
// Topic is the tab's current topic, offered to the model as the
// default.
Topic string
// Files are the paths the turn read or edited.
Files []string
// Provider is the session's provider, used when the config names
// none for memory.
Provider string
// OnUsage reports the extraction call's own token usage.
OnUsage func(providerID, modelID string, inputTokens, outputTokens int)
// OnTopic receives the topic the model settled on for the turn.
OnTopic func(topic string)
}
MemoryTurn is one finished turn queued for concept extraction.
type Message ¶
type Message struct {
Role MessageRole `json:"role"`
Text string `json:"text,omitempty"`
Thoughts []ThoughtPart `json:"thoughts,omitempty"`
Files []FilePart `json:"files,omitempty"`
ToolCalls []ToolCallPart `json:"tool_calls,omitempty"`
ToolResults []ToolResultPart `json:"tool_results,omitempty"`
}
Message is the native ask message structure.
func MessageFromGenAIContent ¶
func MessagesFromEvents ¶
MessagesFromEvents converts ADK session.Event slices to native ask Message slices.
func NewAssistantMessage ¶
func NewAssistantMessage(text string, thoughts []ThoughtPart, toolCalls []ToolCallPart) Message
func NewToolResultMessage ¶
func NewToolResultMessage(toolResults ...ToolResultPart) Message
func NewUserMessage ¶
func (Message) ToGenAIContent ¶
func (*Message) UnmarshalJSON ¶
type MessageRole ¶
type MessageRole string
MessageRole defines the role of a message participant.
const ( RoleUser MessageRole = "user" RoleAssistant MessageRole = "assistant" RoleModel MessageRole = "model" RoleSystem MessageRole = "system" RoleTool MessageRole = "tool" )
type MidTurnDrainedEvent ¶
MidTurnDrainedEvent is emitted when a queued mid-turn message is drained into the session.
func (MidTurnDrainedEvent) Kind ¶
func (MidTurnDrainedEvent) Kind() EventKind
type MidTurnQueue ¶
type MidTurnQueue struct {
// contains filtered or unexported fields
}
MidTurnQueue is a thread-safe FIFO queue for pending user messages mid-turn.
func (*MidTurnQueue) Drain ¶
func (q *MidTurnQueue) Drain() []string
func (*MidTurnQueue) Push ¶
func (q *MidTurnQueue) Push(text string)
type ModelInfoEvent ¶
ModelInfoEvent communicates the resolved model ID for the active session.
func (ModelInfoEvent) Kind ¶
func (ModelInfoEvent) Kind() EventKind
type Options ¶
type Options struct {
Config config.Config
InteractionHandler InteractionHandler
EventListener EventListener
}
Options holds configuration and handlers for the ask Engine.
type Origin ¶
type Origin struct {
Scope OriginScope
Plugin string
}
Origin is the provenance of a discovered skill or agent: a user or project directory, or an installed plugin ("name@marketplace").
type OriginScope ¶
type OriginScope string
OriginScope says where a skill or agent definition lives.
const ( OriginUser OriginScope = "user" OriginProject OriginScope = "project" OriginPlugin OriginScope = "plugin" )
func NormalizeOriginScope ¶
func NormalizeOriginScope(s string) (OriginScope, error)
NormalizeOriginScope maps "" to project and validates writable scopes.
type PermissionRule ¶
type PermissionRule struct {
ToolName string `json:"tool_name"`
RuleContent string `json:"rule_content"`
}
PermissionRule identifies a scoped permission grant.
type PlanRequest ¶
type PlanRequest struct {
Plan string `json:"plan"`
Explanation string `json:"explanation"`
DefaultWorkflow string `json:"default_workflow,omitempty"`
}
PlanRequest asks the user to confirm a finalized plan.
type PlanResponse ¶
type PlanResponse struct {
Headless bool `json:"headless,omitempty"`
Cancelled bool `json:"cancelled,omitempty"`
TalkMore bool `json:"talk_more,omitempty"`
ExecuteInline bool `json:"execute_inline,omitempty"`
WorkflowName string `json:"workflow_name,omitempty"`
WorkflowDone bool `json:"workflow_done,omitempty"`
FailedReason string `json:"failed_reason,omitempty"`
Outcome string `json:"outcome,omitempty"`
Artifacts []string `json:"artifacts,omitempty"`
Source any `json:"-"`
}
PlanResponse contains the user's choice after reviewing a plan.
type PromptOptions ¶
type Question ¶
type Question struct {
Kind string `json:"kind"` // "pick_one", "pick_many", "pick_diagram"
Prompt string `json:"prompt"`
Options []QuestionOption `json:"options"`
AllowCustom bool `json:"allow_custom,omitempty"`
}
Question represents a structured prompt for the user.
type QuestionAnswer ¶
type QuestionAnswer struct {
Picks []string `json:"picks"`
Custom string `json:"custom,omitempty"`
Note string `json:"note,omitempty"`
}
QuestionAnswer contains the user's response to a single question.
type QuestionOption ¶
type QuestionOption struct {
Label string `json:"label"`
Diagram string `json:"diagram,omitempty"`
}
QuestionOption represents a single choice in a question modal.
type QuestionResponse ¶
type QuestionResponse struct {
Answers []QuestionAnswer `json:"answers"`
Cancelled bool `json:"cancelled,omitempty"`
Headless bool `json:"headless,omitempty"`
}
QuestionResponse is the full result from answering one or more questions.
type ResultSummary ¶
type ResultSummary struct {
SessionID string `json:"session_id"`
Result string `json:"result"`
IsError bool `json:"is_error"`
}
ResultSummary contains the outcome of a provider turn.
type Rule ¶
type Rule struct {
// Path is the absolute path to the rule file.
Path string
// Rel is the rule file's label in prompts.
Rel string
// Paths is the compiled glob list from `paths` frontmatter. Empty means eager.
Paths []string
// Body is the markdown instruction text, capped by
// TruncateInstructionDoc.
Body string
// Links are the @-references found in the rule's FULL body, before
// truncation — see LoadedContextDoc.Links.
Links []string
// Root is the directory this rule's @-links resolve against: its own
// scope root, so a user-global rule links within ~/.claude rather
// than into whichever repository is open.
Root string
}
Rule is one parsed .claude/rules/*.md file.
func DiscoverRules ¶
type RuleScope ¶
func RuleSearchScopes ¶
type RunOptions ¶
type RunOptions struct {
// Prompt is the user query, instruction, or task description.
Prompt string `json:"prompt"`
// SessionID is the unique session identifier. If empty, a new session is created.
// If provided, prior conversation turns and tool calls are loaded from disk.
SessionID string `json:"session_id,omitempty"`
// Cwd is the target working directory. Defaults to os.Getwd().
Cwd string `json:"cwd,omitempty"`
// Config optionally overrides default configuration (~/.config/ask/ask.json).
Config config.Config `json:"config,omitempty"`
// Provider optionally overrides the LLM provider (e.g. "vertex"); empty
// means Config.Provider, then the first registered provider.
Provider string `json:"provider,omitempty"`
// Model optionally overrides the default model for the selected provider.
Model string `json:"model,omitempty"`
// Effort optionally sets reasoning/thinking effort level.
Effort string `json:"effort,omitempty"`
// Files provides optional image/media attachments for models with vision.
Files []FilePart `json:"files,omitempty"`
// Tools optionally overrides or augments the default toolset.
Tools []Tool `json:"-"`
// EventListener receives real-time streaming deltas, tool calls, and lifecycle events.
EventListener EventListener `json:"-"`
// InteractionHandler manages tool approval prompts and user questions.
// Defaults to HeadlessInteractionHandler{AutoApproveTools: true}.
InteractionHandler InteractionHandler `json:"-"`
// SkipAllPermissions bypasses confirmation prompts for all tools.
SkipAllPermissions bool `json:"skip_all_permissions,omitempty"`
// SkipMemory leaves the finished turn out of concept extraction. Set
// for sub-agent runs, whose turns are not the user's conversation.
SkipMemory bool `json:"skip_memory,omitempty"`
}
RunOptions defines the input parameters for executing an ask agent turn.
type RunResult ¶
type RunResult struct {
// SessionID is the session identifier used for this turn (persisted on disk).
SessionID string `json:"session_id"`
// Response is the final assistant text output.
Response string `json:"response"`
// Messages contains the complete message history up to this point.
Messages []Message `json:"messages"`
// IsError indicates whether the turn failed.
IsError bool `json:"is_error"`
// Error contains the failure error, if any.
Error error `json:"error,omitempty"`
}
RunResult contains the outcome of the agent turn.
type RunnerBuilderFunc ¶
type RunnerBuilderFunc func(agentInstance agent.Agent, sessSvc session.Service) (*runner.Runner, error)
RunnerBuilder allows customizing or mocking the ADK runner in tests.
var RunnerBuilder RunnerBuilderFunc = func(agentInstance agent.Agent, sessSvc session.Service) (*runner.Runner, error) { var memSvc adkmemory.Service if pkgMem := pkgmemory.Default(); pkgMem != nil && pkgMem.IsOpen() { memSvc = pkgMem } else { memSvc = adkmemory.InMemoryService() } return runner.New(runner.Config{ AppName: "ask", Agent: agentInstance, SessionService: sessSvc, AutoCreateSession: true, MemoryService: memSvc, ArtifactService: artifact.InMemoryService(), PluginConfig: runner.PluginConfig{ Plugins: DefaultPlugins(), }, }) }
type Session ¶
type Session struct {
// contains filtered or unexported fields
}
func NewSession ¶
func NewSession(args SessionArgs, llm model.LLM, system string, tools []Tool, listener EventListener, interaction InteractionHandler) *Session
func (*Session) Emit ¶
func (s *Session) Emit(event EngineEvent)
func (*Session) InterruptTurn ¶
func (*Session) LastResponse ¶
func (*Session) QueueMidTurn ¶
func (*Session) QueueTurnSync ¶
QueueTurnSync sends a turn to the session and blocks until turn execution is completed.
type SessionArgs ¶
type SessionStore ¶
type SessionStore struct {
// contains filtered or unexported fields
}
SessionStore provides backwards compatibility adapter for existing callers.
func NewSessionStore ¶
func NewSessionStore(provider string) *SessionStore
NewSessionStore creates a new SessionStore adapter wrapping FileSessionService.
func (*SessionStore) Delete ¶
func (st *SessionStore) Delete(id string) error
func (*SessionStore) List ¶
func (st *SessionStore) List(cwd string) ([]SessionSummary, error)
func (*SessionStore) Load ¶
func (st *SessionStore) Load(id string) (StoredSessionFile, error)
func (*SessionStore) Root ¶
func (st *SessionStore) Root() (string, error)
func (*SessionStore) SaveEvents ¶
func (st *SessionStore) SaveEvents(id, cwd string, events []*session.Event) error
type SessionSummary ¶
type SessionSummary struct {
ID string `json:"id"`
Cwd string `json:"cwd"`
Preview string `json:"preview"`
ModTime time.Time `json:"modTime"`
}
SessionSummary summarizes a stored session for listing.
type Skill ¶
type Skill struct {
// Name is the slash/invocation name; plugin skills carry the
// "plugin:" prefix the way Claude Code namespaces them.
Name string
BareName string
Description string
// Dir is the skill package directory; Path is its SKILL.md (or the
// command file).
Dir string
Path string
// UserInvocable surfaces the skill as a /name slash command
// (default true; `user-invocable: false` hides it).
UserInvocable bool
// DisableModelInvocation removes the skill from the system-prompt
// trigger list — the user can still invoke it explicitly.
DisableModelInvocation bool
// Frontmatter holds the parsed ADK frontmatter when available.
Frontmatter *skill.Frontmatter
Origin Origin
Command bool
}
Skill is one discovered skill: a SKILL.md package, or a single-file command (Claude Code's commands/*.md) loaded with the same contract.
func CreateSkill ¶
func CreateSkill(cwd string, scope OriginScope, spec SkillSpec) (Skill, error)
CreateSkill writes a new skill package into scope.
func DiscoverSkills ¶
DiscoverSkills walks every root and enabled plugin for skill packages. Invalid packages (bad name, missing description) are skipped rather than failing the session.
func ResolveEditableSkill ¶
func ResolveEditableSkill(cwd, name string, scope OriginScope) (Skill, error)
ResolveEditableSkill finds the one user/project skill called name. With scope "" the name must be unambiguous.
func UpdateSkill ¶
func UpdateSkill(cwd, name string, scope OriginScope, patch SkillPatch) (Skill, error)
UpdateSkill applies patch to an existing user/project skill in place, keeping frontmatter keys it does not model.
type SkillPatch ¶
type SkillPatch struct {
Description *string
Body *string
UserInvocable *bool
DisableModelInvocation *bool
}
SkillPatch is a partial update; nil fields are left unchanged.
type SkillRoot ¶
SkillRoot is one directory of skill packages plus the origin its skills are tagged with.
func SkillSearchRoots ¶
SkillSearchRoots returns the user and project discovery roots in precedence order — later roots win on a name clash, so project skills override user-global ones. Plugin skills are namespaced and never clash; they come from plugin.EnabledPlugins.
type SkillSpec ¶
type SkillSpec struct {
Name string
Description string
Body string
UserInvocable *bool
DisableModelInvocation *bool
License string
Compatibility string
}
SkillSpec describes a skill to create.
type StatusEvent ¶
StatusEvent indicates the agent's current state (e.g. "thinking…", "running tool…").
func (StatusEvent) Kind ¶
func (StatusEvent) Kind() EventKind
type StoredSessionFile ¶
type StoredSessionFile struct {
Version int `json:"version"`
AppName string `json:"appName"`
UserID string `json:"userID"`
SessionID string `json:"sessionID"`
Cwd string `json:"cwd"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
State map[string]any `json:"state,omitempty"`
Events []*session.Event `json:"events"`
}
StoredSessionFile represents the serialized on-disk format for a session transcript and state.
func ReadStoredSessionFile ¶
func ReadStoredSessionFile(path string) (StoredSessionFile, error)
ReadStoredSessionFile reads and parses a StoredSessionFile from disk.
func (StoredSessionFile) Messages ¶
func (f StoredSessionFile) Messages() []Message
Messages converts stored Events into native ask Message slices.
type SubagentDef ¶
type SubagentDef struct {
// Name is the task-tool name; plugin agents carry the "plugin:"
// prefix the way Claude Code namespaces them.
Name string
BareName string
Description string
Provider string
Model string
Tools []string
Prompt string
Source string
Origin Origin
}
SubagentDef is a named subagent definition.
func CreateAgent ¶
func CreateAgent(cwd string, scope OriginScope, spec AgentSpec) (SubagentDef, error)
CreateAgent writes a new agent definition into scope.
func DiscoverSubagents ¶
func DiscoverSubagents(cwd string) []SubagentDef
DiscoverSubagents reads every *.md definition; later roots win on a name clash.
func FindSubagent ¶
func FindSubagent(cwd, name string) (SubagentDef, bool)
FindSubagent returns the discovered agent with name.
func ResolveEditableAgent ¶
func ResolveEditableAgent(cwd, name string, scope OriginScope) (SubagentDef, error)
ResolveEditableAgent finds the one user/project agent called name.
func UpdateAgent ¶
func UpdateAgent(cwd, name string, scope OriginScope, patch AgentPatch) (SubagentDef, error)
UpdateAgent applies patch to an existing user/project agent in place.
type SubagentEndedEvent ¶
type SubagentEndedEvent struct {
BaseEvent
SubagentID string `json:"subagent_id"`
IsError bool `json:"is_error,omitempty"`
}
SubagentEndedEvent is emitted when a subagent completes execution.
func (SubagentEndedEvent) Kind ¶
func (SubagentEndedEvent) Kind() EventKind
type SubagentRoot ¶
SubagentRoot is one directory of agent definitions plus the origin its agents are tagged with.
func SubagentSearchRoots ¶
func SubagentSearchRoots(cwd string) []SubagentRoot
SubagentSearchRoots returns the user and project roots in precedence order (later wins). Plugin agents are namespaced and come from plugin.EnabledPlugins.
type SubagentStartedEvent ¶
type SubagentStartedEvent struct {
BaseEvent
SubagentID string `json:"subagent_id"`
AgentType string `json:"agent_type"`
Description string `json:"description"`
Background bool `json:"background,omitempty"`
}
SubagentStartedEvent is emitted when a subagent starts execution.
func (SubagentStartedEvent) Kind ¶
func (SubagentStartedEvent) Kind() EventKind
type SudoPasswordResponse ¶
type SudoPasswordResponse struct {
Password string `json:"password"`
Cancelled bool `json:"cancelled"`
}
SudoPasswordResponse contains the user's input for a sudo prompt.
type TextDeltaEvent ¶
TextDeltaEvent is emitted as assistant text streams token-by-token.
func (TextDeltaEvent) Kind ¶
func (TextDeltaEvent) Kind() EventKind
type ThoughtPart ¶
ThoughtPart represents a model's reasoning/thought chunk with signature.
type TodoItem ¶
type TodoItem struct {
Status string `json:"status"`
Content string `json:"content"`
ActiveForm string `json:"active_form,omitempty"`
}
TodoItem represents a single item in the task list.
type TodoUpdateEvent ¶
TodoUpdateEvent is emitted when the session's todo list is updated.
func (TodoUpdateEvent) Kind ¶
func (TodoUpdateEvent) Kind() EventKind
type Tool ¶
Tool represents an executable GenAI/ADK tool, aliasing ADK's native tool.Tool.
func SubagentTools ¶
func SubagentTools(def SubagentDef, available map[string]Tool) []Tool
SubagentTools filters the provided tools map by the subagent's allowed tool names.
type ToolCallEvent ¶
type ToolCallEvent struct {
BaseEvent
ToolUseID string `json:"tool_use_id"`
ToolName string `json:"tool_name"`
Input map[string]any `json:"input"`
Background bool `json:"background,omitempty"`
}
ToolCallEvent is emitted when the agent calls a tool.
func (ToolCallEvent) Kind ¶
func (ToolCallEvent) Kind() EventKind
type ToolCallPart ¶
type ToolCallPart struct {
ID string `json:"id,omitempty"`
Name string `json:"name"`
Args map[string]any `json:"args,omitempty"`
ThoughtSignature []byte `json:"thought_signature,omitempty"`
}
ToolCallPart represents an invocation request from the model.
type ToolDiffEvent ¶
ToolDiffEvent is emitted when a tool mutates a file and produces a unified diff.
func (ToolDiffEvent) Kind ¶
func (ToolDiffEvent) Kind() EventKind
type ToolFactory ¶
type ToolFactory func(args ToolFactoryArgs) []Tool
ToolFactory builds a slice of Tools for an engine turn.
func GetDefaultToolFactory ¶
func GetDefaultToolFactory() ToolFactory
GetDefaultToolFactory retrieves the currently registered default tool factory.
type ToolFactoryArgs ¶
type ToolFactoryArgs struct {
Cwd string
TabID int
SkipPermissions bool
EventListener EventListener
InteractionHandler InteractionHandler
AttachWebSearch bool
// SupportsImages reports whether the run's model can see images; it
// gates feeding tool-rendered images back to the model. Nil is treated
// as capable.
SupportsImages func() bool
// WorkflowStep attaches the workflow-step tools (save_artifact,
// load_artifacts) so a step can pass data to a later one.
WorkflowStep bool
// WorkflowFinalStep also attaches finish_workflow, which reports the
// run's outcome and created artifacts to the user. Only meaningful
// with WorkflowStep.
WorkflowFinalStep bool
}
ToolFactoryArgs provides configuration parameters to construct the agent toolset.
type ToolInfo ¶
type ToolInfo struct {
Name string `json:"name"`
Description string `json:"description"`
Parameters map[string]any `json:"parameters,omitempty"`
Required []string `json:"required,omitempty"`
}
ToolInfo provides tool metadata and parameters.
func ExtractToolInfo ¶
ExtractToolInfo extracts ToolInfo from any ADK Tool.
type ToolResponse ¶
type ToolResponse struct {
Content string `json:"content"`
IsError bool `json:"is_error,omitempty"`
}
ToolResponse represents the result of executing a tool.
func NewTextErrorResponse ¶
func NewTextErrorResponse(text string) ToolResponse
func NewTextResponse ¶
func NewTextResponse(text string) ToolResponse
type ToolResultEvent ¶
type ToolResultEvent struct {
BaseEvent
ToolUseID string `json:"tool_use_id"`
ToolName string `json:"tool_name"`
Output string `json:"output"`
IsError bool `json:"is_error"`
Background bool `json:"background,omitempty"`
}
ToolResultEvent is emitted when a tool completes execution.
func (ToolResultEvent) Kind ¶
func (ToolResultEvent) Kind() EventKind
type ToolResultPart ¶
type ToolResultPart struct {
ID string `json:"id,omitempty"`
Name string `json:"name"`
Content string `json:"content"`
IsError bool `json:"is_error,omitempty"`
}
ToolResultPart represents the response from executing a tool.
type TurnCompleteEvent ¶
type TurnCompleteEvent struct {
BaseEvent
}
TurnCompleteEvent signals the conclusion of a turn's event sequence.
func (TurnCompleteEvent) Kind ¶
func (TurnCompleteEvent) Kind() EventKind
type UsageEvent ¶
type UsageEvent struct {
BaseEvent
InputTokens int `json:"input_tokens"`
OutputTokens int `json:"output_tokens"`
TotalTokens int `json:"total_tokens"`
}
UsageEvent records token consumption for an API step.
func (UsageEvent) Kind ¶
func (UsageEvent) Kind() EventKind
type WorkflowDoneEvent ¶
type WorkflowDoneEvent struct {
BaseEvent
Description string `json:"description"`
Artifacts []string `json:"artifacts"`
}
WorkflowDoneEvent is emitted when an entire workflow finishes.
func (WorkflowDoneEvent) Kind ¶
func (WorkflowDoneEvent) Kind() EventKind
type WorkflowFailedEvent ¶
WorkflowFailedEvent is emitted when a workflow fails or is cancelled.
func (WorkflowFailedEvent) Kind ¶
func (WorkflowFailedEvent) Kind() EventKind
type WorkflowStartedEvent ¶
type WorkflowStartedEvent struct {
BaseEvent
Workflow string `json:"workflow"`
Source string `json:"source"`
}
WorkflowStartedEvent is emitted when a workflow begins execution.
func (WorkflowStartedEvent) Kind ¶
func (WorkflowStartedEvent) Kind() EventKind
type WorkflowStepDoneEvent ¶
type WorkflowStepDoneEvent struct {
BaseEvent
StepIdx int `json:"step_idx"`
Summary string `json:"summary"`
}
WorkflowStepDoneEvent is emitted when an individual step completes.
func (WorkflowStepDoneEvent) Kind ¶
func (WorkflowStepDoneEvent) Kind() EventKind
type WorkflowStepStartedEvent ¶
type WorkflowStepStartedEvent struct {
BaseEvent
StepIdx int `json:"step_idx"`
StepName string `json:"step_name"`
Provider string `json:"provider"`
Model string `json:"model"`
}
WorkflowStepStartedEvent is emitted when an individual workflow step begins.
func (WorkflowStepStartedEvent) Kind ¶
func (WorkflowStepStartedEvent) Kind() EventKind