@averyyy/pi-coding-agent 0.99.1-piclient.1 → 1.0.0-piclient.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 (233) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/dist/bundle/chunks/anthropic-messages-5Z4I6I54.js +6 -0
  3. package/dist/bundle/chunks/anthropic.js +2 -2
  4. package/dist/bundle/chunks/{azure-openai-responses-YZ3Q2WVP.js → azure-openai-responses-TXH53UDQ.js} +1 -1
  5. package/dist/bundle/chunks/bedrock-converse-stream.js +2 -2
  6. package/dist/bundle/chunks/{chunk-7BINYQ2V.js → chunk-43NAB75E.js} +54 -49
  7. package/dist/bundle/chunks/{chunk-V7V43FNB.js → chunk-4ILNOXGR.js} +2 -2
  8. package/dist/bundle/chunks/chunk-AV6LYFGH.js +2 -0
  9. package/dist/bundle/chunks/{chunk-7JGR3GZN.js → chunk-F42GKQ7R.js} +1 -1
  10. package/dist/bundle/chunks/chunk-GIUN2MS4.js +16 -0
  11. package/dist/bundle/chunks/{chunk-W2DOMZSC.js → chunk-JTLRGL3E.js} +2 -2
  12. package/dist/bundle/chunks/{chunk-F6ORSP6L.js → chunk-KYK7L7MP.js} +18 -78
  13. package/dist/bundle/chunks/chunk-LD2P6SFZ.js +2 -0
  14. package/dist/bundle/chunks/chunk-LDPPAHPJ.js +4 -0
  15. package/dist/bundle/chunks/{chunk-3YXHSP6S.js → chunk-NEUJZQL3.js} +7 -9
  16. package/dist/bundle/chunks/chunk-OI6YFHHK.js +82 -0
  17. package/dist/bundle/chunks/{chunk-J4CWPC4N.js → chunk-PXGUCLIP.js} +1 -1
  18. package/dist/bundle/chunks/chunk-VIV3CWXG.js +2 -0
  19. package/dist/bundle/chunks/chunk-WGS2XTDX.js +2 -0
  20. package/dist/bundle/chunks/{chunk-FJTXMIZI.js → chunk-Y5O5BZGX.js} +15 -29
  21. package/dist/bundle/chunks/{cli-WF6HDHBO.js → cli-JE36AHMI.js} +8 -6
  22. package/dist/bundle/chunks/{cloudflare-workers-ai-system-one-XJQQYGGU.js → cloudflare-workers-ai-system-one-TF36V7KG.js} +1 -1
  23. package/dist/bundle/chunks/codemode-worker.js +67 -8
  24. package/dist/bundle/chunks/execute-UX73LR4F.js +367 -0
  25. package/dist/bundle/chunks/{google-generative-ai-CQAKKJTA.js → google-generative-ai-XQU2LTWM.js} +1 -1
  26. package/dist/bundle/chunks/{google-vertex-AE36YXJU.js → google-vertex-F6Q2CN55.js} +1 -1
  27. package/dist/bundle/chunks/{https-proxy-agent-2VXB7436.js → https-proxy-agent-UDEHOBGS.js} +1 -1
  28. package/dist/bundle/chunks/{llama-cpp-classify-PJJYKPLD.js → llama-cpp-classify-XT44PI3C.js} +1 -1
  29. package/dist/bundle/chunks/{mistral-conversations-KEYTXJM7.js → mistral-conversations-XAJWHQFR.js} +1 -1
  30. package/dist/bundle/chunks/openai-chatgpt.js +1 -1
  31. package/dist/bundle/chunks/{openai-codex-responses-FUE7WESF.js → openai-codex-responses-3EHOMZYM.js} +1 -1
  32. package/dist/bundle/chunks/openai-codex.js +1 -1
  33. package/dist/bundle/chunks/{openai-completions-XW2Q5HVC.js → openai-completions-QC2IQHSC.js} +1 -1
  34. package/dist/bundle/chunks/{openai-responses-ZUXFVYPI.js → openai-responses-JPLD2GJS.js} +1 -1
  35. package/dist/bundle/chunks/{openrouter-images-TPQ4V6OR.js → openrouter-images-ZVXWCSIM.js} +1 -1
  36. package/dist/bundle/chunks/openrouter.js +1 -1
  37. package/dist/bundle/chunks/pi-logo-animation-APS4JS6B.js +2 -0
  38. package/dist/bundle/chunks/radius.js +1 -1
  39. package/dist/bundle/chunks/runtime-MPXPM7VL.js +2 -0
  40. package/dist/bundle/chunks/{typesafe-system-one-E7A4HNJI.js → typesafe-system-one-7DJTDUKY.js} +1 -1
  41. package/dist/bundle/chunks/virtual-modules-X5AB6TM6.js +2 -0
  42. package/dist/bundle/cli-runtime.js +1 -1
  43. package/dist/bundle/index.js +1 -1
  44. package/dist/bundle/rpc-entry.js +1 -1
  45. package/dist/cli/args.js +2 -2
  46. package/dist/cli/args.js.map +1 -1
  47. package/dist/config.d.ts +5 -8
  48. package/dist/config.d.ts.map +1 -1
  49. package/dist/config.js +16 -13
  50. package/dist/config.js.map +1 -1
  51. package/dist/core/agent-session.d.ts +15 -1
  52. package/dist/core/agent-session.d.ts.map +1 -1
  53. package/dist/core/agent-session.js +80 -12
  54. package/dist/core/agent-session.js.map +1 -1
  55. package/dist/core/cache-warmer.d.ts.map +1 -1
  56. package/dist/core/cache-warmer.js +11 -3
  57. package/dist/core/cache-warmer.js.map +1 -1
  58. package/dist/core/extensions/loader.d.ts.map +1 -1
  59. package/dist/core/extensions/loader.js +13 -1
  60. package/dist/core/extensions/loader.js.map +1 -1
  61. package/dist/core/extensions/types.d.ts +6 -1
  62. package/dist/core/extensions/types.d.ts.map +1 -1
  63. package/dist/core/extensions/types.js.map +1 -1
  64. package/dist/core/mcp-servers.d.ts +34 -7
  65. package/dist/core/mcp-servers.d.ts.map +1 -1
  66. package/dist/core/mcp-servers.js +52 -11
  67. package/dist/core/mcp-servers.js.map +1 -1
  68. package/dist/core/model-registry.d.ts +3 -1
  69. package/dist/core/model-registry.d.ts.map +1 -1
  70. package/dist/core/model-registry.js +4 -0
  71. package/dist/core/model-registry.js.map +1 -1
  72. package/dist/core/model-resolver.js +1 -1
  73. package/dist/core/model-resolver.js.map +1 -1
  74. package/dist/core/model-runtime.d.ts +22 -0
  75. package/dist/core/model-runtime.d.ts.map +1 -1
  76. package/dist/core/model-runtime.js +347 -49
  77. package/dist/core/model-runtime.js.map +1 -1
  78. package/dist/core/pi-server-client.d.ts +21 -1
  79. package/dist/core/pi-server-client.d.ts.map +1 -1
  80. package/dist/core/pi-server-client.js +308 -22
  81. package/dist/core/pi-server-client.js.map +1 -1
  82. package/dist/core/pi-server-protocol.d.ts +12 -1
  83. package/dist/core/pi-server-protocol.d.ts.map +1 -1
  84. package/dist/core/pi-server-protocol.js +1 -0
  85. package/dist/core/pi-server-protocol.js.map +1 -1
  86. package/dist/core/radius.d.ts +2 -0
  87. package/dist/core/radius.d.ts.map +1 -1
  88. package/dist/core/radius.js +2 -0
  89. package/dist/core/radius.js.map +1 -1
  90. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  91. package/dist/core/remote-catalog-provider.js +4 -9
  92. package/dist/core/remote-catalog-provider.js.map +1 -1
  93. package/dist/core/sdk.d.ts.map +1 -1
  94. package/dist/core/sdk.js +52 -18
  95. package/dist/core/sdk.js.map +1 -1
  96. package/dist/core/settings-manager.d.ts +7 -5
  97. package/dist/core/settings-manager.d.ts.map +1 -1
  98. package/dist/core/settings-manager.js +3 -2
  99. package/dist/core/settings-manager.js.map +1 -1
  100. package/dist/core/system-prompt.js +1 -1
  101. package/dist/core/system-prompt.js.map +1 -1
  102. package/dist/core/tools/bash.d.ts.map +1 -1
  103. package/dist/core/tools/bash.js +3 -5
  104. package/dist/core/tools/bash.js.map +1 -1
  105. package/dist/core/tools/renderers/bash.d.ts.map +1 -1
  106. package/dist/core/tools/renderers/bash.js +11 -31
  107. package/dist/core/tools/renderers/bash.js.map +1 -1
  108. package/dist/core/virtual-models.d.ts +2 -0
  109. package/dist/core/virtual-models.d.ts.map +1 -1
  110. package/dist/core/virtual-models.js +19 -12
  111. package/dist/core/virtual-models.js.map +1 -1
  112. package/dist/extensions/codemode/execute.d.ts.map +1 -1
  113. package/dist/extensions/codemode/execute.js +197 -51
  114. package/dist/extensions/codemode/execute.js.map +1 -1
  115. package/dist/extensions/codemode/renderer.d.ts.map +1 -1
  116. package/dist/extensions/codemode/renderer.js +43 -25
  117. package/dist/extensions/codemode/renderer.js.map +1 -1
  118. package/dist/extensions/codemode/tool.d.ts +12 -11
  119. package/dist/extensions/codemode/tool.d.ts.map +1 -1
  120. package/dist/extensions/codemode/tool.js +73 -129
  121. package/dist/extensions/codemode/tool.js.map +1 -1
  122. package/dist/extensions/codemode/worker.d.ts +1 -1
  123. package/dist/extensions/codemode/worker.js +1 -1
  124. package/dist/extensions/codemode/worker.js.map +1 -1
  125. package/dist/extensions/mcp/cli.d.ts.map +1 -1
  126. package/dist/extensions/mcp/cli.js +20 -5
  127. package/dist/extensions/mcp/cli.js.map +1 -1
  128. package/dist/extensions/mcp/config.d.ts +4 -2
  129. package/dist/extensions/mcp/config.d.ts.map +1 -1
  130. package/dist/extensions/mcp/config.js +14 -2
  131. package/dist/extensions/mcp/config.js.map +1 -1
  132. package/dist/extensions/mcp/index.d.ts +32 -8
  133. package/dist/extensions/mcp/index.d.ts.map +1 -1
  134. package/dist/extensions/mcp/index.js +220 -56
  135. package/dist/extensions/mcp/index.js.map +1 -1
  136. package/dist/extensions/mcp/oauth.d.ts +10 -7
  137. package/dist/extensions/mcp/oauth.d.ts.map +1 -1
  138. package/dist/extensions/mcp/oauth.js +56 -31
  139. package/dist/extensions/mcp/oauth.js.map +1 -1
  140. package/dist/extensions/mcp/runtime.d.ts +2 -0
  141. package/dist/extensions/mcp/runtime.d.ts.map +1 -1
  142. package/dist/extensions/mcp/runtime.js +16 -9
  143. package/dist/extensions/mcp/runtime.js.map +1 -1
  144. package/dist/extensions/mcp/tools.d.ts +5 -4
  145. package/dist/extensions/mcp/tools.d.ts.map +1 -1
  146. package/dist/extensions/mcp/tools.js +33 -15
  147. package/dist/extensions/mcp/tools.js.map +1 -1
  148. package/dist/extensions/mcp/ui.d.ts.map +1 -1
  149. package/dist/extensions/mcp/ui.js +4 -2
  150. package/dist/extensions/mcp/ui.js.map +1 -1
  151. package/dist/extensions/tool-search/tool.d.ts +5 -4
  152. package/dist/extensions/tool-search/tool.d.ts.map +1 -1
  153. package/dist/extensions/tool-search/tool.js +7 -28
  154. package/dist/extensions/tool-search/tool.js.map +1 -1
  155. package/dist/index.d.ts +1 -1
  156. package/dist/index.d.ts.map +1 -1
  157. package/dist/index.js.map +1 -1
  158. package/dist/main.d.ts.map +1 -1
  159. package/dist/main.js +24 -11
  160. package/dist/main.js.map +1 -1
  161. package/dist/modes/interactive/components/oauth-selector.d.ts +8 -2
  162. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  163. package/dist/modes/interactive/components/oauth-selector.js +24 -21
  164. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  165. package/dist/modes/interactive/components/pi-logo-animation.d.ts +68 -0
  166. package/dist/modes/interactive/components/pi-logo-animation.d.ts.map +1 -0
  167. package/dist/modes/interactive/components/pi-logo-animation.js +1086 -0
  168. package/dist/modes/interactive/components/pi-logo-animation.js.map +1 -0
  169. package/dist/modes/interactive/components/pi-logo-animation.lazy.d.ts +7 -0
  170. package/dist/modes/interactive/components/pi-logo-animation.lazy.d.ts.map +1 -0
  171. package/dist/modes/interactive/components/pi-logo-animation.lazy.js +12 -0
  172. package/dist/modes/interactive/components/pi-logo-animation.lazy.js.map +1 -0
  173. package/dist/modes/interactive/components/pi-logo.d.ts +7 -0
  174. package/dist/modes/interactive/components/pi-logo.d.ts.map +1 -1
  175. package/dist/modes/interactive/components/pi-logo.js +13 -1
  176. package/dist/modes/interactive/components/pi-logo.js.map +1 -1
  177. package/dist/modes/interactive/components/radius-login-selector.d.ts +15 -0
  178. package/dist/modes/interactive/components/radius-login-selector.d.ts.map +1 -0
  179. package/dist/modes/interactive/components/radius-login-selector.js +85 -0
  180. package/dist/modes/interactive/components/radius-login-selector.js.map +1 -0
  181. package/dist/modes/interactive/components/settings-selector.d.ts +3 -3
  182. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  183. package/dist/modes/interactive/components/settings-selector.js +5 -5
  184. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  185. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  186. package/dist/modes/interactive/components/user-message.js +5 -4
  187. package/dist/modes/interactive/components/user-message.js.map +1 -1
  188. package/dist/modes/interactive/components/visual-truncate.d.ts +27 -3
  189. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
  190. package/dist/modes/interactive/components/visual-truncate.js +39 -6
  191. package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
  192. package/dist/modes/interactive/interactive-mode.d.ts +10 -0
  193. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  194. package/dist/modes/interactive/interactive-mode.js +153 -40
  195. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  196. package/dist/modes/interactive/theme/system-theme.d.ts +2 -1
  197. package/dist/modes/interactive/theme/system-theme.d.ts.map +1 -1
  198. package/dist/modes/interactive/theme/system-theme.js +16 -5
  199. package/dist/modes/interactive/theme/system-theme.js.map +1 -1
  200. package/docs/cli.md +8 -18
  201. package/docs/codemode.md +207 -0
  202. package/docs/docs.json +5 -1
  203. package/docs/environment-variables.md +2 -2
  204. package/docs/extensions.md +3 -3
  205. package/docs/index.md +1 -1
  206. package/docs/mcp.md +142 -82
  207. package/docs/models.md +22 -1
  208. package/docs/providers.md +18 -6
  209. package/docs/sdk.md +2 -2
  210. package/docs/settings.md +5 -3
  211. package/docs/usage.md +1 -1
  212. package/examples/extensions/built-in-tool-renderer.ts +16 -40
  213. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  214. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  215. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  216. package/examples/extensions/gondolin/package-lock.json +2 -2
  217. package/examples/extensions/gondolin/package.json +1 -1
  218. package/examples/extensions/minimal-mode.ts +24 -96
  219. package/examples/extensions/sandbox/package-lock.json +2 -2
  220. package/examples/extensions/sandbox/package.json +1 -1
  221. package/examples/extensions/with-deps/package-lock.json +2 -2
  222. package/examples/extensions/with-deps/package.json +1 -1
  223. package/examples/sdk/14-codemode-mcp.ts +2 -2
  224. package/package.json +10 -10
  225. package/dist/bundle/chunks/anthropic-messages-A6EXUBG6.js +0 -6
  226. package/dist/bundle/chunks/chunk-HSPCVFST.js +0 -2
  227. package/dist/bundle/chunks/chunk-KYJKN5BJ.js +0 -2
  228. package/dist/bundle/chunks/chunk-RO6I2QFQ.js +0 -4
  229. package/dist/bundle/chunks/chunk-WVKBMRQX.js +0 -82
  230. package/dist/bundle/chunks/chunk-XNGRGP62.js +0 -2
  231. package/dist/bundle/chunks/execute-AVGAUHMT.js +0 -308
  232. package/dist/bundle/chunks/runtime-6ZC4MGWD.js +0 -2
  233. package/dist/bundle/chunks/virtual-modules-H7OCXN6W.js +0 -2
