@psnext/slingcli 2.5.20260602-4 → 2.5.20260607-2
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/node_modules/@aws-sdk/core/dist-cjs/index.js +12 -6
- package/node_modules/@aws-sdk/core/dist-cjs/submodules/httpAuthSchemes/index.js +12 -6
- package/node_modules/@aws-sdk/core/dist-es/submodules/httpAuthSchemes/aws_sdk/AwsSdkSigV4ASigner.js +1 -0
- package/node_modules/@aws-sdk/core/dist-es/submodules/httpAuthSchemes/aws_sdk/AwsSdkSigV4Signer.js +11 -6
- package/node_modules/@aws-sdk/core/package.json +7 -7
- package/node_modules/@aws-sdk/credential-provider-env/package.json +6 -6
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-cjs/index.js +6 -4
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-es/node-http-handler.js +7 -6
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-es/node-http2-handler.js +2 -1
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-es/node-http2.js +2 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-es/node-https.js +2 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-types/node-http-handler.d.ts +2 -2
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-types/node-http2-handler.d.ts +1 -1
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-types/node-http2.d.ts +2 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-types/node-https.d.ts +2 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/package.json +1 -1
- package/node_modules/@aws-sdk/credential-provider-http/package.json +8 -8
- package/node_modules/@aws-sdk/credential-provider-ini/package.json +14 -14
- package/node_modules/@aws-sdk/credential-provider-login/package.json +7 -7
- package/node_modules/@aws-sdk/credential-provider-node/package.json +12 -12
- package/node_modules/@aws-sdk/credential-provider-process/package.json +6 -6
- package/node_modules/@aws-sdk/credential-provider-sso/node_modules/@aws-sdk/token-providers/package.json +7 -7
- package/node_modules/@aws-sdk/credential-provider-sso/package.json +8 -8
- package/node_modules/@aws-sdk/credential-provider-web-identity/package.json +7 -7
- package/node_modules/@aws-sdk/eventstream-handler-node/package.json +5 -5
- package/node_modules/@aws-sdk/middleware-eventstream/package.json +5 -5
- package/node_modules/@aws-sdk/middleware-websocket/package.json +8 -8
- package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/cognito-identity/index.js +99 -106
- package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/signin/index.js +62 -120
- package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sso/index.js +55 -86
- package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sso-oidc/index.js +73 -104
- package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sts/index.js +102 -185
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/cognito-identity/auth/httpAuthSchemeProvider.js +4 -5
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/cognito-identity/endpoint/bdd.js +21 -57
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/cognito-identity/runtimeConfig.browser.js +1 -2
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/cognito-identity/runtimeConfig.js +2 -4
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/cognito-identity/schemas/schemas_0.js +73 -41
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/signin/auth/httpAuthSchemeProvider.js +4 -5
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/signin/endpoint/bdd.js +20 -52
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/signin/runtimeConfig.browser.js +1 -2
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/signin/runtimeConfig.js +2 -4
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/signin/schemas/schemas_0.js +36 -59
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/sso/auth/httpAuthSchemeProvider.js +4 -5
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/sso/endpoint/bdd.js +17 -45
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/sso/runtimeConfig.browser.js +1 -2
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/sso/runtimeConfig.js +2 -4
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/sso/schemas/schemas_0.js +32 -32
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/sso-oidc/auth/httpAuthSchemeProvider.js +4 -5
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/sso-oidc/endpoint/bdd.js +17 -45
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/sso-oidc/runtimeConfig.browser.js +1 -2
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/sso-oidc/runtimeConfig.js +2 -4
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/sso-oidc/schemas/schemas_0.js +50 -50
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/sts/auth/httpAuthSchemeProvider.js +4 -5
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/sts/defaultRoleAssumers.js +1 -1
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/sts/endpoint/bdd.js +34 -96
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/sts/runtimeConfig.browser.js +1 -2
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/sts/runtimeConfig.js +3 -6
- package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/sts/schemas/schemas_0.js +63 -80
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-cjs/index.js +6 -4
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-es/node-http-handler.js +7 -6
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-es/node-http2-handler.js +2 -1
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-es/node-http2.js +2 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-es/node-https.js +2 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-types/node-http-handler.d.ts +2 -2
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-types/node-http2-handler.d.ts +1 -1
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-types/node-http2.d.ts +2 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-types/node-https.d.ts +2 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/package.json +1 -1
- package/node_modules/@aws-sdk/nested-clients/package.json +9 -9
- package/node_modules/@aws-sdk/signature-v4-multi-region/package.json +5 -5
- package/node_modules/@aws-sdk/types/package.json +3 -3
- package/node_modules/@aws-sdk/util-locate-window/package.json +2 -2
- package/node_modules/@aws-sdk/xml-builder/package.json +3 -3
- package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
- package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js +3 -0
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +45 -0
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.js +827 -140
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js +32 -12
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/github-copilot.js +13 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.js +4 -2
- package/node_modules/@earendil-works/pi-ai/package.json +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/args.js +15 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.js +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/auth-storage.js +4 -3
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/branch-summarization.js +9 -3
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/export-html/template.js +19 -6
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-resolver.js +3 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.js +47 -13
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/provider-attribution.js +72 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/provider-display-names.js +3 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/resource-loader.js +28 -20
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/sdk.js +2 -30
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/settings-manager.js +71 -30
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/slash-commands.js +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/bash.js +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/find.js +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/grep.js +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/ls.js +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/read.js +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/write.js +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/trust-manager.js +130 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/index.js +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/main.js +54 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/bash-execution.js +2 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/config-selector.js +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/footer.js +7 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/index.js +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +3 -12
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +22 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/trust-selector.js +86 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.js +40 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.js +55 -8
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/git.js +54 -22
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/open-browser.js +22 -0
- package/node_modules/@earendil-works/pi-coding-agent/npm-shrinkwrap.json +12 -12
- package/node_modules/@earendil-works/pi-coding-agent/package.json +5 -4
- package/node_modules/@earendil-works/pi-tui/dist/utils.js +3 -0
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/node_modules/@smithy/credential-provider-imds/dist-es/remoteProvider/httpRequest.js +2 -2
- package/node_modules/@smithy/credential-provider-imds/dist-es/remoteProvider/node-http.js +2 -0
- package/node_modules/@smithy/credential-provider-imds/dist-types/remoteProvider/httpRequest.d.ts +1 -1
- package/node_modules/@smithy/credential-provider-imds/dist-types/remoteProvider/node-http.d.ts +2 -0
- package/node_modules/@smithy/credential-provider-imds/package.json +1 -1
- package/node_modules/@types/node/README.md +1 -1
- package/node_modules/@types/node/http2.d.ts +3 -0
- package/node_modules/@types/node/package.json +2 -2
- package/node_modules/gaxios/build/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/node_modules/gaxios/build/esm/tsconfig.tsbuildinfo +1 -1
- package/node_modules/gaxios/package.json +7 -9
- package/node_modules/google-auth-library/build/src/auth/gdchclient.d.ts +47 -0
- package/node_modules/google-auth-library/build/src/auth/gdchclient.js +307 -0
- package/node_modules/google-auth-library/build/src/auth/googleauth.d.ts +5 -4
- package/node_modules/google-auth-library/build/src/auth/googleauth.js +18 -1
- package/node_modules/google-auth-library/build/src/index.d.ts +1 -0
- package/node_modules/google-auth-library/build/src/index.js +4 -1
- package/node_modules/google-auth-library/package.json +2 -4
- package/node_modules/semver/classes/semver.js +19 -2
- package/node_modules/semver/package.json +1 -1
- package/node_modules/undici/lib/global.js +1 -1
- package/node_modules/undici/lib/handler/unwrap-handler.js +6 -0
- package/node_modules/undici/package.json +1 -1
- package/node_modules/undici/types/dispatcher.d.ts +2 -0
- package/package.json +6 -6
- package/slingshot/index.js +275 -273
|
@@ -461,6 +461,12 @@ function buildParams(model, context, options, compat = getCompat(model), cacheRe
|
|
|
461
461
|
openRouterParams.reasoning = { effort: model.thinkingLevelMap?.off ?? "none" };
|
|
462
462
|
}
|
|
463
463
|
}
|
|
464
|
+
else if (compat.thinkingFormat === "ant-ling" && model.reasoning && options?.reasoningEffort) {
|
|
465
|
+
const effort = model.thinkingLevelMap?.[options.reasoningEffort];
|
|
466
|
+
if (typeof effort === "string") {
|
|
467
|
+
params.reasoning = { effort };
|
|
468
|
+
}
|
|
469
|
+
}
|
|
464
470
|
else if (compat.thinkingFormat === "together" && model.reasoning) {
|
|
465
471
|
const togetherParams = params;
|
|
466
472
|
togetherParams.reasoning = { enabled: !!options?.reasoningEffort };
|
|
@@ -488,7 +494,7 @@ function buildParams(model, context, options, compat = getCompat(model), cacheRe
|
|
|
488
494
|
}
|
|
489
495
|
}
|
|
490
496
|
// OpenRouter provider routing preferences
|
|
491
|
-
if (model.
|
|
497
|
+
if (model.compat?.openRouterRouting) {
|
|
492
498
|
params.provider = model.compat.openRouterRouting;
|
|
493
499
|
}
|
|
494
500
|
// Vercel AI Gateway provider routing preferences
|
|
@@ -873,13 +879,19 @@ function mapStopReason(reason) {
|
|
|
873
879
|
function detectCompat(model) {
|
|
874
880
|
const provider = model.provider;
|
|
875
881
|
const baseUrl = model.baseUrl;
|
|
876
|
-
const isZai = provider === "zai" ||
|
|
882
|
+
const isZai = provider === "zai" ||
|
|
883
|
+
provider === "zai-coding-cn" ||
|
|
884
|
+
baseUrl.includes("api.z.ai") ||
|
|
885
|
+
baseUrl.includes("open.bigmodel.cn");
|
|
877
886
|
const isTogether = provider === "together" || baseUrl.includes("api.together.ai") || baseUrl.includes("api.together.xyz");
|
|
878
887
|
const isMoonshot = provider === "moonshotai" || provider === "moonshotai-cn" || baseUrl.includes("api.moonshot.");
|
|
879
888
|
const isOpenRouter = provider === "openrouter" || baseUrl.includes("openrouter.ai");
|
|
880
889
|
const isCloudflareWorkersAI = provider === "cloudflare-workers-ai" || baseUrl.includes("api.cloudflare.com");
|
|
881
890
|
const isCloudflareAiGateway = provider === "cloudflare-ai-gateway" || baseUrl.includes("gateway.ai.cloudflare.com");
|
|
882
|
-
const
|
|
891
|
+
const isNvidia = provider === "nvidia" || baseUrl.includes("integrate.api.nvidia.com");
|
|
892
|
+
const isAntLing = provider === "ant-ling" || baseUrl.includes("api.ant-ling.com");
|
|
893
|
+
const isNonStandard = isNvidia ||
|
|
894
|
+
provider === "cerebras" ||
|
|
883
895
|
baseUrl.includes("cerebras.ai") ||
|
|
884
896
|
provider === "xai" ||
|
|
885
897
|
baseUrl.includes("api.x.ai") ||
|
|
@@ -891,15 +903,17 @@ function detectCompat(model) {
|
|
|
891
903
|
provider === "opencode" ||
|
|
892
904
|
baseUrl.includes("opencode.ai") ||
|
|
893
905
|
isCloudflareWorkersAI ||
|
|
894
|
-
isCloudflareAiGateway
|
|
895
|
-
|
|
906
|
+
isCloudflareAiGateway ||
|
|
907
|
+
isAntLing;
|
|
908
|
+
const useMaxTokens = baseUrl.includes("chutes.ai") || isMoonshot || isCloudflareAiGateway || isTogether || isNvidia || isAntLing;
|
|
896
909
|
const isGrok = provider === "xai" || baseUrl.includes("api.x.ai");
|
|
897
910
|
const isDeepSeek = provider === "deepseek" || baseUrl.includes("deepseek.com");
|
|
911
|
+
const isOpenRouterDeveloperRoleModel = isOpenRouter && (model.id.startsWith("anthropic/") || model.id.startsWith("openai/"));
|
|
898
912
|
const cacheControlFormat = provider === "openrouter" && model.id.startsWith("anthropic/") ? "anthropic" : undefined;
|
|
899
913
|
return {
|
|
900
914
|
supportsStore: !isNonStandard,
|
|
901
|
-
supportsDeveloperRole: !isNonStandard && !isOpenRouter,
|
|
902
|
-
supportsReasoningEffort: !isGrok && !isZai && !isMoonshot && !isTogether && !isCloudflareAiGateway,
|
|
915
|
+
supportsDeveloperRole: isOpenRouterDeveloperRoleModel || (!isNonStandard && !isOpenRouter),
|
|
916
|
+
supportsReasoningEffort: !isGrok && !isZai && !isMoonshot && !isTogether && !isCloudflareAiGateway && !isNvidia && !isAntLing,
|
|
903
917
|
supportsUsageInStreaming: true,
|
|
904
918
|
maxTokensField: useMaxTokens ? "max_tokens" : "max_completion_tokens",
|
|
905
919
|
requiresToolResultName: false,
|
|
@@ -912,16 +926,22 @@ function detectCompat(model) {
|
|
|
912
926
|
? "zai"
|
|
913
927
|
: isTogether
|
|
914
928
|
? "together"
|
|
915
|
-
:
|
|
916
|
-
? "
|
|
917
|
-
:
|
|
929
|
+
: isAntLing
|
|
930
|
+
? "ant-ling"
|
|
931
|
+
: isOpenRouter
|
|
932
|
+
? "openrouter"
|
|
933
|
+
: "openai",
|
|
918
934
|
openRouterRouting: {},
|
|
919
935
|
vercelGatewayRouting: {},
|
|
920
936
|
zaiToolStream: false,
|
|
921
|
-
supportsStrictMode: !isMoonshot && !isTogether && !isCloudflareAiGateway,
|
|
937
|
+
supportsStrictMode: !isMoonshot && !isTogether && !isCloudflareAiGateway && !isNvidia,
|
|
922
938
|
cacheControlFormat,
|
|
923
939
|
sendSessionAffinityHeaders: false,
|
|
924
|
-
supportsLongCacheRetention: !(isTogether ||
|
|
940
|
+
supportsLongCacheRetention: !(isTogether ||
|
|
941
|
+
isCloudflareWorkersAI ||
|
|
942
|
+
isCloudflareAiGateway ||
|
|
943
|
+
isNvidia ||
|
|
944
|
+
isAntLing),
|
|
925
945
|
};
|
|
926
946
|
}
|
|
927
947
|
/**
|
|
@@ -93,10 +93,22 @@ async function startDeviceFlow(domain) {
|
|
|
93
93
|
typeof expiresIn !== "number") {
|
|
94
94
|
throw new Error("Invalid device code response fields");
|
|
95
95
|
}
|
|
96
|
+
// The verification URI is opened in the user's browser and to prevent `open` from
|
|
97
|
+
// opening an executable or similar, we force it to be a URL.
|
|
98
|
+
let parsedUri;
|
|
99
|
+
try {
|
|
100
|
+
parsedUri = new URL(verificationUri);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
throw new Error("Untrusted verification_uri in device code response");
|
|
104
|
+
}
|
|
105
|
+
if (parsedUri.protocol !== "https:" && parsedUri.protocol !== "http:") {
|
|
106
|
+
throw new Error("Untrusted verification_uri in device code response");
|
|
107
|
+
}
|
|
96
108
|
return {
|
|
97
109
|
device_code: deviceCode,
|
|
98
110
|
user_code: userCode,
|
|
99
|
-
verification_uri:
|
|
111
|
+
verification_uri: parsedUri.href,
|
|
100
112
|
interval,
|
|
101
113
|
expires_in: expiresIn,
|
|
102
114
|
};
|
|
@@ -18,7 +18,6 @@ if (typeof process !== "undefined" && (process.versions?.node || process.version
|
|
|
18
18
|
import { pollOAuthDeviceCodeFlow } from "./device-code.js";
|
|
19
19
|
import { oauthErrorHtml, oauthSuccessHtml } from "./oauth-page.js";
|
|
20
20
|
import { generatePKCE } from "./pkce.js";
|
|
21
|
-
const CALLBACK_HOST = process.env.PI_OAUTH_CALLBACK_HOST || "127.0.0.1";
|
|
22
21
|
const CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
|
|
23
22
|
const AUTH_BASE_URL = "https://auth.openai.com";
|
|
24
23
|
const AUTHORIZE_URL = `${AUTH_BASE_URL}/oauth/authorize`;
|
|
@@ -33,6 +32,9 @@ export const OPENAI_CODEX_BROWSER_LOGIN_METHOD = "browser";
|
|
|
33
32
|
export const OPENAI_CODEX_DEVICE_CODE_LOGIN_METHOD = "device_code";
|
|
34
33
|
const SCOPE = "openid profile email offline_access";
|
|
35
34
|
const JWT_CLAIM_PATH = "https://api.openai.com/auth";
|
|
35
|
+
function getCallbackHost() {
|
|
36
|
+
return typeof process !== "undefined" ? process.env.PI_OAUTH_CALLBACK_HOST || "127.0.0.1" : "127.0.0.1";
|
|
37
|
+
}
|
|
36
38
|
function createState() {
|
|
37
39
|
if (!_randomBytes) {
|
|
38
40
|
throw new Error("OpenAI Codex OAuth is only available in Node.js environments");
|
|
@@ -287,7 +289,7 @@ function startLocalOAuthServer(state) {
|
|
|
287
289
|
});
|
|
288
290
|
return new Promise((resolve) => {
|
|
289
291
|
server
|
|
290
|
-
.listen(1455,
|
|
292
|
+
.listen(1455, getCallbackHost(), () => {
|
|
291
293
|
resolve({
|
|
292
294
|
close: () => server.close(),
|
|
293
295
|
cancelWait: () => {
|
|
@@ -160,6 +160,12 @@ export function parseArgs(args) {
|
|
|
160
160
|
else if (arg === "--verbose") {
|
|
161
161
|
result.verbose = true;
|
|
162
162
|
}
|
|
163
|
+
else if (arg === "--approve" || arg === "-a") {
|
|
164
|
+
result.projectTrustOverride = true;
|
|
165
|
+
}
|
|
166
|
+
else if (arg === "--no-approve" || arg === "-na") {
|
|
167
|
+
result.projectTrustOverride = false;
|
|
168
|
+
}
|
|
163
169
|
else if (arg === "--offline") {
|
|
164
170
|
result.offline = true;
|
|
165
171
|
}
|
|
@@ -212,8 +218,10 @@ ${chalk.bold("Commands:")}
|
|
|
212
218
|
${APP_NAME} remove <source> [-l] Remove extension source from settings
|
|
213
219
|
${APP_NAME} uninstall <source> [-l] Alias for remove
|
|
214
220
|
${APP_NAME} update [source|self|pi] Update pi and installed extensions
|
|
215
|
-
${APP_NAME} list
|
|
216
|
-
|
|
221
|
+
${APP_NAME} list [--approve|--no-approve]
|
|
222
|
+
List installed extensions from settings
|
|
223
|
+
${APP_NAME} config [--no-approve]
|
|
224
|
+
Open TUI to enable/disable package resources
|
|
217
225
|
${APP_NAME} <command> --help Show help for install/remove/uninstall/update/list
|
|
218
226
|
|
|
219
227
|
${chalk.bold("Options:")}
|
|
@@ -253,6 +261,8 @@ ${chalk.bold("Options:")}
|
|
|
253
261
|
--export <file> Export session file to HTML and exit
|
|
254
262
|
--list-models [search] List available models (with optional fuzzy search)
|
|
255
263
|
--verbose Force verbose startup (overrides quietStartup setting)
|
|
264
|
+
--approve, -a Trust project-local files for this run
|
|
265
|
+
--no-approve, -na Ignore project-local files for this run
|
|
256
266
|
--offline Disable startup network operations (same as PI_OFFLINE=1)
|
|
257
267
|
--help, -h Show this help
|
|
258
268
|
--version, -v Show version number
|
|
@@ -315,6 +325,7 @@ ${chalk.bold("Examples:")}
|
|
|
315
325
|
${chalk.bold("Environment Variables:")}
|
|
316
326
|
ANTHROPIC_API_KEY - Anthropic Claude API key
|
|
317
327
|
ANTHROPIC_OAUTH_TOKEN - Anthropic OAuth token (alternative to API key)
|
|
328
|
+
ANT_LING_API_KEY - Ant Ling API key
|
|
318
329
|
OPENAI_API_KEY - OpenAI GPT API key
|
|
319
330
|
AZURE_OPENAI_API_KEY - Azure OpenAI API key
|
|
320
331
|
AZURE_OPENAI_BASE_URL - Azure OpenAI/Cognitive Services base URL (e.g. https://{resource}.openai.azure.com)
|
|
@@ -322,6 +333,7 @@ ${chalk.bold("Environment Variables:")}
|
|
|
322
333
|
AZURE_OPENAI_API_VERSION - Azure OpenAI API version (default: v1)
|
|
323
334
|
AZURE_OPENAI_DEPLOYMENT_NAME_MAP - Azure OpenAI model=deployment map (comma-separated)
|
|
324
335
|
DEEPSEEK_API_KEY - DeepSeek API key
|
|
336
|
+
NVIDIA_API_KEY - NVIDIA NIM API key
|
|
325
337
|
GEMINI_API_KEY - Google Gemini API key
|
|
326
338
|
GROQ_API_KEY - Groq API key
|
|
327
339
|
CEREBRAS_API_KEY - Cerebras API key
|
|
@@ -331,6 +343,7 @@ ${chalk.bold("Environment Variables:")}
|
|
|
331
343
|
OPENROUTER_API_KEY - OpenRouter API key
|
|
332
344
|
AI_GATEWAY_API_KEY - Vercel AI Gateway API key
|
|
333
345
|
ZAI_API_KEY - ZAI API key
|
|
346
|
+
ZAI_CODING_CN_API_KEY - ZAI Coding Plan API key (China)
|
|
334
347
|
MISTRAL_API_KEY - Mistral API key
|
|
335
348
|
MINIMAX_API_KEY - MiniMax API key
|
|
336
349
|
MOONSHOT_API_KEY - Moonshot AI API key
|
|
@@ -2225,6 +2225,7 @@ export class AgentSession {
|
|
|
2225
2225
|
customInstructions,
|
|
2226
2226
|
replaceInstructions,
|
|
2227
2227
|
reserveTokens: branchSummarySettings.reserveTokens,
|
|
2228
|
+
streamFn: this.agent.streamFn,
|
|
2228
2229
|
});
|
|
2229
2230
|
if (result.aborted) {
|
|
2230
2231
|
return { cancelled: true, aborted: true };
|
|
@@ -13,6 +13,7 @@ import lockfile from "proper-lockfile";
|
|
|
13
13
|
import { getAgentDir } from "../config.js";
|
|
14
14
|
import { normalizePath } from "../utils/paths.js";
|
|
15
15
|
import { resolveConfigValue } from "./resolve-config-value.js";
|
|
16
|
+
const AUTH_FILE_WRITE_OPTIONS = { encoding: "utf-8", mode: 0o600 };
|
|
16
17
|
export class FileAuthStorageBackend {
|
|
17
18
|
authPath;
|
|
18
19
|
constructor(authPath = join(getAgentDir(), "auth.json")) {
|
|
@@ -26,7 +27,7 @@ export class FileAuthStorageBackend {
|
|
|
26
27
|
}
|
|
27
28
|
ensureFileExists() {
|
|
28
29
|
if (!existsSync(this.authPath)) {
|
|
29
|
-
writeFileSync(this.authPath, "{}",
|
|
30
|
+
writeFileSync(this.authPath, "{}", AUTH_FILE_WRITE_OPTIONS);
|
|
30
31
|
chmodSync(this.authPath, 0o600);
|
|
31
32
|
}
|
|
32
33
|
}
|
|
@@ -63,7 +64,7 @@ export class FileAuthStorageBackend {
|
|
|
63
64
|
const current = existsSync(this.authPath) ? readFileSync(this.authPath, "utf-8") : undefined;
|
|
64
65
|
const { result, next } = fn(current);
|
|
65
66
|
if (next !== undefined) {
|
|
66
|
-
writeFileSync(this.authPath, next,
|
|
67
|
+
writeFileSync(this.authPath, next, AUTH_FILE_WRITE_OPTIONS);
|
|
67
68
|
chmodSync(this.authPath, 0o600);
|
|
68
69
|
}
|
|
69
70
|
return result;
|
|
@@ -105,7 +106,7 @@ export class FileAuthStorageBackend {
|
|
|
105
106
|
const { result, next } = await fn(current);
|
|
106
107
|
throwIfCompromised();
|
|
107
108
|
if (next !== undefined) {
|
|
108
|
-
writeFileSync(this.authPath, next,
|
|
109
|
+
writeFileSync(this.authPath, next, AUTH_FILE_WRITE_OPTIONS);
|
|
109
110
|
chmodSync(this.authPath, 0o600);
|
|
110
111
|
}
|
|
111
112
|
throwIfCompromised();
|
package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/branch-summarization.js
CHANGED
|
@@ -185,7 +185,7 @@ Keep each section concise. Preserve exact file paths, function names, and error
|
|
|
185
185
|
* @param options - Generation options
|
|
186
186
|
*/
|
|
187
187
|
export async function generateBranchSummary(entries, options) {
|
|
188
|
-
const { model, apiKey, headers, signal, customInstructions, replaceInstructions, reserveTokens = 16384 } = options;
|
|
188
|
+
const { model, apiKey, headers, signal, customInstructions, replaceInstructions, reserveTokens = 16384, streamFn, } = options;
|
|
189
189
|
// Token budget = context window minus reserved space for prompt + response
|
|
190
190
|
const contextWindow = model.contextWindow || 128000;
|
|
191
191
|
const tokenBudget = contextWindow - reserveTokens;
|
|
@@ -216,8 +216,14 @@ export async function generateBranchSummary(entries, options) {
|
|
|
216
216
|
timestamp: Date.now(),
|
|
217
217
|
},
|
|
218
218
|
];
|
|
219
|
-
// Call LLM for summarization
|
|
220
|
-
|
|
219
|
+
// Call LLM for summarization. Prefer the session stream function so SDK
|
|
220
|
+
// request behavior (timeouts, retries, attribution headers) stays consistent
|
|
221
|
+
// without running through agent state/events.
|
|
222
|
+
const context = { systemPrompt: SUMMARIZATION_SYSTEM_PROMPT, messages: summarizationMessages };
|
|
223
|
+
const requestOptions = { apiKey, headers, signal, maxTokens: 2048 };
|
|
224
|
+
const response = streamFn
|
|
225
|
+
? await (await streamFn(model, context, requestOptions)).result()
|
|
226
|
+
: await completeSimple(model, context, requestOptions);
|
|
221
227
|
// Check if aborted or errored
|
|
222
228
|
if (response.stopReason === "aborted") {
|
|
223
229
|
return { aborted: true };
|
|
@@ -613,6 +613,18 @@
|
|
|
613
613
|
.replace(/'/g, ''');
|
|
614
614
|
}
|
|
615
615
|
|
|
616
|
+
function sanitizeMarkdownUrl(value) {
|
|
617
|
+
const href = String(value || '').trim().replace(/[\x00-\x1f\x7f]/g, '');
|
|
618
|
+
if (!href) return href;
|
|
619
|
+
|
|
620
|
+
const scheme = href.match(/^([A-Za-z][A-Za-z0-9+.-]*):/);
|
|
621
|
+
if (scheme && !/^(https?|mailto|tel|ftp)$/i.test(scheme[1])) {
|
|
622
|
+
return null;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
return href;
|
|
626
|
+
}
|
|
627
|
+
|
|
616
628
|
/**
|
|
617
629
|
* Truncate string to maxLen chars, append "..." if truncated.
|
|
618
630
|
*/
|
|
@@ -1569,10 +1581,11 @@
|
|
|
1569
1581
|
}
|
|
1570
1582
|
},
|
|
1571
1583
|
renderer: {
|
|
1572
|
-
// Sanitize link URLs
|
|
1584
|
+
// Sanitize link URLs with a scheme allow-list. Browsers strip C0
|
|
1585
|
+
// controls from schemes, so strip them before checking and emitting.
|
|
1573
1586
|
link(token) {
|
|
1574
|
-
const href = (token.href
|
|
1575
|
-
if (
|
|
1587
|
+
const href = sanitizeMarkdownUrl(token.href);
|
|
1588
|
+
if (href === null) {
|
|
1576
1589
|
return this.parser.parseInline(token.tokens);
|
|
1577
1590
|
}
|
|
1578
1591
|
let out = '<a href="' + escapeHtml(href) + '"';
|
|
@@ -1582,10 +1595,10 @@
|
|
|
1582
1595
|
out += '>' + this.parser.parseInline(token.tokens) + '</a>';
|
|
1583
1596
|
return out;
|
|
1584
1597
|
},
|
|
1585
|
-
// Sanitize image src URLs
|
|
1598
|
+
// Sanitize image src URLs with the same scheme allow-list.
|
|
1586
1599
|
image(token) {
|
|
1587
|
-
const href = (token.href
|
|
1588
|
-
if (
|
|
1600
|
+
const href = sanitizeMarkdownUrl(token.href);
|
|
1601
|
+
if (href === null) {
|
|
1589
1602
|
return escapeHtml(token.text || '');
|
|
1590
1603
|
}
|
|
1591
1604
|
let out = '<img src="' + escapeHtml(href) + '" alt="' + escapeHtml(token.text || '') + '"';
|
|
@@ -9,10 +9,12 @@ import { DEFAULT_THINKING_LEVEL } from "./defaults.js";
|
|
|
9
9
|
/** Default model IDs for each known provider */
|
|
10
10
|
export const defaultModelPerProvider = {
|
|
11
11
|
"amazon-bedrock": "us.anthropic.claude-opus-4-6-v1",
|
|
12
|
+
"ant-ling": "Ring-2.6-1T",
|
|
12
13
|
anthropic: "claude-opus-4-8",
|
|
13
14
|
openai: "gpt-5.4",
|
|
14
15
|
"azure-openai-responses": "gpt-5.4",
|
|
15
16
|
"openai-codex": "gpt-5.5",
|
|
17
|
+
nvidia: "nvidia/nemotron-3-super-120b-a12b",
|
|
16
18
|
deepseek: "deepseek-v4-pro",
|
|
17
19
|
google: "gemini-3.1-pro-preview",
|
|
18
20
|
"google-vertex": "gemini-3.1-pro-preview",
|
|
@@ -23,6 +25,7 @@ export const defaultModelPerProvider = {
|
|
|
23
25
|
groq: "openai/gpt-oss-120b",
|
|
24
26
|
cerebras: "zai-glm-4.7",
|
|
25
27
|
zai: "glm-5.1",
|
|
28
|
+
"zai-coding-cn": "glm-5.1",
|
|
26
29
|
mistral: "devstral-medium-latest",
|
|
27
30
|
minimax: "MiniMax-M2.7",
|
|
28
31
|
"minimax-cn": "MiniMax-M2.7",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
3
|
-
import { homedir
|
|
2
|
+
import { chmodSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
4
|
function getEnv() {
|
|
5
5
|
if (process.platform !== "linux" || Object.keys(process.env).length > 0) {
|
|
6
6
|
return process.env;
|
|
@@ -70,6 +70,12 @@ function toPosixPath(p) {
|
|
|
70
70
|
function getHomeDir() {
|
|
71
71
|
return process.env.HOME || homedir();
|
|
72
72
|
}
|
|
73
|
+
export function getExtensionTempFolder(agentDir) {
|
|
74
|
+
const tempFolder = join(agentDir, "tmp", "extensions");
|
|
75
|
+
mkdirSync(tempFolder, { recursive: true, mode: 0o700 });
|
|
76
|
+
chmodSync(tempFolder, 0o700);
|
|
77
|
+
return tempFolder;
|
|
78
|
+
}
|
|
73
79
|
function prefixIgnorePattern(line, prefix) {
|
|
74
80
|
const trimmed = line.trim();
|
|
75
81
|
if (!trimmed)
|
|
@@ -733,6 +739,7 @@ export class DefaultPackageManager {
|
|
|
733
739
|
async install(source, options) {
|
|
734
740
|
const parsed = this.parseSource(source);
|
|
735
741
|
const scope = options?.local ? "project" : "user";
|
|
742
|
+
this.assertProjectTrustedForScope(scope);
|
|
736
743
|
await this.withProgress("install", source, `Installing ${source}...`, async () => {
|
|
737
744
|
if (parsed.type === "npm") {
|
|
738
745
|
await this.installNpm(parsed, scope, false);
|
|
@@ -759,6 +766,7 @@ export class DefaultPackageManager {
|
|
|
759
766
|
async remove(source, options) {
|
|
760
767
|
const parsed = this.parseSource(source);
|
|
761
768
|
const scope = options?.local ? "project" : "user";
|
|
769
|
+
this.assertProjectTrustedForScope(scope);
|
|
762
770
|
await this.withProgress("remove", source, `Removing ${source}...`, async () => {
|
|
763
771
|
if (parsed.type === "npm") {
|
|
764
772
|
await this.uninstallNpm(parsed, scope);
|
|
@@ -1363,6 +1371,11 @@ export class DefaultPackageManager {
|
|
|
1363
1371
|
const version = match[2];
|
|
1364
1372
|
return { name, version };
|
|
1365
1373
|
}
|
|
1374
|
+
assertProjectTrustedForScope(scope) {
|
|
1375
|
+
if (scope === "project" && !this.settingsManager.isProjectTrusted()) {
|
|
1376
|
+
throw new Error("Project is not trusted; refusing to access project package storage");
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1366
1379
|
getNpmCommand() {
|
|
1367
1380
|
const configuredCommand = this.settingsManager.getNpmCommand();
|
|
1368
1381
|
if (!configuredCommand || configuredCommand.length === 0) {
|
|
@@ -1564,6 +1577,7 @@ export class DefaultPackageManager {
|
|
|
1564
1577
|
return this.getTemporaryDir("npm");
|
|
1565
1578
|
}
|
|
1566
1579
|
if (scope === "project") {
|
|
1580
|
+
this.assertProjectTrustedForScope(scope);
|
|
1567
1581
|
return join(this.cwd, CONFIG_DIR_NAME, "npm");
|
|
1568
1582
|
}
|
|
1569
1583
|
return join(this.agentDir, "npm");
|
|
@@ -1602,6 +1616,7 @@ export class DefaultPackageManager {
|
|
|
1602
1616
|
return join(this.getTemporaryDir("npm"), "node_modules", source.name);
|
|
1603
1617
|
}
|
|
1604
1618
|
if (scope === "project") {
|
|
1619
|
+
this.assertProjectTrustedForScope(scope);
|
|
1605
1620
|
return join(this.cwd, CONFIG_DIR_NAME, "npm", "node_modules", source.name);
|
|
1606
1621
|
}
|
|
1607
1622
|
return join(this.agentDir, "npm", "node_modules", source.name);
|
|
@@ -1626,29 +1641,41 @@ export class DefaultPackageManager {
|
|
|
1626
1641
|
if (scope === "temporary") {
|
|
1627
1642
|
return this.getTemporaryDir(`git-${source.host}`, source.path);
|
|
1628
1643
|
}
|
|
1629
|
-
|
|
1630
|
-
|
|
1644
|
+
const installRoot = this.getGitInstallRoot(scope);
|
|
1645
|
+
if (!installRoot) {
|
|
1646
|
+
throw new Error("Missing git install root");
|
|
1631
1647
|
}
|
|
1632
|
-
return
|
|
1648
|
+
return this.resolveManagedPath(installRoot, source.host, source.path);
|
|
1633
1649
|
}
|
|
1634
1650
|
getGitInstallRoot(scope) {
|
|
1635
1651
|
if (scope === "temporary") {
|
|
1636
1652
|
return undefined;
|
|
1637
1653
|
}
|
|
1638
1654
|
if (scope === "project") {
|
|
1655
|
+
this.assertProjectTrustedForScope(scope);
|
|
1639
1656
|
return join(this.cwd, CONFIG_DIR_NAME, "git");
|
|
1640
1657
|
}
|
|
1641
1658
|
return join(this.agentDir, "git");
|
|
1642
1659
|
}
|
|
1643
1660
|
getTemporaryDir(prefix, suffix) {
|
|
1661
|
+
const root = this.resolveManagedPath(getExtensionTempFolder(this.agentDir), prefix);
|
|
1644
1662
|
const hash = createHash("sha256")
|
|
1645
1663
|
.update(`${prefix}-${suffix ?? ""}`)
|
|
1646
1664
|
.digest("hex")
|
|
1647
1665
|
.slice(0, 8);
|
|
1648
|
-
return
|
|
1666
|
+
return this.resolveManagedPath(root, hash, suffix ?? "");
|
|
1667
|
+
}
|
|
1668
|
+
resolveManagedPath(root, ...parts) {
|
|
1669
|
+
const resolvedRoot = resolve(root);
|
|
1670
|
+
const resolvedPath = resolve(resolvedRoot, ...parts);
|
|
1671
|
+
if (resolvedPath !== resolvedRoot && !resolvedPath.startsWith(`${resolvedRoot}${sep}`)) {
|
|
1672
|
+
throw new Error(`Refusing to use path outside package install root: ${resolvedPath}`);
|
|
1673
|
+
}
|
|
1674
|
+
return resolvedPath;
|
|
1649
1675
|
}
|
|
1650
1676
|
getBaseDirForScope(scope) {
|
|
1651
1677
|
if (scope === "project") {
|
|
1678
|
+
this.assertProjectTrustedForScope(scope);
|
|
1652
1679
|
return join(this.cwd, CONFIG_DIR_NAME);
|
|
1653
1680
|
}
|
|
1654
1681
|
if (scope === "user") {
|
|
@@ -1844,7 +1871,10 @@ export class DefaultPackageManager {
|
|
|
1844
1871
|
themes: join(projectBaseDir, "themes"),
|
|
1845
1872
|
};
|
|
1846
1873
|
const userAgentsSkillsDir = join(getHomeDir(), ".agents", "skills");
|
|
1847
|
-
const
|
|
1874
|
+
const projectTrusted = this.settingsManager.isProjectTrusted();
|
|
1875
|
+
const projectAgentsSkillDirs = projectTrusted
|
|
1876
|
+
? collectAncestorAgentsSkillDirs(this.cwd).filter((dir) => resolve(dir) !== resolve(userAgentsSkillsDir))
|
|
1877
|
+
: [];
|
|
1848
1878
|
const addResources = (resourceType, paths, metadata, overrides, baseDir) => {
|
|
1849
1879
|
const target = this.getTargetMap(accumulator, resourceType);
|
|
1850
1880
|
for (const path of paths) {
|
|
@@ -1852,10 +1882,12 @@ export class DefaultPackageManager {
|
|
|
1852
1882
|
this.addResource(target, path, metadata, enabled);
|
|
1853
1883
|
}
|
|
1854
1884
|
};
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1885
|
+
if (projectTrusted) {
|
|
1886
|
+
// Project extensions from .pi/
|
|
1887
|
+
addResources("extensions", collectAutoExtensionEntries(projectDirs.extensions), projectMetadata, projectOverrides.extensions, projectBaseDir);
|
|
1888
|
+
// Project skills from .pi/
|
|
1889
|
+
addResources("skills", collectAutoSkillEntries(projectDirs.skills, "pi"), projectMetadata, projectOverrides.skills, projectBaseDir);
|
|
1890
|
+
}
|
|
1859
1891
|
// Project skills from .agents/ (each with its own baseDir)
|
|
1860
1892
|
for (const agentsSkillsDir of projectAgentsSkillDirs) {
|
|
1861
1893
|
const agentsBaseDir = dirname(agentsSkillsDir); // the .agents directory
|
|
@@ -1865,8 +1897,10 @@ export class DefaultPackageManager {
|
|
|
1865
1897
|
};
|
|
1866
1898
|
addResources("skills", collectAutoSkillEntries(agentsSkillsDir, "agents"), agentsMetadata, projectOverrides.skills, agentsBaseDir);
|
|
1867
1899
|
}
|
|
1868
|
-
|
|
1869
|
-
|
|
1900
|
+
if (projectTrusted) {
|
|
1901
|
+
addResources("prompts", collectAutoPromptEntries(projectDirs.prompts), projectMetadata, projectOverrides.prompts, projectBaseDir);
|
|
1902
|
+
addResources("themes", collectAutoThemeEntries(projectDirs.themes), projectMetadata, projectOverrides.themes, projectBaseDir);
|
|
1903
|
+
}
|
|
1870
1904
|
// User extensions from ~/.pi/agent/
|
|
1871
1905
|
addResources("extensions", collectAutoExtensionEntries(userDirs.extensions), userMetadata, userOverrides.extensions, globalBaseDir);
|
|
1872
1906
|
// User skills from ~/.pi/agent/
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { isInstallTelemetryEnabled } from "./telemetry.js";
|
|
2
|
+
const OPENROUTER_HOST = "openrouter.ai";
|
|
3
|
+
const NVIDIA_NIM_HOST = "integrate.api.nvidia.com";
|
|
4
|
+
const CLOUDFLARE_API_HOST = "api.cloudflare.com";
|
|
5
|
+
const CLOUDFLARE_AI_GATEWAY_HOST = "gateway.ai.cloudflare.com";
|
|
6
|
+
const OPENCODE_HOST = "opencode.ai";
|
|
7
|
+
function matchesHost(baseUrl, expectedHost) {
|
|
8
|
+
try {
|
|
9
|
+
return new URL(baseUrl).hostname === expectedHost;
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function isOpenRouterModel(model) {
|
|
16
|
+
return model.provider === "openrouter" || model.baseUrl.includes(OPENROUTER_HOST);
|
|
17
|
+
}
|
|
18
|
+
function isNvidiaNimModel(model) {
|
|
19
|
+
return model.provider === "nvidia" || matchesHost(model.baseUrl, NVIDIA_NIM_HOST);
|
|
20
|
+
}
|
|
21
|
+
function isCloudflareModel(model) {
|
|
22
|
+
return (model.provider === "cloudflare-workers-ai" ||
|
|
23
|
+
model.provider === "cloudflare-ai-gateway" ||
|
|
24
|
+
matchesHost(model.baseUrl, CLOUDFLARE_API_HOST) ||
|
|
25
|
+
matchesHost(model.baseUrl, CLOUDFLARE_AI_GATEWAY_HOST));
|
|
26
|
+
}
|
|
27
|
+
function getDefaultAttributionHeaders(model, settingsManager) {
|
|
28
|
+
if (!isInstallTelemetryEnabled(settingsManager)) {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
if (isOpenRouterModel(model)) {
|
|
32
|
+
return {
|
|
33
|
+
"HTTP-Referer": "https://pi.dev",
|
|
34
|
+
"X-OpenRouter-Title": "pi",
|
|
35
|
+
"X-OpenRouter-Categories": "cli-agent",
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
if (isNvidiaNimModel(model)) {
|
|
39
|
+
return {
|
|
40
|
+
"X-BILLING-INVOKE-ORIGIN": "Pi",
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
if (isCloudflareModel(model)) {
|
|
44
|
+
return {
|
|
45
|
+
"User-Agent": "pi-coding-agent",
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
function getSessionHeaders(model, sessionId) {
|
|
51
|
+
if (!sessionId)
|
|
52
|
+
return undefined;
|
|
53
|
+
if (model.provider !== "opencode" &&
|
|
54
|
+
model.provider !== "opencode-go" &&
|
|
55
|
+
!matchesHost(model.baseUrl, OPENCODE_HOST)) {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
return { "x-opencode-session": sessionId, "x-opencode-client": "pi" };
|
|
59
|
+
}
|
|
60
|
+
export function mergeProviderAttributionHeaders(model, settingsManager, sessionId, ...headerSources) {
|
|
61
|
+
const merged = {
|
|
62
|
+
...getSessionHeaders(model, sessionId),
|
|
63
|
+
...getDefaultAttributionHeaders(model, settingsManager),
|
|
64
|
+
};
|
|
65
|
+
for (const headers of headerSources) {
|
|
66
|
+
if (headers) {
|
|
67
|
+
Object.assign(merged, headers);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return Object.keys(merged).length > 0 ? merged : undefined;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=provider-attribution.js.map
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export const BUILT_IN_PROVIDER_DISPLAY_NAMES = {
|
|
2
2
|
anthropic: "Anthropic",
|
|
3
3
|
"amazon-bedrock": "Amazon Bedrock",
|
|
4
|
+
"ant-ling": "Ant Ling",
|
|
4
5
|
"azure-openai-responses": "Azure OpenAI Responses",
|
|
5
6
|
cerebras: "Cerebras",
|
|
6
7
|
"cloudflare-ai-gateway": "Cloudflare AI Gateway",
|
|
@@ -17,6 +18,7 @@ export const BUILT_IN_PROVIDER_DISPLAY_NAMES = {
|
|
|
17
18
|
"minimax-cn": "MiniMax (China)",
|
|
18
19
|
moonshotai: "Moonshot AI",
|
|
19
20
|
"moonshotai-cn": "Moonshot AI (China)",
|
|
21
|
+
nvidia: "NVIDIA NIM",
|
|
20
22
|
opencode: "OpenCode Zen",
|
|
21
23
|
"opencode-go": "OpenCode Go",
|
|
22
24
|
openai: "OpenAI",
|
|
@@ -25,6 +27,7 @@ export const BUILT_IN_PROVIDER_DISPLAY_NAMES = {
|
|
|
25
27
|
"vercel-ai-gateway": "Vercel AI Gateway",
|
|
26
28
|
xai: "xAI",
|
|
27
29
|
zai: "ZAI",
|
|
30
|
+
"zai-coding-cn": "ZAI Coding Plan (China)",
|
|
28
31
|
xiaomi: "Xiaomi MiMo",
|
|
29
32
|
"xiaomi-token-plan-cn": "Xiaomi MiMo Token Plan (China)",
|
|
30
33
|
"xiaomi-token-plan-ams": "Xiaomi MiMo Token Plan (Amsterdam)",
|