@psnext/slingcli 2.5.20260615-2 → 2.5.20260617-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.
Files changed (195) hide show
  1. package/node_modules/@aws-sdk/core/dist-cjs/index.js +45 -50
  2. package/node_modules/@aws-sdk/core/dist-cjs/submodules/account-id-endpoint/index.js +2 -4
  3. package/node_modules/@aws-sdk/core/dist-cjs/submodules/client/index.browser.js +21 -22
  4. package/node_modules/@aws-sdk/core/dist-cjs/submodules/client/index.js +51 -51
  5. package/node_modules/@aws-sdk/core/dist-cjs/submodules/client/index.native.js +21 -22
  6. package/node_modules/@aws-sdk/core/dist-cjs/submodules/httpAuthSchemes/index.js +19 -21
  7. package/node_modules/@aws-sdk/core/dist-cjs/submodules/protocols/index.js +107 -109
  8. package/node_modules/@aws-sdk/core/dist-cjs/submodules/util/index.js +2 -4
  9. package/node_modules/@aws-sdk/core/package.json +8 -8
  10. package/node_modules/@aws-sdk/credential-provider-env/dist-cjs/index.js +4 -6
  11. package/node_modules/@aws-sdk/credential-provider-env/package.json +6 -6
  12. package/node_modules/@aws-sdk/credential-provider-http/dist-cjs/fromHttp/checkUrl.js +3 -7
  13. package/node_modules/@aws-sdk/credential-provider-http/dist-cjs/fromHttp/fromHttp.browser.js +12 -16
  14. package/node_modules/@aws-sdk/credential-provider-http/dist-cjs/fromHttp/fromHttp.js +16 -21
  15. package/node_modules/@aws-sdk/credential-provider-http/dist-cjs/fromHttp/requestHelpers.js +14 -18
  16. package/node_modules/@aws-sdk/credential-provider-http/dist-cjs/fromHttp/retry-wrapper.js +1 -5
  17. package/node_modules/@aws-sdk/credential-provider-http/dist-cjs/index.browser.js +2 -5
  18. package/node_modules/@aws-sdk/credential-provider-http/dist-cjs/index.js +2 -7
  19. package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-cjs/index.js +11 -13
  20. package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/package.json +7 -7
  21. package/node_modules/@aws-sdk/credential-provider-http/package.json +6 -6
  22. package/node_modules/@aws-sdk/credential-provider-ini/dist-cjs/index.js +47 -41
  23. package/node_modules/@aws-sdk/credential-provider-ini/dist-es/resolveProcessCredentials.js +8 -4
  24. package/node_modules/@aws-sdk/credential-provider-ini/dist-es/resolveWebIdentityCredentials.js +14 -10
  25. package/node_modules/@aws-sdk/credential-provider-ini/package.json +13 -13
  26. package/node_modules/@aws-sdk/credential-provider-login/dist-cjs/index.js +31 -33
  27. package/node_modules/@aws-sdk/credential-provider-login/package.json +7 -7
  28. package/node_modules/@aws-sdk/credential-provider-node/dist-cjs/index.js +16 -18
  29. package/node_modules/@aws-sdk/credential-provider-node/package.json +11 -11
  30. package/node_modules/@aws-sdk/credential-provider-process/dist-cjs/index.js +11 -13
  31. package/node_modules/@aws-sdk/credential-provider-process/package.json +6 -6
  32. package/node_modules/@aws-sdk/credential-provider-sso/dist-cjs/index.js +22 -24
  33. package/node_modules/@aws-sdk/credential-provider-sso/dist-cjs/loadSso-BGYXHf8s.js +3 -0
  34. package/node_modules/@aws-sdk/credential-provider-sso/node_modules/@aws-sdk/token-providers/dist-cjs/index.js +26 -28
  35. package/node_modules/@aws-sdk/credential-provider-sso/node_modules/@aws-sdk/token-providers/package.json +7 -7
  36. package/node_modules/@aws-sdk/credential-provider-sso/package.json +8 -8
  37. package/node_modules/@aws-sdk/credential-provider-web-identity/dist-cjs/fromTokenFile.js +10 -14
  38. package/node_modules/@aws-sdk/credential-provider-web-identity/dist-cjs/fromWebToken.js +2 -6
  39. package/node_modules/@aws-sdk/credential-provider-web-identity/dist-cjs/index.js +3 -27
  40. package/node_modules/@aws-sdk/credential-provider-web-identity/package.json +7 -7
  41. package/node_modules/@aws-sdk/eventstream-handler-node/dist-cjs/index.js +7 -9
  42. package/node_modules/@aws-sdk/eventstream-handler-node/package.json +5 -5
  43. package/node_modules/@aws-sdk/middleware-eventstream/dist-cjs/index.js +3 -5
  44. package/node_modules/@aws-sdk/middleware-eventstream/package.json +5 -5
  45. package/node_modules/@aws-sdk/middleware-websocket/dist-cjs/index.js +16 -18
  46. package/node_modules/@aws-sdk/middleware-websocket/package.json +6 -6
  47. package/node_modules/@aws-sdk/nested-clients/dist-cjs/index.js +0 -1
  48. package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/cognito-identity/index.js +82 -84
  49. package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/signin/index.js +158 -119
  50. package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sso/index.js +80 -82
  51. package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sso-oidc/index.js +80 -82
  52. package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sts/index.js +99 -101
  53. package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/signin/commands/CreateOAuth2TokenCommand.js +4 -1
  54. package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/signin/endpoint/bdd.js +70 -35
  55. package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/signin/endpoint/endpointResolver.js +1 -1
  56. package/node_modules/@aws-sdk/nested-clients/dist-es/submodules/signin/models/enums.js +3 -0
  57. package/node_modules/@aws-sdk/nested-clients/dist-types/submodules/signin/endpoint/EndpointParameters.d.ts +1 -0
  58. package/node_modules/@aws-sdk/nested-clients/dist-types/submodules/signin/models/enums.d.ts +12 -0
  59. package/node_modules/@aws-sdk/nested-clients/dist-types/ts3.4/submodules/signin/endpoint/EndpointParameters.d.ts +1 -0
  60. package/node_modules/@aws-sdk/nested-clients/dist-types/ts3.4/submodules/signin/models/enums.d.ts +3 -0
  61. package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-cjs/index.js +11 -13
  62. package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/package.json +7 -7
  63. package/node_modules/@aws-sdk/nested-clients/package.json +9 -8
  64. package/node_modules/@aws-sdk/signature-v4-multi-region/dist-cjs/index.js +4 -6
  65. package/node_modules/@aws-sdk/signature-v4-multi-region/package.json +5 -5
  66. package/node_modules/@aws-sdk/types/dist-cjs/index.js +7 -8
  67. package/node_modules/@aws-sdk/types/package.json +4 -4
  68. package/node_modules/@aws-sdk/util-locate-window/dist-cjs/index.js +0 -2
  69. package/node_modules/@aws-sdk/util-locate-window/package.json +4 -4
  70. package/node_modules/@aws-sdk/xml-builder/dist-cjs/index.js +2 -4
  71. package/node_modules/@aws-sdk/xml-builder/dist-cjs/xml-external/nodable_entities.js +4 -7
  72. package/node_modules/@aws-sdk/xml-builder/dist-cjs/xml-parser.browser.js +2 -5
  73. package/node_modules/@aws-sdk/xml-builder/dist-cjs/xml-parser.js +7 -10
  74. package/node_modules/@aws-sdk/xml-builder/package.json +4 -4
  75. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  76. package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js +21 -57
  77. package/node_modules/@earendil-works/pi-ai/dist/models.generated.js +277 -175
  78. package/node_modules/@earendil-works/pi-ai/dist/models.js +4 -1
  79. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js +52 -34
  80. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js +11 -9
  81. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.js +7 -4
  82. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare.js +4 -3
  83. package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.js +15 -5
  84. package/node_modules/@earendil-works/pi-ai/dist/providers/google.js +2 -1
  85. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js +18 -17
  86. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js +21 -8
  87. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses-shared.js +2 -1
  88. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.js +8 -7
  89. package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.js +1 -0
  90. package/node_modules/@earendil-works/pi-ai/dist/stream.js +1 -1
  91. package/node_modules/@earendil-works/pi-ai/dist/utils/node-http-proxy.js +17 -22
  92. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/anthropic.js +2 -1
  93. package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.js +3 -2
  94. package/node_modules/@earendil-works/pi-ai/dist/utils/provider-env.js +44 -0
  95. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  96. package/node_modules/@earendil-works/pi-coding-agent/dist/bun/restore-sandbox-env.js +4 -0
  97. package/node_modules/@earendil-works/pi-coding-agent/dist/cli/args.js +1 -1
  98. package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.js +10 -7
  99. package/node_modules/@earendil-works/pi-coding-agent/dist/core/auth-storage.js +8 -1
  100. package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/branch-summarization.js +2 -2
  101. package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/compaction.js +10 -10
  102. package/node_modules/@earendil-works/pi-coding-agent/dist/core/export-html/vendor/marked.min.js +75 -3
  103. package/node_modules/@earendil-works/pi-coding-agent/dist/core/http-dispatcher.js +17 -1
  104. package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-registry.js +8 -4
  105. package/node_modules/@earendil-works/pi-coding-agent/dist/core/project-trust.js +1 -1
  106. package/node_modules/@earendil-works/pi-coding-agent/dist/core/provider-attribution.js +10 -0
  107. package/node_modules/@earendil-works/pi-coding-agent/dist/core/resolve-config-value.js +19 -19
  108. package/node_modules/@earendil-works/pi-coding-agent/dist/core/sdk.js +2 -0
  109. package/node_modules/@earendil-works/pi-coding-agent/dist/core/system-prompt.js +6 -6
  110. package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/bash.js +4 -0
  111. package/node_modules/@earendil-works/pi-coding-agent/dist/main.js +17 -5
  112. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/footer.js +4 -0
  113. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +0 -1
  114. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/session-selector.js +0 -5
  115. package/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.js +6 -6
  116. package/node_modules/@earendil-works/pi-coding-agent/dist/utils/child-process.js +23 -5
  117. package/node_modules/@earendil-works/pi-coding-agent/npm-shrinkwrap.json +17 -17
  118. package/node_modules/@earendil-works/pi-coding-agent/package.json +4 -4
  119. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +5 -1
  120. package/node_modules/@earendil-works/pi-tui/package.json +2 -2
  121. package/node_modules/@smithy/core/dist-cjs/index.js +13 -15
  122. package/node_modules/@smithy/core/dist-cjs/submodules/cbor/index.js +29 -31
  123. package/node_modules/@smithy/core/dist-cjs/submodules/checksum/index.browser.js +2 -4
  124. package/node_modules/@smithy/core/dist-cjs/submodules/checksum/index.js +7 -9
  125. package/node_modules/@smithy/core/dist-cjs/submodules/checksum/index.native.js +3 -5
  126. package/node_modules/@smithy/core/dist-cjs/submodules/client/index.js +22 -23
  127. package/node_modules/@smithy/core/dist-cjs/submodules/config/index.browser.js +10 -11
  128. package/node_modules/@smithy/core/dist-cjs/submodules/config/index.js +38 -39
  129. package/node_modules/@smithy/core/dist-cjs/submodules/config/index.native.js +10 -11
  130. package/node_modules/@smithy/core/dist-cjs/submodules/endpoints/index.browser.js +14 -17
  131. package/node_modules/@smithy/core/dist-cjs/submodules/endpoints/index.js +20 -23
  132. package/node_modules/@smithy/core/dist-cjs/submodules/event-streams/index.browser.js +9 -11
  133. package/node_modules/@smithy/core/dist-cjs/submodules/event-streams/index.js +11 -13
  134. package/node_modules/@smithy/core/dist-cjs/submodules/protocols/index.js +59 -60
  135. package/node_modules/@smithy/core/dist-cjs/submodules/retry/index.browser.js +23 -24
  136. package/node_modules/@smithy/core/dist-cjs/submodules/retry/index.js +25 -26
  137. package/node_modules/@smithy/core/dist-cjs/submodules/schema/index.js +5 -7
  138. package/node_modules/@smithy/core/dist-cjs/submodules/serde/index.browser.js +4 -6
  139. package/node_modules/@smithy/core/dist-cjs/submodules/serde/index.js +23 -25
  140. package/node_modules/@smithy/core/dist-cjs/submodules/serde/index.native.js +4 -6
  141. package/node_modules/@smithy/core/dist-cjs/submodules/transport/index.js +2 -4
  142. package/node_modules/@smithy/core/dist-es/legacy-root-exports/middleware-http-auth-scheme/httpAuthSchemeMiddleware.js +1 -1
  143. package/node_modules/@smithy/core/dist-es/legacy-root-exports/middleware-http-signing/httpSigningMiddleware.js +1 -1
  144. package/node_modules/@smithy/core/dist-es/submodules/cbor/SmithyRpcV2CborProtocol.js +1 -1
  145. package/node_modules/@smithy/core/dist-es/submodules/endpoints/middleware-endpoint/endpointMiddleware.js +1 -1
  146. package/node_modules/@smithy/core/dist-types/submodules/schema/TypeRegistry.d.ts +1 -1
  147. package/node_modules/@smithy/core/package.json +7 -6
  148. package/node_modules/@smithy/credential-provider-imds/dist-cjs/index.js +23 -24
  149. package/node_modules/@smithy/credential-provider-imds/package.json +6 -6
  150. package/node_modules/@smithy/fetch-http-handler/dist-cjs/index.js +6 -8
  151. package/node_modules/@smithy/fetch-http-handler/package.json +7 -7
  152. package/node_modules/@smithy/signature-v4/dist-cjs/index.js +27 -29
  153. package/node_modules/@smithy/signature-v4/package.json +6 -6
  154. package/node_modules/@smithy/types/dist-cjs/index.js +23 -18
  155. package/node_modules/@smithy/types/package.json +4 -4
  156. package/node_modules/marked/README.md +13 -4
  157. package/node_modules/marked/bin/main.js +16 -14
  158. package/node_modules/marked/bin/marked.js +2 -1
  159. package/node_modules/marked/lib/marked.d.ts +157 -125
  160. package/node_modules/marked/lib/marked.esm.js +67 -2179
  161. package/node_modules/marked/lib/marked.esm.js.map +3 -3
  162. package/node_modules/marked/lib/marked.umd.js +67 -2201
  163. package/node_modules/marked/lib/marked.umd.js.map +3 -3
  164. package/node_modules/marked/man/marked.1 +4 -2
  165. package/node_modules/marked/man/marked.1.md +2 -1
  166. package/node_modules/marked/package.json +27 -35
  167. package/node_modules/undici/docs/docs/api/Client.md +3 -0
  168. package/node_modules/undici/docs/docs/api/Cookies.md +27 -0
  169. package/node_modules/undici/docs/docs/api/Socks5ProxyAgent.md +1 -0
  170. package/node_modules/undici/lib/core/socks5-client.js +14 -4
  171. package/node_modules/undici/lib/core/socks5-utils.js +18 -4
  172. package/node_modules/undici/lib/dispatcher/agent.js +1 -1
  173. package/node_modules/undici/lib/dispatcher/balanced-pool.js +1 -1
  174. package/node_modules/undici/lib/dispatcher/client-h1.js +69 -1
  175. package/node_modules/undici/lib/dispatcher/client.js +3 -2
  176. package/node_modules/undici/lib/dispatcher/dispatcher-base.js +19 -0
  177. package/node_modules/undici/lib/dispatcher/pool.js +1 -1
  178. package/node_modules/undici/lib/dispatcher/proxy-agent.js +2 -1
  179. package/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +45 -34
  180. package/node_modules/undici/lib/util/cache.js +8 -2
  181. package/node_modules/undici/lib/web/cookies/parse.js +17 -25
  182. package/node_modules/undici/lib/web/websocket/permessage-deflate.js +13 -31
  183. package/node_modules/undici/lib/web/websocket/receiver.js +80 -23
  184. package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +8 -1
  185. package/node_modules/undici/lib/web/websocket/websocket.js +8 -1
  186. package/node_modules/undici/package.json +1 -1
  187. package/node_modules/undici/types/client.d.ts +16 -0
  188. package/package.json +6 -6
  189. package/slingshot/index.js +253 -253
  190. package/node_modules/@aws-sdk/credential-provider-sso/dist-cjs/loadSso-BKDNrsal.js +0 -8
  191. package/node_modules/marked/lib/marked.cjs +0 -2211
  192. package/node_modules/marked/lib/marked.cjs.map +0 -7
  193. package/node_modules/marked/lib/marked.d.cts +0 -728
  194. package/node_modules/marked/marked.min.js +0 -69
  195. /package/node_modules/marked/{LICENSE.md → LICENSE} +0 -0
