mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-21 17:00:45 +00:00
fix: show retry attempt count when aborting during retry
When aborting a retry attempt, surface the retry-aware abort message in the assistant output and tool results instead of a generic "Aborted". - Set errorMessage for aborted streaming messages - Render abort message without forcing a leading newline when no content
This commit is contained in:
parent
a65da1c14b
commit
01f15fcbd2
3 changed files with 38 additions and 13 deletions
|
|
@ -435,6 +435,11 @@ export class AgentSession {
|
||||||
return this.agent.state.isStreaming;
|
return this.agent.state.isStreaming;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Current retry attempt (0 if not retrying) */
|
||||||
|
get retryAttempt(): number {
|
||||||
|
return this._retryAttempt;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the names of currently active tools.
|
* Get the names of currently active tools.
|
||||||
* Returns the names of tools currently set on the agent.
|
* Returns the names of tools currently set on the agent.
|
||||||
|
|
|
||||||
|
|
@ -31,12 +31,11 @@ export class AssistantMessageComponent extends Container {
|
||||||
// Clear content container
|
// Clear content container
|
||||||
this.contentContainer.clear();
|
this.contentContainer.clear();
|
||||||
|
|
||||||
if (
|
const hasVisibleContent = message.content.some(
|
||||||
message.content.length > 0 &&
|
(c) => (c.type === "text" && c.text.trim()) || (c.type === "thinking" && c.thinking.trim()),
|
||||||
message.content.some(
|
);
|
||||||
(c) => (c.type === "text" && c.text.trim()) || (c.type === "thinking" && c.thinking.trim()),
|
|
||||||
)
|
if (hasVisibleContent) {
|
||||||
) {
|
|
||||||
this.contentContainer.addChild(new Spacer(1));
|
this.contentContainer.addChild(new Spacer(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -75,7 +74,12 @@ export class AssistantMessageComponent extends Container {
|
||||||
const hasToolCalls = message.content.some((c) => c.type === "toolCall");
|
const hasToolCalls = message.content.some((c) => c.type === "toolCall");
|
||||||
if (!hasToolCalls) {
|
if (!hasToolCalls) {
|
||||||
if (message.stopReason === "aborted") {
|
if (message.stopReason === "aborted") {
|
||||||
this.contentContainer.addChild(new Text(theme.fg("error", "\nAborted"), 1, 0));
|
const abortMessage =
|
||||||
|
message.errorMessage && message.errorMessage !== "Request was aborted"
|
||||||
|
? message.errorMessage
|
||||||
|
: "Operation aborted";
|
||||||
|
const prefix = hasVisibleContent ? "\n" : "";
|
||||||
|
this.contentContainer.addChild(new Text(theme.fg("error", `${prefix}${abortMessage}`), 1, 0));
|
||||||
} else if (message.stopReason === "error") {
|
} else if (message.stopReason === "error") {
|
||||||
const errorMsg = message.errorMessage || "Unknown error";
|
const errorMsg = message.errorMessage || "Unknown error";
|
||||||
this.contentContainer.addChild(new Spacer(1));
|
this.contentContainer.addChild(new Spacer(1));
|
||||||
|
|
|
||||||
|
|
@ -1559,13 +1559,21 @@ export class InteractiveMode {
|
||||||
if (event.message.role === "user") break;
|
if (event.message.role === "user") break;
|
||||||
if (this.streamingComponent && event.message.role === "assistant") {
|
if (this.streamingComponent && event.message.role === "assistant") {
|
||||||
this.streamingMessage = event.message;
|
this.streamingMessage = event.message;
|
||||||
|
let errorMessage: string | undefined;
|
||||||
|
if (this.streamingMessage.stopReason === "aborted") {
|
||||||
|
const retryAttempt = this.session.retryAttempt;
|
||||||
|
errorMessage =
|
||||||
|
retryAttempt > 0
|
||||||
|
? `Aborted after ${retryAttempt} retry attempt${retryAttempt > 1 ? "s" : ""}`
|
||||||
|
: "Operation aborted";
|
||||||
|
this.streamingMessage.errorMessage = errorMessage;
|
||||||
|
}
|
||||||
this.streamingComponent.updateContent(this.streamingMessage);
|
this.streamingComponent.updateContent(this.streamingMessage);
|
||||||
|
|
||||||
if (this.streamingMessage.stopReason === "aborted" || this.streamingMessage.stopReason === "error") {
|
if (this.streamingMessage.stopReason === "aborted" || this.streamingMessage.stopReason === "error") {
|
||||||
const errorMessage =
|
if (!errorMessage) {
|
||||||
this.streamingMessage.stopReason === "aborted"
|
errorMessage = this.streamingMessage.errorMessage || "Error";
|
||||||
? "Operation aborted"
|
}
|
||||||
: this.streamingMessage.errorMessage || "Error";
|
|
||||||
for (const [, component] of this.pendingTools.entries()) {
|
for (const [, component] of this.pendingTools.entries()) {
|
||||||
component.updateResult({
|
component.updateResult({
|
||||||
content: [{ type: "text", text: errorMessage }],
|
content: [{ type: "text", text: errorMessage }],
|
||||||
|
|
@ -1872,8 +1880,16 @@ export class InteractiveMode {
|
||||||
this.chatContainer.addChild(component);
|
this.chatContainer.addChild(component);
|
||||||
|
|
||||||
if (message.stopReason === "aborted" || message.stopReason === "error") {
|
if (message.stopReason === "aborted" || message.stopReason === "error") {
|
||||||
const errorMessage =
|
let errorMessage: string;
|
||||||
message.stopReason === "aborted" ? "Operation aborted" : message.errorMessage || "Error";
|
if (message.stopReason === "aborted") {
|
||||||
|
const retryAttempt = this.session.retryAttempt;
|
||||||
|
errorMessage =
|
||||||
|
retryAttempt > 0
|
||||||
|
? `Aborted after ${retryAttempt} retry attempt${retryAttempt > 1 ? "s" : ""}`
|
||||||
|
: "Operation aborted";
|
||||||
|
} else {
|
||||||
|
errorMessage = message.errorMessage || "Error";
|
||||||
|
}
|
||||||
component.updateResult({ content: [{ type: "text", text: errorMessage }], isError: true });
|
component.updateResult({ content: [{ type: "text", text: errorMessage }], isError: true });
|
||||||
} else {
|
} else {
|
||||||
this.pendingTools.set(content.id, component);
|
this.pendingTools.set(content.id, component);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue