@averyyy/pi-coding-agent 0.82.1-piclient.9 → 0.84.1-piclient.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 +272 -0
- package/README.md +6 -1
- package/dist/cli/args.d.ts +2 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +27 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/auth-check.d.ts +19 -0
- package/dist/cli/auth-check.d.ts.map +1 -0
- package/dist/cli/auth-check.js +50 -0
- package/dist/cli/auth-check.js.map +1 -0
- package/dist/cli/auth-command.d.ts +24 -0
- package/dist/cli/auth-command.d.ts.map +1 -0
- package/dist/cli/auth-command.js +102 -0
- package/dist/cli/auth-command.js.map +1 -0
- package/dist/cli/config-selector.d.ts.map +1 -1
- package/dist/cli/config-selector.js +2 -2
- package/dist/cli/config-selector.js.map +1 -1
- package/dist/cli/credential-print.d.ts +13 -0
- package/dist/cli/credential-print.d.ts.map +1 -0
- package/dist/cli/credential-print.js +76 -0
- package/dist/cli/credential-print.js.map +1 -0
- package/dist/cli/experimental/auth.d.ts +16 -0
- package/dist/cli/experimental/auth.d.ts.map +1 -0
- package/dist/cli/experimental/auth.js +13 -0
- package/dist/cli/experimental/auth.js.map +1 -0
- package/dist/cli/experimental/cli.d.ts +6 -0
- package/dist/cli/experimental/cli.d.ts.map +1 -0
- package/dist/cli/experimental/cli.js +5 -0
- package/dist/cli/experimental/cli.js.map +1 -0
- package/dist/cli/experimental/command-options.d.ts +17 -0
- package/dist/cli/experimental/command-options.d.ts.map +1 -0
- package/dist/cli/experimental/command-options.js +35 -0
- package/dist/cli/experimental/command-options.js.map +1 -0
- package/dist/cli/experimental/command.d.ts +63 -0
- package/dist/cli/experimental/command.d.ts.map +1 -0
- package/dist/cli/experimental/command.js +130 -0
- package/dist/cli/experimental/command.js.map +1 -0
- package/dist/cli/experimental/commands/client.d.ts +13 -0
- package/dist/cli/experimental/commands/client.d.ts.map +1 -0
- package/dist/cli/experimental/commands/client.js +25 -0
- package/dist/cli/experimental/commands/client.js.map +1 -0
- package/dist/cli/experimental/commands/pi.d.ts +15 -0
- package/dist/cli/experimental/commands/pi.d.ts.map +1 -0
- package/dist/cli/experimental/commands/pi.js +28 -0
- package/dist/cli/experimental/commands/pi.js.map +1 -0
- package/dist/cli/experimental/commands/server.d.ts +13 -0
- package/dist/cli/experimental/commands/server.d.ts.map +1 -0
- package/dist/cli/experimental/commands/server.js +25 -0
- package/dist/cli/experimental/commands/server.js.map +1 -0
- package/dist/cli/experimental/transport-address.d.ts +10 -0
- package/dist/cli/experimental/transport-address.d.ts.map +1 -0
- package/dist/cli/experimental/transport-address.js +38 -0
- package/dist/cli/experimental/transport-address.js.map +1 -0
- package/dist/cli/list-models.d.ts +1 -1
- package/dist/cli/list-models.d.ts.map +1 -1
- package/dist/cli/list-models.js +2 -2
- package/dist/cli/list-models.js.map +1 -1
- package/dist/cli/startup-ui.d.ts +1 -1
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +2 -2
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1 -0
- package/dist/cli.js.map +1 -1
- package/dist/client/index.d.ts +3 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +3 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/remote-session.d.ts +53 -0
- package/dist/client/remote-session.d.ts.map +1 -0
- package/dist/client/remote-session.js +340 -0
- package/dist/client/remote-session.js.map +1 -0
- package/dist/client/transcript.d.ts +12 -0
- package/dist/client/transcript.d.ts.map +1 -0
- package/dist/client/transcript.js +98 -0
- package/dist/client/transcript.js.map +1 -0
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +3 -0
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +1 -0
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +1 -0
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +3 -12
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +74 -65
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +25 -9
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +237 -39
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +43 -20
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +3 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +10 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +33 -3
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +10 -0
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +1 -1
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js +5 -0
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/keybindings.d.ts +44 -4
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/model-config.d.ts +29 -5
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +4 -0
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-registry.d.ts +5 -3
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +13 -10
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +4 -3
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +42 -10
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-runtime.d.ts +32 -13
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +233 -73
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/models-store.d.ts +12 -7
- package/dist/core/models-store.d.ts.map +1 -1
- package/dist/core/models-store.js +83 -14
- package/dist/core/models-store.js.map +1 -1
- package/dist/core/package-manager.d.ts +4 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +76 -42
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/pi-manifest.d.ts +8 -0
- package/dist/core/pi-manifest.d.ts.map +1 -0
- package/dist/core/pi-manifest.js +25 -0
- package/dist/core/pi-manifest.js.map +1 -0
- package/dist/core/pi-server-client.d.ts +2 -2
- package/dist/core/pi-server-client.d.ts.map +1 -1
- package/dist/core/pi-server-client.js +2 -0
- package/dist/core/pi-server-client.js.map +1 -1
- package/dist/core/provider-composer.d.ts +4 -1
- package/dist/core/provider-composer.d.ts.map +1 -1
- package/dist/core/provider-composer.js +36 -15
- package/dist/core/provider-composer.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +73 -67
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/resource-loader.d.ts +15 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +64 -10
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/runtime-credentials.d.ts +5 -5
- package/dist/core/runtime-credentials.d.ts.map +1 -1
- package/dist/core/runtime-credentials.js +11 -8
- package/dist/core/runtime-credentials.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +3 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +12 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +40 -16
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/tools/bash.d.ts +4 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +6 -4
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit.d.ts +4 -0
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +11 -7
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/find.d.ts +7 -0
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +16 -19
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts +4 -0
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +5 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/ls.d.ts +4 -0
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +5 -1
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/read.d.ts +4 -0
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +7 -3
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js +6 -3
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/write.d.ts +4 -0
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +6 -2
- package/dist/core/tools/write.js.map +1 -1
- package/dist/extensions/llama/index.d.ts.map +1 -1
- package/dist/extensions/llama/index.js +11 -2
- package/dist/extensions/llama/index.js.map +1 -1
- package/dist/extensions/llama/provider.d.ts.map +1 -1
- package/dist/extensions/llama/provider.js +22 -8
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +94 -6
- package/dist/main.js.map +1 -1
- package/dist/modes/index.d.ts +1 -0
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/index.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +5 -2
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +13 -4
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +7 -0
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +2 -2
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/markdown-transform.d.ts +3 -0
- package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -0
- package/dist/modes/interactive/components/markdown-transform.js +19 -0
- package/dist/modes/interactive/components/markdown-transform.js.map +1 -0
- package/dist/modes/interactive/components/mermaid.d.ts +11 -0
- package/dist/modes/interactive/components/mermaid.d.ts.map +1 -0
- package/dist/modes/interactive/components/mermaid.js +75 -0
- package/dist/modes/interactive/components/mermaid.js.map +1 -0
- package/dist/modes/interactive/components/model-selector.d.ts +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +20 -5
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts +4 -0
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +26 -0
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +8 -2
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +30 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message.d.ts +3 -1
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js +9 -2
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js +7 -5
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +36 -2
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +481 -150
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/dark.json +1 -0
- package/dist/modes/interactive/theme/light.json +1 -0
- package/dist/modes/interactive/theme/theme-controller.d.ts +3 -0
- package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-controller.js +10 -1
- package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
- package/dist/modes/interactive/theme/theme-schema.json +5 -1
- package/dist/modes/interactive/theme/theme.d.ts +2 -2
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +24 -6
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/json-event.d.ts +28 -0
- package/dist/modes/json-event.d.ts.map +1 -0
- package/dist/modes/json-event.js +12 -0
- package/dist/modes/json-event.js.map +1 -0
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +12 -2
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +5 -4
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +17 -3
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +11 -9
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/rpc-entry.d.ts.map +1 -1
- package/dist/rpc-entry.js +1 -0
- package/dist/rpc-entry.js.map +1 -1
- package/dist/server/create-harness.d.ts +26 -0
- package/dist/server/create-harness.d.ts.map +1 -0
- package/dist/server/create-harness.js +104 -0
- package/dist/server/create-harness.js.map +1 -0
- package/dist/utils/abort.d.ts +5 -0
- package/dist/utils/abort.d.ts.map +1 -0
- package/dist/utils/abort.js +48 -0
- package/dist/utils/abort.js.map +1 -0
- package/dist/utils/clipboard.d.ts +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +22 -2
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/management-http.d.ts +23 -0
- package/dist/utils/management-http.d.ts.map +1 -0
- package/dist/utils/management-http.js +50 -0
- package/dist/utils/management-http.js.map +1 -0
- package/dist/utils/paths.d.ts +3 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +23 -1
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/tool-result-images.d.ts +19 -0
- package/dist/utils/tool-result-images.d.ts.map +1 -0
- package/dist/utils/tool-result-images.js +45 -0
- package/dist/utils/tool-result-images.js.map +1 -0
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +4 -6
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts +4 -0
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +20 -2
- package/dist/utils/version-check.js.map +1 -1
- package/docs/compaction.md +2 -2
- package/docs/custom-provider.md +16 -8
- package/docs/extensions.md +33 -6
- package/docs/json.md +19 -14
- package/docs/keybindings.md +46 -14
- package/docs/models.md +24 -3
- package/docs/providers.md +10 -1
- package/docs/quickstart.md +2 -0
- package/docs/rpc.md +13 -11
- package/docs/sdk.md +21 -2
- package/docs/security.md +1 -1
- package/docs/session-format.md +2 -0
- package/docs/settings.md +4 -1
- package/docs/themes.md +5 -3
- package/docs/usage.md +7 -0
- package/examples/extensions/custom-compaction.ts +1 -16
- package/examples/extensions/custom-provider-anthropic/index.ts +10 -3
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +2 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/doom-overlay/wad-finder.ts +7 -3
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/handoff.ts +2 -11
- package/examples/extensions/qna.ts +3 -7
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/summarize.ts +7 -18
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/rpc-extension-ui.ts +11 -2
- package/examples/sdk/02-custom-model.ts +1 -2
- package/examples/sdk/09-api-keys-and-oauth.ts +1 -1
- package/examples/sdk/12-full-control.ts +3 -1
- package/examples/sdk/README.md +1 -1
- package/package.json +14 -7
|
@@ -2,12 +2,26 @@ import { dirname, join } from "node:path";
|
|
|
2
2
|
import { createModels, lazyStream, ModelsError, } from "@earendil-works/pi-ai";
|
|
3
3
|
import * as builtinProviderCatalog from "@earendil-works/pi-ai/providers/all";
|
|
4
4
|
import { getAgentDir } from "../config.js";
|
|
5
|
+
import { operationSignal, raceWithAbortSignal } from "../utils/abort.js";
|
|
5
6
|
import { AuthStorage as DefaultAuthStorage } from "./auth-storage.js";
|
|
6
7
|
import { ModelConfig } from "./model-config.js";
|
|
7
8
|
import { FileModelsStore, InMemoryCodingAgentModelsStore } from "./models-store.js";
|
|
8
9
|
import { composeModelProvider, configuredRequestAuthStatus, resolveCompatibilityRequestConfig, resolveConfiguredModelHeaders, validateExtensionProvider, } from "./provider-composer.js";
|
|
9
10
|
import { withRemoteCatalog } from "./remote-catalog-provider.js";
|
|
10
11
|
import { RuntimeCredentials } from "./runtime-credentials.js";
|
|
12
|
+
/** Credentials changed successfully, but the local model/auth snapshot could not be synchronized. */
|
|
13
|
+
export class CredentialSynchronizationError extends Error {
|
|
14
|
+
providerId;
|
|
15
|
+
operation;
|
|
16
|
+
credential;
|
|
17
|
+
constructor(providerId, operation, credential, options) {
|
|
18
|
+
super(`Credential ${operation} committed for ${providerId}, but local synchronization failed`, options);
|
|
19
|
+
this.name = "CredentialSynchronizationError";
|
|
20
|
+
this.providerId = providerId;
|
|
21
|
+
this.operation = operation;
|
|
22
|
+
this.credential = credential;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
11
25
|
function mergeHeaders(base, override) {
|
|
12
26
|
if (!base && !override)
|
|
13
27
|
return undefined;
|
|
@@ -41,8 +55,11 @@ export class ModelRuntime {
|
|
|
41
55
|
storedProviders: new Set(),
|
|
42
56
|
auth: new Map(),
|
|
43
57
|
};
|
|
44
|
-
|
|
58
|
+
availabilityRefreshSeq = 0;
|
|
59
|
+
availabilityErrorSeq = 0;
|
|
60
|
+
providerAvailabilitySeq = new Map();
|
|
45
61
|
availabilityError;
|
|
62
|
+
credentialOperations = new Map();
|
|
46
63
|
constructor(credentials, config, modelsPath, modelsStore, providers, modelNetworkEnabled) {
|
|
47
64
|
this.credentials = credentials;
|
|
48
65
|
this.config = config;
|
|
@@ -72,12 +89,17 @@ export class ModelRuntime {
|
|
|
72
89
|
runtime.configureRadiusProviders();
|
|
73
90
|
runtime.rebuildProviders();
|
|
74
91
|
const refreshFromNetwork = runtime.modelNetworkEnabled && options.allowModelNetwork === true;
|
|
75
|
-
const controller = refreshFromNetwork ? new AbortController() : undefined;
|
|
76
|
-
const timeout = controller
|
|
77
|
-
|
|
78
|
-
|
|
92
|
+
const controller = refreshFromNetwork && options.modelRefreshTimeoutMs !== undefined ? new AbortController() : undefined;
|
|
93
|
+
const timeout = controller ? setTimeout(() => controller.abort(), options.modelRefreshTimeoutMs) : undefined;
|
|
94
|
+
const signal = controller
|
|
95
|
+
? options.signal
|
|
96
|
+
? AbortSignal.any([options.signal, controller.signal])
|
|
97
|
+
: controller.signal
|
|
98
|
+
: options.signal;
|
|
79
99
|
try {
|
|
80
|
-
|
|
100
|
+
if (options.refreshOnCreate !== false) {
|
|
101
|
+
await runtime.refresh({ allowNetwork: refreshFromNetwork, signal });
|
|
102
|
+
}
|
|
81
103
|
}
|
|
82
104
|
finally {
|
|
83
105
|
if (timeout)
|
|
@@ -149,16 +171,18 @@ export class ModelRuntime {
|
|
|
149
171
|
available: all.filter((model) => this.snapshot.configuredProviders.has(model.provider)),
|
|
150
172
|
};
|
|
151
173
|
}
|
|
152
|
-
async runAvailabilityRefresh() {
|
|
174
|
+
async runAvailabilityRefresh(seq, errorSeq, signal) {
|
|
153
175
|
const providers = this.models.getProviders();
|
|
154
176
|
const [available, checks, credentials] = await Promise.all([
|
|
155
|
-
this.models.getAvailable(),
|
|
177
|
+
this.models.getAvailable(undefined, { signal }),
|
|
156
178
|
Promise.all(providers.map(async (provider) => [
|
|
157
179
|
provider.id,
|
|
158
|
-
await this.models.checkAuth(provider.id),
|
|
180
|
+
await this.models.checkAuth(provider.id, { signal }),
|
|
159
181
|
])),
|
|
160
|
-
this.credentials.list(),
|
|
182
|
+
this.credentials.list({ signal }),
|
|
161
183
|
]);
|
|
184
|
+
if (seq !== this.availabilityRefreshSeq)
|
|
185
|
+
return;
|
|
162
186
|
const auth = new Map(checks);
|
|
163
187
|
const configuredProviders = new Set(checks
|
|
164
188
|
.filter((entry) => entry[1] !== undefined)
|
|
@@ -170,28 +194,76 @@ export class ModelRuntime {
|
|
|
170
194
|
storedProviders: new Set(credentials.map((entry) => entry.providerId)),
|
|
171
195
|
auth,
|
|
172
196
|
};
|
|
173
|
-
this.
|
|
197
|
+
if (errorSeq === this.availabilityErrorSeq)
|
|
198
|
+
this.availabilityError = undefined;
|
|
174
199
|
}
|
|
175
|
-
queueAvailabilityRefresh(
|
|
176
|
-
const
|
|
177
|
-
const
|
|
178
|
-
this.
|
|
200
|
+
queueAvailabilityRefresh(signal) {
|
|
201
|
+
const seq = ++this.availabilityRefreshSeq;
|
|
202
|
+
for (const [providerId, providerSeq] of this.providerAvailabilitySeq) {
|
|
203
|
+
this.providerAvailabilitySeq.set(providerId, providerSeq + 1);
|
|
204
|
+
}
|
|
205
|
+
const errorSeq = ++this.availabilityErrorSeq;
|
|
206
|
+
const effectiveSignal = operationSignal(signal);
|
|
207
|
+
return this.runAvailabilityRefresh(seq, errorSeq, effectiveSignal).catch((error) => {
|
|
208
|
+
if (errorSeq === this.availabilityErrorSeq && !effectiveSignal.aborted) {
|
|
209
|
+
this.availabilityError = error instanceof Error ? error.message : String(error);
|
|
210
|
+
}
|
|
179
211
|
throw error;
|
|
180
212
|
});
|
|
181
|
-
const tracked = recorded.finally(() => {
|
|
182
|
-
if (this.availabilityRefresh === tracked)
|
|
183
|
-
this.availabilityRefresh = undefined;
|
|
184
|
-
});
|
|
185
|
-
this.availabilityRefresh = tracked;
|
|
186
|
-
return tracked;
|
|
187
|
-
}
|
|
188
|
-
/** Coalesce concurrent readers onto the pending refresh. */
|
|
189
|
-
refreshAvailability() {
|
|
190
|
-
return this.availabilityRefresh ?? this.queueAvailabilityRefresh(undefined);
|
|
191
213
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
214
|
+
async refreshProviderAvailability(providerId, signal) {
|
|
215
|
+
// Invalidate any full availability pass that started before this credential change.
|
|
216
|
+
++this.availabilityRefreshSeq;
|
|
217
|
+
const providerSeq = (this.providerAvailabilitySeq.get(providerId) ?? 0) + 1;
|
|
218
|
+
this.providerAvailabilitySeq.set(providerId, providerSeq);
|
|
219
|
+
const errorSeq = ++this.availabilityErrorSeq;
|
|
220
|
+
try {
|
|
221
|
+
const [available, auth, credential] = await Promise.all([
|
|
222
|
+
this.models.getAvailable(providerId, { signal }),
|
|
223
|
+
this.models.checkAuth(providerId, { signal }),
|
|
224
|
+
this.credentials.read(providerId, { signal }),
|
|
225
|
+
]);
|
|
226
|
+
signal.throwIfAborted();
|
|
227
|
+
if (this.providerAvailabilitySeq.get(providerId) !== providerSeq)
|
|
228
|
+
return;
|
|
229
|
+
const configuredProviders = new Set(this.snapshot.configuredProviders);
|
|
230
|
+
const storedProviders = new Set(this.snapshot.storedProviders);
|
|
231
|
+
const authByProvider = new Map(this.snapshot.auth);
|
|
232
|
+
if (auth) {
|
|
233
|
+
configuredProviders.add(providerId);
|
|
234
|
+
authByProvider.set(providerId, auth);
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
configuredProviders.delete(providerId);
|
|
238
|
+
authByProvider.delete(providerId);
|
|
239
|
+
}
|
|
240
|
+
if (credential)
|
|
241
|
+
storedProviders.add(providerId);
|
|
242
|
+
else
|
|
243
|
+
storedProviders.delete(providerId);
|
|
244
|
+
const all = [...this.models.getModels()];
|
|
245
|
+
const availableById = new Map([...this.snapshot.available.filter((model) => model.provider !== providerId), ...available].map((model) => [
|
|
246
|
+
`${model.provider}\0${model.id}`,
|
|
247
|
+
model,
|
|
248
|
+
]));
|
|
249
|
+
this.snapshot = {
|
|
250
|
+
all,
|
|
251
|
+
available: all.flatMap((model) => availableById.get(`${model.provider}\0${model.id}`) ?? []),
|
|
252
|
+
configuredProviders,
|
|
253
|
+
storedProviders,
|
|
254
|
+
auth: authByProvider,
|
|
255
|
+
};
|
|
256
|
+
if (errorSeq === this.availabilityErrorSeq)
|
|
257
|
+
this.availabilityError = undefined;
|
|
258
|
+
}
|
|
259
|
+
catch (error) {
|
|
260
|
+
if (this.providerAvailabilitySeq.get(providerId) === providerSeq &&
|
|
261
|
+
errorSeq === this.availabilityErrorSeq &&
|
|
262
|
+
!signal.aborted) {
|
|
263
|
+
this.availabilityError = error instanceof Error ? error.message : String(error);
|
|
264
|
+
}
|
|
265
|
+
throw error;
|
|
266
|
+
}
|
|
195
267
|
}
|
|
196
268
|
getProviders() {
|
|
197
269
|
return this.models.getProviders();
|
|
@@ -205,24 +277,26 @@ export class ModelRuntime {
|
|
|
205
277
|
getModel(providerId, modelId) {
|
|
206
278
|
return this.models.getModel(providerId, modelId);
|
|
207
279
|
}
|
|
208
|
-
async checkAuth(providerId) {
|
|
209
|
-
return this.models.checkAuth(providerId);
|
|
280
|
+
async checkAuth(providerId, options) {
|
|
281
|
+
return this.models.checkAuth(providerId, options);
|
|
210
282
|
}
|
|
211
|
-
async getAvailable(providerId) {
|
|
283
|
+
async getAvailable(providerId, options) {
|
|
212
284
|
if (providerId) {
|
|
213
|
-
|
|
214
|
-
await this.availabilityRefresh;
|
|
215
|
-
return this.snapshot.available.filter((model) => model.provider === providerId);
|
|
216
|
-
}
|
|
285
|
+
const errorSeq = ++this.availabilityErrorSeq;
|
|
217
286
|
try {
|
|
218
|
-
|
|
287
|
+
const available = await this.models.getAvailable(providerId, options);
|
|
288
|
+
if (errorSeq === this.availabilityErrorSeq)
|
|
289
|
+
this.availabilityError = undefined;
|
|
290
|
+
return available;
|
|
219
291
|
}
|
|
220
292
|
catch (error) {
|
|
221
|
-
|
|
293
|
+
if (errorSeq === this.availabilityErrorSeq && !options?.signal?.aborted) {
|
|
294
|
+
this.availabilityError = error instanceof Error ? error.message : String(error);
|
|
295
|
+
}
|
|
222
296
|
throw error;
|
|
223
297
|
}
|
|
224
298
|
}
|
|
225
|
-
await this.
|
|
299
|
+
await this.queueAvailabilityRefresh(options?.signal);
|
|
226
300
|
return this.snapshot.available;
|
|
227
301
|
}
|
|
228
302
|
getAvailableSnapshot() {
|
|
@@ -256,6 +330,9 @@ export class ModelRuntime {
|
|
|
256
330
|
isUsingOAuth(providerId) {
|
|
257
331
|
return this.snapshot.auth.get(providerId)?.type === "oauth";
|
|
258
332
|
}
|
|
333
|
+
isUsingSubscription(providerId) {
|
|
334
|
+
return this.isUsingOAuth(providerId) && this.models.getProvider(providerId)?.auth.oauth?.isSubscription === true;
|
|
335
|
+
}
|
|
259
336
|
hasConfiguredAuth(providerId) {
|
|
260
337
|
return this.snapshot.configuredProviders.has(providerId);
|
|
261
338
|
}
|
|
@@ -274,26 +351,62 @@ export class ModelRuntime {
|
|
|
274
351
|
},
|
|
275
352
|
};
|
|
276
353
|
}
|
|
277
|
-
|
|
278
|
-
this.
|
|
279
|
-
|
|
280
|
-
const
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
};
|
|
289
|
-
|
|
354
|
+
enqueueCredentialOperation(providerId, signal, task) {
|
|
355
|
+
const previous = this.credentialOperations.get(providerId) ?? Promise.resolve();
|
|
356
|
+
let markStarted;
|
|
357
|
+
const started = new Promise((resolve) => {
|
|
358
|
+
markStarted = resolve;
|
|
359
|
+
});
|
|
360
|
+
const operation = (async () => {
|
|
361
|
+
await previous.catch(() => { });
|
|
362
|
+
signal.throwIfAborted();
|
|
363
|
+
markStarted?.();
|
|
364
|
+
return task();
|
|
365
|
+
})();
|
|
366
|
+
const tail = operation.catch(() => { });
|
|
367
|
+
this.credentialOperations.set(providerId, tail);
|
|
368
|
+
void tail.then(() => {
|
|
369
|
+
if (this.credentialOperations.get(providerId) === tail)
|
|
370
|
+
this.credentialOperations.delete(providerId);
|
|
371
|
+
});
|
|
372
|
+
return raceWithAbortSignal(started, signal).then(() => operation);
|
|
290
373
|
}
|
|
291
|
-
async
|
|
292
|
-
|
|
293
|
-
|
|
374
|
+
async synchronizeCredentialState(providerId, operation, credential, signal) {
|
|
375
|
+
try {
|
|
376
|
+
signal.throwIfAborted();
|
|
377
|
+
this.recomposeProvider(providerId);
|
|
378
|
+
const compositionError = this.compositionErrors.get(providerId);
|
|
379
|
+
if (compositionError)
|
|
380
|
+
throw new Error(compositionError);
|
|
381
|
+
const result = await this.models.refresh({ allowNetwork: false, providers: [providerId], signal });
|
|
382
|
+
if (result.aborted)
|
|
383
|
+
signal.throwIfAborted();
|
|
384
|
+
const refreshError = result.errors.get(providerId);
|
|
385
|
+
if (refreshError)
|
|
386
|
+
throw refreshError;
|
|
387
|
+
this.updateModelSnapshot();
|
|
388
|
+
await this.refreshProviderAvailability(providerId, signal);
|
|
389
|
+
}
|
|
390
|
+
catch (cause) {
|
|
391
|
+
throw new CredentialSynchronizationError(providerId, operation, credential, { cause });
|
|
392
|
+
}
|
|
294
393
|
}
|
|
295
|
-
|
|
296
|
-
|
|
394
|
+
setRuntimeApiKey(providerId, apiKey, options = {}) {
|
|
395
|
+
const signal = operationSignal(options.signal);
|
|
396
|
+
return this.enqueueCredentialOperation(providerId, signal, async () => {
|
|
397
|
+
this.credentials.setRuntimeApiKey(providerId, apiKey);
|
|
398
|
+
await this.synchronizeCredentialState(providerId, "setRuntimeApiKey", { type: "api_key", key: apiKey }, signal);
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
removeRuntimeApiKey(providerId, options = {}) {
|
|
402
|
+
const signal = operationSignal(options.signal);
|
|
403
|
+
return this.enqueueCredentialOperation(providerId, signal, async () => {
|
|
404
|
+
this.credentials.removeRuntimeApiKey(providerId);
|
|
405
|
+
await this.synchronizeCredentialState(providerId, "removeRuntimeApiKey", undefined, signal);
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
listCredentials(options) {
|
|
409
|
+
return this.credentials.list(options);
|
|
297
410
|
}
|
|
298
411
|
getProviderAuthStatus(providerId) {
|
|
299
412
|
if (this.credentials.hasRuntimeApiKey(providerId))
|
|
@@ -310,10 +423,15 @@ export class ModelRuntime {
|
|
|
310
423
|
const provider = this.models.getProvider(model.provider);
|
|
311
424
|
if (!provider)
|
|
312
425
|
throw new ModelsError("provider", `Unknown provider: ${model.provider}`);
|
|
313
|
-
const resolution = await this.getAuth(model, {
|
|
426
|
+
const resolution = await this.getAuth(model, {
|
|
427
|
+
apiKey: options?.apiKey,
|
|
428
|
+
env: options?.env,
|
|
429
|
+
signal: options?.signal,
|
|
430
|
+
});
|
|
314
431
|
if (!resolution)
|
|
315
432
|
throw new ModelsError("auth", `Provider is not configured: ${model.provider}`);
|
|
316
|
-
const { transformHeaders, ...
|
|
433
|
+
const { transformHeaders, ...rawProviderOptions } = options ?? {};
|
|
434
|
+
const providerOptions = rawProviderOptions;
|
|
317
435
|
let headers = mergeHeaders(resolution.auth.headers, providerOptions.headers);
|
|
318
436
|
if (transformHeaders)
|
|
319
437
|
headers = await transformHeaders(headers ?? {});
|
|
@@ -349,21 +467,48 @@ export class ModelRuntime {
|
|
|
349
467
|
completeSimple(model, context, options) {
|
|
350
468
|
return this.streamSimple(model, context, options).result();
|
|
351
469
|
}
|
|
352
|
-
async
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
470
|
+
async fetchDeferred(model, handle, options) {
|
|
471
|
+
return lazyStream(model, async () => {
|
|
472
|
+
const prepared = await this.prepareRequest(model, options);
|
|
473
|
+
if (!prepared.provider.fetchDeferred) {
|
|
474
|
+
throw new ModelsError("provider", `Provider ${model.provider} does not support deferred responses`);
|
|
475
|
+
}
|
|
476
|
+
return prepared.provider.fetchDeferred(prepared.model, handle, prepared.options);
|
|
477
|
+
}).result();
|
|
356
478
|
}
|
|
357
|
-
async
|
|
358
|
-
await this.
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
479
|
+
async cancelDeferred(model, handle, options) {
|
|
480
|
+
const prepared = await this.prepareRequest(model, options);
|
|
481
|
+
if (!prepared.provider.cancelDeferred) {
|
|
482
|
+
throw new ModelsError("provider", `Provider ${model.provider} does not support deferred responses`);
|
|
483
|
+
}
|
|
484
|
+
await prepared.provider.cancelDeferred(prepared.model, handle, prepared.options);
|
|
485
|
+
}
|
|
486
|
+
login(providerId, type, interaction) {
|
|
487
|
+
const signal = operationSignal(interaction.signal);
|
|
488
|
+
return this.enqueueCredentialOperation(providerId, signal, async () => {
|
|
489
|
+
const credential = await this.models.login(providerId, type, { ...interaction, signal });
|
|
490
|
+
await this.synchronizeCredentialState(providerId, "login", credential, signal);
|
|
491
|
+
return credential;
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
logout(providerId, options = {}) {
|
|
495
|
+
const signal = operationSignal(options.signal);
|
|
496
|
+
return this.enqueueCredentialOperation(providerId, signal, async () => {
|
|
497
|
+
await this.models.logout(providerId, { signal });
|
|
498
|
+
await this.synchronizeCredentialState(providerId, "logout", undefined, signal);
|
|
499
|
+
});
|
|
362
500
|
}
|
|
363
501
|
async refresh(options = {}) {
|
|
364
502
|
this.config = await ModelConfig.load(this.modelsPath);
|
|
365
503
|
this.configureRadiusProviders();
|
|
366
|
-
|
|
504
|
+
if (options.providers) {
|
|
505
|
+
for (const providerId of new Set(options.providers))
|
|
506
|
+
this.recomposeProvider(providerId);
|
|
507
|
+
this.updateModelSnapshot();
|
|
508
|
+
}
|
|
509
|
+
else {
|
|
510
|
+
this.rebuildProviders();
|
|
511
|
+
}
|
|
367
512
|
const refreshOptions = {
|
|
368
513
|
...options,
|
|
369
514
|
allowNetwork: options.allowNetwork ?? this.modelNetworkEnabled,
|
|
@@ -374,14 +519,29 @@ export class ModelRuntime {
|
|
|
374
519
|
aborted: refreshOptions.signal?.aborted ?? false,
|
|
375
520
|
errors: new Map(),
|
|
376
521
|
};
|
|
522
|
+
const errors = new Map(result.errors);
|
|
377
523
|
this.updateModelSnapshot();
|
|
378
|
-
|
|
379
|
-
await
|
|
524
|
+
if (options.providers) {
|
|
525
|
+
await Promise.all([...new Set(options.providers)].map(async (providerId) => {
|
|
526
|
+
try {
|
|
527
|
+
await this.refreshProviderAvailability(providerId, operationSignal(options.signal));
|
|
528
|
+
}
|
|
529
|
+
catch (error) {
|
|
530
|
+
if (!options.signal?.aborted) {
|
|
531
|
+
errors.set(providerId, error instanceof Error ? error : new Error(String(error)));
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
}));
|
|
380
535
|
}
|
|
381
|
-
|
|
382
|
-
|
|
536
|
+
else {
|
|
537
|
+
try {
|
|
538
|
+
await this.queueAvailabilityRefresh(options.signal);
|
|
539
|
+
}
|
|
540
|
+
catch {
|
|
541
|
+
// Availability errors are recorded by the latest pass; refreshed models remain usable.
|
|
542
|
+
}
|
|
383
543
|
}
|
|
384
|
-
return result;
|
|
544
|
+
return { aborted: result.aborted || (options.signal?.aborted ?? false), errors };
|
|
385
545
|
}
|
|
386
546
|
registerNativeProvider(provider) {
|
|
387
547
|
if (!provider.id.trim())
|