Skip to content

SDK: multi-turn agent.chat() replays first-turn events instead of advancing #2

@shreyas-lyzr

Description

@shreyas-lyzr

Symptom

Calling `agent.chat()` more than once on the same `ComputerAgent` instance returns the first turn's response on every subsequent call, even though each call has a different prompt.

Reproduced live against `github.com/shreyas-lyzr/marketing-agent` with `LocalSubstrate` + `claude-haiku-4-5-20251001`. Three sequential `agent.chat()` calls with three distinct prompts all produced the same answer (the response to prompt #1).

Root cause (suspected)

`packages/sdk/src/computer-agent.ts:194` — `openEventStream` opens a fresh SSE connection to `GET /v1/sessions/:id/events` on every `chat()` call but does not pass `Last-Event-ID`. The harness's per-session replay buffer therefore replays from event 0. Combined with the consumer breaking on the first `SDKResultMessage` it sees (or the harness emitting `ca_session_ended` after each turn and closing the stream), the iterator captures only the first turn's `result`.

Either:

  • The harness should not close the SSE stream on `ca_session_ended` for in-progress sessions; OR
  • The SDK should track `lastEventId` across `chat()` calls and pass it on subsequent `/events` opens; OR
  • The SDK should not call `/events` on subsequent `chat()` calls and instead reuse the open stream.

Workaround for users today

Use `runTask({...})` per turn — each call is a fresh session, so multi-turn memory is lost, but each call returns its own correct response. Pass `sessionStore: { kind: "file", options: { root: ... } }` + the same `sessionId` across calls to maintain conversation memory at the engine level.

Definition of done

  • A failing test in `packages/sdk/` that exercises two-turn `agent.chat()` with distinct prompts and asserts both responses are distinct.
  • Fix in `computer-agent.ts` (`openEventStream` and/or session-end handling).
  • Test green.
  • Update the `marketing-agent.ts` example back to using `agent.chat()` for the multi-turn flow.

Repro

```ts
import { ComputerAgent, LocalSubstrate } from "computeragent";

await using agent = new ComputerAgent({
source: { type: "git", url: "github.com/shreyas-lyzr/marketing-agent" },
harness: "claude-agent-sdk",
runtime: new LocalSubstrate(),
envs: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },
options: { permissionMode: "bypassPermissions", model: "claude-haiku-4-5-20251001" },
});

const r1 = await agent.chat("Say 'one'");
const r2 = await agent.chat("Say 'two'");
// Expected: r2.result contains 'two'
// Actual: r2.result contains 'one' (replayed from turn 1)
```

Severity

High for the SDK story — multi-turn is a headline feature and the docs/examples assume it works. Workaround is documented above so users aren't blocked, but the example codebase should not ship in this state long-term.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions