@jini-ai/agent-runtime 0.3.10 → 0.4.1
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/CHANGELOG.md +108 -0
- package/README.md +34 -17
- package/dist/acp-model-probe.d.ts +6 -4
- package/dist/acp-model-probe.js +3 -3
- package/dist/agent-protocol/acp/account-failure.d.ts +4 -2
- package/dist/agent-protocol/acp/account-failure.js +1 -1
- package/dist/agent-protocol/acp/json.d.ts +6 -6
- package/dist/agent-protocol/acp/json.js +3 -3
- package/dist/agent-protocol/acp/models.d.ts +10 -5
- package/dist/agent-protocol/acp/models.js +32 -31
- package/dist/agent-protocol/acp/session-params.d.ts +3 -1
- package/dist/agent-protocol/acp/session-params.js +2 -1
- package/dist/agent-protocol/acp/session.d.ts +28 -22
- package/dist/agent-protocol/acp/session.js +181 -147
- package/dist/agent-protocol/acp/text-suppression.d.ts +1 -1
- package/dist/agent-protocol/acp/text-suppression.js +1 -1
- package/dist/agent-protocol/acp/types.d.ts +3 -2
- package/dist/agent-protocol/acp/updates.d.ts +11 -11
- package/dist/agent-protocol/acp/updates.js +2 -2
- package/dist/agent-protocol/core/json-line-stream.d.ts +24 -8
- package/dist/agent-protocol/core/json-line-stream.js +8 -8
- package/dist/agent-protocol/pi-rpc/events.d.ts +5 -1
- package/dist/agent-protocol/pi-rpc/events.js +36 -36
- package/dist/agent-protocol/pi-rpc/internal.d.ts +4 -1
- package/dist/agent-protocol/pi-rpc/models.d.ts +3 -1
- package/dist/agent-protocol/pi-rpc/models.js +1 -1
- package/dist/agent-protocol/pi-rpc/session.d.ts +1 -1
- package/dist/agent-protocol/pi-rpc/session.js +33 -32
- package/dist/amr-model-cache.d.ts +12 -4
- package/dist/amr-model-cache.js +17 -21
- package/dist/amr-profile-resolver.d.ts +3 -1
- package/dist/anthropic-live-models.js +0 -0
- package/dist/artifact-taxonomy.d.ts +6 -2
- package/dist/auth.d.ts +52 -15
- package/dist/auth.js +36 -36
- package/dist/claude-code-models.js +2 -2
- package/dist/claude-stream.d.ts +22 -3
- package/dist/claude-stream.js +24 -8
- package/dist/copilot-stream.d.ts +7 -3
- package/dist/copilot-stream.js +3 -3
- package/dist/defs/aider.d.ts +8 -1
- package/dist/defs/aider.js +2 -2
- package/dist/defs/amp.d.ts +8 -1
- package/dist/defs/amp.js +2 -2
- package/dist/defs/amr.d.ts +22 -6
- package/dist/defs/amr.js +23 -23
- package/dist/defs/antigravity.d.ts +15 -4
- package/dist/defs/antigravity.js +9 -8
- package/dist/defs/auggie.d.ts +4 -1
- package/dist/defs/auggie.js +1 -1
- package/dist/defs/claude.d.ts +12 -2
- package/dist/defs/claude.js +5 -5
- package/dist/defs/cline.d.ts +4 -1
- package/dist/defs/cline.js +1 -1
- package/dist/defs/codebuddy.d.ts +8 -1
- package/dist/defs/codebuddy.js +2 -2
- package/dist/defs/codex.d.ts +18 -4
- package/dist/defs/codex.js +7 -7
- package/dist/defs/copilot.d.ts +8 -1
- package/dist/defs/copilot.js +2 -2
- package/dist/defs/crush.d.ts +8 -1
- package/dist/defs/crush.js +1 -1
- package/dist/defs/cursor-agent.d.ts +14 -3
- package/dist/defs/cursor-agent.js +5 -5
- package/dist/defs/deepseek.d.ts +8 -1
- package/dist/defs/deepseek.js +2 -2
- package/dist/defs/devin.d.ts +12 -2
- package/dist/defs/devin.js +3 -3
- package/dist/defs/droid.d.ts +8 -1
- package/dist/defs/droid.js +1 -1
- package/dist/defs/gemini.d.ts +8 -1
- package/dist/defs/gemini.js +1 -1
- package/dist/defs/goose.d.ts +4 -1
- package/dist/defs/goose.js +1 -1
- package/dist/defs/grok-build.d.ts +11 -2
- package/dist/defs/grok-build.js +3 -3
- package/dist/defs/hermes.d.ts +4 -1
- package/dist/defs/hermes.js +2 -2
- package/dist/defs/kilo.d.ts +4 -1
- package/dist/defs/kilo.js +2 -2
- package/dist/defs/kimi.d.ts +4 -1
- package/dist/defs/kimi.js +2 -2
- package/dist/defs/kiro.d.ts +4 -1
- package/dist/defs/kiro.js +2 -2
- package/dist/defs/mimo.d.ts +8 -1
- package/dist/defs/mimo.js +2 -2
- package/dist/defs/opencode.d.ts +9 -2
- package/dist/defs/opencode.js +2 -2
- package/dist/defs/pi.d.ts +12 -2
- package/dist/defs/pi.js +9 -9
- package/dist/defs/qoder.d.ts +8 -1
- package/dist/defs/qoder.js +2 -2
- package/dist/defs/qwen.d.ts +8 -1
- package/dist/defs/qwen.js +2 -2
- package/dist/defs/reasonix.d.ts +4 -1
- package/dist/defs/reasonix.js +3 -3
- package/dist/defs/shared.d.ts +4 -2
- package/dist/defs/shared.js +2 -2
- package/dist/defs/trae-cli.d.ts +12 -2
- package/dist/defs/trae-cli.js +3 -3
- package/dist/defs/vibe.d.ts +4 -1
- package/dist/defs/vibe.js +2 -2
- package/dist/detection.d.ts +19 -4
- package/dist/detection.js +33 -33
- package/dist/diagnostics.d.ts +14 -3
- package/dist/diagnostics.js +5 -5
- package/dist/env.d.ts +16 -4
- package/dist/env.js +7 -7
- package/dist/executables.d.ts +24 -8
- package/dist/executables.js +13 -13
- package/dist/index.d.ts +228 -4
- package/dist/index.js +230 -6
- package/dist/invocation.d.ts +6 -1
- package/dist/invocation.js +2 -2
- package/dist/json-event-stream.d.ts +7 -2
- package/dist/json-event-stream.js +3 -3
- package/dist/launch.d.ts +12 -2
- package/dist/launch.js +3 -3
- package/dist/log-file.d.ts +4 -1
- package/dist/log-file.js +2 -2
- package/dist/mcp.d.ts +6 -3
- package/dist/mcp.js +1 -1
- package/dist/metadata.d.ts +7 -3
- package/dist/metadata.js +1 -1
- package/dist/mmd-routes.d.ts +22 -6
- package/dist/mmd-routes.js +14 -14
- package/dist/model-catalog-cache.d.ts +50 -0
- package/dist/model-catalog-cache.js +61 -0
- package/dist/model-loading-state.d.ts +10 -0
- package/dist/model-loading-state.js +23 -0
- package/dist/model-registry.d.ts +28 -7
- package/dist/model-registry.js +11 -8
- package/dist/models.d.ts +31 -6
- package/dist/models.js +6 -6
- package/dist/opencode-log.d.ts +12 -4
- package/dist/opencode-log.js +8 -8
- package/dist/paths.d.ts +6 -2
- package/dist/paths.js +3 -3
- package/dist/pi-models.d.ts +3 -1
- package/dist/pi-models.js +2 -2
- package/dist/prompt-budget.d.ts +17 -4
- package/dist/prompt-budget.js +3 -3
- package/dist/prompt-file.d.ts +5 -1
- package/dist/prompt-file.js +1 -1
- package/dist/providers/aihubmix.d.ts +34 -9
- package/dist/providers/aihubmix.js +26 -26
- package/dist/providers/anthropic-messages.d.ts +77 -20
- package/dist/providers/anthropic-messages.js +53 -50
- package/dist/providers/azure-chat.d.ts +21 -7
- package/dist/providers/azure-chat.js +18 -16
- package/dist/providers/connection-guard.d.ts +45 -31
- package/dist/providers/connection-guard.js +40 -143
- package/dist/providers/connection-test.d.ts +1 -1
- package/dist/providers/connection-test.js +13 -30
- package/dist/providers/elevenlabs.d.ts +7 -2
- package/dist/providers/elevenlabs.js +4 -4
- package/dist/providers/google-messages.d.ts +44 -10
- package/dist/providers/google-messages.js +36 -34
- package/dist/providers/google-schema.d.ts +26 -0
- package/dist/providers/google-schema.js +253 -0
- package/dist/providers/google.d.ts +21 -6
- package/dist/providers/google.js +10 -10
- package/dist/providers/index.d.ts +3 -2
- package/dist/providers/index.js +3 -2
- package/dist/providers/model-catalog.d.ts +1 -1
- package/dist/providers/model-catalog.js +14 -27
- package/dist/providers/oauth-callback-server.d.ts +1 -1
- package/dist/providers/oauth-callback-server.js +3 -2
- package/dist/providers/oauth-credentials.d.ts +7 -1
- package/dist/providers/oauth-credentials.js +5 -5
- package/dist/providers/oauth-provider.d.ts +2 -2
- package/dist/providers/oauth-provider.js +20 -25
- package/dist/providers/oauth-tokens.d.ts +26 -6
- package/dist/providers/oauth-tokens.js +9 -9
- package/dist/providers/ollama-chat.d.ts +66 -31
- package/dist/providers/ollama-chat.js +64 -61
- package/dist/providers/openai-chat.d.ts +77 -22
- package/dist/providers/openai-chat.js +71 -67
- package/dist/providers/pkce.d.ts +33 -20
- package/dist/providers/pkce.js +75 -146
- package/dist/providers/sse-decode.d.ts +3 -1
- package/dist/providers/sse-decode.js +1 -1
- package/dist/providers/token-params.d.ts +16 -5
- package/dist/providers/token-params.js +6 -6
- package/dist/providers/tool-turn-types.d.ts +94 -0
- package/dist/providers/tool-turn-types.js +2 -0
- package/dist/providers/tool-turn.d.ts +10 -0
- package/dist/providers/tool-turn.js +258 -0
- package/dist/qoder-stream.d.ts +7 -3
- package/dist/qoder-stream.js +3 -3
- package/dist/registry.d.ts +6 -2
- package/dist/registry.js +4 -4
- package/dist/resolution.d.ts +5 -1
- package/dist/resolution.js +3 -3
- package/dist/role-marker-guard.d.ts +9 -5
- package/dist/role-marker-guard.js +5 -5
- package/dist/terminal-launch.d.ts +6 -1
- package/dist/terminal-launch.js +2 -2
- package/dist/types.d.ts +22 -6
- package/package.json +43 -4
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* dead, unreachable code would force either a contrived test or a
|
|
15
15
|
* coverage-suppression comment to satisfy this package's >=99% bar, and this
|
|
16
16
|
* repo's coverage-discipline convention calls for refactoring dead branches
|
|
17
|
-
* away rather than either of those. See
|
|
17
|
+
* away rather than either of those. See archived provenance ledger.
|
|
18
18
|
*/
|
|
19
19
|
/** A single streamed text delta event, as consumed by `emitWithTextSuppressor`. */
|
|
20
20
|
type EventSink = (event: {
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* dead, unreachable code would force either a contrived test or a
|
|
15
15
|
* coverage-suppression comment to satisfy this package's >=99% bar, and this
|
|
16
16
|
* repo's coverage-discipline convention calls for refactoring dead branches
|
|
17
|
-
* away rather than either of those. See
|
|
17
|
+
* away rather than either of those. See archived provenance ledger.
|
|
18
18
|
*/
|
|
19
19
|
const ARTIFACT_OPEN_RE = /(?:<\s*\|?\s*DSML[\s,]+artifact\b[^>]*>|<\s*artifact\b[^>]*>)/i;
|
|
20
20
|
const DSML_ARTIFACT_CLOSE_RE = /(?:<\/artifact>|<\/\s*\|?\s*DSML\s*>|<\s*\|?\s*\/\s*DSML\s*\|?\s*>)/i;
|
|
@@ -8,7 +8,8 @@ import type { ChildProcess } from 'node:child_process';
|
|
|
8
8
|
/** A JSON-RPC 2.0 request or response identifier. May be a numeric integer or a string. */
|
|
9
9
|
export type JsonRpcId = string | number;
|
|
10
10
|
/** An arbitrary JSON object with string keys and unknown values. Used as a loose type for parsed RPC frames. */
|
|
11
|
-
|
|
11
|
+
/** ACP records may contain unvalidated provider values; this does not assert JSON safety. */
|
|
12
|
+
export type UnknownRecord = Record<string, unknown>;
|
|
12
13
|
/** Minimal writable interface required to send JSON-RPC newline-delimited frames to an ACP agent's stdin. */
|
|
13
14
|
export type RpcWritable = Pick<Writable, 'write' | 'end'>;
|
|
14
15
|
/** The Node `ChildProcess` handle for a spawned ACP agent subprocess. */
|
|
@@ -21,7 +22,7 @@ export type TimerHandle = ReturnType<typeof setTimeout>;
|
|
|
21
22
|
* (`'text_artifact'`). Inlined here rather than imported from an external
|
|
22
23
|
* contracts package — the upstream type is a trivial two-value literal union
|
|
23
24
|
* with no product-specific branding, so importing a whole package for it
|
|
24
|
-
* would be the tail wagging the dog. See
|
|
25
|
+
* would be the tail wagging the dog. See archived provenance ledger.
|
|
25
26
|
*/
|
|
26
27
|
export type ExecutionProfile = 'filesystem' | 'text_artifact';
|
|
27
28
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* diagnostics. Depends on acp/types, acp/json, and acp/account-failure;
|
|
6
6
|
* consumed exclusively by acp/session.ts.
|
|
7
7
|
*/
|
|
8
|
-
import type {
|
|
8
|
+
import type { UnknownRecord } from './types.js';
|
|
9
9
|
import { type AccountFailureClassifier } from './account-failure.js';
|
|
10
10
|
/**
|
|
11
11
|
* Produces a shallow diagnostic snapshot of an ACP update object for the
|
|
@@ -17,7 +17,7 @@ import { type AccountFailureClassifier } from './account-failure.js';
|
|
|
17
17
|
* @param update - A parsed ACP `session/update` params object.
|
|
18
18
|
* @returns A flat diagnostic object suitable for inclusion in an agent event payload.
|
|
19
19
|
*/
|
|
20
|
-
export declare function acpRawEventShape(update:
|
|
20
|
+
export declare function acpRawEventShape(update: UnknownRecord): {
|
|
21
21
|
sessionUpdate: string | null;
|
|
22
22
|
keys: string[];
|
|
23
23
|
contentKind: string;
|
|
@@ -42,25 +42,25 @@ export declare function acpRawEventShape(update: JsonObject): {
|
|
|
42
42
|
*
|
|
43
43
|
* @param update - A parsed ACP `session/update` params object.
|
|
44
44
|
*/
|
|
45
|
-
export declare function acpUpdateStatus(update:
|
|
45
|
+
export declare function acpUpdateStatus(update: UnknownRecord): string;
|
|
46
46
|
/**
|
|
47
47
|
* Returns `true` when the update's `status` field represents a successful
|
|
48
48
|
* terminal state (`completed`, `complete`, `succeeded`, or `success`).
|
|
49
49
|
* Used to decide when to emit deferred artifact-write tool events.
|
|
50
50
|
*/
|
|
51
|
-
export declare function isAcpCompletedStatus(update:
|
|
51
|
+
export declare function isAcpCompletedStatus(update: UnknownRecord): boolean;
|
|
52
52
|
/**
|
|
53
53
|
* Returns `true` when the update's `status` field represents a terminal
|
|
54
54
|
* failure state (`failed`, `failure`, `error`, `cancelled`, or `canceled`).
|
|
55
55
|
* Used to clean up pending write-suppression state and emit failed tool events.
|
|
56
56
|
*/
|
|
57
|
-
export declare function isAcpTerminalFailureStatus(update:
|
|
57
|
+
export declare function isAcpTerminalFailureStatus(update: UnknownRecord): boolean;
|
|
58
58
|
/**
|
|
59
59
|
* Returns `true` when the update's status is `'retry'`. Signals that the AMR
|
|
60
60
|
* agent wants to restart the request; the session promoter maps this to a
|
|
61
61
|
* structured error payload via `promotedAmrRetryStatusPayload`.
|
|
62
62
|
*/
|
|
63
|
-
export declare function isAcpRetryStatus(update:
|
|
63
|
+
export declare function isAcpRetryStatus(update: UnknownRecord): boolean;
|
|
64
64
|
/**
|
|
65
65
|
* Recursively collects all text-bearing leaf values from an ACP update
|
|
66
66
|
* (strings, numbers, booleans) up to 4 levels deep. Used to produce a flat
|
|
@@ -83,7 +83,7 @@ export declare function acpUpdateDiagnosticText(value: unknown, depth?: number):
|
|
|
83
83
|
* `noopAccountFailureClassifier`, under which this always returns `null`.
|
|
84
84
|
* @returns A structured error payload with `message` and `error`, or `null`.
|
|
85
85
|
*/
|
|
86
|
-
export declare function promotedAmrRetryStatusPayload(update:
|
|
86
|
+
export declare function promotedAmrRetryStatusPayload(update: UnknownRecord, classifier?: AccountFailureClassifier): {
|
|
87
87
|
message: string;
|
|
88
88
|
error: {
|
|
89
89
|
code: string;
|
|
@@ -129,7 +129,7 @@ export declare function promotedAmrStderrPayload(chunk: string, classifier?: Acc
|
|
|
129
129
|
*
|
|
130
130
|
* @param update - A parsed ACP `session/update` params object.
|
|
131
131
|
*/
|
|
132
|
-
export declare function acpToolCallId(update:
|
|
132
|
+
export declare function acpToolCallId(update: UnknownRecord): string | null;
|
|
133
133
|
/**
|
|
134
134
|
* Returns `true` when the update's `title` or `name` field contains a word
|
|
135
135
|
* that indicates a file-write operation (`edit`, `write`, `create`, `update`,
|
|
@@ -138,7 +138,7 @@ export declare function acpToolCallId(update: JsonObject): string | null;
|
|
|
138
138
|
*
|
|
139
139
|
* @param update - A parsed ACP `session/update` params object.
|
|
140
140
|
*/
|
|
141
|
-
export declare function isAcpArtifactWriteLabel(update:
|
|
141
|
+
export declare function isAcpArtifactWriteLabel(update: UnknownRecord): boolean;
|
|
142
142
|
/**
|
|
143
143
|
* Returns `true` when an ACP update represents the terminal completion of an
|
|
144
144
|
* artifact-write tool call and should arm the DSML text suppressor. Requires
|
|
@@ -148,7 +148,7 @@ export declare function isAcpArtifactWriteLabel(update: JsonObject): boolean;
|
|
|
148
148
|
* @param update - A parsed ACP `session/update` params object.
|
|
149
149
|
* @param writeToolCallIds - The set of tool call ids identified as artifact writes so far.
|
|
150
150
|
*/
|
|
151
|
-
export declare function isAcpArtifactWriteUpdate(update:
|
|
151
|
+
export declare function isAcpArtifactWriteUpdate(update: UnknownRecord, writeToolCallIds: Set<string>): boolean;
|
|
152
152
|
/**
|
|
153
153
|
* Best-effort extraction of a concrete file path from an ACP artifact-write
|
|
154
154
|
* tool call update, checking three sources in priority order:
|
|
@@ -162,5 +162,5 @@ export declare function isAcpArtifactWriteUpdate(update: JsonObject, writeToolCa
|
|
|
162
162
|
* @param update - A parsed ACP `session/update` params object.
|
|
163
163
|
* @returns An absolute or relative file path string, or `null` when absent.
|
|
164
164
|
*/
|
|
165
|
-
export declare function acpArtifactWritePath(update:
|
|
165
|
+
export declare function acpArtifactWritePath(update: UnknownRecord): string | null;
|
|
166
166
|
//# sourceMappingURL=updates.d.ts.map
|
|
@@ -130,7 +130,7 @@ export function promotedAmrRetryStatusPayload(update, classifier = noopAccountFa
|
|
|
130
130
|
if (!isAcpRetryStatus(update))
|
|
131
131
|
return null;
|
|
132
132
|
const diagnosticText = acpUpdateDiagnosticText(update).join('\n');
|
|
133
|
-
const failure = classifier.classify(diagnosticText);
|
|
133
|
+
const failure = classifier.classify({ text: diagnosticText });
|
|
134
134
|
if (!failure)
|
|
135
135
|
return null;
|
|
136
136
|
return {
|
|
@@ -162,7 +162,7 @@ export function promotedAmrStderrPayload(chunk, classifier = noopAccountFailureC
|
|
|
162
162
|
return null;
|
|
163
163
|
if (!/\bretry\b/i.test(chunk))
|
|
164
164
|
return null;
|
|
165
|
-
const failure = classifier.classify(chunk);
|
|
165
|
+
const failure = classifier.classify({ text: chunk });
|
|
166
166
|
if (!failure)
|
|
167
167
|
return null;
|
|
168
168
|
return {
|
|
@@ -16,10 +16,19 @@ export interface JsonLineAccumulatorState {
|
|
|
16
16
|
pendingJson: string;
|
|
17
17
|
pendingJsonLineCount: number;
|
|
18
18
|
}
|
|
19
|
-
export declare function emitJsonLine(candidate: string, onMessage: (
|
|
20
|
-
|
|
19
|
+
export declare function emitJsonLine(candidate: string, onMessage: (requiredArgs: {
|
|
20
|
+
message: unknown;
|
|
21
|
+
rawLine: string;
|
|
22
|
+
}) => void): boolean;
|
|
23
|
+
export declare function continuePendingJsonLine(state: JsonLineAccumulatorState, trimmed: string, onMessage: (requiredArgs: {
|
|
24
|
+
message: unknown;
|
|
25
|
+
rawLine: string;
|
|
26
|
+
}) => void): void;
|
|
21
27
|
export declare function tryStartPendingJsonLine(state: JsonLineAccumulatorState, trimmed: string): void;
|
|
22
|
-
export declare function handleJsonLine(state: JsonLineAccumulatorState, line: string, onMessage: (
|
|
28
|
+
export declare function handleJsonLine(state: JsonLineAccumulatorState, line: string, onMessage: (requiredArgs: {
|
|
29
|
+
message: unknown;
|
|
30
|
+
rawLine: string;
|
|
31
|
+
}) => void): void;
|
|
23
32
|
/**
|
|
24
33
|
* Creates a streaming JSON-line parser over a raw byte/string stream.
|
|
25
34
|
* Buffers incoming chunks, splits on newline boundaries, and attempts
|
|
@@ -30,13 +39,20 @@ export declare function handleJsonLine(state: JsonLineAccumulatorState, line: st
|
|
|
30
39
|
* Used as the shared ACP transport: both the acp/ and pi-rpc/ adapters call
|
|
31
40
|
* this to decode JSON-RPC frames from a subprocess's stdout.
|
|
32
41
|
*
|
|
33
|
-
* @param onMessage - Called
|
|
34
|
-
*
|
|
35
|
-
* @returns An object with `feed(chunk)` for incremental input and `flush()` to
|
|
42
|
+
* @param requiredArgs.onMessage - Called with `{ message, rawLine }` for each
|
|
43
|
+
* successfully parsed JSON value and its raw reassembled line string.
|
|
44
|
+
* @returns An object with `feed({ chunk })` for incremental input and `flush()` to
|
|
36
45
|
* drain any residual buffered content at stream end.
|
|
37
46
|
*/
|
|
38
|
-
export declare function createJsonLineStream(onMessage
|
|
39
|
-
|
|
47
|
+
export declare function createJsonLineStream({ onMessage }: {
|
|
48
|
+
onMessage: (requiredArgs: {
|
|
49
|
+
message: unknown;
|
|
50
|
+
rawLine: string;
|
|
51
|
+
}) => void;
|
|
52
|
+
}): {
|
|
53
|
+
feed({ chunk }: {
|
|
54
|
+
chunk: string;
|
|
55
|
+
}): void;
|
|
40
56
|
flush(): void;
|
|
41
57
|
};
|
|
42
58
|
export type JsonObjectScanFrame = {
|
|
@@ -22,7 +22,7 @@ function resetPendingJson(state) {
|
|
|
22
22
|
}
|
|
23
23
|
export function emitJsonLine(candidate, onMessage) {
|
|
24
24
|
try {
|
|
25
|
-
onMessage(JSON.parse(candidate), candidate);
|
|
25
|
+
onMessage({ message: JSON.parse(candidate), rawLine: candidate });
|
|
26
26
|
return true;
|
|
27
27
|
}
|
|
28
28
|
catch {
|
|
@@ -81,16 +81,16 @@ export function handleJsonLine(state, line, onMessage) {
|
|
|
81
81
|
* Used as the shared ACP transport: both the acp/ and pi-rpc/ adapters call
|
|
82
82
|
* this to decode JSON-RPC frames from a subprocess's stdout.
|
|
83
83
|
*
|
|
84
|
-
* @param onMessage - Called
|
|
85
|
-
*
|
|
86
|
-
* @returns An object with `feed(chunk)` for incremental input and `flush()` to
|
|
84
|
+
* @param requiredArgs.onMessage - Called with `{ message, rawLine }` for each
|
|
85
|
+
* successfully parsed JSON value and its raw reassembled line string.
|
|
86
|
+
* @returns An object with `feed({ chunk })` for incremental input and `flush()` to
|
|
87
87
|
* drain any residual buffered content at stream end.
|
|
88
88
|
*/
|
|
89
|
-
export function createJsonLineStream(onMessage) {
|
|
89
|
+
export function createJsonLineStream({ onMessage }) {
|
|
90
90
|
let buffer = '';
|
|
91
91
|
const state = { pendingJson: '', pendingJsonLineCount: 0 };
|
|
92
92
|
return {
|
|
93
|
-
feed(chunk) {
|
|
93
|
+
feed({ chunk }) {
|
|
94
94
|
buffer += chunk;
|
|
95
95
|
const lines = buffer.split('\n');
|
|
96
96
|
buffer = lines.pop() || '';
|
|
@@ -114,7 +114,7 @@ export function createJsonLineStream(onMessage) {
|
|
|
114
114
|
// a defensive `if (pendingJson && emit(pendingJson)) { pendingJson =
|
|
115
115
|
// '' }` here that was provably dead code; removed per this package's
|
|
116
116
|
// coverage-driven dead-branch discipline rather than left uncovered or
|
|
117
|
-
// suppressed. See
|
|
117
|
+
// suppressed. See archived provenance ledger.
|
|
118
118
|
// Ignore trailing non-JSON log lines on stdout.
|
|
119
119
|
},
|
|
120
120
|
};
|
|
@@ -136,7 +136,7 @@ export function afterValue(state) {
|
|
|
136
136
|
// guard was provably dead (verified by a 2M-trial adversarial fuzz,
|
|
137
137
|
// including deliberately malformed bracket sequences, finding zero
|
|
138
138
|
// mismatches) and is removed here per this package's coverage-driven
|
|
139
|
-
// dead-branch discipline. See
|
|
139
|
+
// dead-branch discipline. See archived provenance ledger.
|
|
140
140
|
function closeFrame(state) {
|
|
141
141
|
state.stack.pop();
|
|
142
142
|
afterValue(state);
|
|
@@ -43,5 +43,9 @@ export declare function handleAutoRetryEnd(raw: JsonRecord, send: SendAgentEvent
|
|
|
43
43
|
* @param ctx - Per-run context: start timestamp and first-token sentinel.
|
|
44
44
|
* @returns `'agent_end'` on run completion, `null` otherwise.
|
|
45
45
|
*/
|
|
46
|
-
export declare function mapPiRpcEvent(raw
|
|
46
|
+
export declare function mapPiRpcEvent({ raw, send, ctx }: {
|
|
47
|
+
raw: JsonRecord;
|
|
48
|
+
send: SendAgentEvent;
|
|
49
|
+
ctx: PiRpcContext;
|
|
50
|
+
}): 'agent_end' | null;
|
|
47
51
|
//# sourceMappingURL=events.d.ts.map
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { getRecord } from './internal.js';
|
|
2
2
|
export function handleAgentStart(_raw, send) {
|
|
3
|
-
send('agent', { type: 'status', label: 'working' });
|
|
3
|
+
send({ event: 'agent', payload: { type: 'status', label: 'working' } });
|
|
4
4
|
return null;
|
|
5
5
|
}
|
|
6
6
|
export function handleAgentEnd() {
|
|
7
7
|
return 'agent_end';
|
|
8
8
|
}
|
|
9
9
|
export function handleTurnStart(_raw, send) {
|
|
10
|
-
send('agent', { type: 'status', label: 'thinking' });
|
|
10
|
+
send({ event: 'agent', payload: { type: 'status', label: 'thinking' } });
|
|
11
11
|
return null;
|
|
12
12
|
}
|
|
13
13
|
/** Extracts the subset of pi's `message.usage` fields the daemon reports as token usage. */
|
|
@@ -30,12 +30,12 @@ export function emitTurnEndUsage(u, send, ctx) {
|
|
|
30
30
|
if (Object.keys(usage).length === 0)
|
|
31
31
|
return;
|
|
32
32
|
const cost = getRecord(u.cost);
|
|
33
|
-
send('agent', {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
send({ event: 'agent', payload: {
|
|
34
|
+
type: 'usage',
|
|
35
|
+
usage,
|
|
36
|
+
costUsd: cost?.total ?? cost?.totalCost ?? null,
|
|
37
|
+
durationMs: Date.now() - ctx.runStartedAt,
|
|
38
|
+
} });
|
|
39
39
|
}
|
|
40
40
|
export function emitTurnEndErrorIfPresent(message, raw, send) {
|
|
41
41
|
if (message?.stopReason !== 'error')
|
|
@@ -43,7 +43,7 @@ export function emitTurnEndErrorIfPresent(message, raw, send) {
|
|
|
43
43
|
const messageText = typeof message.errorMessage === 'string' && message.errorMessage.length > 0
|
|
44
44
|
? message.errorMessage
|
|
45
45
|
: 'Pi agent error';
|
|
46
|
-
send('agent', { type: 'error', message: messageText, raw });
|
|
46
|
+
send({ event: 'agent', payload: { type: 'error', message: messageText, raw } });
|
|
47
47
|
}
|
|
48
48
|
export function handleTurnEnd(raw, send, ctx) {
|
|
49
49
|
const message = getRecord(raw.message);
|
|
@@ -58,24 +58,24 @@ export function handleAssistantTextDelta(ev, send, ctx) {
|
|
|
58
58
|
return;
|
|
59
59
|
if (!ctx.sentFirstToken.value) {
|
|
60
60
|
ctx.sentFirstToken.value = true;
|
|
61
|
-
send('agent', {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
61
|
+
send({ event: 'agent', payload: {
|
|
62
|
+
type: 'status',
|
|
63
|
+
label: 'streaming',
|
|
64
|
+
ttftMs: Date.now() - ctx.runStartedAt,
|
|
65
|
+
} });
|
|
66
66
|
}
|
|
67
|
-
send('agent', { type: 'text_delta', delta: ev.delta });
|
|
67
|
+
send({ event: 'agent', payload: { type: 'text_delta', delta: ev.delta } });
|
|
68
68
|
}
|
|
69
69
|
export function handleAssistantThinkingDelta(ev, send) {
|
|
70
70
|
if (typeof ev.delta !== 'string')
|
|
71
71
|
return;
|
|
72
|
-
send('agent', { type: 'thinking_delta', delta: ev.delta });
|
|
72
|
+
send({ event: 'agent', payload: { type: 'thinking_delta', delta: ev.delta } });
|
|
73
73
|
}
|
|
74
74
|
export function handleAssistantThinkingStart(_ev, send) {
|
|
75
|
-
send('agent', { type: 'thinking_start' });
|
|
75
|
+
send({ event: 'agent', payload: { type: 'thinking_start' } });
|
|
76
76
|
}
|
|
77
77
|
export function handleAssistantThinkingEnd(_ev, send) {
|
|
78
|
-
send('agent', { type: 'thinking_end' });
|
|
78
|
+
send({ event: 'agent', payload: { type: 'thinking_end' } });
|
|
79
79
|
}
|
|
80
80
|
// pi's RPC protocol emits a message_update with error delta when
|
|
81
81
|
// the model returns an error (e.g. aborted, context overflow).
|
|
@@ -87,7 +87,7 @@ export function handleAssistantError(ev, send, _ctx, raw) {
|
|
|
87
87
|
: typeof ev.delta === 'string' && ev.delta.length > 0
|
|
88
88
|
? ev.delta
|
|
89
89
|
: 'Agent error';
|
|
90
|
-
send('agent', { type: 'error', message, raw });
|
|
90
|
+
send({ event: 'agent', payload: { type: 'error', message, raw } });
|
|
91
91
|
}
|
|
92
92
|
const ASSISTANT_MESSAGE_EVENT_HANDLERS = {
|
|
93
93
|
text_delta: handleAssistantTextDelta,
|
|
@@ -112,12 +112,12 @@ export function handleMessageEnd() {
|
|
|
112
112
|
return null;
|
|
113
113
|
}
|
|
114
114
|
export function handleToolExecutionStart(raw, send) {
|
|
115
|
-
send('agent', {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
115
|
+
send({ event: 'agent', payload: {
|
|
116
|
+
type: 'tool_use',
|
|
117
|
+
id: raw.toolCallId ?? null,
|
|
118
|
+
name: raw.toolName ?? null,
|
|
119
|
+
input: raw.args ?? null,
|
|
120
|
+
} });
|
|
121
121
|
return null;
|
|
122
122
|
}
|
|
123
123
|
export function handleToolExecutionEnd(raw, send) {
|
|
@@ -133,12 +133,12 @@ export function handleToolExecutionEnd(raw, send) {
|
|
|
133
133
|
: typeof content === 'string'
|
|
134
134
|
? content
|
|
135
135
|
: '';
|
|
136
|
-
send('agent', {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
136
|
+
send({ event: 'agent', payload: {
|
|
137
|
+
type: 'tool_result',
|
|
138
|
+
toolUseId: raw.toolCallId ?? null,
|
|
139
|
+
content: text,
|
|
140
|
+
isError: raw.isError === true,
|
|
141
|
+
} });
|
|
142
142
|
return null;
|
|
143
143
|
}
|
|
144
144
|
// pi's RPC protocol can emit `extension_error` when an extension
|
|
@@ -149,15 +149,15 @@ export function handleExtensionError(raw, send) {
|
|
|
149
149
|
const message = typeof raw.error === 'string' && raw.error.length > 0
|
|
150
150
|
? raw.error
|
|
151
151
|
: 'Extension error';
|
|
152
|
-
send('agent', { type: 'error', message, raw });
|
|
152
|
+
send({ event: 'agent', payload: { type: 'error', message, raw } });
|
|
153
153
|
return null;
|
|
154
154
|
}
|
|
155
155
|
export function handleCompactionStart(_raw, send) {
|
|
156
|
-
send('agent', { type: 'status', label: 'compacting' });
|
|
156
|
+
send({ event: 'agent', payload: { type: 'status', label: 'compacting' } });
|
|
157
157
|
return null;
|
|
158
158
|
}
|
|
159
159
|
export function handleAutoRetryStart(_raw, send) {
|
|
160
|
-
send('agent', { type: 'status', label: 'retrying' });
|
|
160
|
+
send({ event: 'agent', payload: { type: 'status', label: 'retrying' } });
|
|
161
161
|
return null;
|
|
162
162
|
}
|
|
163
163
|
export function handleAutoRetryEnd(raw, send) {
|
|
@@ -169,7 +169,7 @@ export function handleAutoRetryEnd(raw, send) {
|
|
|
169
169
|
const message = typeof raw.finalError === 'string' && raw.finalError.length > 0
|
|
170
170
|
? raw.finalError
|
|
171
171
|
: 'Auto-retry exhausted';
|
|
172
|
-
send('agent', { type: 'error', message, raw });
|
|
172
|
+
send({ event: 'agent', payload: { type: 'error', message, raw } });
|
|
173
173
|
return null;
|
|
174
174
|
}
|
|
175
175
|
const PI_RPC_EVENT_HANDLERS = {
|
|
@@ -196,7 +196,7 @@ const PI_RPC_EVENT_HANDLERS = {
|
|
|
196
196
|
* @param ctx - Per-run context: start timestamp and first-token sentinel.
|
|
197
197
|
* @returns `'agent_end'` on run completion, `null` otherwise.
|
|
198
198
|
*/
|
|
199
|
-
export function mapPiRpcEvent(raw, send, ctx) {
|
|
199
|
+
export function mapPiRpcEvent({ raw, send, ctx }) {
|
|
200
200
|
const handler = typeof raw.type === 'string' ? PI_RPC_EVENT_HANDLERS[raw.type] : undefined;
|
|
201
201
|
return handler ? handler(raw, send, ctx) : null;
|
|
202
202
|
}
|
|
@@ -6,7 +6,10 @@
|
|
|
6
6
|
/** A plain JSON object — the base payload type for pi RPC messages. */
|
|
7
7
|
export type JsonRecord = Record<string, unknown>;
|
|
8
8
|
/** Callback signature for forwarding a typed event to the daemon's SSE layer. */
|
|
9
|
-
export type SendAgentEvent = (
|
|
9
|
+
export type SendAgentEvent = (requiredArgs: {
|
|
10
|
+
event: string;
|
|
11
|
+
payload: JsonRecord;
|
|
12
|
+
}) => void;
|
|
10
13
|
/** Optional token-count fields surfaced by pi's RPC protocol on turn completion. */
|
|
11
14
|
export type TokenUsage = {
|
|
12
15
|
input_tokens?: number;
|
|
@@ -17,5 +17,7 @@ export type PiModelOption = {
|
|
|
17
17
|
* @param stdout - Raw stdout captured from `pi --list-models`, as a string or Buffer.
|
|
18
18
|
* @returns Parsed model array (at least 2 entries), or `null` when nothing is found.
|
|
19
19
|
*/
|
|
20
|
-
export declare function parsePiModels(stdout
|
|
20
|
+
export declare function parsePiModels({ stdout }: {
|
|
21
|
+
stdout: unknown;
|
|
22
|
+
}): PiModelOption[] | null;
|
|
21
23
|
//# sourceMappingURL=models.d.ts.map
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* @param stdout - Raw stdout captured from `pi --list-models`, as a string or Buffer.
|
|
13
13
|
* @returns Parsed model array (at least 2 entries), or `null` when nothing is found.
|
|
14
14
|
*/
|
|
15
|
-
export function parsePiModels(stdout) {
|
|
15
|
+
export function parsePiModels({ stdout }) {
|
|
16
16
|
const lines = String(stdout || '')
|
|
17
17
|
.split('\n')
|
|
18
18
|
.map((l) => l.trim())
|
|
@@ -141,5 +141,5 @@ export declare function handlePiResponseMessage({ raw, parentSessionRpcId, promp
|
|
|
141
141
|
* parent session path for conversation resume.
|
|
142
142
|
* @returns A `PiRpcSession` handle with `hasFatalError`, `getLastSessionPath`, and `abort`.
|
|
143
143
|
*/
|
|
144
|
-
export declare function attachPiRpcSession(
|
|
144
|
+
export declare function attachPiRpcSession(requiredArgs: Pick<PiRpcSessionOptions, "child" | "prompt" | "send">, optionalArgs?: Omit<PiRpcSessionOptions, "child" | "prompt" | "send">): PiRpcSession;
|
|
145
145
|
//# sourceMappingURL=session.d.ts.map
|
|
@@ -247,7 +247,8 @@ export function handlePiResponseMessage({ raw, parentSessionRpcId, promptRpcId,
|
|
|
247
247
|
* parent session path for conversation resume.
|
|
248
248
|
* @returns A `PiRpcSession` handle with `hasFatalError`, `getLastSessionPath`, and `abort`.
|
|
249
249
|
*/
|
|
250
|
-
export function attachPiRpcSession(
|
|
250
|
+
export function attachPiRpcSession(requiredArgs, optionalArgs = {}) {
|
|
251
|
+
const { child, prompt, cwd, model, send, imagePaths, uploadRoot, parentSession, } = { ...optionalArgs, ...requiredArgs };
|
|
251
252
|
const stdin = child.stdin;
|
|
252
253
|
const stdout = child.stdout;
|
|
253
254
|
if (stdin === null) {
|
|
@@ -281,17 +282,17 @@ export function attachPiRpcSession({ child, prompt, cwd, model, send, imagePaths
|
|
|
281
282
|
return;
|
|
282
283
|
finished = true;
|
|
283
284
|
fatal = true;
|
|
284
|
-
send('error', { message, ...(code ? { code } : {}) });
|
|
285
|
+
send({ event: 'error', payload: { message, ...(code ? { code } : {}) } });
|
|
285
286
|
if (!child.killed)
|
|
286
287
|
child.kill('SIGTERM');
|
|
287
288
|
};
|
|
288
289
|
// Emit initial status with model name immediately — before pi even
|
|
289
290
|
// responds — so the UI header shows the model name at session start.
|
|
290
|
-
send('agent', {
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
291
|
+
send({ event: 'agent', payload: {
|
|
292
|
+
type: 'status',
|
|
293
|
+
label: 'initializing',
|
|
294
|
+
model: typeof model === 'string' && model ? model : null,
|
|
295
|
+
} });
|
|
295
296
|
// ---- Outbound: send new_session (if parentSession provided) then prompt via RPC ----
|
|
296
297
|
stdin.on('error', (err) => {
|
|
297
298
|
if (errorCode(err) !== 'EPIPE') {
|
|
@@ -351,33 +352,33 @@ export function attachPiRpcSession({ child, prompt, cwd, model, send, imagePaths
|
|
|
351
352
|
}, shutdownMs);
|
|
352
353
|
};
|
|
353
354
|
// ---- Inbound: parse stdout events ----
|
|
354
|
-
const parser = createJsonLineStream((raw) => {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
355
|
+
const parser = createJsonLineStream({ onMessage: ({ message: raw }) => {
|
|
356
|
+
if (!isRecord(raw))
|
|
357
|
+
return;
|
|
358
|
+
// Once finished (agent_end or abort), stop processing — the run is
|
|
359
|
+
// over, so no more agent events should be emitted. We still drain
|
|
360
|
+
// stdout via parser.feed() so the pipe doesn't break; we just skip
|
|
361
|
+
// acting on the parsed objects.
|
|
362
|
+
if (finished)
|
|
363
|
+
return;
|
|
364
|
+
// Extension UI requests: auto-resolve to keep pi unblocked.
|
|
365
|
+
if (raw.type === 'extension_ui_request') {
|
|
366
|
+
replyExtensionUi(stdin, raw);
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
if (raw.type === 'response') {
|
|
370
|
+
handlePiResponseMessage({ raw, parentSessionRpcId, promptRpcId, fail, sendPromptCommand });
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
// Agent events: delegate to the pure mapper.
|
|
374
|
+
const result = mapPiRpcEvent({ raw: raw, send: send, ctx: { runStartedAt, sentFirstToken } });
|
|
375
|
+
if (result === 'agent_end') {
|
|
376
|
+
handlePiAgentEnd();
|
|
377
|
+
}
|
|
378
|
+
} });
|
|
378
379
|
stdout.on('data', (chunk) => {
|
|
379
380
|
try {
|
|
380
|
-
parser.feed(typeof chunk === 'string' ? chunk : chunk.toString('utf8'));
|
|
381
|
+
parser.feed({ chunk: typeof chunk === 'string' ? chunk : chunk.toString('utf8') });
|
|
381
382
|
}
|
|
382
383
|
catch (err) {
|
|
383
384
|
fail(`parser: ${errorMessage(err)}`);
|
|
@@ -26,11 +26,19 @@ type Fetchers = {
|
|
|
26
26
|
fetchRemote: () => Promise<RuntimeModelOption[]>;
|
|
27
27
|
};
|
|
28
28
|
export declare class AmrModelLoadingCache {
|
|
29
|
-
private readonly refreshIntervalMs;
|
|
30
29
|
private readonly states;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
private readonly refreshIntervalMs;
|
|
31
|
+
constructor(_requiredArgs?: Record<string, never>, { refreshIntervalMs }?: {
|
|
32
|
+
refreshIntervalMs?: number;
|
|
33
|
+
});
|
|
34
|
+
get({ cacheKey, fetchers }: {
|
|
35
|
+
cacheKey: string;
|
|
36
|
+
fetchers: Fetchers;
|
|
37
|
+
}): Promise<AmrModelsResponse>;
|
|
38
|
+
warm({ cacheKey, fetchRemote }: {
|
|
39
|
+
cacheKey: string;
|
|
40
|
+
fetchRemote: () => Promise<RuntimeModelOption[]>;
|
|
41
|
+
}): void;
|
|
34
42
|
resetForTests(): void;
|
|
35
43
|
private stateFor;
|
|
36
44
|
private startRefresh;
|
package/dist/amr-model-cache.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { coalesceModelLoad } from './model-loading-state.js';
|
|
1
2
|
// The AMR model catalog changes rarely (new models land on the order of
|
|
2
3
|
// days), and a cached remote list is returned immediately while a refresh
|
|
3
4
|
// runs in the background — `get()` never blocks on the network when a
|
|
@@ -11,12 +12,12 @@ function errorMessage(error) {
|
|
|
11
12
|
return error instanceof Error ? error.message : String(error ?? 'unknown error');
|
|
12
13
|
}
|
|
13
14
|
export class AmrModelLoadingCache {
|
|
14
|
-
refreshIntervalMs;
|
|
15
15
|
states = new Map();
|
|
16
|
-
|
|
16
|
+
refreshIntervalMs;
|
|
17
|
+
constructor(_requiredArgs = {}, { refreshIntervalMs = DEFAULT_REMOTE_REFRESH_INTERVAL_MS } = {}) {
|
|
17
18
|
this.refreshIntervalMs = refreshIntervalMs;
|
|
18
19
|
}
|
|
19
|
-
async get(cacheKey, fetchers) {
|
|
20
|
+
async get({ cacheKey, fetchers }) {
|
|
20
21
|
const state = this.stateFor(cacheKey);
|
|
21
22
|
const now = Date.now();
|
|
22
23
|
if (state.remote) {
|
|
@@ -40,7 +41,7 @@ export class AmrModelLoadingCache {
|
|
|
40
41
|
...(state.lastRemoteError ? { remoteError: state.lastRemoteError } : {}),
|
|
41
42
|
};
|
|
42
43
|
}
|
|
43
|
-
warm(cacheKey, fetchRemote) {
|
|
44
|
+
warm({ cacheKey, fetchRemote }) {
|
|
44
45
|
this.startRefresh(this.stateFor(cacheKey), fetchRemote);
|
|
45
46
|
}
|
|
46
47
|
resetForTests() {
|
|
@@ -55,24 +56,19 @@ export class AmrModelLoadingCache {
|
|
|
55
56
|
return created;
|
|
56
57
|
}
|
|
57
58
|
startRefresh(state, fetchRemote) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
59
|
+
void coalesceModelLoad({ state, load: async () => {
|
|
60
|
+
try {
|
|
61
|
+
const models = await fetchRemote();
|
|
62
|
+
if (models.length === 0) {
|
|
63
|
+
throw new Error('AMR remote model list returned no chat models');
|
|
64
|
+
}
|
|
65
|
+
state.remote = { models, fetchedAt: Date.now() };
|
|
66
|
+
state.lastRemoteError = null;
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
state.lastRemoteError = errorMessage(error);
|
|
65
70
|
}
|
|
66
|
-
|
|
67
|
-
state.lastRemoteError = null;
|
|
68
|
-
}
|
|
69
|
-
catch (error) {
|
|
70
|
-
state.lastRemoteError = errorMessage(error);
|
|
71
|
-
}
|
|
72
|
-
finally {
|
|
73
|
-
state.inFlight = null;
|
|
74
|
-
}
|
|
75
|
-
})();
|
|
71
|
+
} });
|
|
76
72
|
}
|
|
77
73
|
}
|
|
78
74
|
export const amrModelLoadingCache = new AmrModelLoadingCache();
|