@code-yeongyu/senpi-agent-core 2026.10.16-4 → 2026.10.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-loop.js +24 -2
- package/package.json +3 -3
package/dist/agent-loop.js
CHANGED
|
@@ -609,7 +609,13 @@ async function streamAssistantResponse(context, config, signal, emit, streamFunc
|
|
|
609
609
|
await emit({ type: "message_end", message: finalMessage });
|
|
610
610
|
return { message: finalMessage, providerToolResults };
|
|
611
611
|
}
|
|
612
|
-
|
|
612
|
+
// A caller abort is the reason a turn ended even when the bound fired first on a step that never finished:
|
|
613
|
+
// the user gets the abort's own message, not a timeout and advice to raise it (#3481).
|
|
614
|
+
// A step that rethrows the caller's own reason (`throwIfAborted()`, a fetch rejected with it) shows that reason
|
|
615
|
+
// through the same shaping and cap (#3510).
|
|
616
|
+
const callerAbortedPastBound = signal?.aborted === true &&
|
|
617
|
+
(error instanceof StreamStartTimeoutError || isStreamIdleTimeoutError(error) || error === signal.reason);
|
|
618
|
+
const finalMessage = createTerminalFailureAssistantMessage(config.model, signal?.aborted ? "aborted" : "error", callerAbortedPastBound ? abortError(signal.reason) : error, partialMessage);
|
|
613
619
|
propagateThinkingTiming(finalMessage);
|
|
614
620
|
if (addedPartial) {
|
|
615
621
|
context.messages[context.messages.length - 1] = finalMessage;
|
|
@@ -627,8 +633,24 @@ async function streamAssistantResponse(context, config, signal, emit, streamFunc
|
|
|
627
633
|
}
|
|
628
634
|
}
|
|
629
635
|
const ABORTED = Symbol("aborted");
|
|
636
|
+
const MAX_ABORT_REASON_CHARS = 500;
|
|
630
637
|
function abortError(reason) {
|
|
631
|
-
|
|
638
|
+
if (reason instanceof Error)
|
|
639
|
+
return reason;
|
|
640
|
+
// A caller's own words are its abort reason: a plain string, or an object carrying a `message` (#3510).
|
|
641
|
+
const text = abortReasonText(reason);
|
|
642
|
+
if (text === undefined)
|
|
643
|
+
return new Error("Request was aborted");
|
|
644
|
+
const characters = Array.from(text);
|
|
645
|
+
return new Error(characters.length > MAX_ABORT_REASON_CHARS ? `${characters.slice(0, MAX_ABORT_REASON_CHARS).join("")}…` : text);
|
|
646
|
+
}
|
|
647
|
+
function abortReasonText(reason) {
|
|
648
|
+
const text = typeof reason === "string"
|
|
649
|
+
? reason
|
|
650
|
+
: typeof reason === "object" && reason !== null && "message" in reason && typeof reason.message === "string"
|
|
651
|
+
? reason.message
|
|
652
|
+
: undefined;
|
|
653
|
+
return text !== undefined && text.trim() !== "" ? text : undefined;
|
|
632
654
|
}
|
|
633
655
|
function closeAssistantIterator(iterator) {
|
|
634
656
|
void Promise.resolve(iterator.return?.()).catch(() => undefined);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-yeongyu/senpi-agent-core",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.18",
|
|
4
4
|
"description": "General-purpose agent with transport abstraction, state management, and attachment support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -62,8 +62,8 @@
|
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"@earendil-works/chord": "0.99.1",
|
|
65
|
-
"@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.10.
|
|
66
|
-
"@earendil-works/pi-telemetry": "npm:@code-yeongyu/senpi-telemetry@2026.10.
|
|
65
|
+
"@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.10.18",
|
|
66
|
+
"@earendil-works/pi-telemetry": "npm:@code-yeongyu/senpi-telemetry@2026.10.18",
|
|
67
67
|
"diff": "9.0.0",
|
|
68
68
|
"ignore": "7.0.9",
|
|
69
69
|
"typebox": "1.3.34",
|