@@ -1,6 +1,7 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { setTimeout as sleep } from "node:timers/promises";
3
- import { EventStream, parseStreamingJson, } from "@earendil-works/pi-ai";
3
+ import { EventStream, getModelType, parseStreamingJson, } from "@earendil-works/pi-ai";
4
+ import { raceWithAbortSignal } from "../utils/abort.js";
4
5
  import { buildPiServerTreePrefixHashes, hashPiServerSessionEntries, hashPiServerStaticContext, } from "./pi-server-protocol.js";
5
6
  import { ChunkRequest } from "./pi-server-request.js";
6
7
  class PiServerEventStream extends EventStream {
@@ -294,10 +295,6 @@ function getServerSentEventFieldValue(line, field) {
294
295
  const value = line.slice(prefix.length);
295
296
  return value.startsWith(" ") ? value.slice(1) : value;
296
297
  }
297
- function parseServerSentEvents(bodyText) {
298
- const parser = new ServerSentEventParser();
299
- return [...parser.feed(bodyText), ...parser.finish()];
300
- }
301
298
  function parseServerSentEventData(event, errorPrefix) {
302
299
  try {
303
300
  return JSON.parse(event.data);
@@ -310,17 +307,44 @@ function formatServerSentEventError(response, payload) {
310
307
  const message = isObject(payload) && typeof payload.error === "string" ? payload.error : JSON.stringify(payload);
311
308
  return `${getResponseStatus(response)}; content-type: ${getResponseContentType(response)}; body excerpt: ${getBodyExcerpt(message)}`;
312
309
  }
313
- async function readPiServerEventStreamJson(response, errorPrefix) {
314
- const bodyText = await response.text();
315
- for (const event of parseServerSentEvents(bodyText)) {
316
- if (event.event === "error") {
317
- throw new Error(`${errorPrefix} (${formatServerSentEventError(response, parseServerSentEventData(event, errorPrefix))})`);
310
+ async function readPiServerEventStreamJson(response, errorPrefix, onCallback) {
311
+ if (!response.body)
312
+ throw new Error(`${errorPrefix} (missing event stream body)`);
313
+ const reader = response.body.getReader();
314
+ const decoder = new TextDecoder();
315
+ const parser = new ServerSentEventParser();
316
+ const processEvents = async (events) => {
317
+ for (const event of events) {
318
+ if (event.event === "provider_callback") {
319
+ if (!onCallback)
320
+ throw new Error(`${errorPrefix} (unexpected provider callback)`);
321
+ await onCallback(parseServerSentEventData(event, errorPrefix));
322
+ }
323
+ else if (event.event === "error") {
324
+ throw new Error(`${errorPrefix} (${formatServerSentEventError(response, parseServerSentEventData(event, errorPrefix))})`);
325
+ }
326
+ else if (event.event === "result") {
327
+ return { value: parseServerSentEventData(event, errorPrefix) };
328
+ }
318
329
  }
319
- if (event.event === "result") {
320
- return parseServerSentEventData(event, errorPrefix);
330
+ return undefined;
331
+ };
332
+ try {
333
+ for (;;) {
334
+ const chunk = await reader.read();
335
+ const result = await processEvents(chunk.done
336
+ ? [...parser.feed(decoder.decode()), ...parser.finish()]
337
+ : parser.feed(decoder.decode(chunk.value, { stream: true })));
338
+ if (result)
339
+ return result.value;
340
+ if (chunk.done)
341
+ break;
321
342
  }
343
+ throw new Error(`${errorPrefix} (expected result event)`);
344
+ }
345
+ finally {
346
+ await reader.cancel().catch(() => { });
322
347
  }
323
- throw new Error(`${errorPrefix} (${formatResponseDetails(response, bodyText)}; expected result event)`);
324
348
  }
325
349
  async function readPiServerCompactResponse(response, errorPrefix) {
326
350
  const contentType = getResponseContentType(response).toLowerCase().split(";")[0]?.trim();
@@ -607,6 +631,10 @@ function serializeOptions(options) {
607
631
  return {
608
632
  temperature: options?.temperature,
609
633
  maxTokens: options?.maxTokens,
634
+ samplingParams: options?.samplingParams,
635
+ toolChoice: options?.toolChoice,
636
+ deferred: options?.deferred,
637
+ env: options?.env,
610
638
  reasoning: options?.reasoning,
611
639
  cacheRetention: options?.cacheRetention,
612
640
  sessionId: options?.sessionId,
@@ -621,6 +649,35 @@ function serializeOptions(options) {
621
649
  maxRetryDelayMs: options?.maxRetryDelayMs,
622
650
  };
623
651
  }
652
+ export function streamRawPiServer(model, context, options) {
653
+ if (options?.transformPreparedStreamOptions) {
654
+ throw new Error("Prepared stream option transforms cannot execute on pi-server");
655
+ }
656
+ return streamPiServer(model, context, {
657
+ signal: options?.signal,
658
+ sessionId: options?.sessionId,
659
+ onProviderStreamEvent: options?.onProviderStreamEvent,
660
+ onPayload: options?.onPayload,
661
+ onResponse: options?.onResponse,
662
+ fetch: options?.fetch,
663
+ requestKind: "api",
664
+ apiOptions: options ?? {},
665
+ });
666
+ }
667
+ export function fetchDeferredPiServer(model, handle, options) {
668
+ return streamPiServer(model, { messages: [] }, {
669
+ ...options,
670
+ requestKind: "deferred",
671
+ deferredHandle: handle,
672
+ apiOptions: options,
673
+ });
674
+ }
675
+ export async function cancelDeferredPiServer(model, handle, options) {
676
+ assertNoCustomPiServerFetch(options);
677
+ const result = await postPiServerModelOperation("/api/cancel-deferred", { model, handle, options: serializeApiOptions(options ?? {}) }, model, options);
678
+ if (result.cancelled !== true || result.stopReason !== "stop")
679
+ throw new Error("pi-server deferred cancellation did not complete");
680
+ }
624
681
  export async function compactPiServer(model, context, options) {
625
682
  const sessionId = options?.sessionId ?? "default";
626
683
  const runId = randomUUID();
@@ -712,6 +769,8 @@ export async function compactPiServer(model, context, options) {
712
769
  }
713
770
  }
714
771
  export async function streamPiServer(model, context, options) {
772
+ assertNoCustomPiServerFetch(options);
773
+ assertNoCustomPiServerFetch(options?.apiOptions);
715
774
  const sessionId = options?.sessionId ?? randomUUID();
716
775
  const runId = randomUUID();
717
776
  const isEphemeralSession = options?.sessionId === undefined;
@@ -737,6 +796,28 @@ export async function streamPiServer(model, context, options) {
737
796
  (async () => {
738
797
  let phase = "session_init";
739
798
  let streamOpened = false;
799
+ let observerFailed = false;
800
+ let callbackFailed = false;
801
+ let cacheRetention;
802
+ const requireCacheRetention = options?.requireCacheRetention || options?.onCacheRetentionResolved !== undefined;
803
+ const applyCachePolicy = async (retention) => {
804
+ try {
805
+ if (retention !== "none" && retention !== "short" && retention !== "long") {
806
+ throw new Error("pi-server cache policy has an invalid cacheRetention");
807
+ }
808
+ if (cacheRetention !== undefined) {
809
+ if (cacheRetention !== retention)
810
+ throw new Error("pi-server cache policy changed during the same run");
811
+ return;
812
+ }
813
+ cacheRetention = retention;
814
+ await raceWithAbortSignal(Promise.resolve().then(() => options?.onCacheRetentionResolved?.(retention)), options?.signal);
815
+ }
816
+ catch (error) {
817
+ observerFailed = true;
818
+ throw error;
819
+ }
820
+ };
740
821
  try {
741
822
  const request = createPiServerRequest(options?.signal);
742
823
  await ensureSessionInit(sessionId, context, request);
@@ -744,7 +825,13 @@ export async function streamPiServer(model, context, options) {
744
825
  sessionId,
745
826
  runId,
746
827
  model,
747
- options: serializeOptions(options),
828
+ options: options?.requestKind === "api" || options?.requestKind === "deferred"
829
+ ? serializeApiOptions(options.apiOptions ?? {})
830
+ : serializeOptions(options),
831
+ requestKind: options?.requestKind,
832
+ deferredHandle: options?.deferredHandle,
833
+ observeProviderStreamEvents: options?.onProviderStreamEvent !== undefined,
834
+ callbacks: { onPayload: options?.onPayload !== undefined, onResponse: options?.onResponse !== undefined },
748
835
  contextOverlay: options?.contextOverlay ?? [
749
836
  ...context.messages,
750
837
  ...(options?.ephemeralMessages ?? []),
@@ -775,9 +862,44 @@ export async function streamPiServer(model, context, options) {
775
862
  const decoder = new TextDecoder();
776
863
  const parser = new ServerSentEventParser();
777
864
  let terminalReceived = false;
778
- const consumeEvents = (events) => {
865
+ const consumeEvents = async (events) => {
779
866
  for (const serverEvent of events) {
867
+ if (serverEvent.event === "cache_policy") {
868
+ try {
869
+ const policy = parseServerSentEventData(serverEvent, "pi-server cache policy");
870
+ await applyCachePolicy(isObject(policy) ? policy.cacheRetention : undefined);
871
+ }
872
+ catch (error) {
873
+ observerFailed = true;
874
+ throw error;
875
+ }
876
+ continue;
877
+ }
878
+ if (serverEvent.event === "provider_callback") {
879
+ try {
880
+ await handleProviderCallback(parseServerSentEventData(serverEvent, "pi-server callback"), model, options, sessionId, runId, request);
881
+ }
882
+ catch (error) {
883
+ callbackFailed = true;
884
+ throw error;
885
+ }
886
+ continue;
887
+ }
780
888
  const proxyEvent = parseServerSentEventData(serverEvent, "pi-server stream");
889
+ if (requireCacheRetention && cacheRetention === undefined && proxyEvent.type !== "error") {
890
+ observerFailed = true;
891
+ throw new Error("pi-server stream is missing its resolved cache policy");
892
+ }
893
+ if (proxyEvent.type === "provider_stream_event") {
894
+ try {
895
+ await options?.onProviderStreamEvent?.(proxyEvent.data, proxyEvent.model);
896
+ }
897
+ catch (error) {
898
+ observerFailed = true;
899
+ throw error;
900
+ }
901
+ continue;
902
+ }
781
903
  const event = processProxyEvent(proxyEvent, partial);
782
904
  if (!event)
783
905
  continue;
@@ -793,10 +915,10 @@ export async function streamPiServer(model, context, options) {
793
915
  if (options?.signal?.aborted) {
794
916
  throw new Error("Request aborted by user");
795
917
  }
796
- consumeEvents(parser.feed(decoder.decode(value, { stream: true })));
918
+ await consumeEvents(parser.feed(decoder.decode(value, { stream: true })));
797
919
  }
798
- consumeEvents(parser.feed(decoder.decode()));
799
- consumeEvents(parser.finish());
920
+ await consumeEvents(parser.feed(decoder.decode()));
921
+ await consumeEvents(parser.finish());
800
922
  if (options?.signal?.aborted) {
801
923
  throw new Error("Request aborted by user");
802
924
  }
@@ -814,9 +936,17 @@ export async function streamPiServer(model, context, options) {
814
936
  // failures before the stream starts (502/504/fetch failed) never opened a run
815
937
  // we can poll; attempting recovery against a down proxy reclassifies the error
816
938
  // as history_reconcile and blocks session auto-retry.
817
- if (!options?.signal?.aborted && phase === "provider_stream" && streamOpened) {
939
+ if (!options?.signal?.aborted &&
940
+ phase === "provider_stream" &&
941
+ streamOpened &&
942
+ !observerFailed &&
943
+ !callbackFailed) {
818
944
  try {
819
945
  const recoveredRun = await waitForPiServerRunCompletion(sessionId, runId, createPiServerRequest(options?.signal), options);
946
+ if (recoveredRun?.cacheRetention !== undefined ||
947
+ (requireCacheRetention && recoveredRun?.status === "completed")) {
948
+ await applyCachePolicy(recoveredRun?.cacheRetention);
949
+ }
820
950
  if (recoveredRun?.status === "completed" && recoveredRun.message) {
821
951
  switch (recoveredRun.message.stopReason) {
822
952
  case "stop":
@@ -840,6 +970,11 @@ export async function streamPiServer(model, context, options) {
840
970
  return;
841
971
  }
842
972
  if (recoveredRun?.status === "failed" && recoveredRun.errorMessage) {
973
+ if (recoveredRun.message) {
974
+ stream.push({ type: "error", reason: "error", error: recoveredRun.message });
975
+ stream.end();
976
+ return;
977
+ }
843
978
  errorMessage = recoveredRun.errorMessage;
844
979
  }
845
980
  if (recoveredRun?.status === "aborted") {
@@ -851,7 +986,9 @@ export async function streamPiServer(model, context, options) {
851
986
  errorMessage = recoveryError instanceof Error ? recoveryError.message : String(recoveryError);
852
987
  }
853
988
  }
854
- if (options?.signal?.aborted && operation && !operation.cancelConfirmed) {
989
+ if ((options?.signal?.aborted || callbackFailed || observerFailed) &&
990
+ operation &&
991
+ !operation.cancelConfirmed) {
855
992
  try {
856
993
  await cancelPiServerOperation(operation);
857
994
  }
@@ -871,7 +1008,7 @@ export async function streamPiServer(model, context, options) {
871
1008
  details: {
872
1009
  phase,
873
1010
  source: "pi-server",
874
- retryable: isRetryablePiServerFailure(phase, error),
1011
+ retryable: !callbackFailed && !observerFailed && isRetryablePiServerFailure(phase, error),
875
1012
  },
876
1013
  },
877
1014
  ];
@@ -884,7 +1021,7 @@ export async function streamPiServer(model, context, options) {
884
1021
  }
885
1022
  finally {
886
1023
  try {
887
- await finishPiServerOperation(operation, options?.signal?.aborted === true);
1024
+ await finishPiServerOperation(operation, options?.signal?.aborted === true || callbackFailed || observerFailed);
888
1025
  }
889
1026
  catch {
890
1027
  // The owning session's cancellation helper reports the failure and keeps
@@ -896,6 +1033,8 @@ export async function streamPiServer(model, context, options) {
896
1033
  }
897
1034
  function processProxyEvent(proxyEvent, partial) {
898
1035
  switch (proxyEvent.type) {
1036
+ case "provider_stream_event":
1037
+ return undefined;
899
1038
  case "start":
900
1039
  return { type: "start", partial };
901
1040
  case "text_start":
@@ -972,6 +1111,8 @@ function processProxyEvent(proxyEvent, partial) {
972
1111
  partial.deferred = proxyEvent.deferred;
973
1112
  return { type: "done", reason: proxyEvent.reason, message: partial };
974
1113
  case "error":
1114
+ if (proxyEvent.message)
1115
+ return { type: "error", reason: proxyEvent.reason, error: proxyEvent.message };
975
1116
  partial.stopReason = proxyEvent.reason;
976
1117
  partial.errorMessage = proxyEvent.errorMessage;
977
1118
  partial.usage = proxyEvent.usage;
@@ -984,4 +1125,149 @@ function processProxyEvent(proxyEvent, partial) {
984
1125
  }
985
1126
  }
986
1127
  export { getServerUrl, getAuthToken };
1128
+ function serializeApiOptions(options) {
1129
+ const { signal: _signal, fetch: _fetch, onPayload: _onPayload, onResponse: _onResponse, onProviderStreamEvent: _onProviderStreamEvent, telemetryContext: _telemetryContext, ...serialized } = options;
1130
+ return serialized;
1131
+ }
1132
+ export async function fetchPiServerModels(options) {
1133
+ const response = await createPiServerRequest(options?.signal).getJson("/api/models");
1134
+ return readPiServerJson(response, "pi-server model catalog failed");
1135
+ }
1136
+ export async function generateImagesPiServer(model, context, options) {
1137
+ assertNoCustomPiServerFetch(options);
1138
+ return postPiServerModelOperation("/api/generate-images", {
1139
+ model,
1140
+ context,
1141
+ options: {
1142
+ apiKey: options?.apiKey,
1143
+ env: options?.env,
1144
+ headers: options?.headers,
1145
+ metadata: options?.metadata,
1146
+ timeoutMs: options?.timeoutMs,
1147
+ maxRetries: options?.maxRetries,
1148
+ maxRetryDelayMs: options?.maxRetryDelayMs,
1149
+ },
1150
+ }, model, options);
1151
+ }
1152
+ export async function classifyPiServer(model, context, options) {
1153
+ assertNoCustomPiServerFetch(options);
1154
+ return postPiServerModelOperation("/api/classify", {
1155
+ model,
1156
+ context,
1157
+ options: {
1158
+ apiKey: options?.apiKey,
1159
+ env: options?.env,
1160
+ headers: options?.headers,
1161
+ temperature: options?.temperature,
1162
+ timeoutMs: options?.timeoutMs,
1163
+ maxRetries: options?.maxRetries,
1164
+ maxRetryDelayMs: options?.maxRetryDelayMs,
1165
+ },
1166
+ }, model, options);
1167
+ }
1168
+ function assertNoCustomPiServerFetch(options) {
1169
+ if (options?.fetch)
1170
+ throw new Error("Custom fetch functions cannot execute on pi-server");
1171
+ }
1172
+ async function handleProviderCallback(callback, model, options, sessionId, runId, request) {
1173
+ if (!callback ||
1174
+ typeof callback.callbackId !== "string" ||
1175
+ !callback.model ||
1176
+ callback.model.provider !== model.provider ||
1177
+ callback.model.id !== model.id ||
1178
+ callback.model.api !== model.api ||
1179
+ getModelType(callback.model) !== getModelType(model)) {
1180
+ throw new Error("pi-server provider callback has an invalid model or callback identity");
1181
+ }
1182
+ const remoteModel = callback.model;
1183
+ let result;
1184
+ let failure;
1185
+ let failed = false;
1186
+ try {
1187
+ if (callback.kind === "payload") {
1188
+ if (!options?.onPayload)
1189
+ throw new Error("Unexpected pi-server payload callback");
1190
+ const replacement = await raceWithAbortSignal(Promise.resolve().then(() => options.onPayload(callback.payload, remoteModel)), options.signal);
1191
+ result = replacement === undefined ? callback.payload : replacement;
1192
+ }
1193
+ else if (callback.kind === "response") {
1194
+ if (!options?.onResponse)
1195
+ throw new Error("Unexpected pi-server response callback");
1196
+ await raceWithAbortSignal(Promise.resolve().then(() => options.onResponse(callback.response, remoteModel)), options.signal);
1197
+ }
1198
+ else {
1199
+ throw new Error("Unknown pi-server provider callback kind");
1200
+ }
1201
+ }
1202
+ catch (error) {
1203
+ if (options?.signal?.aborted)
1204
+ throw error;
1205
+ failure = error;
1206
+ failed = true;
1207
+ }
1208
+ const response = await request.postJson("/api/provider-callback", {
1209
+ sessionId,
1210
+ runId,
1211
+ callbackId: callback.callbackId,
1212
+ result,
1213
+ error: !failed
1214
+ ? undefined
1215
+ : {
1216
+ name: failure instanceof Error ? failure.name : "Error",
1217
+ message: failure instanceof Error ? failure.message : String(failure),
1218
+ },
1219
+ });
1220
+ const reply = await readPiServerJson(response, "pi-server callback reply failed");
1221
+ if (!reply.accepted || reply.callbackId !== callback.callbackId || reply.runId !== runId) {
1222
+ throw new Error("pi-server callback reply did not acknowledge the pending callback");
1223
+ }
1224
+ if (failed)
1225
+ throw failure;
1226
+ }
1227
+ async function postPiServerModelOperation(endpoint, body, model, options) {
1228
+ const signal = options?.signal;
1229
+ const sessionId = randomUUID();
1230
+ const runId = randomUUID();
1231
+ const operation = registerPiServerOperation(sessionId, sessionId, runId, signal);
1232
+ const request = createPiServerRequest(signal);
1233
+ let callbackFailed = false;
1234
+ try {
1235
+ const response = await request.postJson(endpoint, {
1236
+ ...body,
1237
+ sessionId,
1238
+ runId,
1239
+ callbacks: { onPayload: options?.onPayload !== undefined, onResponse: options?.onResponse !== undefined },
1240
+ });
1241
+ if (!response.ok)
1242
+ return await readPiServerJson(response, "pi-server model operation failed");
1243
+ await ensurePiServerEventStream(response);
1244
+ try {
1245
+ return await readPiServerEventStreamJson(response, "pi-server model operation failed", async (callback) => {
1246
+ try {
1247
+ await handleProviderCallback(callback, model, options, sessionId, runId, request);
1248
+ }
1249
+ catch (error) {
1250
+ callbackFailed = true;
1251
+ throw error;
1252
+ }
1253
+ });
1254
+ }
1255
+ catch (error) {
1256
+ if (signal?.aborted || callbackFailed)
1257
+ throw error;
1258
+ const recovered = await waitForPiServerRunCompletion(sessionId, runId, request, { signal });
1259
+ if (recovered?.operationResult)
1260
+ return recovered.operationResult;
1261
+ throw error;
1262
+ }
1263
+ }
1264
+ catch (error) {
1265
+ if ((signal?.aborted || callbackFailed) && operation && !operation.cancelConfirmed)
1266
+ await cancelPiServerOperation(operation);
1267
+ throw error;
1268
+ }
1269
+ finally {
1270
+ await finishPiServerOperation(operation, signal?.aborted === true || callbackFailed);
1271
+ }
1272
+ }
987
1273
  //# sourceMappingURL=pi-server-client.js.map