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