feat(core,server,web): images reach every input — steering, goal objectives, one fold (#71)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
rank-Yu
2026-07-30 16:50:35 +08:00
committed by GitHub
parent de6380f278
commit 97852f43b8
40 changed files with 1474 additions and 254 deletions
@@ -281,6 +281,8 @@ export class TraceService {
// request that resumes after compaction starts yet another Task.
let taskIndex = -1;
let continuation = false; // The previous round's Request called a tool -> the next request_begin continues the same Task
/** Inside the image run that follows a `[user_steering]` text (see the turn-start rule below). */
let steeringImages = false;
let sawToolCallThisRequest = false;
// Compaction interval (compaction_begin..compaction_end): the compaction
// request's request_begin/request_end and token_usage all fall inside it (see
@@ -360,10 +362,22 @@ export class TraceService {
typeof p.text === "string" &&
parseUserSteeringText(p.text) !== null;
if (isSteeringText) continuation = true;
// Images sent with a steering message ride immediately behind its text, exactly as a
// Prompt's images ride behind theirs — and they inherit its exclusion: still the same
// Task, so `steeringImages` keeps the window open across the whole run of them and
// anything else on the main session closes it (an images-only Prompt after a steering
// message is a genuine new turn). A subagent's messages pass through without closing it:
// they belong to another session's stream and say nothing about this one's grouping.
// The Web answers the same "what is one Task" question over the live stream — see
// `openSteering` in web/src/lib/omni/stream-model.ts; the two need to stay in step.
const isImage = !hasOrigin && msg.type === "model_msg" && p.type === "image_url";
if (!hasOrigin && !isSteeringText && !(isImage && steeringImages)) steeringImages = false;
if (isSteeringText) steeringImages = true;
const startsUserTurn =
!hasOrigin &&
!compactionActive &&
!isSteeringText &&
!steeringImages &&
msg.type === "model_msg" &&
((p.type === "text" && p.role === "user") || p.type === "image_url");
const startsCompactionTurn =