Add a first-class SDK hook named onAgentActivityChanged so app clients do not need to infer “thinking” from raw broker events themselves.
Goal:
- Add
onAgentActivityChanged to the high-level AgentRelay API in the SDK.
- This should be an SDK-level derived signal built from existing broker events.
- Prefer not to add any new broker protocol events unless you conclude the existing events are insufficient. If you do change protocol, explain why.
Why:
- Today clients have to combine
delivery_*, relay_inbound, and agent_idle to show a simple “agent is active/thinking” badge.
- That logic belongs in the SDK, not in each app.
Relevant files:
packages/sdk/src/relay.ts
packages/sdk/src/protocol.ts
src/pty_worker.rs
Current event context:
AgentRelay already has hooks like onMessageReceived, onMessageSent, onDeliveryUpdate, onAgentIdle, and onWorkerOutput.
- Broker events already include:
delivery_queued
delivery_injected
delivery_active
delivery_ack
delivery_failed
relay_inbound
agent_idle
agent_exited
agent_released
Requested API:
-
Add a new hook on AgentRelay, something like:
interface AgentActivityChange {
name: string;
active: boolean;
pendingDeliveries: number;
reason:
| 'delivery_queued'
| 'delivery_injected'
| 'delivery_active'
| 'delivery_ack'
| 'delivery_failed'
| 'relay_inbound'
| 'agent_idle'
| 'agent_exited'
| 'agent_released';
eventId?: string;
}
onAgentActivityChanged: EventHook = null;
Semantics:
- This is an “activity” signal, not a literal cognition signal.
active=true should mean: the SDK has seen an in-flight delivery for the agent that has not yet been closed out.
- Mark an agent active when a delivery enters activity:
delivery_queued
delivery_injected
delivery_active
delivery_ack
- Mark an agent inactive when activity is closed out:
relay_inbound from that agent
agent_idle
delivery_failed when no pending deliveries remain
agent_exited
agent_released
- Maintain per-agent pending delivery state so concurrent deliveries behave correctly.
- Do not emit duplicate callbacks when the derived
active state has not changed.
Notes:
delivery_ack is not proof the model is actively reasoning; it is still useful as part of the broader “activity” signal.
- If you think a different state shape is better, keep the API simple and app-facing.
Tests:
- Add focused SDK tests covering:
- emits active on first delivery event
- does not emit repeated active transitions while already active
- emits inactive on
relay_inbound
- emits inactive on
agent_idle
- concurrent deliveries do not flip inactive too early
- emits inactive on exit/release
delivery_failed only clears activity when the last pending delivery is gone
Docs:
- Add a short SDK example showing how a UI could render a “thinking” badge from
onAgentActivityChanged.
Output:
- Implement the change
- Run relevant tests
- Summarize semantics/tradeoffs
- List changed files
This keeps the change SDK-side and avoids pushing relay/broker event inference into each app.
Add a first-class SDK hook named
onAgentActivityChangedso app clients do not need to infer “thinking” from raw broker events themselves.Goal:
onAgentActivityChangedto the high-levelAgentRelayAPI in the SDK.Why:
delivery_*,relay_inbound, andagent_idleto show a simple “agent is active/thinking” badge.Relevant files:
packages/sdk/src/relay.tspackages/sdk/src/protocol.tssrc/pty_worker.rsCurrent event context:
AgentRelayalready has hooks likeonMessageReceived,onMessageSent,onDeliveryUpdate,onAgentIdle, andonWorkerOutput.delivery_queueddelivery_injecteddelivery_activedelivery_ackdelivery_failedrelay_inboundagent_idleagent_exitedagent_releasedRequested API:
Add a new hook on
AgentRelay, something like:interface AgentActivityChange {
name: string;
active: boolean;
pendingDeliveries: number;
reason:
| 'delivery_queued'
| 'delivery_injected'
| 'delivery_active'
| 'delivery_ack'
| 'delivery_failed'
| 'relay_inbound'
| 'agent_idle'
| 'agent_exited'
| 'agent_released';
eventId?: string;
}
onAgentActivityChanged: EventHook = null;
Semantics:
active=trueshould mean: the SDK has seen an in-flight delivery for the agent that has not yet been closed out.delivery_queueddelivery_injecteddelivery_activedelivery_ackrelay_inboundfrom that agentagent_idledelivery_failedwhen no pending deliveries remainagent_exitedagent_releasedactivestate has not changed.Notes:
delivery_ackis not proof the model is actively reasoning; it is still useful as part of the broader “activity” signal.Tests:
relay_inboundagent_idledelivery_failedonly clears activity when the last pending delivery is goneDocs:
onAgentActivityChanged.Output:
This keeps the change SDK-side and avoids pushing relay/broker event inference into each app.