@@ -2,6 +2,7 @@ import OpenAI from "openai";
2
2
  import { clampThinkingLevel } from "../models.js";
3
3
  import { AssistantMessageEventStream } from "../utils/event-stream.js";
4
4
  import { headersToRecord } from "../utils/headers.js";
5
+ import { getProviderEnvValue } from "../utils/provider-env.js";
5
6
  import { isCloudflareProvider, resolveCloudflareBaseUrl } from "./cloudflare.js";
6
7
  import { buildCopilotDynamicHeaders, hasCopilotVisionInput } from "./github-copilot-headers.js";
7
8
  import { clampOpenAIPromptCacheKey } from "./openai-prompt-cache.js";
@@ -12,11 +13,11 @@ const OPENAI_TOOL_CALL_PROVIDERS = new Set(["openai", "openai-codex", "opencode"
12
13
  * Resolve cache retention preference.
13
14
  * Defaults to "short" and uses PI_CACHE_RETENTION for backward compatibility.
14
15
  */
15
- function resolveCacheRetention(cacheRetention) {
16
+ function resolveCacheRetention(cacheRetention, env) {
16
17
  if (cacheRetention) {
17
18
  return cacheRetention;
18
19
  }
19
- if (typeof process !== "undefined" && process.env.PI_CACHE_RETENTION === "long") {
20
+ if (getProviderEnvValue("PI_CACHE_RETENTION", env) === "long") {
20
21
  return "long";
21
22
  }
22
23
  return "short";
@@ -77,9 +78,9 @@ export const streamOpenAIResponses = (model, context, options) => {
77
78
  if (!apiKey) {
78
79
  throw new Error(`No API key for provider: ${model.provider}`);
79
80
  }
80
- const cacheRetention = resolveCacheRetention(options?.cacheRetention);
81
+ const cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);
81
82
  const cacheSessionId = cacheRetention === "none" ? undefined : options?.sessionId;
82
- const client = createClient(model, context, apiKey, options?.headers, cacheSessionId);
83
+ const client = createClient(model, context, apiKey, options?.headers, cacheSessionId, options?.env);
83
84
  let params = buildParams(model, context, options);
84
85
  const nextParams = await options?.onPayload?.(params, model);
85
86
  if (nextParams !== undefined) {
@@ -133,7 +134,7 @@ export const streamSimpleOpenAIResponses = (model, context, options) => {
133
134
  reasoningEffort,
134
135
  });
135
136
  };
136
- function createClient(model, context, apiKey, optionsHeaders, sessionId) {
137
+ function createClient(model, context, apiKey, optionsHeaders, sessionId, env) {
137
138
  const compat = getCompat(model);
138
139
  const headers = { ...model.headers };
139
140
  if (model.provider === "github-copilot") {
@@ -163,14 +164,14 @@ function createClient(model, context, apiKey, optionsHeaders, sessionId) {
163
164
  : headers;
164
165
  return new OpenAI({
165
166
  apiKey,
166
- baseURL: isCloudflareProvider(model.provider) ? resolveCloudflareBaseUrl(model) : model.baseUrl,
167
+ baseURL: isCloudflareProvider(model.provider) ? resolveCloudflareBaseUrl(model, env) : model.baseUrl,
167
168
  dangerouslyAllowBrowser: true,
168
169
  defaultHeaders,
169
170
  });
170
171
  }
171
172
  function buildParams(model, context, options) {
172
173
  const messages = convertResponsesMessages(model, context, OPENAI_TOOL_CALL_PROVIDERS);
173
- const cacheRetention = resolveCacheRetention(options?.cacheRetention);
174
+ const cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);
174
175
  const compat = getCompat(model);
175
176
  const params = {
176
177
  model: model.id,
@@ -15,6 +15,7 @@ export function buildBaseOptions(_model, options, apiKey) {
15
15
  maxRetries: options?.maxRetries,
16
16
  maxRetryDelayMs: options?.maxRetryDelayMs,
17
17
  metadata: options?.metadata,
18
+ env: options?.env,
18
19
  };
19
20
  }
20
21
  export function clampReasoning(effort) {
@@ -8,7 +8,7 @@ function hasExplicitApiKey(apiKey) {
8
8
  function withEnvApiKey(model, options) {
9
9
  if (hasExplicitApiKey(options?.apiKey))
10
10
  return options;
11
- const apiKey = getEnvApiKey(model.provider);
11
+ const apiKey = getEnvApiKey(model.provider, options?.env);
12
12
  if (!apiKey)
13
13
  return options;
14
14
  return { ...options, apiKey };
@@ -1,5 +1,4 @@
1
- import { HttpProxyAgent } from "http-proxy-agent";
2
- import { HttpsProxyAgent } from "https-proxy-agent";
1
+ import { getProviderEnvValue } from "./provider-env.js";
3
2
  const DEFAULT_PROXY_PORTS = {
4
3
  ftp: 21,
5
4
  gopher: 70,
@@ -8,9 +7,14 @@ const DEFAULT_PROXY_PORTS = {
8
7
  ws: 80,
9
8
  wss: 443,
10
9
  };
11
- export const UNSUPPORTED_PROXY_PROTOCOL_MESSAGE = "Unsupported proxy protocol. SOCKS and PAC proxy URLs are not supported; use an HTTP or HTTPS proxy URL.";
12
- function getProxyEnv(key) {
13
- return process.env[key.toLowerCase()] || process.env[key.toUpperCase()] || "";
10
+ function getProxyEnv(key, env) {
11
+ const lowercaseKey = key.toLowerCase();
12
+ const uppercaseKey = key.toUpperCase();
13
+ return (env?.[lowercaseKey] ||
14
+ env?.[uppercaseKey] ||
15
+ getProviderEnvValue(lowercaseKey) ||
16
+ getProviderEnvValue(uppercaseKey) ||
17
+ "");
14
18
  }
15
19
  function parseProxyTargetUrl(targetUrl) {
16
20
  if (targetUrl instanceof URL) {
@@ -23,8 +27,8 @@ function parseProxyTargetUrl(targetUrl) {
23
27
  return undefined;
24
28
  }
25
29
  }
26
- function shouldProxyHostname(hostname, port) {
27
- const noProxy = getProxyEnv("no_proxy").toLowerCase();
30
+ function shouldProxyHostname(hostname, port, env) {
31
+ const noProxy = getProxyEnv("no_proxy", env).toLowerCase();
28
32
  if (!noProxy) {
29
33
  return true;
30
34
  }
@@ -50,7 +54,7 @@ function shouldProxyHostname(hostname, port) {
50
54
  return !hostname.endsWith(proxyHostname);
51
55
  });
52
56
  }
53
- function getProxyForUrl(targetUrl) {
57
+ function getProxyForUrl(targetUrl, env) {
54
58
  const parsedUrl = parseProxyTargetUrl(targetUrl);
55
59
  if (!parsedUrl?.protocol || !parsedUrl.host) {
56
60
  return "";
@@ -58,17 +62,18 @@ function getProxyForUrl(targetUrl) {
58
62
  const protocol = parsedUrl.protocol.split(":", 1)[0];
59
63
  const hostname = parsedUrl.host.replace(/:\d*$/, "");
60
64
  const port = Number.parseInt(parsedUrl.port, 10) || DEFAULT_PROXY_PORTS[protocol] || 0;
61
- if (!shouldProxyHostname(hostname, port)) {
65
+ if (!shouldProxyHostname(hostname, port, env)) {
62
66
  return "";
63
67
  }
64
- let proxy = getProxyEnv(`${protocol}_proxy`) || getProxyEnv("all_proxy");
68
+ let proxy = getProxyEnv(`${protocol}_proxy`, env) || getProxyEnv("all_proxy", env);
65
69
  if (proxy && !proxy.includes("://")) {
66
70
  proxy = `${protocol}://${proxy}`;
67
71
  }
68
72
  return proxy;
69
73
  }
70
- export function resolveHttpProxyUrlForTarget(targetUrl) {
71
- const proxy = getProxyForUrl(targetUrl);
74
+ export const UNSUPPORTED_PROXY_PROTOCOL_MESSAGE = "Unsupported proxy protocol. SOCKS and PAC proxy URLs are not supported; use an HTTP or HTTPS proxy URL.";
75
+ export function resolveHttpProxyUrlForTarget(targetUrl, env) {
76
+ const proxy = getProxyForUrl(targetUrl, env);
72
77
  if (!proxy) {
73
78
  return undefined;
74
79
  }
@@ -84,14 +89,4 @@ export function resolveHttpProxyUrlForTarget(targetUrl) {
84
89
  }
85
90
  return proxyUrl;
86
91
  }
87
- export function createHttpProxyAgentsForTarget(targetUrl) {
88
- const proxyUrl = resolveHttpProxyUrlForTarget(targetUrl);
89
- if (!proxyUrl) {
90
- return undefined;
91
- }
92
- return {
93
- httpAgent: new HttpProxyAgent(proxyUrl),
94
- httpsAgent: new HttpsProxyAgent(proxyUrl),
95
- };
96
- }
97
92
  //# sourceMappingURL=node-http-proxy.js.map
@@ -4,6 +4,7 @@
4
4
  * NOTE: This module uses Node.js http.createServer for the OAuth callback server.
5
5
  * It is only intended for CLI use, not browser environments.
6
6
  */
7
+ import { getProviderEnvValue } from "../provider-env.js";
7
8
  import { oauthErrorHtml, oauthSuccessHtml } from "./oauth-page.js";
8
9
  import { generatePKCE } from "./pkce.js";
9
10
  let nodeApis = null;
@@ -12,7 +13,7 @@ const decode = (s) => atob(s);
12
13
  const CLIENT_ID = decode("OWQxYzI1MGEtZTYxYi00NGQ5LTg4ZWQtNTk0NGQxOTYyZjVl");
13
14
  const AUTHORIZE_URL = "https://claude.ai/oauth/authorize";
14
15
  const TOKEN_URL = "https://platform.claude.com/v1/oauth/token";
15
- const CALLBACK_HOST = process.env.PI_OAUTH_CALLBACK_HOST || "127.0.0.1";
16
+ const CALLBACK_HOST = getProviderEnvValue("PI_OAUTH_CALLBACK_HOST") || "127.0.0.1";
16
17
  const CALLBACK_PORT = 53692;
17
18
  const CALLBACK_PATH = "/callback";
18
19
  const REDIRECT_URI = `http://localhost:${CALLBACK_PORT}${CALLBACK_PATH}`;
@@ -15,6 +15,7 @@ if (typeof process !== "undefined" && (process.versions?.node || process.version
15
15
  _http = m;
16
16
  });
17
17
  }
18
+ import { getProviderEnvValue } from "../provider-env.js";
18
19
  import { pollOAuthDeviceCodeFlow } from "./device-code.js";
19
20
  import { oauthErrorHtml, oauthSuccessHtml } from "./oauth-page.js";
20
21
  import { generatePKCE } from "./pkce.js";
@@ -33,7 +34,7 @@ export const OPENAI_CODEX_DEVICE_CODE_LOGIN_METHOD = "device_code";
33
34
  const SCOPE = "openid profile email offline_access";
34
35
  const JWT_CLAIM_PATH = "https://api.openai.com/auth";
35
36
  function getCallbackHost() {
36
- return typeof process !== "undefined" ? process.env.PI_OAUTH_CALLBACK_HOST || "127.0.0.1" : "127.0.0.1";
37
+ return getProviderEnvValue("PI_OAUTH_CALLBACK_HOST") || "127.0.0.1";
37
38
  }
38
39
  function createState() {
39
40
  if (!_randomBytes) {
@@ -224,7 +225,7 @@ async function pollOpenAICodexDeviceAuth(device, signal) {
224
225
  },
225
226
  });
226
227
  }
227
- async function createAuthorizationFlow(originator = "sling") {
228
+ async function createAuthorizationFlow(originator = "pi") {
228
229
  const { verifier, challenge } = await generatePKCE();
229
230
  const state = createState();
230
231
  const url = new URL(AUTHORIZE_URL);
@@ -0,0 +1,44 @@
1
+ let procEnvCache = null;
2
+ /**
3
+ * Fallback for https://github.com/oven-sh/bun/issues/27802.
4
+ * Bun compiled binaries can expose an empty process.env inside Linux sandboxes
5
+ * even though /proc/self/environ contains the environment.
6
+ *
7
+ * This intentionally duplicates restoreSandboxEnv() in
8
+ * packages/coding-agent/src/bun/restore-sandbox-env.ts. The ai package can be
9
+ * used directly, without going through that entrypoint, so provider env lookup
10
+ * must not depend on process.env having been patched.
11
+ */
12
+ function getBunSandboxEnvValue(name) {
13
+ if (typeof process === "undefined" || !process.versions?.bun || Object.keys(process.env).length > 0) {
14
+ return undefined;
15
+ }
16
+ if (procEnvCache === null) {
17
+ procEnvCache = new Map();
18
+ try {
19
+ const { readFileSync } = require("node:fs");
20
+ const data = readFileSync("/proc/self/environ", "utf-8");
21
+ for (const entry of data.split("\0")) {
22
+ const idx = entry.indexOf("=");
23
+ if (idx > 0) {
24
+ procEnvCache.set(entry.slice(0, idx), entry.slice(idx + 1));
25
+ }
26
+ }
27
+ }
28
+ catch {
29
+ // /proc/self/environ may not exist or may not be readable.
30
+ }
31
+ }
32
+ return procEnvCache.get(name);
33
+ }
34
+ /**
35
+ * Resolve a provider env value from scoped overrides, normal process.env, then
36
+ * the duplicated Bun sandbox fallback for direct pi-ai consumers.
37
+ */
38
+ export function getProviderEnvValue(name, env) {
39
+ return (env?.[name] ||
40
+ (typeof process !== "undefined" ? process.env[name] : undefined) ||
41
+ getBunSandboxEnvValue(name) ||
42
+ undefined);
43
+ }
44
+ //# sourceMappingURL=provider-env.js.map
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-ai",
3
- "version": "0.79.3",
3
+ "version": "0.79.6",
4
4
  "description": "Unified LLM API with automatic model discovery and provider configuration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -4,6 +4,10 @@
4
4
  * Bun compiled binaries have an empty `process.env` when running inside
5
5
  * sandbox environments (e.g. nono on Linux/macOS). On Linux we can recover
6
6
  * the environment from `/proc/self/environ`.
7
+ *
8
+ * Keep this in sync with getBunSandboxEnvValue() in
9
+ * packages/ai/src/utils/provider-env.ts. The ai package duplicates the lookup
10
+ * for direct consumers that do not go through this coding-agent entrypoint.
7
11
  */
8
12
  import { readFileSync } from "node:fs";
9
13
  /**
@@ -217,7 +217,7 @@ ${chalk.bold("Commands:")}
217
217
  ${APP_NAME} install <source> [-l] Install extension source and add to settings
218
218
  ${APP_NAME} remove <source> [-l] Remove extension source from settings
219
219
  ${APP_NAME} uninstall <source> [-l] Alias for remove
220
- ${APP_NAME} update [source|self|sling] Update sling and installed extensions
220
+ ${APP_NAME} update [source|self|pi] Update pi and installed extensions
221
221
  ${APP_NAME} list List installed extensions from settings
222
222
  ${APP_NAME} config Open TUI to enable/disable package resources
223
223
  ${APP_NAME} <command> --help Show help for install/remove/uninstall/update/list
@@ -150,7 +150,7 @@ export class AgentSession {
150
150
  throw new Error(result.error);
151
151
  }
152
152
  if (result.apiKey) {
153
- return { apiKey: result.apiKey, headers: result.headers };
153
+ return { apiKey: result.apiKey, headers: result.headers, env: result.env };
154
154
  }
155
155
  const isOAuth = this._modelRegistry.isUsingOAuth(model);
156
156
  if (isOAuth) {
@@ -165,7 +165,7 @@ export class AgentSession {
165
165
  return this._getRequiredRequestAuth(model);
166
166
  }
167
167
  const result = await this._modelRegistry.getApiKeyAndHeaders(model);
168
- return result.ok ? { apiKey: result.apiKey, headers: result.headers } : {};
168
+ return result.ok ? { apiKey: result.apiKey, headers: result.headers, env: result.env } : {};
169
169
  }
170
170
  /**
171
171
  * Install tool hooks once on the Agent instance.
@@ -1273,7 +1273,7 @@ export class AgentSession {
1273
1273
  if (!this.model) {
1274
1274
  throw new Error(formatNoModelSelectedMessage());
1275
1275
  }
1276
- const { apiKey, headers } = await this._getCompactionRequestAuth(this.model);
1276
+ const { apiKey, headers, env } = await this._getCompactionRequestAuth(this.model);
1277
1277
  const pathEntries = this.sessionManager.getBranch();
1278
1278
  const settings = this.settingsManager.getCompactionSettings();
1279
1279
  const preparation = prepareCompaction(pathEntries, settings);
@@ -1316,7 +1316,7 @@ export class AgentSession {
1316
1316
  }
1317
1317
  else {
1318
1318
  // Generate compaction result
1319
- const result = await compact(preparation, this.model, apiKey, headers, customInstructions, this._compactionAbortController.signal, this.thinkingLevel, this.agent.streamFn);
1319
+ const result = await compact(preparation, this.model, apiKey, headers, customInstructions, this._compactionAbortController.signal, this.thinkingLevel, this.agent.streamFn, env);
1320
1320
  summary = result.summary;
1321
1321
  firstKeptEntryId = result.firstKeptEntryId;
1322
1322
  tokensBefore = result.tokensBefore;
@@ -1486,6 +1486,7 @@ export class AgentSession {
1486
1486
  }
1487
1487
  let apiKey;
1488
1488
  let headers;
1489
+ let env;
1489
1490
  if (this.agent.streamFn === streamSimple) {
1490
1491
  const authResult = await this._modelRegistry.getApiKeyAndHeaders(this.model);
1491
1492
  if (!authResult.ok || !authResult.apiKey) {
@@ -1500,9 +1501,10 @@ export class AgentSession {
1500
1501
  }
1501
1502
  apiKey = authResult.apiKey;
1502
1503
  headers = authResult.headers;
1504
+ env = authResult.env;
1503
1505
  }
1504
1506
  else {
1505
- ({ apiKey, headers } = await this._getCompactionRequestAuth(this.model));
1507
+ ({ apiKey, headers, env } = await this._getCompactionRequestAuth(this.model));
1506
1508
  }
1507
1509
  const pathEntries = this.sessionManager.getBranch();
1508
1510
  const preparation = prepareCompaction(pathEntries, settings);
@@ -1554,7 +1556,7 @@ export class AgentSession {
1554
1556
  }
1555
1557
  else {
1556
1558
  // Generate compaction result
1557
- const compactResult = await compact(preparation, this.model, apiKey, headers, undefined, this._autoCompactionAbortController.signal, this.thinkingLevel, this.agent.streamFn);
1559
+ const compactResult = await compact(preparation, this.model, apiKey, headers, undefined, this._autoCompactionAbortController.signal, this.thinkingLevel, this.agent.streamFn, env);
1558
1560
  summary = compactResult.summary;
1559
1561
  firstKeptEntryId = compactResult.firstKeptEntryId;
1560
1562
  tokensBefore = compactResult.tokensBefore;
@@ -2221,12 +2223,13 @@ export class AgentSession {
2221
2223
  let summaryDetails;
2222
2224
  if (options.summarize && entriesToSummarize.length > 0 && !extensionSummary) {
2223
2225
  const model = this.model;
2224
- const { apiKey, headers } = await this._getRequiredRequestAuth(model);
2226
+ const { apiKey, headers, env } = await this._getRequiredRequestAuth(model);
2225
2227
  const branchSummarySettings = this.settingsManager.getBranchSummarySettings();
2226
2228
  const result = await generateBranchSummary(entriesToSummarize, {
2227
2229
  model,
2228
2230
  apiKey,
2229
2231
  headers,
2232
+ env,
2230
2233
  signal: this._branchSummaryAbortController.signal,
2231
2234
  customInstructions,
2232
2235
  replaceInstructions,
@@ -241,6 +241,13 @@ export class AuthStorage {
241
241
  get(provider) {
242
242
  return this.data[provider] ?? undefined;
243
243
  }
244
+ /**
245
+ * Get provider-scoped environment values for an API key credential.
246
+ */
247
+ getProviderEnv(provider) {
248
+ const cred = this.data[provider];
249
+ return cred?.type === "api_key" && cred.env ? { ...cred.env } : undefined;
250
+ }
244
251
  /**
245
252
  * Set credential for a provider.
246
253
  */
@@ -386,7 +393,7 @@ export class AuthStorage {
386
393
  }
387
394
  const cred = this.data[providerId];
388
395
  if (cred?.type === "api_key") {
389
- return resolveConfigValue(cred.key);
396
+ return resolveConfigValue(cred.key, cred.env);
390
397
  }
391
398
  if (cred?.type === "oauth") {
392
399
  const provider = getOAuthProvider(providerId);
@@ -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, streamFn, } = options;
188
+ const { model, apiKey, headers, env, 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;
@@ -220,7 +220,7 @@ export async function generateBranchSummary(entries, options) {
220
220
  // request behavior (timeouts, retries, attribution headers) stays consistent
221
221
  // without running through agent state/events.
222
222
  const context = { systemPrompt: SUMMARIZATION_SYSTEM_PROMPT, messages: summarizationMessages };
223
- const requestOptions = { apiKey, headers, signal, maxTokens: 2048 };
223
+ const requestOptions = { apiKey, headers, env, signal, maxTokens: 2048 };
224
224
  const response = streamFn
225
225
  ? await (await streamFn(model, context, requestOptions)).result()
226
226
  : await completeSimple(model, context, requestOptions);
@@ -419,8 +419,8 @@ Use this EXACT format:
419
419
  - [Preserve important context, add new if needed]
420
420
 
421
421
  Keep each section concise. Preserve exact file paths, function names, and error messages.`;
422
- function createSummarizationOptions(model, maxTokens, apiKey, headers, signal, thinkingLevel) {
423
- const options = { maxTokens, signal, apiKey, headers };
422
+ function createSummarizationOptions(model, maxTokens, apiKey, headers, env, signal, thinkingLevel) {
423
+ const options = { maxTokens, signal, apiKey, headers, env };
424
424
  if (model.reasoning && thinkingLevel && thinkingLevel !== "off") {
425
425
  options.reasoning = thinkingLevel;
426
426
  }
@@ -437,7 +437,7 @@ async function completeSummarization(model, context, options, streamFn) {
437
437
  * Generate a summary of the conversation using the LLM.
438
438
  * If previousSummary is provided, uses the update prompt to merge.
439
439
  */
440
- export async function generateSummary(currentMessages, model, reserveTokens, apiKey, headers, signal, customInstructions, previousSummary, thinkingLevel, streamFn) {
440
+ export async function generateSummary(currentMessages, model, reserveTokens, apiKey, headers, signal, customInstructions, previousSummary, thinkingLevel, streamFn, env) {
441
441
  const maxTokens = Math.min(Math.floor(0.8 * reserveTokens), model.maxTokens > 0 ? model.maxTokens : Number.POSITIVE_INFINITY);
442
442
  // Use update prompt if we have a previous summary, otherwise initial prompt
443
443
  let basePrompt = previousSummary ? UPDATE_SUMMARIZATION_PROMPT : SUMMARIZATION_PROMPT;
@@ -461,7 +461,7 @@ export async function generateSummary(currentMessages, model, reserveTokens, api
461
461
  timestamp: Date.now(),
462
462
  },
463
463
  ];
464
- const completionOptions = createSummarizationOptions(model, maxTokens, apiKey, headers, signal, thinkingLevel);
464
+ const completionOptions = createSummarizationOptions(model, maxTokens, apiKey, headers, env, signal, thinkingLevel);
465
465
  const response = await completeSummarization(model, { systemPrompt: SUMMARIZATION_SYSTEM_PROMPT, messages: summarizationMessages }, completionOptions, streamFn);
466
466
  if (response.stopReason === "error") {
467
467
  throw new Error(`Summarization failed: ${response.errorMessage || "Unknown error"}`);
@@ -560,7 +560,7 @@ Be concise. Focus on what's needed to understand the kept suffix.`;
560
560
  * @param preparation - Pre-calculated preparation from prepareCompaction()
561
561
  * @param customInstructions - Optional custom focus for the summary
562
562
  */
563
- export async function compact(preparation, model, apiKey, headers, customInstructions, signal, thinkingLevel, streamFn) {
563
+ export async function compact(preparation, model, apiKey, headers, customInstructions, signal, thinkingLevel, streamFn, env) {
564
564
  const { firstKeptEntryId, messagesToSummarize, turnPrefixMessages, isSplitTurn, tokensBefore, previousSummary, fileOps, settings, } = preparation;
565
565
  // Generate summaries (can be parallel if both needed) and merge into one
566
566
  let summary;
@@ -568,16 +568,16 @@ export async function compact(preparation, model, apiKey, headers, customInstruc
568
568
  // Generate both summaries in parallel
569
569
  const [historyResult, turnPrefixResult] = await Promise.all([
570
570
  messagesToSummarize.length > 0
571
- ? generateSummary(messagesToSummarize, model, settings.reserveTokens, apiKey, headers, signal, customInstructions, previousSummary, thinkingLevel, streamFn)
571
+ ? generateSummary(messagesToSummarize, model, settings.reserveTokens, apiKey, headers, signal, customInstructions, previousSummary, thinkingLevel, streamFn, env)
572
572
  : Promise.resolve("No prior history."),
573
- generateTurnPrefixSummary(turnPrefixMessages, model, settings.reserveTokens, apiKey, headers, signal, thinkingLevel, streamFn),
573
+ generateTurnPrefixSummary(turnPrefixMessages, model, settings.reserveTokens, apiKey, headers, env, signal, thinkingLevel, streamFn),
574
574
  ]);
575
575
  // Merge into single summary
576
576
  summary = `${historyResult}\n\n---\n\n**Turn Context (split turn):**\n\n${turnPrefixResult}`;
577
577
  }
578
578
  else {
579
579
  // Just generate history summary
580
- summary = await generateSummary(messagesToSummarize, model, settings.reserveTokens, apiKey, headers, signal, customInstructions, previousSummary, thinkingLevel, streamFn);
580
+ summary = await generateSummary(messagesToSummarize, model, settings.reserveTokens, apiKey, headers, signal, customInstructions, previousSummary, thinkingLevel, streamFn, env);
581
581
  }
582
582
  // Compute file lists and append to summary
583
583
  const { readFiles, modifiedFiles } = computeFileLists(fileOps);
@@ -595,7 +595,7 @@ export async function compact(preparation, model, apiKey, headers, customInstruc
595
595
  /**
596
596
  * Generate a summary for a turn prefix (when splitting a turn).
597
597
  */
598
- async function generateTurnPrefixSummary(messages, model, reserveTokens, apiKey, headers, signal, thinkingLevel, streamFn) {
598
+ async function generateTurnPrefixSummary(messages, model, reserveTokens, apiKey, headers, env, signal, thinkingLevel, streamFn) {
599
599
  const maxTokens = Math.min(Math.floor(0.5 * reserveTokens), model.maxTokens > 0 ? model.maxTokens : Number.POSITIVE_INFINITY); // Smaller budget for turn prefix
600
600
  const llmMessages = convertToLlm(messages);
601
601
  const conversationText = serializeConversation(llmMessages);
@@ -607,7 +607,7 @@ async function generateTurnPrefixSummary(messages, model, reserveTokens, apiKey,
607
607
  timestamp: Date.now(),
608
608
  },
609
609
  ];
610
- const response = await completeSummarization(model, { systemPrompt: SUMMARIZATION_SYSTEM_PROMPT, messages: summarizationMessages }, createSummarizationOptions(model, maxTokens, apiKey, headers, signal, thinkingLevel), streamFn);
610
+ const response = await completeSummarization(model, { systemPrompt: SUMMARIZATION_SYSTEM_PROMPT, messages: summarizationMessages }, createSummarizationOptions(model, maxTokens, apiKey, headers, env, signal, thinkingLevel), streamFn);
611
611
  if (response.stopReason === "error") {
612
612
  throw new Error(`Turn prefix summarization failed: ${response.errorMessage || "Unknown error"}`);
613
613
  }