feat: configurable max_turns for elfs — LLM sets via agent tool param
This commit is contained in:
@@ -146,12 +146,12 @@ func TestManager_SpawnAndList(t *testing.T) {
|
||||
})
|
||||
|
||||
// Spawn two elfs
|
||||
e1, err := mgr.Spawn(context.Background(), router.TaskGeneration, "task 1", "you are elf 1")
|
||||
e1, err := mgr.Spawn(context.Background(), router.TaskGeneration, "task 1", "you are elf 1", 30)
|
||||
if err != nil {
|
||||
t.Fatalf("Spawn 1: %v", err)
|
||||
}
|
||||
|
||||
e2, err := mgr.Spawn(context.Background(), router.TaskReview, "task 2", "you are elf 2")
|
||||
e2, err := mgr.Spawn(context.Background(), router.TaskReview, "task 2", "you are elf 2", 30)
|
||||
if err != nil {
|
||||
t.Fatalf("Spawn 2: %v", err)
|
||||
}
|
||||
@@ -202,9 +202,9 @@ func TestManager_WaitAll(t *testing.T) {
|
||||
|
||||
mgr := NewManager(ManagerConfig{Router: rtr, Tools: tool.NewRegistry()})
|
||||
|
||||
mgr.Spawn(context.Background(), router.TaskGeneration, "a", "")
|
||||
mgr.Spawn(context.Background(), router.TaskGeneration, "b", "")
|
||||
mgr.Spawn(context.Background(), router.TaskGeneration, "c", "")
|
||||
mgr.Spawn(context.Background(), router.TaskGeneration, "a", "", 30)
|
||||
mgr.Spawn(context.Background(), router.TaskGeneration, "b", "", 30)
|
||||
mgr.Spawn(context.Background(), router.TaskGeneration, "c", "", 30)
|
||||
|
||||
results := mgr.WaitAll()
|
||||
if len(results) != 3 {
|
||||
|
||||
@@ -42,7 +42,7 @@ func NewManager(cfg ManagerConfig) *Manager {
|
||||
|
||||
// Spawn creates a new background elf with a router-selected provider.
|
||||
// The elf gets its own engine, history, and tools — no shared state.
|
||||
func (m *Manager) Spawn(ctx context.Context, taskType router.TaskType, prompt, systemPrompt string) (Elf, error) {
|
||||
func (m *Manager) Spawn(ctx context.Context, taskType router.TaskType, prompt, systemPrompt string, maxTurns int) (Elf, error) {
|
||||
// Ask router for the best arm for this task type
|
||||
task := router.Task{
|
||||
Type: taskType,
|
||||
@@ -69,7 +69,7 @@ func (m *Manager) Spawn(ctx context.Context, taskType router.TaskType, prompt, s
|
||||
Tools: m.tools,
|
||||
System: systemPrompt,
|
||||
Model: arm.ModelName,
|
||||
MaxTurns: 20,
|
||||
MaxTurns: maxTurns,
|
||||
Logger: m.logger,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -87,13 +87,13 @@ func (m *Manager) Spawn(ctx context.Context, taskType router.TaskType, prompt, s
|
||||
}
|
||||
|
||||
// SpawnWithProvider creates an elf using a specific provider (bypasses router).
|
||||
func (m *Manager) SpawnWithProvider(prov provider.Provider, model, prompt, systemPrompt string) (Elf, error) {
|
||||
func (m *Manager) SpawnWithProvider(prov provider.Provider, model, prompt, systemPrompt string, maxTurns int) (Elf, error) {
|
||||
eng, err := engine.New(engine.Config{
|
||||
Provider: prov,
|
||||
Tools: m.tools,
|
||||
System: systemPrompt,
|
||||
Model: model,
|
||||
MaxTurns: 20,
|
||||
MaxTurns: maxTurns,
|
||||
Logger: m.logger,
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
@@ -28,6 +28,10 @@ var paramSchema = json.RawMessage(`{
|
||||
"wait": {
|
||||
"type": "boolean",
|
||||
"description": "Wait for the elf to complete (default true)"
|
||||
},
|
||||
"max_turns": {
|
||||
"type": "integer",
|
||||
"description": "Maximum tool-calling rounds for the elf (default 30)"
|
||||
}
|
||||
},
|
||||
"required": ["prompt"]
|
||||
@@ -58,6 +62,7 @@ type agentArgs struct {
|
||||
Prompt string `json:"prompt"`
|
||||
TaskType string `json:"task_type,omitempty"`
|
||||
Wait *bool `json:"wait,omitempty"`
|
||||
MaxTurns int `json:"max_turns,omitempty"`
|
||||
}
|
||||
|
||||
func (t *Tool) Execute(ctx context.Context, args json.RawMessage) (tool.Result, error) {
|
||||
@@ -74,10 +79,14 @@ func (t *Tool) Execute(ctx context.Context, args json.RawMessage) (tool.Result,
|
||||
if a.Wait != nil {
|
||||
wait = *a.Wait
|
||||
}
|
||||
maxTurns := a.MaxTurns
|
||||
if maxTurns <= 0 {
|
||||
maxTurns = 30 // default
|
||||
}
|
||||
|
||||
systemPrompt := "You are an elf — a focused sub-agent of gnoma. Complete the given task thoroughly and concisely. Use tools as needed."
|
||||
|
||||
e, err := t.manager.Spawn(ctx, taskType, a.Prompt, systemPrompt)
|
||||
e, err := t.manager.Spawn(ctx, taskType, a.Prompt, systemPrompt, maxTurns)
|
||||
if err != nil {
|
||||
return tool.Result{Output: fmt.Sprintf("Failed to spawn elf: %v", err)}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user