mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
fix(coding-agent): avoid Fable split-turn summary refusals (#9908)
Separate conversation content from instructions and replace prefix/suffix wording with continuation-oriented summarization guidance. Hopefully this avoids the refusals. Fixes #9652
This commit is contained in:
parent
25cc5c7bf4
commit
d192bd6dca
4 changed files with 15 additions and 12 deletions
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
### Fixed
|
||||
|
||||
- Fixed split-turn compaction summaries being refused by Claude Fable 5.1 by clearly separating the conversation and using continuation-oriented instructions ([#9652](https://github.com/earendil-works/pi/issues/9652)).
|
||||
- Fixed missing or invalid `--mode` values being silently ignored instead of reporting an error and exiting with a nonzero status ([#9045](https://github.com/earendil-works/pi/issues/9045)).
|
||||
|
||||
## [0.87.0] - 2026-09-21
|
||||
|
|
|
|||
|
|
@ -961,20 +961,20 @@ export function prepareCompaction(
|
|||
// Main compaction function
|
||||
// ============================================================================
|
||||
|
||||
const TURN_PREFIX_SUMMARIZATION_PROMPT = `This is the PREFIX of a turn that was too large to keep. The SUFFIX (recent work) is retained.
|
||||
const TURN_PREFIX_SUMMARIZATION_PROMPT = `The messages above are earlier context from an ongoing conversation. Later messages are stored separately and do not need to be reconstructed.
|
||||
|
||||
Summarize the prefix to provide context for the retained suffix:
|
||||
Create a concise checkpoint of the user's request and the progress shown above. This checkpoint will be placed before the later messages so the conversation can continue with the necessary context.
|
||||
|
||||
## Original Request
|
||||
[What did the user ask for in this turn?]
|
||||
[What did the user ask for?]
|
||||
|
||||
## Early Progress
|
||||
- [Key decisions and work done in the prefix]
|
||||
## Progress So Far
|
||||
- [Key decisions and work completed in these messages]
|
||||
|
||||
## Context for Suffix
|
||||
- [Information needed to understand the retained recent work]
|
||||
## Context Needed to Continue
|
||||
- [Information from these messages needed to understand the later work]
|
||||
|
||||
Be concise. Focus on what's needed to understand the kept suffix.`;
|
||||
Only summarize information explicitly present above. Do not infer or recreate later messages.`;
|
||||
|
||||
/**
|
||||
* Generate summaries for compaction using prepared data.
|
||||
|
|
@ -1115,7 +1115,7 @@ async function generateTurnPrefixSummary(
|
|||
); // Smaller budget for turn prefix
|
||||
const llmMessages = convertToLlm(messages);
|
||||
const conversationText = serializeConversation(llmMessages);
|
||||
const promptText = `<conversation>\n${conversationText}\n</conversation>\n\n${TURN_PREFIX_SUMMARIZATION_PROMPT}`;
|
||||
const promptText = `# Conversation\n${conversationText}\n\n# Instructions\n${TURN_PREFIX_SUMMARIZATION_PROMPT}`;
|
||||
|
||||
const response = await completeSummarization(
|
||||
model,
|
||||
|
|
|
|||
|
|
@ -146,8 +146,9 @@ describe("generateSummary reasoning options", () => {
|
|||
expect(result.summary).toContain("previous checkpoint");
|
||||
const requestContext = completeSimpleMock.mock.calls[0][1] as TranscriptContext;
|
||||
const prompt = JSON.stringify(requestContext.messages);
|
||||
expect(prompt).toContain("This is the PREFIX of a turn that was too large to keep");
|
||||
expect(prompt).toContain("<conversation>");
|
||||
// Regression test for #9652: clear boundaries and continuation wording avoid the reasoning-extraction false positive.
|
||||
expect(prompt).toContain("# Conversation\\n[User]: Summarize this.");
|
||||
expect(prompt).toContain("# Instructions\\nThe messages above are earlier context from an ongoing conversation.");
|
||||
});
|
||||
|
||||
it("rejects tool calls from conversation summaries", async () => {
|
||||
|
|
|
|||
|
|
@ -354,7 +354,8 @@ describe("AgentSession compaction characterization", () => {
|
|||
expect(transformContext).not.toHaveBeenCalled();
|
||||
expect(getCurrentSystemPrompt(requestContext?.messages ?? [])).not.toBe(harness.session.agent.state.systemPrompt);
|
||||
expect(getCurrentTools(requestContext?.messages ?? [])).toEqual([]);
|
||||
expect(JSON.stringify(requestContext?.messages)).toContain("<conversation>");
|
||||
// Regression test for #9652: split-turn summaries use a clear Markdown conversation boundary.
|
||||
expect(JSON.stringify(requestContext?.messages)).toContain("# Conversation\\n[User]: message to compact");
|
||||
expect(requestOptions).toMatchObject({ cacheRetention: "none" });
|
||||
expect(requestOptions?.sessionId).not.toBe("active-routing-session");
|
||||
expect(requestOptions?.transport).toBeUndefined();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue