Ege Chelebi d74dd1d9d3 fix: don't emit empty agent_message_chunk (#841)
## Why this is needed

`toAcpNotifications` can emit an `agent_message_chunk` whose content is
an empty string. This happens in two situations:

1. **Streamed text deltas** — the `text` / `text_delta` case builds the
update unconditionally from `chunk.text`, and the Claude Agent SDK can
stream zero-length text deltas (for example, an empty trailing assistant
block at the end of a turn).
2. **Full-string content** — the string-content path emits a chunk even
when the string is empty.

An empty message chunk carries no information, so at best it is noise.
At worst it breaks clients: the ACP spec does not forbid empty content,
so clients handle it inconsistently and some throw. In JetBrains Air the
frontend event consumer throws on an empty-content `agent_message_chunk`
(`Failed to handle agent event`); once that happens the transcript is
**frozen for the rest of the turn** — no further updates render and
queued prompts are never dispatched. In practice this reproduced
repeatedly around image reads and end-of-turn, and the only recovery was
restarting the IDE.

Because the adapter is client-agnostic, this affects any ACP client that
is strict about chunk content, not a single editor — so the correct
place to fix it is here, in the adapter, rather than working around it
in each client.

## Fix

Do not emit empty content. Both call sites are guarded, mirroring the
empty-`thinking` guard that already exists a few lines below in the same
function, so behavior is consistent across content types:

- `text` / `text_delta`: only build the update when `chunk.text.length >
0`;
- string content: return `[]` when the string is empty.

The change is intentionally minimal and conservative — no information is
lost, and non-empty chunks are entirely unaffected.

## Tests

Three unit tests added on `toAcpNotifications`:

- empty string content → no notifications emitted;
- non-empty string content → still emitted unchanged;
- a stream containing an empty text block followed by a non-empty one →
only the non-empty block is emitted.

Full suite green (476 passing); eslint and prettier clean.
2026-07-07 08:17:17 +00:00
2025-09-02 19:06:32 -03:00
2026-03-26 12:19:06 +01:00
2026-03-26 12:19:06 +01:00

ACP adapter for the Claude Agent SDK

npm

Use Claude Agent SDK from ACP-compatible clients!

This tool implements an ACP agent by using the official Claude Agent SDK, supporting:

  • Context @-mentions
  • Images
  • Tool calls (with permission requests)
  • Following
  • Edit review
  • TODO lists
  • Interactive (and background) terminals
  • Custom Slash commands
  • Client MCP servers

Learn more about the Agent Client Protocol.

Contribution Policy

This project does not require a Contributor License Agreement (CLA). Instead, contributions are accepted under the following terms:

By contributing to this project, you agree that your contributions will be licensed under the Apache License, Version 2.0. You affirm that you have the legal right to submit your work, that you are not including code you do not have rights to, and that you understand contributions are made without requiring a Contributor License Agreement (CLA).

Description
Pull mirror of agentclientprotocol/claude-agent-acp (Apache-2.0): the ACP bridge that lets Buzz drive Claude Code
Readme 107 MiB
Languages
TypeScript 99.2%
JavaScript 0.6%
Shell 0.2%