mirror of
https://github.com/mark3labs/kit.git
synced 2026-06-14 03:30:26 +00:00
rename spawn_subagent tool to subagent; remove redundant toolDisplayNames map
Tool rename (breaking change for ToolName string comparisons in event handlers): - internal/core/subagent.go: Name field 'spawn_subagent' → 'subagent' - internal/extensions/wrapper.go: update coreToolKinds map key - pkg/kit/events.go: update coreToolKinds map key and ToolKindSubagent comment - pkg/kit/extensions_bridge.go: update three ToolName == ... guards - internal/ui/tool_renderers.go: update two toolName == ... case guards - internal/ui/stream.go: remove special-case branch (toolName is now already 'subagent', so the title-case fallback produces 'Subagent' naturally) Comments/docs updated everywhere (no logic changes): - internal/core/tools.go, internal/extensions/api.go, events.go - pkg/kit/kit.go, tools.go - examples/extensions/subagent-test.go, kit-telegram/main.go - README.md, skills/kit-sdk/SKILL.md - www/pages/advanced/subagents.md, extensions/capabilities.md - www/pages/index.md, sdk/callbacks.md - www/public/session/index.html (tracked UI asset) Redundant toolDisplayNames map removed (item #14): - internal/ui/messages.go: delete the 7-entry map whose every value was identical to what the title-case fallback already produced; simplify toolDisplayName() to just the fallback
This commit is contained in:
@@ -18,7 +18,7 @@ A powerful, extensible AI coding agent CLI with multi-provider support, built-in
|
||||
## Features
|
||||
|
||||
- **Multi-Provider LLM Support**: Anthropic, OpenAI, Google Gemini, Ollama, Azure OpenAI, AWS Bedrock, OpenRouter, and more
|
||||
- **Built-in Core Tools**: bash, read, write, edit, grep, find, ls, spawn_subagent - no MCP overhead
|
||||
- **Built-in Core Tools**: bash, read, write, edit, grep, find, ls, subagent - no MCP overhead
|
||||
- **MCP Integration**: Connect external MCP servers for expanded capabilities
|
||||
- **Extension System**: Write custom tools, commands, widgets, and UI modifications in Go
|
||||
- **Theming**: 22 built-in color themes (KITT, Catppuccin, Dracula, Nord, etc.) with runtime switching, persistence, and custom theme files
|
||||
|
||||
@@ -908,7 +908,7 @@ func summarizeToolAction(toolName string, inputJSON string) string {
|
||||
return "searching " + getStr("pattern", "text")
|
||||
case "ls":
|
||||
return "listing " + getStr("path", "directory")
|
||||
case "spawn_subagent":
|
||||
case "subagent":
|
||||
return "spawning subagent"
|
||||
default:
|
||||
return "using " + toolName
|
||||
|
||||
@@ -37,7 +37,7 @@ func Init(api ext.API) {
|
||||
"Subagent Test Extension loaded\n\n" +
|
||||
"/subtest <task> Spawn blocking subagent\n" +
|
||||
"/subbg <task> Spawn background subagent\n\n" +
|
||||
"The LLM can also use the spawn_subagent tool.")
|
||||
"The LLM can also use the subagent tool.")
|
||||
})
|
||||
|
||||
api.OnAgentEnd(func(_ ext.AgentEndEvent, ctx ext.Context) {
|
||||
|
||||
@@ -28,14 +28,14 @@ type SubagentSpawnResult struct {
|
||||
// SubagentSpawnFunc is a callback that spawns an in-process subagent. The
|
||||
// parent Kit instance injects this into the context so the core tool can
|
||||
// call back without importing pkg/kit (which would create a cycle).
|
||||
// The toolCallID parameter is the LLM-assigned ID of the spawn_subagent
|
||||
// The toolCallID parameter is the LLM-assigned ID of the subagent
|
||||
// tool call, enabling the parent to correlate subagent events.
|
||||
type SubagentSpawnFunc func(ctx context.Context, toolCallID, prompt, model, systemPrompt string, timeout time.Duration) (*SubagentSpawnResult, error)
|
||||
|
||||
type subagentCtxKey struct{}
|
||||
|
||||
// WithSubagentSpawner stores a spawn function in the context so that the
|
||||
// spawn_subagent core tool can create in-process subagents.
|
||||
// subagent core tool can create in-process subagents.
|
||||
func WithSubagentSpawner(ctx context.Context, fn SubagentSpawnFunc) context.Context {
|
||||
return context.WithValue(ctx, subagentCtxKey{}, fn)
|
||||
}
|
||||
@@ -49,7 +49,7 @@ func getSubagentSpawner(ctx context.Context) SubagentSpawnFunc {
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// spawn_subagent tool
|
||||
// subagent tool
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
type subagentArgs struct {
|
||||
@@ -59,11 +59,11 @@ type subagentArgs struct {
|
||||
TimeoutSeconds int `json:"timeout_seconds,omitempty"`
|
||||
}
|
||||
|
||||
// NewSubagentTool creates the spawn_subagent core tool.
|
||||
// NewSubagentTool creates the subagent core tool.
|
||||
func NewSubagentTool(opts ...ToolOption) fantasy.AgentTool {
|
||||
return &coreTool{
|
||||
info: fantasy.ToolInfo{
|
||||
Name: "spawn_subagent",
|
||||
Name: "subagent",
|
||||
Description: `Spawn a subagent to perform a task autonomously.
|
||||
|
||||
The subagent runs as a separate in-process Kit instance with full tool access
|
||||
|
||||
@@ -86,7 +86,7 @@ func ReadOnlyTools(opts ...ToolOption) []fantasy.AgentTool {
|
||||
}
|
||||
}
|
||||
|
||||
// SubagentTools returns all core tools except spawn_subagent. This prevents
|
||||
// SubagentTools returns all core tools except subagent. This prevents
|
||||
// infinite recursion when a subagent is itself a Kit instance.
|
||||
func SubagentTools(opts ...ToolOption) []fantasy.AgentTool {
|
||||
return []fantasy.AgentTool{
|
||||
|
||||
@@ -1022,7 +1022,7 @@ func (a *API) OnToolResult(handler func(ToolResultEvent, Context) *ToolResultRes
|
||||
a.onToolResult(handler)
|
||||
}
|
||||
|
||||
// OnSubagentStart registers a handler that fires when a spawn_subagent tool
|
||||
// OnSubagentStart registers a handler that fires when a subagent tool
|
||||
// call begins executing. Use the ToolCallID to correlate with subsequent
|
||||
// OnSubagentChunk and OnSubagentEnd events for the same subagent.
|
||||
func (a *API) OnSubagentStart(handler func(SubagentStartEvent, Context)) {
|
||||
@@ -1037,7 +1037,7 @@ func (a *API) OnSubagentChunk(handler func(SubagentChunkEvent, Context)) {
|
||||
a.onSubagentChunk(handler)
|
||||
}
|
||||
|
||||
// OnSubagentEnd registers a handler that fires when a spawn_subagent call
|
||||
// OnSubagentEnd registers a handler that fires when a subagent call
|
||||
// completes. ErrorMsg is non-empty when the subagent failed.
|
||||
func (a *API) OnSubagentEnd(handler func(SubagentEndEvent, Context)) {
|
||||
a.onSubagentEnd(handler)
|
||||
@@ -2046,9 +2046,9 @@ func (BeforeCompactResult) isResult() {}
|
||||
// Subagent lifecycle events (exposed to Yaegi — concrete structs)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// SubagentStartEvent fires when a spawn_subagent tool call begins executing.
|
||||
// SubagentStartEvent fires when a subagent tool call begins executing.
|
||||
type SubagentStartEvent struct {
|
||||
// ToolCallID is the LLM-assigned ID of the spawn_subagent tool call.
|
||||
// ToolCallID is the LLM-assigned ID of the subagent tool call.
|
||||
// Use this to correlate SubagentChunkEvent and SubagentEndEvent.
|
||||
ToolCallID string
|
||||
// Task is the task description passed to the subagent.
|
||||
@@ -2088,7 +2088,7 @@ type SubagentChunkEvent struct {
|
||||
|
||||
func (e SubagentChunkEvent) Type() EventType { return SubagentChunk }
|
||||
|
||||
// SubagentEndEvent fires when a spawn_subagent tool call completes.
|
||||
// SubagentEndEvent fires when a subagent tool call completes.
|
||||
type SubagentEndEvent struct {
|
||||
// ToolCallID matches the SubagentStartEvent.ToolCallID for this subagent.
|
||||
ToolCallID string
|
||||
|
||||
@@ -72,7 +72,7 @@ const (
|
||||
// cancel compaction by returning Cancel=true.
|
||||
BeforeCompact EventType = "before_compact"
|
||||
|
||||
// SubagentStart fires when a spawn_subagent tool call begins executing.
|
||||
// SubagentStart fires when a subagent tool call begins executing.
|
||||
// Carries the tool call ID and the task description.
|
||||
SubagentStart EventType = "subagent_start"
|
||||
|
||||
@@ -80,7 +80,7 @@ const (
|
||||
// subagent: text chunks, tool calls, tool results, etc.
|
||||
SubagentChunk EventType = "subagent_chunk"
|
||||
|
||||
// SubagentEnd fires when a spawn_subagent tool call completes (success
|
||||
// SubagentEnd fires when a subagent tool call completes (success
|
||||
// or error). Carries the final response and any error message.
|
||||
SubagentEnd EventType = "subagent_end"
|
||||
)
|
||||
|
||||
@@ -49,7 +49,7 @@ var coreToolKinds = map[string]string{
|
||||
"ls": "read",
|
||||
"grep": "search",
|
||||
"find": "search",
|
||||
"spawn_subagent": "agent",
|
||||
"subagent": "agent",
|
||||
}
|
||||
|
||||
// toolKindFor returns the ToolKind for a given tool name, defaulting to
|
||||
|
||||
+2
-15
@@ -41,27 +41,14 @@ type UIMessage struct {
|
||||
Streaming bool
|
||||
}
|
||||
|
||||
// toolDisplayNames maps raw tool names to human-friendly display names.
|
||||
var toolDisplayNames = map[string]string{
|
||||
"bash": "Bash",
|
||||
"read": "Read",
|
||||
"write": "Write",
|
||||
"edit": "Edit",
|
||||
"grep": "Grep",
|
||||
"find": "Find",
|
||||
"ls": "Ls",
|
||||
}
|
||||
|
||||
// getTheme returns the current theme (helper for compact_renderer.go)
|
||||
func getTheme() Theme {
|
||||
return GetTheme()
|
||||
}
|
||||
|
||||
// toolDisplayName returns a human-friendly display name for a tool.
|
||||
// toolDisplayName returns a human-friendly display name for a tool,
|
||||
// title-casing the first letter of the raw name.
|
||||
func toolDisplayName(rawName string) string {
|
||||
if display, ok := toolDisplayNames[rawName]; ok {
|
||||
return display
|
||||
}
|
||||
if rawName != "" {
|
||||
return strings.ToUpper(rawName[:1]) + rawName[1:]
|
||||
}
|
||||
|
||||
@@ -650,10 +650,6 @@ func removeToolID(ids []string, id string) []string {
|
||||
}
|
||||
|
||||
// formatToolExecutionMessage creates a descriptive spinner message for tool execution.
|
||||
// For spawn_subagent, it shows simply as "Subagent".
|
||||
func formatToolExecutionMessage(toolName string) string {
|
||||
if toolName == "spawn_subagent" {
|
||||
return "Subagent"
|
||||
}
|
||||
return toolName
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ func renderToolBody(toolName, toolArgs, toolResult string, width int) string {
|
||||
if body := renderBashBody(toolResult, width); body != "" {
|
||||
return body
|
||||
}
|
||||
case toolName == "spawn_subagent":
|
||||
case toolName == "subagent":
|
||||
if body := renderSubagentBody(toolResult, width); body != "" {
|
||||
return body
|
||||
}
|
||||
@@ -780,7 +780,7 @@ func renderToolBodyCompact(toolName, toolArgs, toolResult string, width int) str
|
||||
case toolName == "bash" || toolName == "grep" || toolName == "find" ||
|
||||
strings.Contains(toolName, "shell") || strings.Contains(toolName, "command"):
|
||||
return renderBashCompact(toolResult, width)
|
||||
case toolName == "spawn_subagent":
|
||||
case toolName == "subagent":
|
||||
return renderSubagentCompact(toolResult)
|
||||
}
|
||||
return ""
|
||||
|
||||
+5
-5
@@ -70,7 +70,7 @@ const (
|
||||
ToolKindEdit = "edit" // File modification (edit, write)
|
||||
ToolKindRead = "read" // File reading (read, ls)
|
||||
ToolKindSearch = "search" // Content/file search (grep, find)
|
||||
ToolKindSubagent = "agent" // Subagent spawning (spawn_subagent)
|
||||
ToolKindSubagent = "agent" // Subagent spawning (subagent)
|
||||
)
|
||||
|
||||
// coreToolKinds maps built-in tool names to their kind. MCP and extension
|
||||
@@ -83,7 +83,7 @@ var coreToolKinds = map[string]string{
|
||||
"ls": ToolKindRead,
|
||||
"grep": ToolKindSearch,
|
||||
"find": ToolKindSearch,
|
||||
"spawn_subagent": ToolKindSubagent,
|
||||
"subagent": ToolKindSubagent,
|
||||
}
|
||||
|
||||
// toolKindFor returns the ToolKind for a given tool name, defaulting to
|
||||
@@ -216,7 +216,7 @@ type ToolResultEvent struct {
|
||||
// ToolResultMetadata carries structured data from tool executions.
|
||||
type ToolResultMetadata struct {
|
||||
FileDiffs []FileDiffInfo `json:"file_diffs,omitempty"` // Present for edit/write tools
|
||||
SubagentSessionID string `json:"subagent_session_id,omitempty"` // Present for spawn_subagent tool
|
||||
SubagentSessionID string `json:"subagent_session_id,omitempty"` // Present for subagent tool
|
||||
}
|
||||
|
||||
// FileDiffInfo describes a file modification from an edit or write tool.
|
||||
@@ -457,13 +457,13 @@ func (s *subagentListenerSet) emit(event Event) {
|
||||
//
|
||||
// The listener receives the same event types as Subscribe() (ToolCallEvent,
|
||||
// MessageUpdateEvent, etc.) but scoped to the child agent's activity. If the
|
||||
// tool call ID doesn't correspond to an active or future spawn_subagent call,
|
||||
// tool call ID doesn't correspond to an active or future subagent call,
|
||||
// the listener simply never fires.
|
||||
//
|
||||
// Typical usage — register inside an OnToolCall handler:
|
||||
//
|
||||
// kit.OnToolCall(func(e kit.ToolCallEvent) {
|
||||
// if e.ToolName == "spawn_subagent" {
|
||||
// if e.ToolName == "subagent" {
|
||||
// kit.SubscribeSubagent(e.ToolCallID, func(child kit.Event) {
|
||||
// // real-time subagent events
|
||||
// })
|
||||
|
||||
@@ -126,9 +126,9 @@ func (m *Kit) bridgeExtensions(runner *extensions.Runner) {
|
||||
// extension runner.
|
||||
//
|
||||
// Flow:
|
||||
// ToolExecutionStartEvent(spawn_subagent) → emit SubagentStartEvent
|
||||
// ToolExecutionStartEvent(subagent) → emit SubagentStartEvent
|
||||
// → SubscribeSubagent → emit SubagentChunkEvents
|
||||
// ToolResultEvent(spawn_subagent) → emit SubagentEndEvent
|
||||
// ToolResultEvent(subagent) → emit SubagentEndEvent
|
||||
//
|
||||
// We use ToolExecutionStart (not ToolCall) for SubagentStart because that
|
||||
// is when the subagent actually begins running. We use ToolResult for
|
||||
@@ -146,7 +146,7 @@ func (m *Kit) bridgeExtensions(runner *extensions.Runner) {
|
||||
// Intercept ToolCall to capture the task and subscribe to child events.
|
||||
m.Subscribe(func(e Event) {
|
||||
ev, ok := e.(ToolCallEvent)
|
||||
if !ok || ev.ToolName != "spawn_subagent" {
|
||||
if !ok || ev.ToolName != "subagent" {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -201,7 +201,7 @@ func (m *Kit) bridgeExtensions(runner *extensions.Runner) {
|
||||
if runner.HasHandlers(extensions.SubagentStart) {
|
||||
m.Subscribe(func(e Event) {
|
||||
ev, ok := e.(ToolExecutionStartEvent)
|
||||
if !ok || ev.ToolName != "spawn_subagent" {
|
||||
if !ok || ev.ToolName != "subagent" {
|
||||
return
|
||||
}
|
||||
task := taskMu.get(taskByCallID, ev.ToolCallID)
|
||||
@@ -216,7 +216,7 @@ func (m *Kit) bridgeExtensions(runner *extensions.Runner) {
|
||||
if runner.HasHandlers(extensions.SubagentEnd) {
|
||||
m.Subscribe(func(e Event) {
|
||||
ev, ok := e.(ToolResultEvent)
|
||||
if !ok || ev.ToolName != "spawn_subagent" {
|
||||
if !ok || ev.ToolName != "subagent" {
|
||||
return
|
||||
}
|
||||
task := taskMu.get(taskByCallID, ev.ToolCallID)
|
||||
|
||||
+3
-3
@@ -1256,7 +1256,7 @@ type SubagentConfig struct {
|
||||
SystemPrompt string
|
||||
|
||||
// Tools overrides the tool set. If nil, SubagentTools() is used (all
|
||||
// core tools except spawn_subagent, preventing infinite recursion).
|
||||
// core tools except subagent, preventing infinite recursion).
|
||||
Tools []Tool
|
||||
|
||||
// NoSession, when true, uses an in-memory ephemeral session. When false
|
||||
@@ -1330,7 +1330,7 @@ func (m *Kit) Subagent(ctx context.Context, cfg SubagentConfig) (*SubagentResult
|
||||
systemPrompt = "You are a helpful coding assistant. Complete the task efficiently and thoroughly."
|
||||
}
|
||||
|
||||
// Default tools: everything except spawn_subagent.
|
||||
// Default tools: everything except subagent.
|
||||
tools := cfg.Tools
|
||||
if tools == nil {
|
||||
tools = SubagentTools()
|
||||
@@ -1438,7 +1438,7 @@ func (m *Kit) generate(ctx context.Context, messages []fantasy.Message) (*agent.
|
||||
})
|
||||
|
||||
// Inject the in-process subagent spawner into the context so the
|
||||
// spawn_subagent core tool can create child Kit instances without
|
||||
// subagent core tool can create child Kit instances without
|
||||
// importing pkg/kit (which would create an import cycle).
|
||||
ctx = core.WithSubagentSpawner(ctx, func(
|
||||
spawnCtx context.Context, toolCallID, prompt, model, systemPrompt string, timeout time.Duration,
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ func CodingTools(opts ...ToolOption) []Tool { return core.CodingTools(opts...) }
|
||||
// read, grep, find, ls.
|
||||
func ReadOnlyTools(opts ...ToolOption) []Tool { return core.ReadOnlyTools(opts...) }
|
||||
|
||||
// SubagentTools returns all core tools except spawn_subagent. Use this when
|
||||
// SubagentTools returns all core tools except subagent. Use this when
|
||||
// creating child Kit instances (in-process subagents) to prevent infinite
|
||||
// recursion.
|
||||
func SubagentTools(opts ...ToolOption) []Tool { return core.SubagentTools(opts...) }
|
||||
|
||||
@@ -251,7 +251,7 @@ Tools are classified by kind for UI rendering:
|
||||
- `ToolKindEdit` = `"edit"` — edit, write
|
||||
- `ToolKindRead` = `"read"` — read, ls
|
||||
- `ToolKindSearch` = `"search"` — grep, find
|
||||
- `ToolKindSubagent` = `"agent"` — spawn_subagent
|
||||
- `ToolKindSubagent` = `"agent"` — subagent
|
||||
|
||||
---
|
||||
|
||||
@@ -358,7 +358,7 @@ kit.NewLsTool(opts...) // directory listing
|
||||
kit.AllTools(opts...) // all 7 core tools
|
||||
kit.CodingTools(opts...) // bash, read, write, edit
|
||||
kit.ReadOnlyTools(opts...) // read, grep, find, ls
|
||||
kit.SubagentTools(opts...) // all except spawn_subagent (prevents recursion)
|
||||
kit.SubagentTools(opts...) // all except subagent (prevents recursion)
|
||||
```
|
||||
|
||||
### Tool options
|
||||
@@ -514,7 +514,7 @@ result, err := host.Subagent(ctx, kit.SubagentConfig{
|
||||
Prompt: "Analyze the test files and summarize coverage",
|
||||
Model: "anthropic/claude-haiku-3-5-20241022", // empty = parent's model
|
||||
SystemPrompt: "You are a test analysis expert.",
|
||||
Tools: nil, // nil = SubagentTools() (all except spawn_subagent)
|
||||
Tools: nil, // nil = SubagentTools() (all except subagent)
|
||||
NoSession: true, // ephemeral
|
||||
Timeout: 2 * time.Minute, // 0 = 5 minute default
|
||||
OnEvent: func(e kit.Event) {
|
||||
@@ -532,7 +532,7 @@ result, err := host.Subagent(ctx, kit.SubagentConfig{
|
||||
|
||||
```go
|
||||
host.OnToolCall(func(e kit.ToolCallEvent) {
|
||||
if e.ToolName == "spawn_subagent" {
|
||||
if e.ToolName == "subagent" {
|
||||
host.SubscribeSubagent(e.ToolCallID, func(child kit.Event) {
|
||||
// Real-time events scoped to this subagent
|
||||
})
|
||||
|
||||
@@ -32,12 +32,12 @@ Key flags for subprocess usage:
|
||||
|
||||
Positional arguments are the prompt. `@file` arguments attach file content as context.
|
||||
|
||||
## Built-in spawn_subagent tool
|
||||
## Built-in subagent tool
|
||||
|
||||
Kit includes a built-in `spawn_subagent` tool that the LLM can use to delegate tasks to independent child agents:
|
||||
Kit includes a built-in `subagent` tool that the LLM can use to delegate tasks to independent child agents:
|
||||
|
||||
```
|
||||
spawn_subagent(
|
||||
subagent(
|
||||
task: "Analyze the test files and summarize coverage",
|
||||
model: "anthropic/claude-haiku-latest", // optional
|
||||
system_prompt: "You are a test analysis expert.", // optional
|
||||
@@ -61,7 +61,7 @@ result := ctx.SpawnSubagent(ext.SubagentConfig{
|
||||
|
||||
### Monitoring subagents from extensions
|
||||
|
||||
When the LLM (not the extension itself) spawns a subagent using the `spawn_subagent` tool, extensions can monitor its activity in real-time using three lifecycle event handlers:
|
||||
When the LLM (not the extension itself) spawns a subagent using the `subagent` tool, extensions can monitor its activity in real-time using three lifecycle event handlers:
|
||||
|
||||
```go
|
||||
// Track active subagents and display their output
|
||||
@@ -147,11 +147,11 @@ result, err := host.Subagent(ctx, kit.SubagentConfig{
|
||||
|
||||
### Real-time subagent events
|
||||
|
||||
Use `SubscribeSubagent` to receive real-time events from LLM-initiated subagents (i.e., when the model uses the `spawn_subagent` tool). Register inside an `OnToolCall` handler using the tool call ID:
|
||||
Use `SubscribeSubagent` to receive real-time events from LLM-initiated subagents (i.e., when the model uses the `subagent` tool). Register inside an `OnToolCall` handler using the tool call ID:
|
||||
|
||||
```go
|
||||
host.OnToolCall(func(e kit.ToolCallEvent) {
|
||||
if e.ToolName == "spawn_subagent" {
|
||||
if e.ToolName == "subagent" {
|
||||
host.SubscribeSubagent(e.ToolCallID, func(event kit.Event) {
|
||||
switch ev := event.(type) {
|
||||
case kit.MessageUpdateEvent:
|
||||
|
||||
@@ -239,7 +239,7 @@ result := ctx.SpawnSubagent(ext.SubagentConfig{
|
||||
|
||||
### Monitoring subagents spawned by the main agent
|
||||
|
||||
When the LLM uses the built-in `spawn_subagent` tool, extensions can monitor the subagent's activity in real-time using three lifecycle events:
|
||||
When the LLM uses the built-in `subagent` tool, extensions can monitor the subagent's activity in real-time using three lifecycle events:
|
||||
|
||||
```go
|
||||
// Subagent started
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ A powerful, extensible AI coding agent CLI with multi-provider support, built-in
|
||||
## Features
|
||||
|
||||
- **Multi-Provider LLM Support** — Anthropic, OpenAI, Google Gemini, Ollama, Azure OpenAI, AWS Bedrock, OpenRouter, and more
|
||||
- **Built-in Core Tools** — bash, read, write, edit, grep, find, ls, spawn_subagent with no MCP overhead
|
||||
- **Built-in Core Tools** — bash, read, write, edit, grep, find, ls, subagent with no MCP overhead
|
||||
- **MCP Integration** — Connect external MCP servers for expanded capabilities
|
||||
- **Extension System** — Write custom tools, commands, widgets, and UI modifications in Go
|
||||
- **Interactive TUI** — Rich terminal interface powered by Bubble Tea with streaming, syntax highlighting, and custom rendering
|
||||
|
||||
@@ -74,11 +74,11 @@ The first argument is a priority (lower = runs first).
|
||||
|
||||
## Subagent event monitoring
|
||||
|
||||
Monitor real-time events from LLM-initiated subagents (when the model uses the `spawn_subagent` tool):
|
||||
Monitor real-time events from LLM-initiated subagents (when the model uses the `subagent` tool):
|
||||
|
||||
```go
|
||||
host.OnToolCall(func(e kit.ToolCallEvent) {
|
||||
if e.ToolName == "spawn_subagent" {
|
||||
if e.ToolName == "subagent" {
|
||||
host.SubscribeSubagent(e.ToolCallID, func(event kit.Event) {
|
||||
// Receives the same event types as Subscribe(), scoped to the child agent
|
||||
switch ev := event.(type) {
|
||||
|
||||
@@ -1566,7 +1566,7 @@ a:hover { text-decoration: underline; }
|
||||
'grep': '🔍',
|
||||
'find': '📁',
|
||||
'ls': '📂',
|
||||
'spawn_subagent': '🤖',
|
||||
'subagent': '🤖',
|
||||
'fetch': '🌐',
|
||||
'todo': '✅'
|
||||
};
|
||||
@@ -1612,7 +1612,7 @@ a:hover { text-decoration: underline; }
|
||||
headerLabel = formatLsHeader(input);
|
||||
bodyHtml = renderGenericBody(input, result);
|
||||
break;
|
||||
case 'spawn_subagent':
|
||||
case 'subagent':
|
||||
headerLabel = formatSubagentHeader(input);
|
||||
bodyHtml = renderSubagentBody(input, result);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user