rony-llm-agent/pkg/agent/subagent.go
Victor Vargas 49353485e5 feat(agent): thread the new turn through Loop as llm.Message
Run/RunStream took the new turn as a bare string, which had nowhere
to carry ContentPart attachments. Both now take an llm.Message
(Role is forced to RoleUser regardless of what the caller sets), so a
caller building a multimodal turn just fills in Content/Parts on it
instead of the loop needing a second, parallel parameter.
subagent.go and every test call site are updated to wrap their string
prompt as llm.Message{Role: llm.RoleUser, Content: ...} — SubAgent.Run
itself is untouched, it still takes a plain task string.
2026-07-16 22:24:03 -07:00

46 lines
1.4 KiB
Go

package agent
import (
"context"
"github.com/VictorVargas/rony-llm-agent/pkg/llm"
"github.com/VictorVargas/rony-llm-agent/pkg/persona"
"github.com/VictorVargas/rony-llm-agent/pkg/tools"
)
// SubAgent describes a specialized agent invocable via a delegate tool (see
// docs/phase2.md §5). The caller (the harness) is responsible for building
// Persona and Tools — the boundary is the same as for the main Loop: this
// package orchestrates, it doesn't decide personas or wire concrete tools.
type SubAgent struct {
Name string
Description string
Persona persona.Persona
Tools tools.Registry
MaxIterations int
}
// Run executes the sub-agent's task to completion using llmClient and the
// given AGENTS.md content, and returns its final response.
func (s SubAgent) Run(ctx context.Context, llmClient llm.LLMClient, agentsMD string, task string) (Response, error) {
cfg := Config{
LLM: llmClient,
Persona: s.Persona,
Tools: s.Tools,
MaxIters: s.MaxIterations,
AgentsMD: agentsMD,
}
if cfg.MaxIters == 0 {
cfg.MaxIters = DefaultMaxIterations
}
return New(cfg).Run(ctx, llm.Message{Role: llm.RoleUser, Content: task})
}
// SubAgentRegistry looks up SubAgents by name for the delegate tool.
type SubAgentRegistry map[string]SubAgent
// Get returns the named sub-agent, if registered.
func (r SubAgentRegistry) Get(name string) (SubAgent, bool) {
s, ok := r[name]
return s, ok
}