Fix abort detection to use message stopReason instead of global isStreaming

When abort happens during tool call streaming, the tool result should show as aborted.
Previously used global isStreaming state which would flip when new messages streamed in,
causing spinner to reappear incorrectly.

Changes:
- Use message.stopReason === "aborted" to detect aborted tool calls
- Create synthetic error result for aborted tool calls in ToolMessage component
- Fix Ollama provider key test to return true (can't know which model to test)
- Add newline before HTML execution logs in artifacts update
This commit is contained in:
Mario Zechner 2025-10-10 01:40:59 +02:00
parent 6bc098e57b
commit 961112ff83
3 changed files with 14 additions and 4 deletions

View file

@ -112,7 +112,8 @@ export class AssistantMessage extends LitElement {
const tool = this.tools?.find((t) => t.name === chunk.name);
const pending = this.pendingToolCalls?.has(chunk.id) ?? false;
const result = this.toolResultsById?.get(chunk.id);
const aborted = !pending && !result && !this.isStreaming;
// A tool call is aborted if the message was aborted and there's no result for this tool call
const aborted = this.message.stopReason === "aborted" && !result;
orderedParts.push(
html`<tool-message
.tool=${tool}
@ -227,7 +228,15 @@ export class ToolMessage extends LitElement {
const toolName = this.tool?.name || this.toolCall.name;
// Render tool content (renderer handles errors and styling)
const toolContent = renderTool(toolName, this.toolCall.arguments, this.result, this.isStreaming || this.pending);
const result: ToolResultMessageType<any> | undefined = this.aborted
? { role: "toolResult", isError: true, output: "", toolCallId: this.toolCall.id, toolName: this.toolCall.name }
: this.result;
const toolContent = renderTool(
toolName,
this.toolCall.arguments,
result,
!this.aborted && (this.isStreaming || this.pending),
);
return html`
<div class="p-2.5 border border-border rounded-md bg-card text-card-foreground shadow-xs">

View file

@ -45,7 +45,8 @@ export class ProviderKeyInput extends LitElement {
private async testApiKey(provider: string, apiKey: string): Promise<boolean> {
try {
const modelId = TEST_MODELS[provider];
if (!modelId) return false;
// Returning true here for Ollama and friends. Can' know which model to use for testing
if (!modelId) return true;
let model = getModel(provider as any, modelId);
if (!model) return false;

View file

@ -449,7 +449,7 @@ export class ArtifactsPanel extends LitElement {
let result = `Updated file ${params.filename}`;
if (this.getFileType(params.filename) === "html" && !options.skipWait) {
const logs = await this.waitForHtmlExecution(params.filename);
result += logs;
result += `\n${logs}`;
}
return result;