Feature Request
Expose a host-facing progress channel for one concrete tool invocation, shared by native and MCP tools.
Rig already gives hosts a stable internal_call_id around tool-call lifecycle events, but the executing tool cannot publish intermediate progress that the host can correlate with that invocation. A host can therefore show requested/running/completed states, but it cannot faithfully show updates such as “scanned 42/100 files” or “downloaded 8 MiB”.
This is different from streamed tool-call argument deltas: the requested API reports progress while the tool itself is executing.
Motivation
Without a public per-invocation progress contract, downstream hosts must either show an indefinite spinner, infer progress from unrelated events, or correlate by tool name/arguments. The latter two approaches are incorrect when identical tools run concurrently or recursively.
The same gap exists for MCP. MCP can carry a progress token on the request and send progress notifications, but Rig does not currently project those notifications into a host-facing event associated with the Rig invocation.
Related work provides useful pieces but not the complete contract:
- #1311 added
internal_call_id for lifecycle correlation.
- #1906 discusses host-facing tool metadata including
emits_progress and MCP progress tokens, but does not provide a progress transport.
- #2094 discusses call-scoped state under concurrency, but not live tool-to-host events.
- #2121 contains an operation-backend
ProgressSink; it is not a general progress channel for arbitrary Tool/McpTool dispatch.
- The closed #2122 explicitly listed a general tool-progress event channel as remaining work.
Proposal
Add an additive, runtime-neutral progress contract with these properties.
Correlated event
Expose a normalized event whose exact shape is open for design, but which carries at least:
pub struct ToolProgress {
pub internal_call_id: String,
pub sequence: u64,
pub message: Option<String>,
pub completed: Option<f64>,
pub total: Option<f64>,
}
It must support both determinate and indeterminate progress. Sequence values must be monotonic within one invocation so hosts can discard stale updates.
Native tools
The per-call execution context/extensions supplied to a native tool should expose:
- the stable
internal_call_id for that dispatch; and
- a host-installed, concurrency-safe
ToolProgressSink or reporter bound to that invocation.
Progress is host-only observation and must not be appended to the model-visible tool result.
MCP tools
For an MCP call, Rig should:
- allocate or project a matching MCP progress token without overwriting unrelated caller metadata;
- route matching MCP progress notifications into the same host-facing progress channel; and
- preserve the same
internal_call_id used by normal Rig lifecycle events.
MCP servers that do not emit progress remain valid tools and must not receive fabricated percentage updates.
Semantics
- Native, MCP, parallel, nested, and duplicate-name calls remain independently correlated.
- Streaming and non-streaming agent runs expose the same progress semantics.
- Updates after completion, failure, denial, or cancellation are ignored or rejected deterministically.
- Progress observation does not alter the tool result or agent control flow.
Acceptance criteria
- A native tool can emit multiple updates during execution and the host receives them with the matching
internal_call_id.
- Two concurrent identical calls cannot cross-update.
- Real MCP progress notifications are forwarded through the same public API.
- A non-progress MCP tool emits no synthetic progress.
- Cancellation and all terminal tool states handle late updates deterministically.
- Tests cover native, MCP, concurrency, nested calls, cancellation, and streaming/non-streaming parity.
Alternatives
- Downstream-only progress registries: cannot generically bind Rig's private invocation lifecycle to arbitrary native and MCP tools, and every host would rebuild the same fragile bridge.
- A running spinner: useful as lifecycle UI, but it is not tool-reported progress.
- Tool-name or argument correlation: incorrect for concurrent or recursive identical calls.
- Operation-backend-only progress: useful for command/code backends, but it does not cover the general
Tool and McpTool execution boundary.
Feature Request
Expose a host-facing progress channel for one concrete tool invocation, shared by native and MCP tools.
Rig already gives hosts a stable
internal_call_idaround tool-call lifecycle events, but the executing tool cannot publish intermediate progress that the host can correlate with that invocation. A host can therefore show requested/running/completed states, but it cannot faithfully show updates such as “scanned 42/100 files” or “downloaded 8 MiB”.This is different from streamed tool-call argument deltas: the requested API reports progress while the tool itself is executing.
Motivation
Without a public per-invocation progress contract, downstream hosts must either show an indefinite spinner, infer progress from unrelated events, or correlate by tool name/arguments. The latter two approaches are incorrect when identical tools run concurrently or recursively.
The same gap exists for MCP. MCP can carry a progress token on the request and send progress notifications, but Rig does not currently project those notifications into a host-facing event associated with the Rig invocation.
Related work provides useful pieces but not the complete contract:
internal_call_idfor lifecycle correlation.emits_progressand MCP progress tokens, but does not provide a progress transport.ProgressSink; it is not a general progress channel for arbitraryTool/McpTooldispatch.Proposal
Add an additive, runtime-neutral progress contract with these properties.
Correlated event
Expose a normalized event whose exact shape is open for design, but which carries at least:
It must support both determinate and indeterminate progress. Sequence values must be monotonic within one invocation so hosts can discard stale updates.
Native tools
The per-call execution context/extensions supplied to a native tool should expose:
internal_call_idfor that dispatch; andToolProgressSinkor reporter bound to that invocation.Progress is host-only observation and must not be appended to the model-visible tool result.
MCP tools
For an MCP call, Rig should:
internal_call_idused by normal Rig lifecycle events.MCP servers that do not emit progress remain valid tools and must not receive fabricated percentage updates.
Semantics
Acceptance criteria
internal_call_id.Alternatives
ToolandMcpToolexecution boundary.