You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Title: SDK runtime: request for an opt-in best-effort live streaming channel alongside durable events (0.1.5-rc.1)
Body:
Context
We build a multi-user web chat UI on top of deepseek-harness-sdk (Python). The backend spawns the SDK runtime per session and fans out agent output to browsers over SSE.
Between 0.1.2rc1 and 0.1.5rc1 the SDK runtime stopped forwarding live assistant deltas. In 0.1.2rc1 we received per-token assistant/chunk notifications; in 0.1.5rc1 the only text-bearing event is assistant/message, emitted once per step at commit time, carrying the whole agent step as a compacted timed stream (data.stream[] with text-chunks / reasoning-chunks / tool-call-chunks records: time0 + dt[] + fragment arrays).
Impact on interactive consumers
First-byte latency for any client is now bounded below by the full duration of the step — the model may start generating immediately, but nothing reaches the wire until the step commits. With reasoning-heavy models a single step routinely takes 30-60s+, during which the UI shows a completely dead screen: the only step-time events on the wire are step/start, agent/status, turn/*, and tool lifecycle events, none of which carry text.
We worked around the presentation side by expanding the timeline and replaying fragments with time0/dt[] pacing (a simulated typewriter), which preserves the rhythm but cannot fix the latency: users still wait the entire step before seeing anything.
This looks like a deliberate design, not a bug
Verified against the source:
packages/core/session/src/types.ts — SessionEventMap contains no chunk/delta event at all; text only exists inside assistant/message / assistant/attempt payloads.
packages/sdk/protocol/src/types.ts — InitializeParams has exactly cwd, provider, model, reasoningEffort?, maxTokens?; there is no streaming-related option anywhere in the wire surface (3 request methods, 4 notifications).
packages/acp/acp/src/session.ts — even the first-party ACP bridge only projects assistant/message at step commit (whole-block agent_message_chunk updates, no per-token update type), so no first-party consumer has a hidden live channel either.
We understand the rationale: emit only durable facts so the on-disk log stays the single source of truth (and it's clearly the foundation needed for real cross-process resume — the new SessionHandle + session lock in 0.1.5-rc.1 points the same way). We're not asking to weaken that invariant.
Proposal
An opt-in, best-effort live delta channel that runs in parallel with durable persistence, for example:
jsonc
// initialize
{ "cwd": "...", "provider": "...", "model": "...",
"stream": { "liveChunks": true } }
When enabled, the server additionally forwards deltas as they arrive from the provider — e.g. a new session.event variant like assistant/delta ({ text?, reasoning?, toolCall? }), with explicit documented semantics:
Non-durable: never written to the session log, never replayed, not part of migration contracts.
Lossy / unordered-tolerant: consumers must treat it as a rendering hint only; assistant/message remains the single source of truth and always arrives at step commit.
Off by default: zero overhead and zero behavior change for existing consumers (ACP, headless, persistence tooling all keep current semantics).
This mirrors the pre-0.1.5 behavior but with honest semantics: 0.1.2rc1's chunks were ambiguous (live and persisted), which is presumably part of why they were removed. A channel that is explicitly only a hint avoids that trap while restoring interactive UX.
What this unlocks
Web/desktop clients get real first-token latency again (model-side, not step-side) without giving up anything: durable consumers ignore the channel entirely, interactive consumers render from deltas and reconcile against assistant/message on arrival. If deltas are dropped mid-flight, the UI self-heals at step commit — exactly how consumers already handle the compacted timeline.
Questions
Is a best-effort live channel on the roadmap, or explicitly out of scope for the SDK server profile?
If acceptable in principle, would you prefer it as an initialize option (global) or a per-session/prompt flag?
Any objection to the "hint only, never persisted" framing vs. reintroducing persisted chunks (v0-style)?
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Title: SDK runtime: request for an opt-in best-effort live streaming channel alongside durable events (0.1.5-rc.1)
Body:
Context
We build a multi-user web chat UI on top of deepseek-harness-sdk (Python). The backend spawns the SDK runtime per session and fans out agent output to browsers over SSE.
Between 0.1.2rc1 and 0.1.5rc1 the SDK runtime stopped forwarding live assistant deltas. In 0.1.2rc1 we received per-token assistant/chunk notifications; in 0.1.5rc1 the only text-bearing event is assistant/message, emitted once per step at commit time, carrying the whole agent step as a compacted timed stream (data.stream[] with text-chunks / reasoning-chunks / tool-call-chunks records: time0 + dt[] + fragment arrays).
Impact on interactive consumers
First-byte latency for any client is now bounded below by the full duration of the step — the model may start generating immediately, but nothing reaches the wire until the step commits. With reasoning-heavy models a single step routinely takes 30-60s+, during which the UI shows a completely dead screen: the only step-time events on the wire are step/start, agent/status, turn/*, and tool lifecycle events, none of which carry text.
We worked around the presentation side by expanding the timeline and replaying fragments with time0/dt[] pacing (a simulated typewriter), which preserves the rhythm but cannot fix the latency: users still wait the entire step before seeing anything.
This looks like a deliberate design, not a bug
Verified against the source:
packages/core/session/src/types.ts — SessionEventMap contains no chunk/delta event at all; text only exists inside assistant/message / assistant/attempt payloads.
packages/sdk/protocol/src/types.ts — InitializeParams has exactly cwd, provider, model, reasoningEffort?, maxTokens?; there is no streaming-related option anywhere in the wire surface (3 request methods, 4 notifications).
packages/acp/acp/src/session.ts — even the first-party ACP bridge only projects assistant/message at step commit (whole-block agent_message_chunk updates, no per-token update type), so no first-party consumer has a hidden live channel either.
We understand the rationale: emit only durable facts so the on-disk log stays the single source of truth (and it's clearly the foundation needed for real cross-process resume — the new SessionHandle + session lock in 0.1.5-rc.1 points the same way). We're not asking to weaken that invariant.
Proposal
An opt-in, best-effort live delta channel that runs in parallel with durable persistence, for example:
jsonc
// initialize
{ "cwd": "...", "provider": "...", "model": "...",
"stream": { "liveChunks": true } }
When enabled, the server additionally forwards deltas as they arrive from the provider — e.g. a new session.event variant like assistant/delta ({ text?, reasoning?, toolCall? }), with explicit documented semantics:
Non-durable: never written to the session log, never replayed, not part of migration contracts.
Lossy / unordered-tolerant: consumers must treat it as a rendering hint only; assistant/message remains the single source of truth and always arrives at step commit.
Off by default: zero overhead and zero behavior change for existing consumers (ACP, headless, persistence tooling all keep current semantics).
This mirrors the pre-0.1.5 behavior but with honest semantics: 0.1.2rc1's chunks were ambiguous (live and persisted), which is presumably part of why they were removed. A channel that is explicitly only a hint avoids that trap while restoring interactive UX.
What this unlocks
Web/desktop clients get real first-token latency again (model-side, not step-side) without giving up anything: durable consumers ignore the channel entirely, interactive consumers render from deltas and reconcile against assistant/message on arrival. If deltas are dropped mid-flight, the UI self-heals at step commit — exactly how consumers already handle the compacted timeline.
Questions
Is a best-effort live channel on the roadmap, or explicitly out of scope for the SDK server profile?
If acceptable in principle, would you prefer it as an initialize option (global) or a per-session/prompt flag?
Any objection to the "hint only, never persisted" framing vs. reintroducing persisted chunks (v0-style)?
All reactions