mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
fix(coding-agent): pass thinking level to branch summarization (#11482)
The `/tree` "Summarize" option ignored the session's thinking level. `AgentSession` already passes `thinkingLevel` into the `generateBranchSummary` options, but `generateBranchSummary` never read it, so the request was built without `reasoning`. For reasoning models on OpenAI Responses and Azure Responses, a missing `reasoning` becomes `effort: thinkingLevelMap.off ?? "none"`. Models that don't accept `"none"` then reject the branch summary with a 400 error: ``` Unsupported value: 'none' is not supported with the 'gpt-6-astra-…' model. ``` This change adds `thinkingLevel` to `GenerateBranchSummaryOptions`. It sets `reasoning` on the request when the model supports reasoning and the level is not `off`, the same rule compaction uses in `createSummarizationOptions`. **Testing** - Added a test to `packages/coding-agent/test/branch-summarization.test.ts` that records the stream options for three cases: a reasoning model at `xhigh`, a reasoning model at `off`, and a non-reasoning model. The expected `reasoning` values are `["xhigh", undefined, undefined]`. Without the fix, the test fails and every case gets `undefined`. With the fix, it passes. - Ran `branch-summarization`, `agent-session-branching`, `branch-summary-extensions` and `compaction-summary-reasoning`: all pass. - `npm run check` passes. - Not tested against a real provider endpoint. Fixes #11444 Requested by @davidbrai Co-authored-by: triagent <triagent@localhost>
This commit is contained in:
parent
842c73170a
commit
269afc66ab
2 changed files with 27 additions and 1 deletions
|
|
@ -5,7 +5,7 @@
|
|||
* a summary of the branch being left so context isn't lost.
|
||||
*/
|
||||
|
||||
import type { AgentMessage, StreamFn } from "@earendil-works/pi-agent-core";
|
||||
import type { AgentMessage, StreamFn, ThinkingLevel } from "@earendil-works/pi-agent-core";
|
||||
import type { RetryCallbacks, RetryPolicy } from "@earendil-works/pi-ai";
|
||||
import { contentText, normalizeContext } from "@earendil-works/pi-ai";
|
||||
import type { Model, SimpleStreamOptions, Usage } from "@earendil-works/pi-ai/compat";
|
||||
|
|
@ -75,6 +75,8 @@ export interface GenerateBranchSummaryOptions {
|
|||
env?: Record<string, string>;
|
||||
/** Abort signal for cancellation */
|
||||
signal: AbortSignal;
|
||||
/** Thinking level for reasoning-capable models */
|
||||
thinkingLevel?: ThinkingLevel;
|
||||
/** Optional custom instructions for summarization */
|
||||
customInstructions?: string;
|
||||
/** If true, customInstructions replaces the default prompt instead of being appended */
|
||||
|
|
@ -300,6 +302,7 @@ export async function generateBranchSummary(
|
|||
headers,
|
||||
env,
|
||||
signal,
|
||||
thinkingLevel,
|
||||
customInstructions,
|
||||
replaceInstructions,
|
||||
reserveTokens = 16384,
|
||||
|
|
@ -348,6 +351,9 @@ export async function generateBranchSummary(
|
|||
// so transient stream drops reuse the configured retry policy.
|
||||
const context = normalizeContext({ systemPrompt: SUMMARIZATION_SYSTEM_PROMPT, messages: summarizationMessages });
|
||||
const requestOptions: SimpleStreamOptions = { apiKey, headers, env, signal };
|
||||
if (model.reasoning && thinkingLevel && thinkingLevel !== "off") {
|
||||
requestOptions.reasoning = thinkingLevel;
|
||||
}
|
||||
const response = await completeSummarization(model, context, requestOptions, streamFn, retry, callbacks);
|
||||
|
||||
// Check if aborted or errored
|
||||
|
|
|
|||
|
|
@ -44,6 +44,26 @@ function response(content: AssistantMessage["content"]): AssistantMessage {
|
|||
}
|
||||
|
||||
describe("branch summarization", () => {
|
||||
it("passes the thinking level only for reasoning-capable models", async () => {
|
||||
const seen: Array<SimpleStreamOptions["reasoning"]> = [];
|
||||
const streamFn: StreamFn = (_model, _context, options) => {
|
||||
seen.push(options?.reasoning);
|
||||
const stream = createAssistantMessageEventStream();
|
||||
queueMicrotask(() =>
|
||||
stream.push({ type: "done", reason: "stop", message: response([{ type: "text", text: "summary" }]) }),
|
||||
);
|
||||
return stream;
|
||||
};
|
||||
const reasoningModel = { ...model, reasoning: true };
|
||||
const signal = new AbortController().signal;
|
||||
|
||||
await generateBranchSummary(entries, { model: reasoningModel, signal, streamFn, thinkingLevel: "xhigh" });
|
||||
await generateBranchSummary(entries, { model: reasoningModel, signal, streamFn, thinkingLevel: "off" });
|
||||
await generateBranchSummary(entries, { model, signal, streamFn, thinkingLevel: "high" });
|
||||
|
||||
expect(seen).toEqual(["xhigh", undefined, undefined]);
|
||||
});
|
||||
|
||||
it("does not override tool choice for branch summaries", async () => {
|
||||
let requestOptions: SimpleStreamOptions | undefined;
|
||||
const streamFn: StreamFn = (_model, _context, options) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue