feat: add tool call lifecycle events and handler registration - #44
feat: add tool call lifecycle events and handler registration#44sr-anam wants to merge 11 commits into
Conversation
Port the tool call events refactor from the JavaScript SDK. Introduces three-phase tool call lifecycle (started → completed/failed) with per-tool-name handler registration and execution time tracking. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds first-class tool call lifecycle support to the Python SDK, including new public events/payloads, a ToolCallManager to manage started→completed/failed flows, and client APIs for per-tool handler registration.
Changes:
- Introduces
ToolCallManagerto track pending tool calls, dispatch handlers, and compute execution time. - Adds new
AnamEventtool call events plus payload dataclasses and aToolCallHandlerprotocol. - Routes incoming
toolCallStarted/toolCallCompleted/toolCallFaileddata-channel messages through the manager and adds comprehensive tests.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_tool_call_manager.py | New unit/integration coverage for tool call events, handler registration, and execution time. |
| src/anam/types.py | Adds tool call events, payload types, and ToolCallHandler protocol. |
| src/anam/client.py | Integrates tool call routing and exposes register_tool_call_handler(). |
| src/anam/_tool_call_manager.py | New lifecycle manager for tool call tracking/dispatch and execution timing. |
| src/anam/init.py | Re-exports tool call types/handler in the public package surface. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
There was a problem hiding this comment.
3 issues found across 5 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/anam/client.py">
<violation number="1" location="src/anam/client.py:326">
P2: Auto-completed and auto-failed client tools always report a ~0 ms execution_time because the completed/failed payloads reuse the started-event timestamp.</violation>
<violation number="2" location="src/anam/client.py:326">
P1: Returning a value from a client tool handler never completes the tool call on the wire. The SDK emits a local completion event, but the backend never receives the result, so client-side tools cannot actually unblock the conversation.</violation>
</file>
<file name="src/anam/types.py">
<violation number="1" location="src/anam/types.py:350">
P2: `ToolCallHandler` makes all lifecycle callbacks mandatory, which conflicts with the runtime/API contract that handlers can implement only the methods they need.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
1 issue found across 3 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/anam/types.py">
<violation number="1" location="src/anam/types.py:371">
P2: This docstring describes a deferred completion path for `on_start(...)->None`, but the SDK does not expose a public API to emit those completion/failure events later.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
There was a problem hiding this comment.
1 issue found across 2 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/anam/types.py">
<violation number="1" location="src/anam/types.py:349">
P2: Changing `ToolCallHandler` from `Protocol` to a normal class breaks structural typing for `register_tool_call_handler` and makes existing handler examples/type-checked callers invalid.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
sebvanleuven
left a comment
There was a problem hiding this comment.
Can you add an example that demonstrates this end-to-end?
There was a problem hiding this comment.
1 issue found across 1 file (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="examples/tool_call_test.py">
<violation number="1" location="examples/tool_call_test.py:431">
P2: Trim and filter `ANAM_TOOL_HANDLERS` entries before registration; otherwise names with leading/trailing spaces won’t match actual tool names or prefixes.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
There was a problem hiding this comment.
1 issue found across 1 file (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="scripts/tool_call_test.py">
<violation number="1" location="scripts/tool_call_test.py:437">
P2: Only parse `ANAM_TOOLS` when ephemeral persona mode is being used; otherwise invalid JSON in an unrelated env var can crash persona-id runs.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Port the tool call events refactor from the JavaScript SDK. Introduces three-phase tool call lifecycle (started → completed/failed) with per-tool-name handler registration and execution time tracking.
Summary by cubic
Adds tool call lifecycle events with per-tool handlers to the Python SDK and adds inline/server tool config for ephemeral personas. The client now emits started/completed/failed events with execution timing and supports local auto-complete/fail for client tools.
AnamEvent.TOOL_CALL_STARTED/TOOL_CALL_COMPLETED/TOOL_CALL_FAILED; routestoolCallStarted/toolCallCompleted/toolCallFailedfrom the data channel.AnamClient.register_tool_call_handler(tool_name, handler)returns an unsubscribe function; partial handlers are supported.handler.on_start(...)auto-emitsTOOL_CALL_COMPLETED; raising inon_startauto-emitsTOOL_CALL_FAILED(local-only).execution_time(ms); completed payloads may includedocuments_accessed.ToolCallManagerfor lifecycle tracking and event dispatch; clears pending calls on client close.ClientToolConfig,WebhookToolConfig,KnowledgeToolConfig,ToolParametersConfig, andToolConfig; extendsPersonaConfigwithtools/tool_idsand exports all fromanam.examples/tool_call_handler.py,scripts/tool_call_test.py(interactive test app), andtests/test_tool_call_manager.py.Written for commit 1aebb31. Summary will update on new commits.