shell: keep typed segments QML-compatible
This commit is contained in:
parent
8c434dfb74
commit
23cebc531d
1 changed files with 43 additions and 16 deletions
|
|
@ -262,12 +262,13 @@ Singleton {
|
|||
const segments = root.streamingMessage.segments ?? [];
|
||||
const last = segments.length > 0 ? segments[segments.length - 1] : null;
|
||||
if (last && last.type === type) {
|
||||
root.streamingMessage.segments = [
|
||||
...segments.slice(0, -1),
|
||||
{ ...last, content: String(last.content ?? "") + text }
|
||||
];
|
||||
const replacement = {
|
||||
type: last.type,
|
||||
content: String(last.content ?? "") + text,
|
||||
};
|
||||
root.streamingMessage.segments = segments.slice(0, -1).concat([replacement]);
|
||||
} else {
|
||||
root.streamingMessage.segments = [...segments, { type, content: text }];
|
||||
root.streamingMessage.segments = segments.concat([{ type, content: text }]);
|
||||
}
|
||||
// `content` remains a plain compatibility projection for Copy, TTS,
|
||||
// and old snapshot consumers. It no longer drives the renderer.
|
||||
|
|
@ -281,7 +282,8 @@ Singleton {
|
|||
const name = String(fn.name ?? "tool");
|
||||
const arguments = String(fn.arguments ?? "");
|
||||
const id = String(tool.id ?? "");
|
||||
root.streamingMessage.segments = [...root.streamingMessage.segments, {
|
||||
const nextSegments = root.streamingMessage.segments.slice();
|
||||
nextSegments.push({
|
||||
type: "tool",
|
||||
id,
|
||||
name,
|
||||
|
|
@ -290,7 +292,8 @@ Singleton {
|
|||
status: "running",
|
||||
output: "",
|
||||
failed: false,
|
||||
}];
|
||||
});
|
||||
root.streamingMessage.segments = nextSegments;
|
||||
root.appendToStreaming(`\n${name}(${arguments})\n`);
|
||||
}
|
||||
|
||||
|
|
@ -317,11 +320,22 @@ Singleton {
|
|||
const failed = /error|fail/i.test(status);
|
||||
const output = String(result.output ?? "");
|
||||
if (index >= 0) {
|
||||
root.streamingMessage.segments = segments.map((segment, i) => i === index
|
||||
? { ...segment, status, output, failed }
|
||||
: segment);
|
||||
const nextSegments = segments.slice();
|
||||
const previous = segments[index];
|
||||
nextSegments[index] = {
|
||||
type: previous.type,
|
||||
id: previous.id,
|
||||
name: previous.name,
|
||||
arguments: previous.arguments,
|
||||
round: previous.round,
|
||||
status,
|
||||
output,
|
||||
failed,
|
||||
};
|
||||
root.streamingMessage.segments = nextSegments;
|
||||
} else {
|
||||
root.streamingMessage.segments = [...segments, {
|
||||
const nextSegments = segments.slice();
|
||||
nextSegments.push({
|
||||
type: "tool",
|
||||
id: resultId,
|
||||
name: String(result.name ?? "tool"),
|
||||
|
|
@ -330,7 +344,8 @@ Singleton {
|
|||
status,
|
||||
output,
|
||||
failed,
|
||||
}];
|
||||
});
|
||||
root.streamingMessage.segments = nextSegments;
|
||||
}
|
||||
root.appendToStreaming(`\n[${status}] ${output}\n`);
|
||||
}
|
||||
|
|
@ -390,12 +405,24 @@ Singleton {
|
|||
|
||||
function finishStreaming() {
|
||||
if (!root.streamingMessage) return;
|
||||
root.streamingMessage.segments = (root.streamingMessage.segments ?? []).map(segment => {
|
||||
const resolvedSegments = [];
|
||||
for (const segment of (root.streamingMessage.segments ?? [])) {
|
||||
if (segment.type === "tool" && segment.status === "running") {
|
||||
return { ...segment, status: "unresolved", failed: true };
|
||||
resolvedSegments.push({
|
||||
type: segment.type,
|
||||
id: segment.id,
|
||||
name: segment.name,
|
||||
arguments: segment.arguments,
|
||||
round: segment.round,
|
||||
status: "unresolved",
|
||||
output: segment.output,
|
||||
failed: true,
|
||||
});
|
||||
} else {
|
||||
resolvedSegments.push(segment);
|
||||
}
|
||||
return segment;
|
||||
});
|
||||
}
|
||||
root.streamingMessage.segments = resolvedSegments;
|
||||
root.streamingMessage.thinking = false;
|
||||
root.streamingMessage.done = true;
|
||||
// If the turn finished while the session is locked, the finished
|
||||
|
|
|
|||
Loading…
Reference in a new issue