package main import ( "context" "fmt" ) // Task tools are nomos-LOCAL, not MCP tools. They are session-scoped, and the // shared MCP server (api:8090/mcp) has no session id — so these are handled // in-process by nomos, which knows the session/task and holds the store. // buildTools appends these to the model's tool list; the agent loop routes a // call whose name isTaskTool to handleTaskTool instead of the MCP client. // // Phase 3 ships complete_task; set_goal / propose_plan / update_plan_step / // ask_operator land in later phases through the same mechanism. func taskToolDefs() []toolDef { return []toolDef{ { Name: "complete_task", Description: "Mark the current task finished. Call this once the goal is " + "verified done — or when you've genuinely failed or only partially " + "succeeded. Sets the task's outcome and a one-line summary shown on the " + "task board. Record what you learned with upsert_knowledge BEFORE " + "completing, so future tasks on the same entities benefit.", InputSchema: map[string]any{ "type": "object", "properties": map[string]any{ "outcome": map[string]any{ "type": "string", "enum": []string{"success", "failure", "partial"}, "description": "Did the task achieve its goal?", }, "summary": map[string]any{ "type": "string", "description": "One line describing the result (shown on the task card).", }, }, "required": []string{"outcome", "summary"}, }, }, } } func isTaskTool(name string) bool { switch name { case "complete_task": return true default: return false } } // handleTaskTool executes a nomos-local task tool. Returns (result, true) if it // handled the call, or (nil, false) if name is not a local task tool (so the // caller forwards it to the MCP client). func (a *agent) handleTaskTool(ctx context.Context, sessionID, name string, args map[string]any) (any, bool) { switch name { case "complete_task": outcome, _ := args["outcome"].(string) summary, _ := args["summary"].(string) if outcome == "" { outcome = "success" } if err := a.store.completeTask(ctx, sessionID, outcome, summary); err != nil { return fmt.Sprintf("error completing task: %v", err), true } return fmt.Sprintf("Task marked %s: %s", outcome, summary), true default: return nil, false } }