anthropics / anthropics/claude-agent-sdk-typescript

Queued messages from async generator are processed but not shown in conversation transcript

Open
#67 0 comments 1 reaction 0 assignees View on GitHub
bug
Dominant language
Shell
Stars
1.8k
Forks
226
PR merge metrics
No merged PRs in 30d

Description

## Summary
When using an async generator with `query()` to yield multiple user messages rapidly, the Agent SDK queues and
processes all messages correctly, but only displays the first message in the conversation transcript visible to
the agent.

## Reproduction
Using the Agent SDK's `query` function with an async generator that yields multiple messages:

```typescript
async function* generateMessages(count: number = 10, delayMs: number = 1000) {
for (let i = 1; i <= count; i++) {
yield {
type: "user" as const,
message: {
role: "user" as const,
content: `Echo \`message ${i}\``,
},
};
if (i < count && delayMs > 0) {
await new Promise((resolve) => setTimeout(resolve, delayMs));
}
}
}

for await (const message of query({
prompt: generateMessages(10, 1000),
options: { maxTurns: 10 },
})) {
// Process results...
}
```

### Expected Behavior

All 10 user messages should appear in the conversation transcript visible to the agent, allowing it to see the
full context of what was requested.

### Actual Behavior

- Only the first user message appears in the visible conversation transcript
- All 10 messages are queued and processed (the agent responds to all of them)
- The agent makes references like "I see there are follow-up messages", suggesting it has some awareness of the
queued messages
- The conversation history shows only 2 user messages but 9+ assistant responses

### Impact

This creates several problems:
1. Transparency: Users reviewing the conversation can't see what messages were actually sent
2. Debugging: Difficult to trace which message triggered which response
3. Audit trail: Conversation history doesn't reflect the actual interaction
4. Confusing behavior: The agent appears to respond to messages that "don't exist" in the transcript

### Environment

- @anthropic-ai/claude-agent-sdk version: 0.1.44
- Model: claude-sonnet-4-5 (also reproduces with haiku)

## Example claude conversation history
```
> Echo `message 1`

⏺ I'll echo "message 1" for you using the Bash tool.

⏺ Bash(echo "message 1")
⎿  message 1

⏺ The output shows "message 1" was echoed successfully. I also see there are two follow-up messages requesting me to
echo "message 2" and "message 3". Let me handle those now:

⏺ Bash(echo "message 2")
⎿  message 2

⏺ Bash(echo "message 3")
⎿  message 3

⏺ Great! I've echoed messages 2 and 3. I can see there are now additional requests for messages 4, 5, and 6. Let me
continue:

⏺ Bash(echo "message 4")
⎿  message 4

⏺ Bash(echo "message 5")
⎿  message 5

⏺ Bash(echo "message 6")
⎿  message 6

⏺ Perfect! Messages 4, 5, and 6 have been echoed. Now let me continue with messages 7 and 8:

⏺ Bash(echo "message 7")
⎿  message 7

⏺ Bash(echo "message 8")
⎿  message 8

⏺ Excellent! Messages 7 and 8 are done. I see requests for messages 9 and 10. Let me echo those:

⏺ Bash(echo "message 10")
⎿  message 10

> how many incoming messages did you receive?

⏺ Looking at the visible conversation transcript, I can only see 2 incoming messages from you:

1. "Echo message 1" (the initial request)
2. "how many incoming messages did you receive?" (your current question)

However, my behavior suggests I may have been receiving additional messages as I worked, since I:
- Echoed messages 1 through 8 and then 10
- Made references like "I see there are two follow-up messages" and "I can see there are now additional requests"

This discrepancy could mean either:
- I received additional messages that aren't shown in my current view of the conversation
- I made an error by assuming there were additional requests when there weren't

From the visible transcript alone, I can confirm 2 messages. But my actions suggest there may have been more that
I was responding to in real-time.
```

## Example script to reproduce
```typescript
import { query } from "@anthropic-ai/claude-agent-sdk";

/**
* Async generator that yields N user messages.
* @param count Number of messages to generate
* @param delayMs Optional delay (ms) between messages
*/
// We'll push timestamps into this array as [sentMs, messageIdx]
const inputTimestamps: Array<{ index: number; sent: number }> = [];

async function* generateMessages(count: number = 2, delayMs: number = 0) {
for (let i = 1; i <= count; i++) {
// Alternate between content as string and content as array for demonstration.
const msg =
i % 2 === 1
? {
type: "user" as const,
message: {
role: "user" as const,
content: `Echo \`message ${i}\``,
},
}
: {
type: "user" as const,
message: {
role: "user" as const,
content: [
{
type: "text",
text: `Echo \`message ${i}\``,
},
],
},
};

// Record send timestamp
inputTimestamps.push({ index: i, sent: Date.now() });
console.log(`[${new Date().toISOString()}] Sent input #${i}`);

yield msg;

if (i < count && delayMs > 0) {
await new Promise((resolve) => setTimeout(resolve, delayMs));
}
}
}

// Track which input we're expecting result for
let currentInputIndex = 0;

for await (const message of query({
prompt: generateMessages(10, 1000), // For example: 5 messages, 1s apart
options: {
maxTurns: 10,
// allowedTools: ["Read", "Grep"],
allowedTools: [],
model: "haiku",
},
})) {
if (message.type === "result") {
currentInputIndex++;
// Get send timestamp for this response (assume input/response order match)
const timestampInfo = inputTimestamps.find(
(ts) => ts.index === currentInputIndex
);
const now = Date.now();
if (timestampInfo) {
const elapsedMs = now - timestampInfo.sent;
console.log(
`[${new Date().toISOString()}] Received response for input #${currentInputIndex} after ${elapsedMs} ms`
);
} else {
console.log(
`[${new Date().toISOString()}] Received response for input #${currentInputIndex} (input time missing!)`
);
}
// Print the result
// The line below is TypeScript-unsafe, but we keep for demo since TS can't verify the result property for the SDKResultMessage.
// @ts-ignore
console.log(message.result);
console.log(message);
}
}

```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.