refactor(rap-protocol)!: type tool-call IDs (ToolCallId, ProviderCallId, ChoiceId) - #116
Open
MingweiSamuel wants to merge 1 commit into
Open
refactor(rap-protocol)!: type tool-call IDs (ToolCallId, ProviderCallId, ChoiceId)#116MingweiSamuel wants to merge 1 commit into
MingweiSamuel wants to merge 1 commit into
Conversation
Deploying infinity with
|
| Latest commit: |
4aaf963
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://19af7c80.infinity-dc7.pages.dev |
| Branch Preview URL: | https://mingwei-strkind3.infinity-dc7.pages.dev |
MingweiSamuel
added a commit
that referenced
this pull request
Sep 3, 2026
…Id, ChoiceId) Stage 4 of the string-ID to typed-ID migration (#108). The two distinct call-ID spaces documented in rap_tool.rs are now distinct types, and choice IDs are a documented alias. Wire formats unchanged (serde transparent; full suite + web e2e green; zero snapshot changes). * rap-protocol: `ToolCallId` (RAP `id`; provider-minted or runtime UUID) and `ProviderCallId` (RAP `call_id`; provider-scoped echo-back) kinds; `type ChoiceId<T = String> = ToolCallId<T>` per #109 (choices are keyed by the requesting tool call). All callback types' `id`/`call_id`/ `tool_call_id` fields typed; `send_subscription_event` takes ToolCallId * infinity-protocol: re-exports; `UserChoiceRequired.id`, `UserChoiceAnswered`/`UserChoiceComplete.choice_id` are ChoiceId * infinity-agent-core: `Tool::execute(id: ToolCallId, call_id: Option<ProviderCallId>)`, `execute_synchronous` takes the borrowed `<str>` forms; `SyntheticKind`/`TaggedSyntheticKind` tool_call_id fields + backward-compat bare-string variant typed; OAuth/UserChoice message ids; store traits (`spawn_thread`, `get_thread_parent_info`, subscription add/remove/list, `remove_pending_user_choice`) take typed borrows; `ThreadInfo.spawn_tool_call_id`, subscription sets, `UserChoice.id`, `AgentEvent::UserChoiceDismissed`, `CompletionAction::ExecuteToolCall`, `PrepareResult::UserChoiceRequired`, interrupted-call tracking all typed. Conversions live only at the rig boundary (rig ToolCall/ToolResult keep String ids; `WireStreamItem` in provider-protocol deliberately stays a rig mirror since `internal_call_id` is rig's own delta-matching nanoid) * daemon/lambda/bridges/sandbox/poller/slack/CLI: trait impls + internal maps typed (sandbox in-flight + pending-choice maps keyed by ToolCallId, github-poller Subscription + subscriptions map, slack sidecar choice routing, CLI choice picker queue + answer channel); DSQL binds and Dynamo string sets convert at the storage boundary BREAKING CHANGE: rap-protocol callback types and agent-core Tool trait signatures use ToolCallId/ProviderCallId instead of String. Co-authored-by: Infinity 🤖 <infinity@hydro.run> PR: #116
MingweiSamuel
force-pushed
the
mingwei/strkind2
branch
from
September 3, 2026 17:25
85abb33 to
6d22148
Compare
MingweiSamuel
force-pushed
the
mingwei/strkind3
branch
from
September 3, 2026 17:25
e074692 to
ca00991
Compare
MingweiSamuel
added a commit
that referenced
this pull request
Sep 3, 2026
…Id, ChoiceId) Stage 4 of the string-ID to typed-ID migration (#108). The two distinct call-ID spaces documented in rap_tool.rs are now distinct types, and choice IDs are a documented alias. Wire formats unchanged (serde transparent; full suite + web e2e green; zero snapshot changes). * rap-protocol: `ToolCallId` (RAP `id`; provider-minted or runtime UUID) and `ProviderCallId` (RAP `call_id`; provider-scoped echo-back) kinds; `type ChoiceId<T = String> = ToolCallId<T>` per #109 (choices are keyed by the requesting tool call). All callback types' `id`/`call_id`/ `tool_call_id` fields typed; `send_subscription_event` takes ToolCallId * infinity-protocol: re-exports; `UserChoiceRequired.id`, `UserChoiceAnswered`/`UserChoiceComplete.choice_id` are ChoiceId * infinity-agent-core: `Tool::execute(id: ToolCallId, call_id: Option<ProviderCallId>)`, `execute_synchronous` takes the borrowed `<str>` forms; `SyntheticKind`/`TaggedSyntheticKind` tool_call_id fields + backward-compat bare-string variant typed; OAuth/UserChoice message ids; store traits (`spawn_thread`, `get_thread_parent_info`, subscription add/remove/list, `remove_pending_user_choice`) take typed borrows; `ThreadInfo.spawn_tool_call_id`, subscription sets, `UserChoice.id`, `AgentEvent::UserChoiceDismissed`, `CompletionAction::ExecuteToolCall`, `PrepareResult::UserChoiceRequired`, interrupted-call tracking all typed. Conversions live only at the rig boundary (rig ToolCall/ToolResult keep String ids; `WireStreamItem` in provider-protocol deliberately stays a rig mirror since `internal_call_id` is rig's own delta-matching nanoid) * daemon/lambda/bridges/sandbox/poller/slack/CLI: trait impls + internal maps typed (sandbox in-flight + pending-choice maps keyed by ToolCallId, github-poller Subscription + subscriptions map, slack sidecar choice routing, CLI choice picker queue + answer channel); DSQL binds and Dynamo string sets convert at the storage boundary BREAKING CHANGE: rap-protocol callback types and agent-core Tool trait signatures use ToolCallId/ProviderCallId instead of String. Co-authored-by: Infinity 🤖 <infinity@hydro.run> PR: #116
MingweiSamuel
force-pushed
the
mingwei/strkind3
branch
from
September 3, 2026 21:35
ca00991 to
a9372fd
Compare
MingweiSamuel
force-pushed
the
mingwei/strkind2
branch
from
September 3, 2026 21:37
e470bdc to
9a8a235
Compare
MingweiSamuel
added a commit
that referenced
this pull request
Sep 3, 2026
…Id, ChoiceId) Stage 4 of the string-ID to typed-ID migration (#108). The two distinct call-ID spaces documented in rap_tool.rs are now distinct types, and choice IDs are a documented alias. Wire formats unchanged (serde transparent; full suite + web e2e green; zero snapshot changes). * rap-protocol: `ToolCallId` (RAP `id`; provider-minted or runtime UUID) and `ProviderCallId` (RAP `call_id`; provider-scoped echo-back) kinds; `type ChoiceId<T = String> = ToolCallId<T>` per #109 (choices are keyed by the requesting tool call). All callback types' `id`/`call_id`/ `tool_call_id` fields typed; `send_subscription_event` takes ToolCallId * infinity-protocol: re-exports; `UserChoiceRequired.id`, `UserChoiceAnswered`/`UserChoiceComplete.choice_id` are ChoiceId * infinity-agent-core: `Tool::execute(id: ToolCallId, call_id: Option<ProviderCallId>)`, `execute_synchronous` takes the borrowed `<str>` forms; `SyntheticKind`/`TaggedSyntheticKind` tool_call_id fields + backward-compat bare-string variant typed; OAuth/UserChoice message ids; store traits (`spawn_thread`, `get_thread_parent_info`, subscription add/remove/list, `remove_pending_user_choice`) take typed borrows; `ThreadInfo.spawn_tool_call_id`, subscription sets, `UserChoice.id`, `AgentEvent::UserChoiceDismissed`, `CompletionAction::ExecuteToolCall`, `PrepareResult::UserChoiceRequired`, interrupted-call tracking all typed. Conversions live only at the rig boundary (rig ToolCall/ToolResult keep String ids; `WireStreamItem` in provider-protocol deliberately stays a rig mirror since `internal_call_id` is rig's own delta-matching nanoid) * daemon/lambda/bridges/sandbox/poller/slack/CLI: trait impls + internal maps typed (sandbox in-flight + pending-choice maps keyed by ToolCallId, github-poller Subscription + subscriptions map, slack sidecar choice routing, CLI choice picker queue + answer channel); DSQL binds and Dynamo string sets convert at the storage boundary BREAKING CHANGE: rap-protocol callback types and agent-core Tool trait signatures use ToolCallId/ProviderCallId instead of String. Co-authored-by: Infinity 🤖 <infinity@hydro.run> PR: #116
MingweiSamuel
force-pushed
the
mingwei/strkind3
branch
from
September 3, 2026 21:37
a9372fd to
69b516f
Compare
MingweiSamuel
marked this pull request as ready for review
September 4, 2026 00:49
Contributor
There was a problem hiding this comment.
🔵 Needs a closer look
The change is a broad, breaking, cross-crate API refactor that warrants a final human verification of downstream compile/test results and compatibility boundaries.
Pull request overview
This PR advances the workspace-wide string-ID → typed-ID migration (issue #108, stage 4) by introducing distinct RAP tool-call identifier types (ToolCallId vs ProviderCallId) and formalizing ChoiceId as an alias of ToolCallId, then propagating those types through protocol messages, tool traits, stores, and service integrations while keeping wire formats unchanged via transparent serde.
Changes:
- Add
ToolCallId,ProviderCallId, andChoiceId(alias) torap-protocol, and type RAP invocation/callback fields accordingly. - Re-export the typed IDs from
infinity-protocoland update agent-core tool/store traits plus event/message handling to use typed IDs (with conversion kept at the rig/storage boundaries). - Update downstream crates (daemon, lambda, slack bot, github poller, sandbox, CLI, MCP bridge) to use typed IDs in handler signatures, maps/sets, and serialization glue.
File summaries
| File | Description |
|---|---|
| crates/sandbox-local/tests/common.rs | Test helpers now construct typed RapInvocation.id via .into(). |
| crates/sandbox-core/src/server.rs | In-flight cancellation + pending-choice maps keyed by ToolCallId. |
| crates/rap-protocol/src/lib.rs | Introduces ToolCallId/ProviderCallId and ChoiceId alias; types callback fields. |
| crates/rap-github-event-poller/src/main.rs | Converts cancel requests to typed ToolCallId at the boundary. |
| crates/rap-github-event-poller/src/lib.rs | Subscription structs/maps updated to typed tool/call IDs. |
| crates/rap-client/src/notifier.rs | Notifier API now takes &ToolCallId<str>. |
| crates/infinity-slack-bot/src/sidecar.rs | Slack actions use typed ChoiceId for choice button routing/dismissal. |
| crates/infinity-slack-bot/src/session_store.rs | PendingChoice.choice_id becomes typed ChoiceId. |
| crates/infinity-slack-bot/src/flow.rs | Button-click parsing now converts to typed ChoiceId for daemon commands. |
| crates/infinity-slack-bot/src/daemon_sidecar.rs | Sidecar command uses typed ChoiceId. |
| crates/infinity-slack-bot/src/daemon_client.rs | Daemon client answer_choice takes &ChoiceId<str>. |
| crates/infinity-rap-bridge/src/callback.rs | Converts typed RAP callback IDs back to rig String at the boundary. |
| crates/infinity-protocol/src/lib.rs | Re-exports typed ID kinds and types choice fields as ChoiceId. |
| crates/infinity-mcp-bridge/src/lib.rs | MCP tool execute signature uses typed IDs; dedup uses id.as_str(). |
| crates/infinity-daemon/tests/mcp_proxy_callback.rs | Test invocation IDs updated to typed .into(). |
| crates/infinity-daemon/src/set_title_tool.rs | Tool trait signature updated; tool results convert typed IDs back to String. |
| crates/infinity-daemon/src/session/tests.rs | Session tests updated for typed tool-call/choice IDs and comparisons. |
| crates/infinity-daemon/src/session/display.rs | Subscription display lookups compare against typed ToolCallId via as_str(). |
| crates/infinity-daemon/src/rap_servers.rs | Managed RAP tool now implements typed Tool signature. |
| crates/infinity-daemon/src/memory_store.rs | Store APIs updated to typed tool-call IDs for spawn/subscriptions/choices. |
| crates/infinity-agent-lambda/src/tools/sleep.rs | Lambda sleep tools accept typed IDs; dedup uses id.as_str(). |
| crates/infinity-agent-lambda/src/state_store.rs | DynamoDB subscription/choice APIs updated to typed IDs with boundary conversion. |
| crates/infinity-agent-lambda/src/event_handler.rs | Lambda output shaping converts typed ChoiceId to String for outbound messages. |
| crates/infinity-agent-lambda/src/conversation_history.rs | DSQL store APIs bind typed tool-call IDs via as_str(); parent info returns typed ID. |
| crates/infinity-agent-core/src/traits.rs | Core store traits updated to typed ToolCallId/ChoiceId signatures. |
| crates/infinity-agent-core/src/tools/thread.rs | Tools updated to accept typed IDs; rig tool results still use String IDs. |
| crates/infinity-agent-core/src/tools/sleep.rs | Agent sleep tools updated to typed IDs + boundary conversions. |
| crates/infinity-agent-core/src/tools/rap_tool.rs | RAP invocation params and tool trait signature now use typed IDs. |
| crates/infinity-agent-core/src/tools/mod.rs | Tool trait + error helper updated to typed IDs and as_str() dedup. |
| crates/infinity-agent-core/src/tools/cancel_subscription.rs | Cancel tool parses tool_call_id into ToolCallId and returns rig String IDs. |
| crates/infinity-agent-core/src/system/thread.rs | Pending-choice dismissal/retention updated to typed ChoiceId interop. |
| crates/infinity-agent-core/src/system/tests.rs | System tests updated for typed IDs and comparisons. |
| crates/infinity-agent-core/src/system/test_support.rs | Test tools updated to typed tool-call/call IDs. |
| crates/infinity-agent-core/src/system/events.rs | UserChoice and AgentEvent::UserChoiceDismissed now use typed ChoiceId. |
| crates/infinity-agent-core/src/stores.rs | In-memory stores now key subscriptions/spawn IDs using typed ToolCallId/ChoiceId. |
| crates/infinity-agent-core/src/message.rs | Runtime message types updated to typed IDs; synthetic kind tool-call IDs typed. |
| crates/infinity-agent-core/src/event_processor.rs | Completion actions + interruption/subscription tracking migrated to typed IDs. |
| crates/infinity-agent-core/examples/agent_scale.rs | Example tool updated for typed IDs with conversion to rig String payloads. |
| crates/infinity-agent-cli/tests/tui_viewport_snapshots.rs | CLI snapshot tests updated to typed ChoiceId. |
| crates/infinity-agent-cli/tests/tui_flow_snapshots.rs | CLI snapshot tests updated to typed ChoiceId for required/complete events. |
| crates/infinity-agent-cli/tests/common/mod.rs | CLI harness channel now carries typed ChoiceId. |
| crates/infinity-agent-cli/src/terminal.rs | CLI pending choice queue + channel types updated to typed ChoiceId. |
| crates/infinity-agent-cli/src/display.rs | CLI display event types updated to typed ChoiceId. |
| crates/infinity-agent-cli/src/daemon_client.rs | CLI internal channels updated to carry typed ChoiceId. |
Review details
- Files reviewed: 44/44 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
546
to
+551
| if let Some(cid) = choice_id { | ||
| let rt = crate::runtime::get(); | ||
| rt.choice_messages | ||
| .lock() | ||
| .expect("bug: lock poisoned") | ||
| .insert(cid, (channel, msg_ts)); | ||
| .insert(cid.into_inner(), (channel, msg_ts)); |
…Id, ChoiceId) Stage 4 of the string-ID to typed-ID migration (#108). The two distinct call-ID spaces documented in rap_tool.rs are now distinct types, and choice IDs are a documented alias. Wire formats unchanged (serde transparent; full suite + web e2e green; zero snapshot changes). * rap-protocol: `ToolCallId` (RAP `id`; provider-minted or runtime UUID) and `ProviderCallId` (RAP `call_id`; provider-scoped echo-back) kinds; `type ChoiceId<T = String> = ToolCallId<T>` per #109 (choices are keyed by the requesting tool call). All callback types' `id`/`call_id`/ `tool_call_id` fields typed; `send_subscription_event` takes ToolCallId * infinity-protocol: re-exports; `UserChoiceRequired.id`, `UserChoiceAnswered`/`UserChoiceComplete.choice_id` are ChoiceId * infinity-agent-core: `Tool::execute(id: ToolCallId, call_id: Option<ProviderCallId>)`, `execute_synchronous` takes the borrowed `<str>` forms; `SyntheticKind`/`TaggedSyntheticKind` tool_call_id fields + backward-compat bare-string variant typed; OAuth/UserChoice message ids; store traits (`spawn_thread`, `get_thread_parent_info`, subscription add/remove/list, `remove_pending_user_choice`) take typed borrows; `ThreadInfo.spawn_tool_call_id`, subscription sets, `UserChoice.id`, `AgentEvent::UserChoiceDismissed`, `CompletionAction::ExecuteToolCall`, `PrepareResult::UserChoiceRequired`, interrupted-call tracking all typed. Conversions live only at the rig boundary (rig ToolCall/ToolResult keep String ids; `WireStreamItem` in provider-protocol deliberately stays a rig mirror since `internal_call_id` is rig's own delta-matching nanoid) * daemon/lambda/bridges/sandbox/poller/slack/CLI: trait impls + internal maps typed (sandbox in-flight + pending-choice maps keyed by ToolCallId, github-poller Subscription + subscriptions map, slack sidecar choice routing, CLI choice picker queue + answer channel); DSQL binds and Dynamo string sets convert at the storage boundary BREAKING CHANGE: rap-protocol callback types and agent-core Tool trait signatures use ToolCallId/ProviderCallId instead of String. Co-authored-by: Infinity 🤖 <infinity@hydro.run> PR: #116
MingweiSamuel
force-pushed
the
mingwei/strkind3
branch
from
September 4, 2026 18:07
69b516f to
4aaf963
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stage 4 of the string-ID to typed-ID migration (#108). The two distinct
call-ID spaces documented in rap_tool.rs are now distinct types, and choice
IDs are a documented alias. Wire formats unchanged (serde transparent; full
suite + web e2e green; zero snapshot changes).
ToolCallId(RAPid; provider-minted or runtime UUID)and
ProviderCallId(RAPcall_id; provider-scoped echo-back) kinds;type ChoiceId<T = String> = ToolCallId<T>per refactor: decide whether ChoiceId should be a distinct kind or remain an alias of ToolCallId #109 (choices are keyedby the requesting tool call). All callback types'
id/call_id/tool_call_idfields typed;send_subscription_eventtakes ToolCallIdUserChoiceRequired.id,UserChoiceAnswered/UserChoiceComplete.choice_idare ChoiceIdTool::execute(id: ToolCallId, call_id: Option<ProviderCallId>),execute_synchronoustakes the borrowed<str>forms;SyntheticKind/TaggedSyntheticKindtool_call_id fieldsids; store traits (
spawn_thread,get_thread_parent_info,subscription add/remove/list,
remove_pending_user_choice) take typedborrows;
ThreadInfo.spawn_tool_call_id, subscription sets,UserChoice.id,AgentEvent::UserChoiceDismissed,CompletionAction::ExecuteToolCall,PrepareResult::UserChoiceRequired,interrupted-call tracking all typed. Conversions live only at the rig
boundary (rig ToolCall/ToolResult keep String ids;
WireStreamIteminprovider-protocol deliberately stays a rig mirror since
internal_call_idis rig's own delta-matching nanoid)maps typed (sandbox in-flight + pending-choice maps keyed by ToolCallId,
github-poller Subscription + subscriptions map, slack sidecar choice
routing, CLI choice picker queue + answer channel); DSQL binds and
Dynamo string sets convert at the storage boundary
BREAKING CHANGE: rap-protocol callback types and agent-core Tool trait
signatures use ToolCallId/ProviderCallId instead of String.