@fastagent-sh/fastagent 0.24.3 → 0.24.4
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.
|
@@ -11,7 +11,7 @@ import { resolveModel } from "./config.js";
|
|
|
11
11
|
import { MissingModel, activePath, resolveSessionSettings } from "./session-settings.js";
|
|
12
12
|
import { DEFAULT_THINKING_LEVEL, withModelRegistration } from "./models.js";
|
|
13
13
|
import { registerAccountModels } from "./openai-account-models.js";
|
|
14
|
-
import { asksToEndRun, markEndsRun } from "./turn-kit.js";
|
|
14
|
+
import { abortedAnswer, asksToEndRun, markEndsRun } from "./turn-kit.js";
|
|
15
15
|
import { agentSessionManager, sessionToolActivation, turnContext } from "./tool-context.js";
|
|
16
16
|
/**
|
|
17
17
|
* What pi's own coding tools say about themselves in its default prompt. The coding tools fastagent mounts are pi's
|
|
@@ -217,6 +217,7 @@ export function definitionResourceLoaderOptions(source) {
|
|
|
217
217
|
...nativeExtensions,
|
|
218
218
|
compactAdmission,
|
|
219
219
|
recordEndsRun,
|
|
220
|
+
recordAbortedAnswers,
|
|
220
221
|
...(definition.sections && Object.keys(definition.sections).length > 0
|
|
221
222
|
? [fastagentSections(definition.sections)]
|
|
222
223
|
: []),
|
|
@@ -279,6 +280,23 @@ const recordEndsRun = {
|
|
|
279
280
|
});
|
|
280
281
|
},
|
|
281
282
|
};
|
|
283
|
+
/**
|
|
284
|
+
* Records an answer that failed because its run was stopped as aborted ({@link abortedAnswer}), through pi's
|
|
285
|
+
* `message_end` replacement, which runs before pi appends the message to the record and before the plane's own
|
|
286
|
+
* listener sees it. `ctx.signal` is the run's own abort signal, the one pi's readings use.
|
|
287
|
+
*/
|
|
288
|
+
const recordAbortedAnswers = {
|
|
289
|
+
name: "fastagent-record-aborted-answers",
|
|
290
|
+
hidden: true,
|
|
291
|
+
factory: (pi) => {
|
|
292
|
+
pi.on("message_end", (event, ctx) => {
|
|
293
|
+
if (event.message.role !== "assistant")
|
|
294
|
+
return;
|
|
295
|
+
const aborted = abortedAnswer(event.message, ctx.signal);
|
|
296
|
+
return aborted ? { message: aborted } : undefined;
|
|
297
|
+
});
|
|
298
|
+
},
|
|
299
|
+
};
|
|
282
300
|
/** Manual compactions waiting for pi's admission, keyed by the session's record (what an extension's `ctx` names). */
|
|
283
301
|
const compactAdmissions = new WeakMap();
|
|
284
302
|
const COMPACT_ADMISSION = "fastagent-compact-admission";
|
|
@@ -18,6 +18,15 @@ export declare function classifyRetryable(details: string, signal: {
|
|
|
18
18
|
* the recorded one cannot disagree.
|
|
19
19
|
*/
|
|
20
20
|
export declare function answerOutcome(message: AssistantMessage): AnswerOutcome | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* An answer that failed while its run's abort was in effect, as what it was: aborted. Undefined when that is not the
|
|
23
|
+
* case (no abort, or not a failure). pi's own reading is `signal.aborted ? "aborted" : "error"` (`handleRunFailure`,
|
|
24
|
+
* the providers), but its request-setup path (`lazyStream`: auth, request preparation) writes "error" whatever the
|
|
25
|
+
* signal (pi 0.99.2). A run stopped during a tool lands there: the loop asks the model once more, and the setup throws
|
|
26
|
+
* the abort. Recorded this way, the answer's {@link answerOutcome} is the `aborted` the run settled with, live and read
|
|
27
|
+
* back. A failure recorded BEFORE the abort (a provider error whose retry was then stopped) stays as recorded.
|
|
28
|
+
*/
|
|
29
|
+
export declare function abortedAnswer(message: AssistantMessage, runSignal: AbortSignal | undefined): AssistantMessage | undefined;
|
|
21
30
|
/**
|
|
22
31
|
* An answer's recorded thinking: its published thinking blocks, in order, joined with nothing between them, exactly as
|
|
23
32
|
* their live deltas add up (the stream marks no block boundary, and the answer's `text` is joined the same way).
|
|
@@ -91,6 +91,19 @@ export function answerOutcome(message) {
|
|
|
91
91
|
return undefined;
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* An answer that failed while its run's abort was in effect, as what it was: aborted. Undefined when that is not the
|
|
96
|
+
* case (no abort, or not a failure). pi's own reading is `signal.aborted ? "aborted" : "error"` (`handleRunFailure`,
|
|
97
|
+
* the providers), but its request-setup path (`lazyStream`: auth, request preparation) writes "error" whatever the
|
|
98
|
+
* signal (pi 0.99.2). A run stopped during a tool lands there: the loop asks the model once more, and the setup throws
|
|
99
|
+
* the abort. Recorded this way, the answer's {@link answerOutcome} is the `aborted` the run settled with, live and read
|
|
100
|
+
* back. A failure recorded BEFORE the abort (a provider error whose retry was then stopped) stays as recorded.
|
|
101
|
+
*/
|
|
102
|
+
export function abortedAnswer(message, runSignal) {
|
|
103
|
+
return message.stopReason === "error" && runSignal?.aborted === true
|
|
104
|
+
? { ...message, stopReason: "aborted" }
|
|
105
|
+
: undefined;
|
|
106
|
+
}
|
|
94
107
|
/**
|
|
95
108
|
* Whether a thinking block is PUBLISHED: readable reasoning. A redacted one holds a provider's opaque payload and a
|
|
96
109
|
* placeholder (pi writes "[Reasoning redacted]" for it), not reasoning anyone can read, so it is neither streamed nor
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fastagent-sh/fastagent",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.4",
|
|
4
4
|
"description": "Vibe first. Then FastAgent: turn a local agent directory into a live service in your app, on Telegram, Slack, Feishu, or behind any channel.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|