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.
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:
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
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.