Answer budget within the context window; enforced reviews of completed todos
Context window - Requests asked for the model's full max_output, but providers count input + output against the window: long chats with large-output models (DeepSeek V4.1 Flash, 384k) failed with "input too long" before automatic compaction (85 %) kicked in. max_tokens is now what the window leaves (estimated input = last usage + messages since), the chat is compacted when less than 32k would remain for an answer, and a context-overflow error compacts and retries once. - ModelConfig.max_input (catalogue limit.input, editable in the provider settings) lowers the compaction threshold for models with an input limit. Enforced reviews (modes with refine.rounds > 0, refine.after_todos default on) - Every todo marked completed is reviewed against the work since the last review; with findings it is reopened and the feedback goes to the agent (max. rounds per todo). Passed reviews leave a visible note. - Ending the turn with open todos sends the agent back to work while it makes progress (max. 10 reminders in a row without progress); such modes may take up to 2,000 steps per turn. Reaching the step limit is reported. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ca14ba3338
commit
bd896794fd
14 files changed
+386
-27
No files matched your search
@@ -115,7 +115,36 @@ function BackgroundResult({ text }: { text: string }) {
|
||||
);
|
||||
}
|
||||
|
||||
const REFINE_RE = /^<refine-feedback round="([^"]*)" reviewer="([^"]*)">\n?([\s\S]*?)\n?<\/refine-feedback>/;
|
||||
const REFINE_RE = /^<refine-feedback round="([^"]*)" reviewer="([^"]*)"(?: todos="\d+")?>\n?([\s\S]*?)\n?<\/refine-feedback>/;
|
||||
/** Enforced reviews: a completed todo passed, or a reminder about open todos. */
|
||||
const NOTE_RE = /^<(refine-approved|todo-reminder)(?: reviewer="([^"]*)")?(?: open="\d+")?>\n?([\s\S]*?)\n?<\/(?:refine-approved|todo-reminder)>/;
|
||||
/** Messages from the harness shown as cards instead of user bubbles. */
|
||||
const isHarnessNote = (text: string) => BG_RE.test(text) || REFINE_RE.test(text) || NOTE_RE.test(text);
|
||||
|
||||
/** A todo passed its review, or the agent was sent back to its open todos. */
|
||||
function HarnessNote({ text }: { text: string }) {
|
||||
const t = useT();
|
||||
const m = text.match(NOTE_RE);
|
||||
if (!m) return null;
|
||||
const [, kind, reviewer, body] = m;
|
||||
const items = body.split("\n").map((l) => l.replace(/^- /, "").trim()).filter(Boolean);
|
||||
const approved = kind === "refine-approved";
|
||||
return (
|
||||
<div className={`harness-note ${approved ? "ok" : ""}`}>
|
||||
<Icon name={approved ? "check" : "refresh"} />
|
||||
<span className="grow">
|
||||
<b>{t(approved ? "chat.reviewPassed" : "chat.todoReminder", { n: items.length })}</b> {items.join(" · ")}
|
||||
</span>
|
||||
{reviewer && <span className="chip">{reviewer}</span>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function HarnessMessage({ text }: { text: string }) {
|
||||
if (REFINE_RE.test(text)) return <RefineFeedback text={text} />;
|
||||
if (NOTE_RE.test(text)) return <HarnessNote text={text} />;
|
||||
return <BackgroundResult text={text} />;
|
||||
}
|
||||
|
||||
/** Findings of the review loop, sent back to the agent. */
|
||||
function RefineFeedback({ text }: { text: string }) {
|
||||
@@ -469,14 +498,14 @@ export function ChatView({ sessionId, onMenu, onClosePane }: { sessionId: string
|
||||
);
|
||||
}
|
||||
const allTexts = m.parts.filter((p) => p.type === "text") as { text: string }[];
|
||||
const background = allTexts.filter((p) => BG_RE.test(p.text) || REFINE_RE.test(p.text));
|
||||
const texts = allTexts.filter((p) => !BG_RE.test(p.text) && !REFINE_RE.test(p.text));
|
||||
const background = allTexts.filter((p) => isHarnessNote(p.text));
|
||||
const texts = allTexts.filter((p) => !isHarnessNote(p.text));
|
||||
const imgs = m.parts.filter((p) => p.type === "image") as { image: ImageData }[];
|
||||
if (texts.length === 0 && imgs.length === 0) {
|
||||
return background.length ? (
|
||||
<div key={m.id} className="msg">
|
||||
{background.map((p, i) => (
|
||||
REFINE_RE.test(p.text) ? <RefineFeedback key={i} text={p.text} /> : <BackgroundResult key={i} text={p.text} />
|
||||
<HarnessMessage key={i} text={p.text} />
|
||||
))}
|
||||
</div>
|
||||
) : null;
|
||||
@@ -484,7 +513,7 @@ export function ChatView({ sessionId, onMenu, onClosePane }: { sessionId: string
|
||||
return (
|
||||
<div key={m.id} className="msg">
|
||||
{background.map((p, i) => (
|
||||
REFINE_RE.test(p.text) ? <RefineFeedback key={i} text={p.text} /> : <BackgroundResult key={i} text={p.text} />
|
||||
<HarnessMessage key={i} text={p.text} />
|
||||
))}
|
||||
<div className="msg-user">
|
||||
{!busy && !readOnly && (
|
||||
|
||||
Reference in new issue
Block a user