Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ The release workflow uses a tag's section here as its release notes (a
hand-written `docs/releases/<tag>.md` wins if present), so keeping this file
current is part of cutting a release.

## v0.302.68

- Claude Agent compaction sends its summary request as the request. Cut mid tool loop, the request was folded into the conversation checkpoint and followed by "Continue from where the checkpoint ends.", so in a long chat the model carried on with the task or asked a question, and that reply was installed as the summary (#1792, #1793, #1797).
- Claude Agent: a prompt sent after a turn that ended on a tool call keeps its text and images instead of joining the checkpoint as text (#1792, #1793).
- Retains all changes from v0.302.67.

## v0.302.67

- Claude Agent refreshes a changed tool list in place. Removing and re-adding graff's tools (to make Claude Code re-read them) failed the `load_tool_schemas` call that caused the change with "Connection closed", and the model often ended its turn or got "No such tool available"; graff now sends `tools/list_changed` and keeps the connection (#1789, ADR 0311).
Expand Down
8 changes: 8 additions & 0 deletions docs/releases/v0.302.68.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# v0.302.68

Claude Agent compaction writes a real summary again, and a prompt after a finished turn keeps its images.

- **Compaction summarizes instead of carrying on.** Claude Agent runs compaction on a fresh Claude Code process. When it was cut in the middle of a tool loop, the summary request was folded into the conversation text and followed by "Continue from where the checkpoint ends." In a long chat the model kept working on the task, or asked you a question, and that reply was installed as the summary. The summary request is now always sent as the request. (#1792, #1793, #1797)
- **A prompt after a finished turn is read as a prompt.** The same fault hit a new message sent after a turn that ended on a tool call such as `attempt_completion`: it joined the old conversation as text, and its images arrived as "[image]". The message now reaches the model as itself, images included. (#1792, #1793)

Includes all changes from v0.302.67.
2 changes: 1 addition & 1 deletion scripts/eval/tier1-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"src/main.zig",
"src/repl.zig"
],
"test_count_baseline": 3585,
"test_count_baseline": 3587,
"test_count_slack": 25,
"required_invariants": [
{
Expand Down
32 changes: 32 additions & 0 deletions src/claude_agent_tests.zig
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,38 @@ test "claude-agent version floor" {
try std.testing.expect(wire.effortFlag("none") == null);
}

test "claude-agent compaction mid tool loop: the summary request is the prompt, never checkpoint to continue" {
// Compaction runs on a fresh tools-off process. Cut mid loop, its history
// ends on tool results (or a call) and then the summary request. Folding
// the request into the checkpoint and adding "Continue from where the
// checkpoint ends." made the model carry on with the task, or ask the
// user a question, and that text was installed as the "summary".
var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
defer arena.deinit();
const a = arena.allocator();
const request = "Write a handoff summary of the conversation so far.";
const shapes = [_][]const u8{
\\[{"role":"user","content":"fix the bug"},
\\ {"role":"assistant","content":[{"type":"tool_use","id":"t1","name":"read_file","input":{"path":"a.zig"}}]},
\\ {"role":"user","content":[{"type":"tool_result","tool_use_id":"t1","content":"fn main() {}"}]},
\\ {"role":"user","content":"Write a handoff summary of the conversation so far."}]
,
\\[{"role":"user","content":"fix the bug"},
\\ {"role":"assistant","content":[{"type":"tool_use","id":"t1","name":"read_file","input":{"path":"a.zig"}}]},
\\ {"role":"user","content":"Write a handoff summary of the conversation so far."}]
,
};
for (shapes) |shape| {
const msgs = try parse(a, shape);
const blocks = (try history.freshContent(a, msgs.array.items)).array.items;
try std.testing.expectEqual(@as(usize, 2), blocks.len);
const cp = blocks[0].object.get("text").?.string;
try std.testing.expect(std.mem.indexOf(u8, cp, "read_file") != null);
try std.testing.expect(std.mem.indexOf(u8, cp, request) == null);
try std.testing.expectEqualStrings(request, blocks[1].object.get("text").?.string);
}
}

test "claude-agent fresh session: earlier history is a checkpoint, the prompt keeps its blocks" {
var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
defer arena.deinit();
Expand Down
4 changes: 4 additions & 0 deletions src/cli_text_source.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
pub const changelog_text =
\\What's new
\\──────────
\\0.302.68
\\ • Claude Agent: compaction writes a summary instead of continuing the task
\\ • Claude Agent: a prompt after a finished turn keeps its images
\\
\\0.302.67
\\ • Claude Agent: loading a tool no longer drops the call or ends the turn
\\ • a finished task still hears peers who message it directly
Expand Down
Loading