feat(protocol)!: narrow the supported scope to sixteen events - #3
Merged
Conversation
`session:input_state`, `session:required_action` and `session:task_ready` leave the supported surface. All three continue to be emitted by the server and to reach callers unchanged; the SDK no longer models them and makes no commitment about them. ## Why each one goes `session:input_state` described whether the composer accepts input. It was also the SDK's signal that a turn had ended, and recording a live session showed why that does not hold: the event arrives twice at the very start of a turn, before the agent has said anything. A turn ending on it truncates the reply. `session:required_action` restated in a dedicated event what other events already carry. `session:task_ready` reports what a task will cost. The server computes `confirmed` from the balance and, when it is sufficient, starts the task itself — so the event asks nothing of a client and its absence costs a client nothing. ## What a client keeps A session stopped on its credit balance is still visible: `session:state` is in scope and its values include `credits_exhausted` and `task_paused`. Together with `session:restriction` and `session:error` — and `is_stale` over REST for an expired session — every condition that halts a session remains reportable except one. The exception is an outstanding phone verification, which is a provisioning prerequisite with no in-session remedy and now no in-session signal. The README says so rather than leaving it implicit. `session:task_ready` was also counted towards the SDK's judgement that an agent had responded, which governs how long a turn waits between events. Removing it narrows that set — an accurate narrowing, since a cost estimate is not a reply. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
a7vinx
force-pushed
the
feat/narrow-scope
branch
from
August 12, 2026 15:16
f1f93bd to
88d682e
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.
Summary
Three events leave the supported protocol scope:
session:input_state,session:required_actionandsession:task_ready. The supported surface goes from nineteen events to sixteen.All three continue to be emitted by the server and to reach callers unchanged. What changes is that the SDK no longer models them and makes no compatibility commitment about them — the same treatment every other unsupported event receives.
Why each one leaves
session:input_statedescribed whether the composer accepts input, and served as the SDK's signal that a turn had ended. Recording a live session showed the signal does not hold: the event arrives twice at the very start of a turn, before the agent has produced anything.A turn that ends on this event ends before the reply. The exit path that depended on it is removed with it.
session:required_actionrestated in a dedicated event what other events already carry. Nothing in the SDK consumed it.session:task_readyreports what a task will cost in credits. The server computesconfirmedfrom the account balance and, when the balance is sufficient, starts the task itself. The event asks nothing of a client.What a client keeps
A session stopped on its credit balance remains visible.
session:stateis in scope, and its values includecredits_exhaustedandtask_paused.session:state—credits_exhausted,task_pausedsession:restrictionsession:errorsession:form_to_useris_stale, over RESTThe exception is phone verification, a provisioning prerequisite that has no in-session remedy and now no in-session signal. The README states this rather than leaving it implicit.
Removed from the public API
InputState,InputStateCode,RequiredActionDataandTaskReadyData, along with the threeS2CEventmembers. Callers that need these payloads can still read them off the raw event.session:task_readywas also counted towards the SDK's judgement that an agent had responded, which governs how long a turn waits between events. Removing it narrows that set — an accurate narrowing, since a cost estimate is not a reply.Verification
ruff checkclean;python -m buildandtwine checkpass.PINE_BASE_URL=http://…:9513. The outbound-call test was deselected: it places a real call and spends credits.Note on 0.4.0
0.4.0 is unreleased — PyPI is on 0.3.3 — so these changes fold into its changelog entry rather than opening a new version.
🤖 Generated with Claude Code