Files
SneakyCode/app/tools/finish.py
Phillip Tarrant 91187a0728 Add Phase 5: ReAct-style agent loop with tool execution
Implement the core autonomy layer — AgentLoop streams LLM responses,
parses tool calls, executes them with permission checks, feeds results
back, and repeats until the task completes or finish is called.

- Add FinishTool for explicit loop termination
- Add tools parameter to LLMClient.stream_chat() for function calling
- Add compact tool result display (status line, not full output)
- Refactor REPL to delegate to AgentLoop.run_turn()
- Fix Ollama null content rejection (always send content as string)
- Add finish to auto_approve permissions
- 9 unit tests for agent loop (34 total, zero regressions)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 08:37:22 -05:00

36 lines
1.1 KiB
Python

"""FinishTool — signals agent loop termination."""
from typing import Any, ClassVar
from pydantic import BaseModel, Field
from app.models.config import AppConfig
from app.models.tool_call import ToolResult, ToolResultStatus
from app.tools.base import BaseTool
class FinishParams(BaseModel):
"""Parameters for the finish tool."""
message: str = Field(default="Task complete.", description="Final message to the user")
class FinishTool(BaseTool):
"""Signal that the agent has completed its task."""
name: ClassVar[str] = "finish"
description: ClassVar[str] = (
"Call this tool when you have completed the user's task. "
"Provide a brief summary message."
)
params_model: ClassVar[type[BaseModel]] = FinishParams
def execute(self, *, tool_call_id: str, **kwargs: Any) -> ToolResult:
message = kwargs.get("message", "Task complete.")
return ToolResult(
tool_call_id=tool_call_id,
tool_name=self.name,
status=ToolResultStatus.SUCCESS,
output=message,
)