@code-yeongyu/senpi 2026.10.11 → 2026.10.12

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 (188) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/dist/bundle/chunks/anthropic-messages-GYG6YZY5.js +10 -0
  3. package/dist/bundle/chunks/{app-server-command-NHDOL4HQ.js → app-server-command-OL6PPUOA.js} +1 -1
  4. package/dist/bundle/chunks/{azure-openai-responses-EJF2XJ7Q.js → azure-openai-responses-GU6FOSJR.js} +1 -1
  5. package/dist/bundle/chunks/{chunk-ZABLYCHT.js → chunk-46JEQXD7.js} +1 -1
  6. package/dist/bundle/chunks/{chunk-VE3D74HN.js → chunk-55VKYA5V.js} +1 -1
  7. package/dist/bundle/chunks/{chunk-7UNN3YHW.js → chunk-5AVFHHDF.js} +230 -221
  8. package/dist/bundle/chunks/{chunk-2JE2DOIF.js → chunk-5DPTM5E2.js} +1 -1
  9. package/dist/bundle/chunks/chunk-5UPUSGP5.js +2 -0
  10. package/dist/bundle/chunks/chunk-5VMRMY6N.js +16 -0
  11. package/dist/bundle/chunks/{chunk-7X3VRAM3.js → chunk-7P3QPVTF.js} +1 -1
  12. package/dist/bundle/chunks/{chunk-T6IYKWIH.js → chunk-BUGZZVQW.js} +1 -1
  13. package/dist/bundle/chunks/chunk-DL7EFVT2.js +12 -0
  14. package/dist/bundle/chunks/chunk-E5YUVGLQ.js +11 -0
  15. package/dist/bundle/chunks/{chunk-RLFQICEY.js → chunk-EQJY2B5F.js} +1 -1
  16. package/dist/bundle/chunks/{chunk-VYKBN4MR.js → chunk-GC2RU5TS.js} +1 -1
  17. package/dist/bundle/chunks/chunk-GPKEJOTQ.js +202 -0
  18. package/dist/bundle/chunks/{chunk-KCVSSFOV.js → chunk-GQ5PWY6P.js} +4 -3
  19. package/dist/bundle/chunks/{chunk-4GPJOGXZ.js → chunk-I4AEC6MH.js} +1 -1
  20. package/dist/bundle/chunks/chunk-JXSFGRBE.js +8 -0
  21. package/dist/bundle/chunks/{chunk-YGCMN2CX.js → chunk-NAY5LB53.js} +1 -1
  22. package/dist/bundle/chunks/{chunk-EBOD66AS.js → chunk-PBN2CATL.js} +2 -2
  23. package/dist/bundle/chunks/chunk-PFNBY43W.js +2 -0
  24. package/dist/bundle/chunks/{chunk-CY2B4QRR.js → chunk-PUWEQK2W.js} +1 -1
  25. package/dist/bundle/chunks/{chunk-5DBPUQSX.js → chunk-SF6AUNQZ.js} +1 -1
  26. package/dist/bundle/chunks/{chunk-G2XAU4BX.js → chunk-TMTT5CLA.js} +1 -1
  27. package/dist/bundle/chunks/{chunk-2JKDZXIY.js → chunk-VWFKLW73.js} +2 -2
  28. package/dist/bundle/chunks/chunk-WZMSBRTW.js +2 -0
  29. package/dist/bundle/chunks/{chunk-55HLKZSB.js → chunk-XVJRRLGN.js} +1 -1
  30. package/dist/bundle/chunks/chunk-Z2PWWBBD.js +31 -0
  31. package/dist/bundle/chunks/cli-main-RSIYAR4J.js +3 -0
  32. package/dist/bundle/chunks/{cloudflare-workers-ai-system-one-SWVU2AXJ.js → cloudflare-workers-ai-system-one-LVWRKOUD.js} +1 -1
  33. package/dist/bundle/chunks/{google-generative-ai-XG4YX6FQ.js → google-generative-ai-JMGYPTXL.js} +1 -1
  34. package/dist/bundle/chunks/{google-vertex-BBOZ6OUB.js → google-vertex-CI4FPIU7.js} +1 -1
  35. package/dist/bundle/chunks/{help-fast-path-EZ3KEW6V.js → help-fast-path-M7KMBM6K.js} +1 -1
  36. package/dist/bundle/chunks/host-command-6UR3DSFR.js +2 -0
  37. package/dist/bundle/chunks/host-lifecycle-2BKCCK5X.js +3 -0
  38. package/dist/bundle/chunks/host-lifecycle.js +10 -7
  39. package/dist/bundle/chunks/host-session-command-A2MZHEBP.js +19 -0
  40. package/dist/bundle/chunks/interactive-mode-EJBMTJOH.js +2 -0
  41. package/dist/bundle/chunks/{list-tips-WE2YGQM6.js → list-tips-BEQAOA4N.js} +1 -1
  42. package/dist/bundle/chunks/{mistral-conversations-RB3ZBCGE.js → mistral-conversations-5OD7662T.js} +1 -1
  43. package/dist/bundle/chunks/{multi-session-host-V4CUQLV7.js → multi-session-host-YYMLHCUA.js} +4 -4
  44. package/dist/bundle/chunks/{openai-codex-responses-DBTPUXRW.js → openai-codex-responses-FN3UPAFI.js} +1 -1
  45. package/dist/bundle/chunks/{openai-completions-QAJQC4BY.js → openai-completions-KMUQ3T4M.js} +1 -1
  46. package/dist/bundle/chunks/{openai-responses-UBJWCEHG.js → openai-responses-V4Q5GVLO.js} +1 -1
  47. package/dist/bundle/chunks/{package-manager-cli-WTRDT4ZH.js → package-manager-cli-6A5ZP26E.js} +1 -1
  48. package/dist/bundle/chunks/rotation-stream-PT6LLBMJ.js +2 -0
  49. package/dist/bundle/chunks/rpc-mode-XNYJPYUM.js +2 -0
  50. package/dist/bundle/chunks/runtime-session-ZBHFMT65.js +2 -0
  51. package/dist/bundle/chunks/{schedule-command-PJVRKAKD.js → schedule-command-FYQG2MFX.js} +1 -1
  52. package/dist/bundle/chunks/session-control-endpoint-7TX4XHN4.js +3 -0
  53. package/dist/bundle/chunks/session-picker-4RNB27SM.js +2 -0
  54. package/dist/bundle/chunks/session-worker.js +418 -412
  55. package/dist/bundle/chunks/{typesafe-system-one-B5TW3FHM.js → typesafe-system-one-WUHW7HR4.js} +1 -1
  56. package/dist/bundle/cli.js +1 -1
  57. package/dist/bundle/index.js +1 -1
  58. package/dist/bundle/rpc-entry.js +1 -1
  59. package/dist/bundle/runtime-manifest.json +1 -1
  60. package/dist/core/agent-session.d.ts +11 -2
  61. package/dist/core/agent-session.js +152 -43
  62. package/dist/core/compaction/compaction.js +2 -0
  63. package/dist/core/extensions/builtin/anthropic-web-search/index.js +22 -14
  64. package/dist/core/extensions/builtin/cache-keepalive/index.js +8 -4
  65. package/dist/core/extensions/builtin/cache-keepalive/session-prewarm.d.ts +2 -1
  66. package/dist/core/extensions/builtin/cache-keepalive/session-prewarm.js +55 -7
  67. package/dist/core/extensions/builtin/cache-keepalive/startup-activity-gate.d.ts +8 -0
  68. package/dist/core/extensions/builtin/cache-keepalive/startup-activity-gate.js +25 -0
  69. package/dist/core/extensions/builtin/compaction/index.js +13 -5
  70. package/dist/core/extensions/builtin/compaction/speculative.d.ts +1 -0
  71. package/dist/core/extensions/builtin/compaction/speculative.js +8 -4
  72. package/dist/core/extensions/builtin/moved-path-guard/tool-classes.js +1 -0
  73. package/dist/core/extensions/builtin/openai-web-search/index.d.ts +4 -1
  74. package/dist/core/extensions/builtin/openai-web-search/index.js +54 -17
  75. package/dist/core/extensions/builtin/server-search-fallback.d.ts +12 -0
  76. package/dist/core/extensions/builtin/server-search-fallback.js +50 -0
  77. package/dist/core/extensions/builtin/terminal/runtime-session.d.ts +10 -1
  78. package/dist/core/extensions/builtin/terminal/runtime-session.js +48 -4
  79. package/dist/core/extensions/builtin/websearch/index.d.ts +1 -1
  80. package/dist/core/extensions/builtin/websearch/index.js +119 -18
  81. package/dist/core/extensions/builtin/websearch/server-search.d.ts +11 -0
  82. package/dist/core/extensions/builtin/websearch/server-search.js +230 -0
  83. package/dist/core/extensions/builtin/websearch/websearch/native.d.ts +2 -0
  84. package/dist/core/extensions/builtin/websearch/websearch/search-model.js +15 -0
  85. package/dist/core/extensions/runner.d.ts +8 -1
  86. package/dist/core/extensions/runner.js +56 -7
  87. package/dist/core/extensions/types.d.ts +12 -2
  88. package/dist/core/extensions/user-activity.d.ts +10 -0
  89. package/dist/core/extensions/user-activity.js +20 -0
  90. package/dist/core/model-config-schema.d.ts +34 -0
  91. package/dist/core/model-config-schema.js +2 -0
  92. package/dist/core/model-config.js +1 -0
  93. package/dist/core/reserved-keywords.d.ts +28 -0
  94. package/dist/core/reserved-keywords.js +81 -0
  95. package/dist/core/retry-fallback/candidates.d.ts +1 -1
  96. package/dist/core/retry-fallback/candidates.js +1 -12
  97. package/dist/core/retry-fallback/controller.d.ts +3 -1
  98. package/dist/core/retry-fallback/controller.js +11 -5
  99. package/dist/core/retry-fallback/cooldown.d.ts +2 -1
  100. package/dist/core/retry-fallback/cooldown.js +21 -12
  101. package/dist/core/retry-fallback/unusable.d.ts +2 -0
  102. package/dist/core/retry-fallback/unusable.js +14 -2
  103. package/dist/core/retry-fallback/usage-limit.d.ts +10 -1
  104. package/dist/core/retry-fallback/usage-limit.js +39 -2
  105. package/dist/core/session-title-generator.js +2 -0
  106. package/dist/index.d.ts +2 -1
  107. package/dist/index.js +1 -0
  108. package/dist/modes/index.d.ts +1 -1
  109. package/dist/modes/interactive/components/assistant-render-descriptors.js +7 -1
  110. package/dist/modes/interactive/composer-user-activity.d.ts +6 -0
  111. package/dist/modes/interactive/composer-user-activity.js +30 -0
  112. package/dist/modes/interactive/grok/chrome.js +2 -1
  113. package/dist/modes/interactive/interactive-mode.js +15 -6
  114. package/dist/modes/interactive/session-control-registry.js +8 -1
  115. package/dist/modes/interactive/theme/reserved-keyword-rainbow.d.ts +11 -0
  116. package/dist/modes/interactive/theme/reserved-keyword-rainbow.js +50 -0
  117. package/dist/modes/interactive/theme/theme.d.ts +3 -1
  118. package/dist/modes/interactive/theme/theme.js +9 -0
  119. package/dist/modes/print-mode.js +7 -2
  120. package/dist/modes/rpc/connection-handler.js +43 -11
  121. package/dist/modes/rpc/custom-capability.d.ts +2 -0
  122. package/dist/modes/rpc/custom-capability.js +2 -0
  123. package/dist/modes/rpc/host-admission-proxy.d.ts +9 -0
  124. package/dist/modes/rpc/host-admission-proxy.js +211 -0
  125. package/dist/modes/rpc/host-admission.d.ts +21 -0
  126. package/dist/modes/rpc/host-admission.js +59 -0
  127. package/dist/modes/rpc/host-capabilities.js +2 -1
  128. package/dist/modes/rpc/host-client-occupancy.d.ts +2 -1
  129. package/dist/modes/rpc/host-client-occupancy.js +7 -0
  130. package/dist/modes/rpc/host-decision.d.ts +2 -2
  131. package/dist/modes/rpc/host-decision.js +4 -0
  132. package/dist/modes/rpc/host-ensure-types.d.ts +2 -0
  133. package/dist/modes/rpc/host-ensure.js +31 -3
  134. package/dist/modes/rpc/host-lifecycle-drain.d.ts +2 -1
  135. package/dist/modes/rpc/host-lifecycle-drain.js +3 -1
  136. package/dist/modes/rpc/host-lifecycle-proxy.d.ts +3 -2
  137. package/dist/modes/rpc/host-lifecycle-proxy.js +10 -19
  138. package/dist/modes/rpc/host-lifecycle-shutdown.d.ts +2 -0
  139. package/dist/modes/rpc/host-lifecycle-shutdown.js +3 -1
  140. package/dist/modes/rpc/host-lifecycle-ticker.d.ts +11 -0
  141. package/dist/modes/rpc/host-lifecycle-ticker.js +27 -0
  142. package/dist/modes/rpc/host-lifecycle.js +15 -23
  143. package/dist/modes/rpc/host-outcome.js +1 -0
  144. package/dist/modes/rpc/host-protocol-info.d.ts +2 -0
  145. package/dist/modes/rpc/host-protocol-info.js +1 -0
  146. package/dist/modes/rpc/host-session-runner.js +22 -1
  147. package/dist/modes/rpc/host-status-all.js +1 -0
  148. package/dist/modes/rpc/host-status.d.ts +1 -0
  149. package/dist/modes/rpc/host-status.js +5 -1
  150. package/dist/modes/rpc/rpc-client.d.ts +7 -1
  151. package/dist/modes/rpc/rpc-client.js +12 -0
  152. package/dist/modes/rpc/rpc-types.d.ts +49 -1
  153. package/dist/modes/rpc/rpc-types.js +5 -0
  154. package/dist/modes/rpc/session-command-activity.js +2 -0
  155. package/dist/modes/rpc/session-held.js +3 -0
  156. package/docs/extensions.md +13 -1
  157. package/docs/providers.md +88 -0
  158. package/docs/rpc.md +150 -5
  159. package/docs/web-search.md +3 -1
  160. package/package.json +7 -7
  161. package/dist/bundle/chunks/anthropic-messages-5QQJVQPZ.js +0 -9
  162. package/dist/bundle/chunks/chunk-2A3MS2Z7.js +0 -8
  163. package/dist/bundle/chunks/chunk-6SBY4ZWC.js +0 -2
  164. package/dist/bundle/chunks/chunk-6WCOSBI7.js +0 -2
  165. package/dist/bundle/chunks/chunk-E75RO54O.js +0 -14
  166. package/dist/bundle/chunks/chunk-JMYO34RK.js +0 -2
  167. package/dist/bundle/chunks/chunk-KRNXUTZJ.js +0 -2
  168. package/dist/bundle/chunks/chunk-L4HVJWIF.js +0 -11
  169. package/dist/bundle/chunks/chunk-N5WLLHUE.js +0 -2
  170. package/dist/bundle/chunks/chunk-NEFNNQSV.js +0 -9
  171. package/dist/bundle/chunks/chunk-PWIYVLIA.js +0 -9
  172. package/dist/bundle/chunks/chunk-Q3R44CGT.js +0 -5
  173. package/dist/bundle/chunks/chunk-QIARZN7G.js +0 -31
  174. package/dist/bundle/chunks/chunk-QKU6JOA4.js +0 -2
  175. package/dist/bundle/chunks/chunk-QYWXDE47.js +0 -2
  176. package/dist/bundle/chunks/chunk-XHELSLN3.js +0 -188
  177. package/dist/bundle/chunks/chunk-YDJ4HGWO.js +0 -16
  178. package/dist/bundle/chunks/chunk-ZJHRDQCH.js +0 -2
  179. package/dist/bundle/chunks/cli-main-TUBNBZNK.js +0 -3
  180. package/dist/bundle/chunks/host-command-WO7VKJBJ.js +0 -2
  181. package/dist/bundle/chunks/host-lifecycle-X2J5FTJL.js +0 -3
  182. package/dist/bundle/chunks/host-session-command-ICBOH5RP.js +0 -19
  183. package/dist/bundle/chunks/interactive-mode-UGDNCGQ5.js +0 -2
  184. package/dist/bundle/chunks/rotation-stream-OODURUGZ.js +0 -2
  185. package/dist/bundle/chunks/rpc-mode-22MCT32O.js +0 -2
  186. package/dist/bundle/chunks/runtime-session-I4NDNGC5.js +0 -2
  187. package/dist/bundle/chunks/session-control-endpoint-SFPRQBDO.js +0 -3
  188. package/dist/bundle/chunks/session-picker-3ZQPV7Z3.js +0 -2
package/docs/rpc.md CHANGED
@@ -13,6 +13,114 @@ RPC mode enables headless operation of the coding agent via a JSON protocol over
13
13
 
14
14
  **Note for Node.js/TypeScript users**: If you're building a Node.js application, consider using `AgentSession` directly from `@code-yeongyu/senpi` instead of spawning a subprocess. See [`src/core/agent-session.ts`](../src/core/agent-session.ts) for the API. For a subprocess-based TypeScript client, see [`src/modes/rpc/rpc-client.ts`](../src/modes/rpc/rpc-client.ts).
15
15
 
16
+ ## Eval cell control
17
+
18
+ `eval_cells.list`, `eval_cells.peek`, and `eval_cells.stop` are session-scoped
19
+ control commands, not model tools. On a shared host include the same `sessionId`
20
+ routing handle used for other session commands. They use the session's current
21
+ codemode detached-cell manager, the same one used by the eval tool's
22
+ `list`/`peek`/`stop` actions. They do not execute a tool, add model context, or
23
+ append session history. Stopping a detached cell still delivers the ordinary
24
+ `senpi-codemode:notification` completion message to the agent, exactly once.
25
+
26
+ Both classic and shared hosts advertise the host capability `eval_cells` in
27
+ the `data.capabilities` array of a `get_protocol_info` response. It indicates
28
+ protocol support, not that codemode is loaded in every session. A session without
29
+ the extension returns `errorCode: "eval_cells_unavailable"`.
30
+
31
+ On shared hosts, the three named commands bypass the foreign-session-holder
32
+ guard as explicit reads/cancellation controls. They only touch this host's
33
+ manager for the routed session, never the foreign process's cells. List and
34
+ peek are observations and do not renew an otherwise idle detached session;
35
+ stop counts as activity. Cancelling an already-admitted detached cell may
36
+ persist its ordinary completion notification, like the existing abort control.
37
+
38
+ ### eval_cells.list
39
+
40
+ ```json
41
+ {"id":"cells","type":"eval_cells.list"}
42
+ ```
43
+
44
+ ```json
45
+ {"id":"cells","type":"response","command":"eval_cells.list","success":true,"data":[{"cellId":"cell_1","language":"js","state":"detached","startedAtMs":1720000000000,"summary":"Read the input files"}]}
46
+ ```
47
+
48
+ The array contains live and recently settled cells, in the eval tool's existing
49
+ list order. `language` is `js`, `py`, `rb`, or `jl`; `state` is `queued`,
50
+ `running`, `detached`, `completed`, `failed`, or `cancelled`. `summary` is
51
+ optional, and a queued cell can include `queuedBehind: string[]`. A detached
52
+ queued cell has state `detached` and its predecessors in `queuedBehind`.
53
+ An empty or not-yet-started manager returns `[]`. Recent snapshots have the
54
+ manager's existing retention limits; a removed snapshot is no longer addressable.
55
+
56
+ ### eval_cells.peek
57
+
58
+ ```json
59
+ {"id":"tail","type":"eval_cells.peek","cellId":"cell_1","tailBytes":8192}
60
+ ```
61
+
62
+ ```json
63
+ {"id":"tail","type":"response","command":"eval_cells.peek","success":true,"data":{"cellId":"cell_1","language":"js","state":"detached","startedAtMs":1720000000000,"summary":"Read the input files","outputTail":"Read 12 files\n"}}
64
+ ```
65
+
66
+ The text-only snapshot includes the list metadata and `outputTail`, taken from
67
+ the manager's buffered output. `tailBytes` defaults to 8192, is capped at 65536,
68
+ and must be a non-negative safe integer. Zero returns an empty tail. A partial
69
+ leading UTF-8 character is dropped, so the returned text never exceeds the byte
70
+ budget. Full result bodies, source code, and inline images are not duplicated
71
+ in this control response. Available snapshots also include `stateRetained`,
72
+ `interruptNote`, `hardLimitSeconds`, and `runBudgetSeconds` when defined.
73
+
74
+ ### eval_cells.stop
75
+
76
+ ```json
77
+ {"id":"stop","type":"eval_cells.stop","cellId":"cell_1"}
78
+ ```
79
+
80
+ ```json
81
+ {"id":"stop","type":"response","command":"eval_cells.stop","success":true,"data":{"cellId":"cell_1","language":"js","state":"cancelled","startedAtMs":1720000000000,"summary":"Read the input files","outputTail":"Read 12 files\n","stateRetained":true}}
82
+ ```
83
+
84
+ The response waits for interrupt completion and confirms the terminal state,
85
+ including whether kernel state was retained. Its output tail uses the default
86
+ 8192-byte budget. If the cell ended between list and stop, the response succeeds
87
+ with its existing `completed`, `failed`, or `cancelled` snapshot: no second
88
+ interrupt or completion notification is sent.
89
+
90
+ Unknown IDs, including IDs owned only by another session, fail with
91
+ `errorCode: "eval_cell_not_found"`. A malformed `cellId` or `tailBytes` fails with
92
+ `errorCode: "invalid_eval_cell_request"`. Clients must inspect the code or the
93
+ returned `state`, not match error text.
94
+
95
+ The extension handlers are also reachable through
96
+ `extension_request {name: "eval_cells.peek", data: {cellId, tailBytes?}}`
97
+ (likewise list/stop). Those aliases preserve the same eval error codes.
98
+ Use the named commands for shared-host observation/control admission:
99
+ generic `extension_request` remains conservatively session-writing.
100
+
101
+ `RpcClient` exposes `listEvalCells()`, `peekEvalCell(cellId, tailBytes?)`, and
102
+ `stopEvalCell(cellId)` with exported `RpcEvalCell` / `RpcEvalCellSnapshot` types.
103
+ Failed commands reject with `RpcCommandError.errorCode`.
104
+
105
+ ### Eval liveness event
106
+
107
+ The existing `wake_source_state` snapshot already reaches RPC clients that
108
+ advertise the `extension_events` capability. Codemode publishes it on session
109
+ start and each detached-cell transition, including a zero-count snapshot on
110
+ settlement. It travels in the normal extension-event envelope, tagged with the
111
+ owning routing `sessionId` on a shared host:
112
+
113
+ ```json
114
+ {"type":"extension_event","name":"wake_source_state","sessionId":"session_1","data":{"source":"senpi-codemode","activeCount":1,"items":[{"id":"cell_1","description":"Read the input files","startedAtMs":1720000000000}]}}
115
+ ```
116
+
117
+ Each event is a full per-source snapshot, not a delta. Filter
118
+ `data.source === "senpi-codemode"` and replace the previous detached-cell
119
+ liveness set. `items` carry `id`, `description`, and epoch `startedAtMs`.
120
+ Use `eval_cells.list` to load initial state after attaching and peek on demand
121
+ for output; transitions need no polling. The liveness event itself adds no
122
+ model context or history.
123
+
16
124
  ## Account display names
17
125
 
18
126
  `get_provider_accounts` returns secret-free descriptors containing `name`, `source`, `blocked`, `pinned`, and optional `displayName`. Render a named account as `displayName (name)`; keep using the immutable `name` for `account_pin`, `account_remove`, and comparisons. Legacy accounts omit `displayName`.
@@ -158,6 +266,29 @@ count the host enforces.
158
266
 
159
267
  ### Host identity (`get_protocol_info`)
160
268
 
269
+ Supervised socket hosts additionally report `lifecycle: "ready" | "stopping"`.
270
+ The supervisor closes admission synchronously when shutdown or a drain begins,
271
+ including owner-expiry shutdown. It keeps answering protocol probes while waiting
272
+ for its child to exit, even if the child no longer responds. `senpi host status`
273
+ and `status --all` expose the same `lifecycle` field (`null` for an older or
274
+ unreachable host). Session counts during stopping are unobserved and represented
275
+ by the existing empty listing, not a claim that the child has already exited.
276
+
277
+ A ready probe does not reserve an open: a later `open_session` can fail with
278
+ `errorCode: "host_stopping"` and `errorData.instanceId`, including on a connection
279
+ that previously read ready. An open still pending when stopping begins receives
280
+ the same refusal rather than a late successful attachment. Existing admitted
281
+ sessions may finish a drain.
282
+
283
+ `ensureHost()` never adopts a stopping generation. Under the endpoint lock it
284
+ waits for that registered supervisor and its child to exit, without signalling
285
+ them, within the existing stop budget. `stoppingTimeoutMs` may shorten that wait;
286
+ expiry or an unprovable generation returns `HostEnsureRefusedError` with reason
287
+ `host_stopping`. A fresh ensure then performs ordinary discovery/startup.
288
+ `senpi host session open` retries a typed stopping refusal with its original
289
+ launch specification and a shared stop deadline. Socket-only `RpcClient` reports
290
+ the typed error to its caller; it cannot launch a successor without launch options.
291
+
161
292
  Every `get_protocol_info` answer - classic and multi-session alike - carries the identity of the host that
162
293
  answered it, so a client sharing one machine-wide host can tell hosts, builds and launches apart without
163
294
  parsing a version string:
@@ -592,11 +723,17 @@ which prints the bare socket path).
592
723
  attach-only even when its caller requested an upgrade: a host generation never starts its own successor.
593
724
  This is process-local state, not an environment marker, so a shell child remains free to run the explicit
594
725
  `senpi host handoff` command.
595
- - `status` prints `{ reachable, socket, pid, instanceId, generation, engineVersion, capabilities,
726
+ - `status` prints `{ reachable, lifecycle, socket, pid, instanceId, generation, engineVersion, capabilities,
596
727
  launchProfile, runtimeBuildId, handover, sessions: { total, interactive, worker, retained, foreign_attached, foreign_retained },
597
728
  zombies, rss_mb, host_rss_mb, open_fds, memory_pressure, env_keys, generations, crashes, shard, session_rows,
598
729
  claims_live, claims }` and exits 3 when nothing answers - with the same
599
- field set, so a caller parses one shape and branches on one boolean. `sessions` is what `list_sessions`
730
+ field set, so a caller parses one shape and branches on one boolean. The additive `lifecycle` field is
731
+ `"ready"` while an answering supervised host accepts opens, `"stopping"` while it shuts down or drains,
732
+ and `null` when nobody answers or the answering host does not advertise its lifecycle. An unserved
733
+ socket therefore includes both `"reachable": false` and `"lifecycle": null`; `null` is not `"ready"`.
734
+ `status --all` carries the same field and values on each endpoint row. While stopping, session listing
735
+ is not queried and its empty counts are unobserved, not proof that all sessions have finished.
736
+ Otherwise, `sessions` is what `list_sessions`
600
737
  reports under the same flag, so `worker` stays `0` without `--include-workers`; `foreign_*` is the same
601
738
  count from the point of view of a client holding none of those sessions itself. `rss_mb`, `open_fds` and
602
739
  `zombies` describe the daemon's whole process tree (supervisor, host, and every tool, kernel and server its
@@ -1227,7 +1364,8 @@ without a known replacement. This record has no request id or session handle; ol
1227
1364
  The connection closes after its last attached session parks; a connection shared with another active session
1228
1365
  stays open until that session also settles. A command racing parking on the old connection is either served
1229
1366
  or answered by that terminal record and close, never `unknown_session` for the parked handle. New opens on a
1230
- draining connection are refused with `host_draining`.
1367
+ draining supervised connection are refused with `host_stopping`; a bare (unsupervised) socket host
1368
+ still returns `host_draining`. Re-resolve the public endpoint rather than retrying the draining connection.
1231
1369
  4. The **supervisor** starts `SENPI_RPC_HANDOFF_GRACE_MS` at supersession (default **600000 ms / 10 minutes**).
1232
1370
  This is a soft grace, not an abort deadline or a delay before parking. At expiry it reports outstanding work
1233
1371
  and requests another drain pass. Sessions still mid-turn or handling requests remain alive even beyond grace;
@@ -1723,9 +1861,13 @@ capability inventory in both `in-process` and `worker` runtimes. Probe it before
1723
1861
  enabling in-place binding with an engine pin. Classic bindings do not run this guard
1724
1862
  and do not advertise it, even if a client supplies the string in its flags.
1725
1863
 
1726
- In the response `error` field, machine-matchable:
1864
+ Match `errorCode` when present; legacy responses expose machine-matchable
1865
+ codes or code prefixes in `error`:
1727
1866
 
1728
1867
  - `unknown_session`
1868
+ - `eval_cells_unavailable` (the routed session has no eval-cell RPC handler)
1869
+ - `eval_cell_not_found` (unknown or foreign-session cell ID)
1870
+ - `invalid_eval_cell_request` (malformed eval-cell identifier or tail budget)
1729
1871
  - `session_closing` (an entry whose owner is tearing down). A worker that FAILS while its session is being opened is not that case and reports `open_failed` carrying the worker's own reason, so the code a client matches on always names what actually happened.
1730
1872
  - `session_held` (`open_session`, including attach, or any session-writing RPC whose JSONL has a live holder outside this daemon family). The refusal has `errorCode: "session_held"` and exactly `errorData { holders: [{ pid, cwd? }] }`; no boot or process-start metadata is exposed. A single dispatch guard covers prompt/steer/follow-up, continuation/custom messages/wake/compaction, model/thinking changes, bash/results, edits/name/labels, appends and tree/session changes; only explicit read/control commands bypass it. The host queries `liveSessionHolders` afresh, resolves moved paths, ignores stale/dead/reused-pid records, and excludes its own PID and worker threads. Live generation identities registered to the same endpoint are also excluded, preserving the daemon's `session_path_in_use` retry/reclaim protocol. Open is checked again after runtime holder publication, before attachment or success, with rollback on refusal. Retry after the other process exits; no restart is needed. An interactive CLI opening or resuming a held session warns with pid/cwd; lookup filesystem errors warn and continue.
1731
1873
  - **Mid-turn policy:** a turn admitted before the foreign holder appeared finishes and persists its results; subsequent writing RPCs are refused. Read/control requests, including abort, queue clearing, `extension_ui_response` and `extension_ui_progress`, remain available.
@@ -1735,7 +1877,8 @@ In the response `error` field, machine-matchable:
1735
1877
  - `session_reservation_limit` (this worker already holds 64 live session paths; the open or session replacement was refused without disturbing the existing session)
1736
1878
  - `missing_session_id` (session-scoped command without `sessionId` in multi mode)
1737
1879
  - `multi_session_disabled` (`open_session` in classic mode)
1738
- - `host_draining` (`open_session` or `release_session` on a connection whose generation is parking for a handoff; the successor already owns the public path, so re-resolve it and open or release there rather than retrying this connection)
1880
+ - `host_stopping` (`open_session` refused by a supervised host that is shutting down or draining, including opens previously answered with `host_draining`; `errorData.instanceId` identifies the stopping generation. Re-resolve the public endpoint; a launch-owning caller may wait for this generation's exit within the stop budget and start a successor.)
1881
+ - `host_draining` (`open_session` on a bare, unsupervised host, or `release_session` forwarded to a child whose generation is parking for a handoff; re-resolve the public path and open or release on the successor rather than retrying this connection)
1739
1882
  - `turn_active` (`release_session` while a turn runs or is about to start - a prompt in preflight, an admitted delivery not yet written - without `interrupt: true`; `errorData { attachments, busy }`)
1740
1883
  - `session_busy` (`release_session` while other session work runs - bash, compaction, barrier-held work, another request for the session - without `interrupt: true`; `errorData { attachments, busy }`)
1741
1884
  - `attached` (`release_session` while clients are attached, without `force: true`; `errorData { attachments }` names how many)
@@ -2072,6 +2215,8 @@ The `model` field is a full [Model](#model) object or `null`. `pendingModelSwitc
2072
2215
 
2073
2216
  #### get_messages
2074
2217
 
2218
+ Account-scoped usage failures are projected as recovery advice with `errorCause: {"type":"usage_limit","scope":"account"}` in `message_*`, `agent_end`, `entry_appended`, `get_messages`, `get_entries`, and `get_tree`. The engine message and session file retain the original provider error for diagnostics; these raw stored messages are not the user-facing RPC representation. Entry ids, parent links, timestamps, tree labels, and provider diagnostics are preserved by the projection.
2219
+
2075
2220
  Get all messages in the conversation.
2076
2221
 
2077
2222
  ```json
@@ -139,7 +139,9 @@ With `auto` on (the default), the model you are chatting with still searches thr
139
139
 
140
140
  ## Native (hosted) search
141
141
 
142
- When `auto` is `true` (the default), senpi puts a native entry in front of your configured providers, or in front of the free chain when there is no config file. That entry calls the hosted web search of the session's own provider (Anthropic Messages or OpenAI Responses compatible endpoints, the ChatGPT subscription, xAI, DeepSeek, Perplexity, Z.AI, Kimi Code) with the session's own credential. Google Search grounding is never added this way; it is opt-in (see below). Sessions on the first-party Anthropic and OpenAI APIs instead get the provider's server-side search tool in the main request, and `web_search` stays out of the way there.
142
+ When `auto` is `true` (the default), senpi puts a native entry in front of your configured providers, or in front of the free chain when there is no config file. That entry calls the hosted web search of the session's own provider with the session's own credential. Main-request server search takes precedence on enabled routes: direct Anthropic/Claude OAuth and OpenAI/Azure remain default-on, unchanged from main; the live-verified ChatGPT subscription is default-on (except Spark). Compatible gateways including ccapi and z.ai's GLM coding-plan Anthropic endpoint, plus xAI, Gemini 2/3, OpenRouter, Moonshot PAYG and Z.AI PAYG require explicit route compatibility opt-in. See [In-Turn Web Search](providers.md#in-turn-web-search) for exact flags and verification status. Standalone summaries, titles and default projections exclude only server tools. Cache-friendly compaction preserves the original main-turn hook and tools/include prefix.
143
+
144
+ A search-specific failure is remembered for the session/model, so later prompts do not repeat a rejected native request. A new session clears that failure. On an enabled server-search route, a different `nativeModel` setting is ignored: both main-request search and its standalone fallback retain the session model. The cheaper auxiliary-model setting below applies only to routes without an enabled server tool.
143
145
 
144
146
  ### Choosing the model native search runs on
145
147
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/senpi",
3
- "version": "2026.10.11",
3
+ "version": "2026.10.12",
4
4
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "piConfig": {
@@ -54,16 +54,16 @@
54
54
  "build:binary": "npm --prefix ../tui run build && npm --prefix ../telemetry run build && npm --prefix ../ai run build && npm --prefix ../agent run build && npm --prefix ../protocol run build && npm --prefix ../client run build && npm --prefix ../pty run build && npm run build && node ../../scripts/prepare-bun-compile-assets.mjs && bun build --compile --splitting --compile-autoload-package-json --no-compile-autoload-dotenv --no-compile-autoload-bunfig --minify --keep-names ./dist/bun/cli.js ./src/modes/rpc/session-worker.ts ./src/utils/image-resize-worker.ts --outfile dist/pi && npm run copy-binary-assets",
55
55
  "copy-assets": "shx mkdir -p dist/modes/interactive/theme && shx cp src/modes/interactive/theme/*.json dist/modes/interactive/theme/ && shx mkdir -p dist/modes/interactive/assets && shx cp src/modes/interactive/assets/*.png dist/modes/interactive/assets/ && shx mkdir -p dist/core/export-html/vendor && shx cp src/core/export-html/template.html src/core/export-html/template.css src/core/export-html/template.js dist/core/export-html/ && shx cp src/core/export-html/vendor/*.js dist/core/export-html/vendor/ && shx mkdir -p dist/core/extensions/builtin/imagegen/skill && shx cp src/core/extensions/builtin/imagegen/skill/SKILL.md dist/core/extensions/builtin/imagegen/skill/",
56
56
  "copy-binary-assets": "shx mkdir -p dist && shx rm -f dist/package.json && shx cp README.md dist/ && shx cp CHANGELOG.md dist/ && shx mkdir -p dist/theme && shx cp src/modes/interactive/theme/*.json dist/theme/ && shx mkdir -p dist/assets && shx cp src/modes/interactive/assets/*.png dist/assets/ && shx mkdir -p dist/export-html/vendor && shx cp src/core/export-html/template.html src/core/export-html/template.css src/core/export-html/template.js dist/export-html/ && shx cp -r docs dist/ && shx cp -r examples dist/ && node ../../scripts/copy-codemode-sidecar.mjs dist && shx cp package.json dist/ && shx cp ../../node_modules/@silvia-odwyer/photon-node/photon_rs_bg.wasm dist/ && shx mkdir -p dist/native/darwin dist/native/win32 && shx cp -r ../../packages/tui/native/darwin/prebuilds dist/native/darwin/ && shx cp -r ../../packages/tui/native/win32/prebuilds dist/native/win32/ && shx mkdir -p dist/core/extensions/builtin/imagegen/skill && shx cp src/core/extensions/builtin/imagegen/skill/SKILL.md dist/core/extensions/builtin/imagegen/skill/ && node ../../scripts/copy-pty-native.mjs",
57
- "test": "vitest --run",
57
+ "test": "node ../../scripts/run-tests.mjs vitest --run",
58
58
  "prepublishOnly": "npm run clean && npm run build",
59
59
  "dev": "tsc -p tsconfig.build.json --watch --preserveWatchOutput",
60
60
  "qa:app-server": "node scripts/qa-app-server/run-all.mjs"
61
61
  },
62
62
  "dependencies": {
63
63
  "@earendil-works/chord": "0.99.1",
64
- "@earendil-works/pi-agent-core": "npm:@code-yeongyu/senpi-agent-core@2026.10.11",
65
- "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.10.11",
66
- "@earendil-works/pi-tui": "npm:@code-yeongyu/senpi-tui@2026.10.11",
64
+ "@earendil-works/pi-agent-core": "npm:@code-yeongyu/senpi-agent-core@2026.10.12",
65
+ "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.10.12",
66
+ "@earendil-works/pi-tui": "npm:@code-yeongyu/senpi-tui@2026.10.12",
67
67
  "@silvia-odwyer/photon-node": "0.3.4",
68
68
  "chalk": "6.0.0",
69
69
  "cross-spawn": "7.0.6",
@@ -82,8 +82,8 @@
82
82
  "yaml": "2.9.1",
83
83
  "@anthropic-ai/claude-agent-sdk": "0.3.292",
84
84
  "@anthropic-ai/sdk": "0.127.0",
85
- "@code-yeongyu/senpi-codemode": "2026.10.11",
86
- "@earendil-works/pi-pty": "npm:@code-yeongyu/senpi-pty@2026.10.11",
85
+ "@code-yeongyu/senpi-codemode": "2026.10.12",
86
+ "@earendil-works/pi-pty": "npm:@code-yeongyu/senpi-pty@2026.10.12",
87
87
  "@modelcontextprotocol/sdk": "1.32.1",
88
88
  "@mozilla/readability": "0.6.0",
89
89
  "linkedom": "0.18.13",
@@ -1,9 +0,0 @@
1
- import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{normalizeToolCallId}from"./chunk-T6IYKWIH.js";import{resolveCloudflareBaseUrl}from"./chunk-OZNCR6E6.js";import{anthropicProviderDiagnosticFromError,anthropicProviderDiagnosticFromSseData,awaitProviderTransport,formatGitHubCopilotToolLimitError,limitGitHubCopilotTools,recordGitHubCopilotToolLimit,withGitHubCopilotFailureNote}from"./chunk-ZABLYCHT.js";import{getPiUserAgent}from"./chunk-QTG7MY2X.js";import{combineAbortSignals}from"./chunk-SJ5DSOBX.js";import{ANTHROPIC_RESERVED_BODY_KEYS,adjustMaxTokensForThinking,buildBaseOptions,clampMaxTokensToContext}from"./chunk-RLFQICEY.js";import{retryProviderRequest}from"./chunk-GQ3YLXVZ.js";import{claudeCodeVersionTooOldHint,getClaudeCodeVersion,isClaudeCodeVersionTooOldError,recoverClaudeCodeVersion}from"./chunk-QXREUA5F.js";import{resolveToolNameMatch}from"./chunk-WASCMT6Y.js";import{ANTHROPIC_FEDERATION_RULE_ID_ENV,ANTHROPIC_IDENTITY_TOKEN_FILE_ENV,ANTHROPIC_ORGANIZATION_ID_ENV,ANTHROPIC_SERVICE_ACCOUNT_ID_ENV,ANTHROPIC_WORKSPACE_ID_ENV,applyServerFallbackAbort,applyServerFallbackContinuation,parseServerFallbackReceipt,parseStickyFallbackReceipt,sanitizeAnthropicToolPairs}from"./chunk-RKJNJ3GI.js";import{resolveRootObjectSchema}from"./chunk-CWLCGRUS.js";import{getAnthropicCompat,isAnthropicApiBaseUrl}from"./chunk-6WCOSBI7.js";import{sendWithForcedToolChoiceFallback}from"./chunk-YGCMN2CX.js";import{buildCopilotDynamicHeaders,hasCopilotVisionInput}from"./chunk-KRNXUTZJ.js";import{readProviderDiagnostic}from"./chunk-YOPVJDSU.js";import{registerSessionResourceCleanup}from"./chunk-WHPDEDCC.js";import{splitDeferredTools}from"./chunk-HK46JMSC.js";import{getJsonSchemaToolParameters,isVideoMimeType,resolveJsonSchemaStrictSampling,transformMessages}from"./chunk-VYKBN4MR.js";import{sanitizeSurrogates}from"./chunk-WDTJ6JKE.js";import{getProviderEnvValue}from"./chunk-5ROMKDLK.js";import{parseJsonWithRepair,parseStreamingJson}from"./chunk-3W47LTXQ.js";import{attachProviderDiagnostic}from"./chunk-45SZOLCU.js";import"./chunk-TAV6QZFM.js";import{appendRetryAfterMsMarker,extract429RetryAfterMs}from"./chunk-PELNNWGO.js";import{calculateCost,getCurrentTools,getDeclaredTools,getInitialSystemMessage,getSystemMessageText,hasToolRedefinitions,normalizeContext,renderSystemMessageUpdate,resolveTranscript}from"./chunk-L4HVJWIF.js";import{AssistantMessageEventStream,appendAssistantMessageDiagnostic}from"./chunk-DMI55M2N.js";import{headersToRecord,providerHeadersToRecord}from"./chunk-PJ34QVL5.js";import{Anthropic}from"./chunk-PUTWVHNH.js";import"./chunk-IKOFCODM.js";var MAX_MESSAGE_CHARS=500,QUOTA_WORDING_PATTERN=/exceeded_current_quota_error|insufficient\s+balance|credits?_required|quota|billing/i,IMAGE_FORMAT_PATTERN=/unsupported image format|unsupported media type for base64 image|invalid data url for image/i;function sdkErrorClassName(error){if(!(error instanceof Error))return;let name=error.constructor?.name;return typeof name=="string"&&name.length>0?name:void 0}function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function toShaped(error){return error instanceof Error?error:void 0}function numericStatus(shaped){let status=shaped?.status;return typeof status=="number"&&Number.isFinite(status)?status:void 0}function headerObject(shaped){return shaped?.headers instanceof Headers?shaped.headers:void 0}function nestedProviderCodes(body){if(!isRecord(body))return;let inner=body.error;if(!isRecord(inner))return;let codes=[];for(let key of["type","code"]){let value=inner[key];typeof value=="string"&&value.length>0&&codes.push(value)}return codes.length>0?codes:void 0}function parseLeadingJson(text){let candidate=text.slice(text.indexOf("{"),text.lastIndexOf("}")+1);if(!(!candidate.startsWith("{")||!candidate.endsWith("}")))try{return JSON.parse(candidate)}catch{return}}function quotaWording(shaped,bodyText){return[shaped?.message,bodyText].some(text=>typeof text=="string"&&QUOTA_WORDING_PATTERN.test(text))}function normalizeAnthropicRetryFailure(error,context){let message=error instanceof Error?error.message:String(error),shaped=toShaped(error),status=numericStatus(shaped),headers=headerObject(shaped),bodyText=context?.bodyText??message,kind,providerCodes;if(error instanceof Error&&error.name==="AbortError")kind="abort";else if(sdkErrorClassName(error)==="APIConnectionTimeoutError")kind="timeout";else if(sdkErrorClassName(error)==="APIConnectionError")kind="connection";else if(typeof message=="string"&&IMAGE_FORMAT_PATTERN.test(message))kind="image-format";else if(status!==void 0)kind=status===429&&quotaWording(shaped,bodyText)?"quota-exhausted":"http-status",providerCodes=nestedProviderCodes(shaped?.error);else{let parsed=parseLeadingJson(bodyText);providerCodes=nestedProviderCodes(parsed),kind=providerCodes!==void 0?"provider":"unknown"}let retryAfterMs=extract429RetryAfterMs({status,headers,bodyText}),shouldRetryHeader=headers?.get("x-should-retry"),shouldRetry=shouldRetryHeader==="true"?!0:shouldRetryHeader==="false"?!1:void 0;return{origin:"anthropic-messages",kind,message:message.slice(0,MAX_MESSAGE_CHARS),...status!==void 0?{statusCode:status}:{},...providerCodes!==void 0?{providerCodes}:{},...retryAfterMs!==void 0?{retryAfterMs}:{},...shouldRetry!==void 0?{shouldRetry}:{}}}function escapeXmlAttribute(value){return value.replaceAll("&","&amp;").replaceAll('"',"&quot;").replaceAll("'","&apos;").replaceAll("<","&lt;").replaceAll(">","&gt;")}function availableToolGuidance(availableToolNames){if(availableToolNames.length===0)return"To edit files, call only tools available in this request.";let listed=availableToolNames.slice(0,8).join(", "),omitted=availableToolNames.length-8,suffix=omitted>0?` (and ${omitted} more)`:"";return`To edit files, call your own tools: ${listed}${suffix}.`}function demotedToolCallText(name,availableToolNames,firstOccurrence){let escapedName=escapeXmlAttribute(name);return firstOccurrence?[`<unavailable-tool-call name="${escapedName}">`,"Transcript record, not an action available to you. An earlier model in this session",`called "${escapedName}"; that tool does not exist for you and its input is omitted.`,availableToolGuidance(availableToolNames),"</unavailable-tool-call>"].join(`
3
- `):`<unavailable-tool-call name="${escapedName}"/>`}function demotedToolResultText(name,content){let escapedName=escapeXmlAttribute(name),safeContent=content.replace(/<\/unavailable-tool-result/gi,match=>`&lt;${match.slice(1)}`);return`<unavailable-tool-result name="${escapedName}">${safeContent}</unavailable-tool-result>`}function isRecord2(value){return typeof value=="object"&&value!==null}function collectAvailableToolNames(tools){let defined=new Set;if(Array.isArray(tools))for(let tool of tools)isRecord2(tool)&&typeof tool.name=="string"&&defined.add(tool.name);return defined}function isNativeToolSearchResultBlock(block){return isRecord2(block)&&block.type==="tool_search_tool_result"&&typeof block.tool_use_id=="string"&&isRecord2(block.content)&&Array.isArray(block.content.tool_references)}function demoteUnavailableToolReferences(params){let messages=params.messages;if(!Array.isArray(messages)||messages.length===0)return params;let available=collectAvailableToolNames(params.tools),resolve=name=>resolveToolNameMatch(name,available),demotedCallNames=new Map,renamedCallNames=new Map;for(let message of messages)if(!(message.role!=="assistant"||!Array.isArray(message.content)))for(let block of message.content){if(!isRecord2(block)||block.type!=="tool_use"||typeof block.name!="string")continue;let resolved=resolve(block.name);resolved===void 0?demotedCallNames.set(block.id,block.name):resolved!==block.name&&renamedCallNames.set(block.id,resolved)}let changed=!1,availableToolNames=[...available],droppedSearchUseIds=new Set,droppedSearchNames=new Map;for(let message of messages)if(!(message.role!=="assistant"||!Array.isArray(message.content)))for(let block of message.content){if(!isNativeToolSearchResultBlock(block))continue;let names=block.content.tool_references.filter(item=>isRecord2(item)&&item.type==="tool_reference").map(item=>typeof item.tool_name=="string"?item.tool_name:"");names.length>0&&names.every(name=>resolve(name)===void 0)&&(droppedSearchUseIds.add(block.tool_use_id),droppedSearchNames.set(block.tool_use_id,names))}let seenDemotedCallNames=new Set,rewrittenMessages=[];for(let message of messages){if(!Array.isArray(message.content)){rewrittenMessages.push(message);continue}let messageChanged=!1,content=[];for(let block of message.content){if(message.role==="assistant"&&isRecord2(block)&&block.type==="tool_use"){let demotedName=demotedCallNames.get(block.id);if(demotedName!==void 0){messageChanged=!0;let firstOccurrence=!seenDemotedCallNames.has(demotedName);seenDemotedCallNames.add(demotedName),content.push({type:"text",text:demotedToolCallText(demotedName,availableToolNames,firstOccurrence)});continue}let renamedName=renamedCallNames.get(block.id);if(renamedName!==void 0){messageChanged=!0,content.push({...block,name:renamedName});continue}}if(message.role==="assistant"&&isRecord2(block)&&block.type==="server_tool_use"&&typeof block.id=="string"&&droppedSearchUseIds.has(block.id)){messageChanged=!0;continue}if(message.role==="assistant"&&isNativeToolSearchResultBlock(block)){let omitted=droppedSearchNames.get(block.tool_use_id);if(omitted!==void 0){messageChanged=!0,content.push({type:"text",text:`Tool reference unavailable: ${[...new Set(omitted)].join(", ")}`});continue}let rewritten=rewriteToolReferenceItems(block.content.tool_references,resolve);if(rewritten!==void 0){messageChanged=!0,content.push({...block,content:{...block.content,tool_references:rewritten.kept}});continue}}if(isRecord2(block)&&block.type==="tool_result"){let demotedName=demotedCallNames.get(block.tool_use_id);if(demotedName!==void 0){messageChanged=!0,content.push({type:"text",text:demotedToolResultText(demotedName,toolResultText(block.content))});continue}if(Array.isArray(block.content)){let rewritten=rewriteToolReferenceItems(block.content,resolve);if(rewritten!==void 0){messageChanged=!0;let nextContent=rewritten.kept.length>0?rewritten.kept:[{type:"text",text:`Tool reference unavailable: ${[...new Set(rewritten.omitted)].join(", ")}`}];content.push({...block,content:nextContent});continue}}}content.push(block)}if(messageChanged&&content.length===0){changed=!0;continue}if(messageChanged){changed=!0,rewrittenMessages.push({...message,content});continue}rewrittenMessages.push(message)}return changed?{...params,messages:rewrittenMessages}:params}function demoteToolReferenceReplay(params){let messages=params.messages;if(!Array.isArray(messages)||messages.length===0)return params;let searchUseIds=new Set;for(let message of messages)if(!(message.role!=="assistant"||!Array.isArray(message.content)))for(let block of message.content)isRecord2(block)&&block.type==="tool_search_tool_result"&&typeof block.tool_use_id=="string"&&searchUseIds.add(block.tool_use_id);let changed=!1,demotedNames=new Set,rewrittenMessages=[];for(let message of messages){if(!Array.isArray(message.content)){rewrittenMessages.push(message);continue}let messageChanged=!1,content=[];for(let block of message.content){if(message.role==="assistant"&&isRecord2(block)){if(block.type==="server_tool_use"&&typeof block.id=="string"&&searchUseIds.has(block.id)){messageChanged=!0;continue}if(block.type==="tool_search_tool_result"){messageChanged=!0;let names=isNativeToolSearchResultBlock(block)?toolReferenceNames(block.content.tool_references):[];for(let name of names)demotedNames.add(name);content.push({type:"text",text:names.length>0?`Tool search found: ${names.join(", ")}`:"Tool search found no tools."});continue}}if(isRecord2(block)&&block.type==="tool_result"&&Array.isArray(block.content)){let names=toolReferenceNames(block.content);if(names.length>0){messageChanged=!0;for(let name of names)demotedNames.add(name);let kept=block.content.filter(item=>!(isRecord2(item)&&item.type==="tool_reference"));content.push({...block,content:[...kept,{type:"text",text:`Tools loaded: ${names.join(", ")}`}]});continue}}content.push(block)}if(!messageChanged){rewrittenMessages.push(message);continue}changed=!0,content.length>0&&rewrittenMessages.push({...message,content})}return changed?{...params,messages:rewrittenMessages,...residentTools(params.tools,demotedNames)}:params}function residentTools(tools,names){if(!Array.isArray(tools)||names.size===0)return{};let changed=!1,rewritten=tools.map(tool=>{if(!isRecord2(tool)||tool.defer_loading!==!0||typeof tool.name!="string"||!names.has(tool.name))return tool;changed=!0;let{defer_loading:_deferLoading,...resident}=tool;return resident});return changed?{tools:rewritten}:{}}function toolReferenceNames(items){let names=new Set;for(let item of items)isRecord2(item)&&item.type==="tool_reference"&&typeof item.tool_name=="string"&&names.add(item.tool_name);return[...names]}function rewriteToolReferenceItems(items,resolve){let kept=[],omitted=[],rewritten=!1;for(let item of items){if(!isRecord2(item)||item.type!=="tool_reference"||typeof item.tool_name!="string"){kept.push(item);continue}let resolved=resolve(item.tool_name);if(resolved===void 0){omitted.push(item.tool_name),rewritten=!0;continue}if(resolved!==item.tool_name){kept.push({...item,tool_name:resolved}),rewritten=!0;continue}kept.push(item)}return rewritten?{kept,omitted}:void 0}function toolResultText(content){if(typeof content=="string")return content;if(Array.isArray(content)){let parts=[];for(let item of content)isRecord2(item)&&(item.type==="text"&&typeof item.text=="string"?parts.push(item.text):typeof item.type=="string"&&parts.push(`[${item.type}]`));if(parts.length>0)return parts.join(`
4
- `)}return"Tool output unavailable."}function resolveCacheRetention(cacheRetention,env,fallback="short"){return cacheRetention||(getProviderEnvValue("PI_CACHE_RETENTION",env)==="long"?"long":typeof process<"u"&&process.env.PI_CACHE_RETENTION!==void 0?"short":fallback)}function getCacheControl(model,cacheRetention,env){let retention=resolveCacheRetention(cacheRetention,env,"short");if(retention==="none")return{retention};let ttl=retention==="long"&&isAnthropicApiBaseUrl(model.baseUrl)&&getAnthropicCompat(model).supportsLongCacheRetention?"1h":void 0;return{retention,cacheControl:{type:"ephemeral",...ttl&&{ttl}}}}var claudeCodeVersion="2.1.292",claudeCodeTools=["Read","Write","Edit","Bash","Grep","Glob","AskUserQuestion","EnterPlanMode","ExitPlanMode","KillShell","NotebookEdit","Skill","Task","TaskOutput","TodoWrite","WebFetch","WebSearch"],ccToolLookup=new Map(claudeCodeTools.map(t=>[t.toLowerCase(),t])),ccToolAliases=new Map([["ask_user_question","AskUserQuestion"]]),toClaudeCodeName=name=>ccToolAliases.get(name)??ccToolLookup.get(name.toLowerCase())??name,fromClaudeCodeName=(name,tools)=>{if(tools&&tools.length>0){let alias=[...ccToolAliases].find(([,wireName])=>wireName===name);if(alias&&tools.some(tool=>tool.name===alias[0]))return alias[0];let lowerName=name.toLowerCase(),matchedTool=tools.find(tool=>tool.name.toLowerCase()===lowerName);if(matchedTool)return matchedTool.name}return name};function convertContentBlocks(content){if(!content.some(c=>c.type==="image"))return sanitizeSurrogates(content.map(c=>c.text).join(`
5
- `));let blocks=content.map(block=>block.type==="text"?{type:"text",text:sanitizeSurrogates(block.text)}:isVideoMimeType(block.mimeType)?{type:"video",source:{type:"base64",media_type:block.mimeType,data:block.data}}:{type:"image",source:{type:"base64",media_type:block.mimeType,data:block.data}});return blocks.some(b=>b.type==="text")||blocks.unshift({type:"text",text:"(see attached image)"}),blocks}var FINE_GRAINED_TOOL_STREAMING_BETA="fine-grained-tool-streaming-2025-05-14",INTERLEAVED_THINKING_BETA="interleaved-thinking-2025-05-14",COMPUTER_USE_BETA_PREFIX="computer-use-",NATIVE_COMPUTER_TOOL_TYPE="computer_20250124",ADAPTIVE_THINKING_MODEL_MARKERS=["opus-4-6","opus-4-7","opus-4-8","opus-5","sonnet-4-6","sonnet-5","haiku-5-5","fable-5","mythos-5"],NATIVE_XHIGH_EFFORT_MODEL_MARKERS=["opus-4-7","opus-4-8","opus-5","sonnet-5","haiku-5-5","fable-5","mythos-5"],DISABLED_THINKING_REJECTING_MODEL_MARKERS=["fable-5","mythos-5","opus-5-5","opus-5.5","sonnet-5-5","sonnet-5.5","haiku-5-5","haiku-5.5"],UNSUPPORTED_NATIVE_COMPUTER_TOOL_MODEL_MARKERS=["opus-4-6","opus-4.6","opus-4-7","opus-4.7","opus-4-8","opus-4.8"],SERVER_SIDE_FALLBACK_BETA="server-side-fallback-2026-07-01";function shouldUseServerSideFallbackBeta(model){return(model.compat?.allowedFallbackModels?.length??0)>0}var MID_CONVERSATION_OUTPUT_CONFIG_BETA="mid-conversation-output-config-2026-07-01",THINKING_BINDING_CONTROLS_BETA="thinking-binding-controls-2026-08-01",MID_CONVERSATION_TOOL_CHANGES_BETA="mid-conversation-tool-changes-2026-07-01",DEFERRED_TOOL_PLACEHOLDER={name:"__pi_deferred_placeholder__",description:"Reserved placeholder. Never available. Never call this.",input_schema:{type:"object",properties:{},required:[]},defer_loading:!0};function supportsMidConvoSystemMessages(model){return model.compat?.supportsMidConvoSystemMessages??!1}function supportsMidConvoToolChanges(model){return model.compat?.supportsMidConvoToolChanges??!1}var unsignedThinkingTextReplayFallbacks=new Set,toolReferenceReplayFallbacks=new Set;registerSessionResourceCleanup(sessionId=>{if(sessionId===void 0){unsignedThinkingTextReplayFallbacks.clear(),toolReferenceReplayFallbacks.clear();return}let prefix=`${sessionId}\0`;for(let fallbacks of[unsignedThinkingTextReplayFallbacks,toolReferenceReplayFallbacks])for(let key of fallbacks)key.startsWith(prefix)&&fallbacks.delete(key)});function unsignedThinkingFallbackKey(model,sessionId){return sessionId===void 0?void 0:`${sessionId}\0${model.baseUrl}\0${model.id}`}function isInvalidUnsignedThinkingSignatureError(error){return typeof error=="object"&&error!==null&&"status"in error&&error.status===400&&error instanceof Error&&/Invalid signature in thinking block/i.test(error.message)}function isToolReferenceNotFoundError(error){return error instanceof Error&&"status"in error&&error.status===400&&/Tool reference '[^']*' not found in available tools/i.test(error.message)}function mergeHeaders(...headerSources){let merged={};for(let headers of headerSources)headers&&Object.assign(merged,headers);return merged}function mergeClientHeaders(_model,...headerSources){return mergeHeaders({"User-Agent":getPiUserAgent()},...headerSources)}function hasHeader(headers,name){if(!headers)return!1;let expected=name.toLowerCase();for(let[key,value]of Object.entries(headers))if(key.toLowerCase()===expected&&value!==null&&value.trim().length>0)return!0;return!1}function hasRequestAuth(apiKey,headers){return!!apiKey||hasHeader(headers,"authorization")||hasHeader(headers,"x-api-key")||hasHeader(headers,"cf-aig-authorization")}function assertRequestAuth(provider,apiKey,headers){if(!hasRequestAuth(apiKey,headers))throw new Error(`No API key for provider: ${provider}`)}var PiAnthropic=class extends Anthropic{_shouldResolveDefaultCredentials(){return!1}};function getAnthropicFederation(model,apiKey,headers,env){if(model.provider!=="anthropic"||hasRequestAuth(apiKey,headers))return;let federationRuleId=getProviderEnvValue(ANTHROPIC_FEDERATION_RULE_ID_ENV,env),organizationId=getProviderEnvValue(ANTHROPIC_ORGANIZATION_ID_ENV,env),identityTokenFile=getProviderEnvValue(ANTHROPIC_IDENTITY_TOKEN_FILE_ENV,env);if(!(!federationRuleId||!organizationId||!identityTokenFile))return{organization_id:organizationId,workspace_id:getProviderEnvValue(ANTHROPIC_WORKSPACE_ID_ENV,env),authentication:{type:"oidc_federation",federation_rule_id:federationRuleId,service_account_id:getProviderEnvValue(ANTHROPIC_SERVICE_ACCOUNT_ID_ENV,env),identity_token:{source:"file",path:identityTokenFile}}}}var federationClient;function isRecord3(value){return typeof value=="object"&&value!==null}var REPLAYABLE_ANTHROPIC_PROVIDER_NATIVE_TYPES=new Set(["server_tool_use","web_search_tool_result","web_fetch_tool_result","code_execution_tool_result","bash_code_execution_tool_result","text_editor_code_execution_tool_result","tool_search_tool_result","container_upload"]);function isReplayableAnthropicProviderNativeBlock(raw){return isRecord3(raw)&&typeof raw.type=="string"&&REPLAYABLE_ANTHROPIC_PROVIDER_NATIVE_TYPES.has(raw.type)}function isSameAnthropicModel(message,model){return message.provider===model.provider&&message.api===model.api&&message.model===model.id}function isAnthropicFallbackMarkerBlock(block){return block.type==="providerNative"&&block.subtype==="fallback"&&isRecord3(block.raw)&&block.raw.type==="fallback"}function lastAnthropicFallbackBoundary(content){let boundary=-1;for(let index=0;index<content.length;index++)isAnthropicFallbackMarkerBlock(content[index])&&(boundary=index);return boundary}function isAnthropicServerToolUseBlock(raw){return isRecord3(raw)&&raw.type==="server_tool_use"&&typeof raw.id=="string"}function isProviderNativeToolUseBlock(raw){return isRecord3(raw)&&(raw.type==="server_tool_use"||raw.type==="mcp_tool_use")}function isAnthropicWebSearchReplayBlock(raw){return isRecord3(raw)?raw.type==="web_search_tool_result"?!0:raw.type==="server_tool_use"&&raw.name==="web_search":!1}function userMessageClosesServerTurn(message){return typeof message.content=="string"?message.content.trim().length>0:message.content.some(block=>block.type==="text"&&block.text.trim().length>0||block.type==="image")}function collectProviderNativeToolPairing(messages,model,deferredToolNames,normalizeToolName,discardedFallbackToolCallIds){let resolvedUseIds=new Set,validResultIds=new Set,pendingUseIds=new Set,loadedReferenceNames=new Set;for(let message of messages){if(message.role==="assistant"){let priorUseIds=pendingUseIds;if(pendingUseIds=new Set,!isSameAnthropicModel(message,model))continue;for(let block of message.content){if(block.type!=="providerNative"||!isRecord3(block.raw))continue;let raw=block.raw;typeof raw.type!="string"||!REPLAYABLE_ANTHROPIC_PROVIDER_NATIVE_TYPES.has(raw.type)||isProviderNativeToolUseBlock(raw)&&typeof raw.id=="string"&&pendingUseIds.add(raw.id)}for(let block of message.content){if(block.type!=="providerNative"||!isRecord3(block.raw))continue;let raw=block.raw;if(typeof raw.type!="string"||!REPLAYABLE_ANTHROPIC_PROVIDER_NATIVE_TYPES.has(raw.type))continue;let toolUseId=raw.tool_use_id;typeof toolUseId=="string"&&(priorUseIds.has(toolUseId)||pendingUseIds.has(toolUseId))&&(resolvedUseIds.add(toolUseId),validResultIds.add(toolUseId))}continue}if(message.role==="toolResult"){if(discardedFallbackToolCallIds.has(message.toolCallId))continue;let emitsReferences=!1;for(let name of message.addedToolNames??[]){let normalizedName=normalizeToolName(name);!deferredToolNames.has(normalizedName)||loadedReferenceNames.has(normalizedName)||(loadedReferenceNames.add(normalizedName),emitsReferences=!0)}emitsReferences&&(pendingUseIds=new Set);continue}message.role==="user"&&userMessageClosesServerTurn(message)&&(pendingUseIds=new Set)}return{resolvedUseIds,liveUseIds:pendingUseIds,validResultIds}}function isUnpairedProviderNativeToolBlock(raw,pairing){if(!isRecord3(raw))return!1;if(isProviderNativeToolUseBlock(raw))return typeof raw.id!="string"||!(pairing.resolvedUseIds.has(raw.id)||pairing.liveUseIds.has(raw.id));let toolUseId=raw.tool_use_id;return typeof toolUseId=="string"&&!pairing.validResultIds.has(toolUseId)}function pairedServerToolUseIdsBeforeBoundary(content,boundary){let paired=new Set;for(let index=0;index<boundary;index++){let block=content[index];if(block.type!=="providerNative"||!isRecord3(block.raw))continue;let toolUseId=block.raw.tool_use_id;typeof toolUseId=="string"&&paired.add(toolUseId)}return paired}function collectDiscardedFallbackToolCallIds(messages,model){let discarded=new Set;for(let message of messages){if(message.role!=="assistant"||!isSameAnthropicModel(message,model))continue;let boundary=lastAnthropicFallbackBoundary(message.content);if(!(boundary<0))for(let index=0;index<boundary;index++){let block=message.content[index];block.type==="toolCall"&&discarded.add(block.id)}}return discarded}function stringRecord(value){if(!isRecord3(value))return;let entries=Object.entries(value);if(!entries.some(([,item])=>typeof item!="string"))return Object.fromEntries(entries)}function isForcedAnthropicToolChoice(toolChoice){return isRecord3(toolChoice)&&(toolChoice.type==="any"||toolChoice.type==="tool")}function extractPayloadRequestMetadata(params){let payload=params,headers=stringRecord(payload.headers);if(!("headers"in payload)&&!("extra_body"in payload))return headers?{params,headers}:{params};let stripped={...payload};return delete stripped.headers,delete stripped.extra_body,headers?{params:stripped,headers}:{params:stripped}}function removeAnthropicBetaHeaders(headers,shouldRemoveBeta){if(!headers)return{changed:!1};let nextHeaders={},changed=!1;for(let[key,value]of Object.entries(headers)){if(key.toLowerCase()!=="anthropic-beta"||value===null){nextHeaders[key]=value;continue}let betas=value.split(",").map(beta=>beta.trim()).filter(beta=>beta.length>0),supportedBetas=betas.filter(beta=>!shouldRemoveBeta(beta));changed=changed||supportedBetas.length!==betas.length,supportedBetas.length>0&&(nextHeaders[key]=supportedBetas.join(", "))}return changed?{changed:!0,headers:Object.keys(nextHeaders).length>0?nextHeaders:void 0}:{changed:!1,headers}}function removeComputerUseBetaHeader(headers){return removeAnthropicBetaHeaders(headers,beta=>beta.startsWith(COMPUTER_USE_BETA_PREFIX))}function sanitizeAdaptiveThinkingHeaders(model,headers){if(!supportsAdaptiveThinking(model))return headers;let headerSanitization=removeAnthropicBetaHeaders(headers,beta=>beta===INTERLEAVED_THINKING_BETA);return headerSanitization.changed?headerSanitization.headers??{}:headers}function rejectsNativeComputerTool(model,toolType){return model.provider==="cloudflare-ai-gateway"&&model.baseUrl.includes("anthropic")?toolType.startsWith("computer_"):matchesModelMarker(model,UNSUPPORTED_NATIVE_COMPUTER_TOOL_MODEL_MARKERS)&&toolType===NATIVE_COMPUTER_TOOL_TYPE}function rejectsComputerUseBeta(model){return model.provider==="cloudflare-ai-gateway"&&model.baseUrl.includes("anthropic")||matchesModelMarker(model,UNSUPPORTED_NATIVE_COMPUTER_TOOL_MODEL_MARKERS)}function isAnthropicWebSearchToolType(toolType){return toolType.startsWith("web_search_")}function sanitizeUnsupportedNativeTools(model,params){let payload=params,headers=stringRecord(payload.headers),headerSanitization=rejectsComputerUseBeta(model)?removeComputerUseBetaHeader(headers):{changed:!1},rejectsNativeWebSearch=!getAnthropicCompat(model).supportsWebSearch,tools=payload.tools,sanitized={...payload},changed=!1;if(Array.isArray(tools)){let supportedTools=[];for(let tool of tools){let hookTool=tool;if(isRecord3(hookTool)&&typeof hookTool.type=="string"&&(rejectsNativeComputerTool(model,hookTool.type)||rejectsNativeWebSearch&&isAnthropicWebSearchToolType(hookTool.type))){changed=!0;continue}supportedTools.push(tool)}changed&&(supportedTools.length>0?sanitized.tools=supportedTools:delete sanitized.tools)}if(headerSanitization.changed&&(changed=!0,headerSanitization.headers?sanitized.headers=headerSanitization.headers:delete sanitized.headers),changed&&isRecord3(sanitized.tool_choice)){let toolChoiceName=sanitized.tool_choice.name,hasSelectedTool=typeof toolChoiceName=="string"&&Array.isArray(sanitized.tools)&&sanitized.tools.some(tool=>isRecord3(tool)&&tool.name===toolChoiceName);(sanitized.tools===void 0||typeof toolChoiceName=="string"&&!hasSelectedTool)&&delete sanitized.tool_choice}return changed?sanitized:params}function httpStatusOfError(error){if(!isRecord3(error))return;let status=error.status;return typeof status=="number"&&Number.isInteger(status)&&status>=100&&status<600?status:void 0}function sanitizeAdaptiveThinkingPayload(model,params,options){if(!supportsAdaptiveThinking(model))return params;let payload=params,headers=stringRecord(payload.headers),headerSanitization=removeAnthropicBetaHeaders(headers,beta=>beta===INTERLEAVED_THINKING_BETA),sanitized={...payload},changed=!1,thinking=isRecord3(payload.thinking)?payload.thinking:void 0;if(thinking?.type==="enabled"){let display=thinking.display==="omitted"||thinking.display==="summarized"?thinking.display:options?.thinkingDisplay??"summarized";sanitized.thinking={type:"adaptive",display},options?.effort!==void 0&&!isRecord3(payload.output_config)&&(sanitized.output_config={effort:options.effort}),changed=!0}return headerSanitization.changed&&(changed=!0,headerSanitization.headers?sanitized.headers=headerSanitization.headers:delete sanitized.headers),changed?sanitized:params}function isCacheableUserContentBlock(block){return block?.type==="text"||block?.type==="image"||block?.type==="tool_result"}function appendUserBlocks(params,newBlocks){if(newBlocks.length===0)return;let lastParam=params[params.length-1];lastParam?.role==="user"?typeof lastParam.content=="string"?lastParam.content=[{type:"text",text:lastParam.content},...newBlocks]:Array.isArray(lastParam.content)&&lastParam.content.push(...newBlocks):params.push({role:"user",content:newBlocks})}function isToolLoopContinuation(messages){let tail=messages[messages.length-1],preceding=messages[messages.length-2];return tail?.role==="user"&&Array.isArray(tail.content)&&tail.content.some(block=>block.type==="tool_result")&&preceding?.role==="assistant"&&Array.isArray(preceding.content)&&preceding.content.some(block=>block.type==="tool_use")}function markSystemMessageCacheCheckpoint(message,cacheControl){if(!Array.isArray(message.content))return;let lastBlock=message.content[message.content.length-1];lastBlock&&(lastBlock.type==="text"||lastBlock.type==="tool_addition"||lastBlock.type==="tool_removal")&&(lastBlock.cache_control=cacheControl)}function markUserMessageCacheCheckpoint(message,cacheControl){if(message.role!=="user")return!1;if(Array.isArray(message.content)){let lastBlock=message.content[message.content.length-1];return isCacheableUserContentBlock(lastBlock)?(lastBlock.cache_control=cacheControl,!0):!1}return typeof message.content=="string"?(message.content=[{type:"text",text:message.content,cache_control:cacheControl}],!0):!1}var ANTHROPIC_MESSAGE_EVENTS=new Set(["message_start","message_delta","message_stop","content_block_start","content_block_delta","content_block_stop"]);function flushSseEvent(state){if(!state.event&&state.data.length===0)return null;let event={event:state.event,data:state.data.join(`
6
- `),raw:[...state.raw]};return state.event=null,state.data=[],state.raw=[],event}function decodeSseLine(line,state){if(line==="")return flushSseEvent(state);if(state.raw.push(line),line.startsWith(":"))return null;let delimiterIndex=line.indexOf(":"),fieldName=delimiterIndex===-1?line:line.slice(0,delimiterIndex),value=delimiterIndex===-1?"":line.slice(delimiterIndex+1);return value.startsWith(" ")&&(value=value.slice(1)),fieldName==="event"?state.event=value:fieldName==="data"&&state.data.push(value),null}function nextLineBreakIndex(text){let carriageReturnIndex=text.indexOf("\r"),newlineIndex=text.indexOf(`
7
- `);return carriageReturnIndex===-1?newlineIndex:newlineIndex===-1?carriageReturnIndex:Math.min(carriageReturnIndex,newlineIndex)}function consumeLine(text){let lineBreakIndex=nextLineBreakIndex(text);if(lineBreakIndex===-1)return null;let nextIndex=lineBreakIndex+1;return text[lineBreakIndex]==="\r"&&text[nextIndex]===`
8
- `&&(nextIndex+=1),{line:text.slice(0,lineBreakIndex),rest:text.slice(nextIndex)}}async function*iterateSseMessages(body,signal){let reader=body.getReader(),decoder=new TextDecoder,state={event:null,data:[],raw:[]},buffer="";try{for(;;){if(signal?.aborted)throw new Error("Request was aborted");let{value,done}=await reader.read();if(done)break;buffer+=decoder.decode(value,{stream:!0});let consumed2=consumeLine(buffer);for(;consumed2;){buffer=consumed2.rest;let event=decodeSseLine(consumed2.line,state);event&&(yield event),consumed2=consumeLine(buffer)}}buffer+=decoder.decode();let consumed=consumeLine(buffer);for(;consumed;){buffer=consumed.rest;let event=decodeSseLine(consumed.line,state);event&&(yield event),consumed=consumeLine(buffer)}if(buffer.length>0){let event=decodeSseLine(buffer,state);event&&(yield event)}let trailingEvent=flushSseEvent(state);trailingEvent&&(yield trailingEvent)}finally{reader.releaseLock()}}async function*iterateAnthropicEvents(response,signal){if(!response.body)throw new Error("Attempted to iterate over an Anthropic response with no body");let sawMessageStart=!1,sawMessageEnd=!1;for await(let sse of iterateSseMessages(response.body,signal)){if(sse.event==="error"){let errorText=sse.data,hintMs=extract429RetryAfterMs({bodyText:sse.data});throw hintMs!==void 0&&(errorText=appendRetryAfterMsMarker(errorText,hintMs)),attachProviderDiagnostic(new Error(errorText),anthropicProviderDiagnosticFromSseData(sse.data))}if(ANTHROPIC_MESSAGE_EVENTS.has(sse.event??""))try{let event=parseJsonWithRepair(sse.data);event.type==="message_start"?sawMessageStart=!0:event.type==="message_stop"&&(sawMessageEnd=!0),yield event}catch(error){let message=error instanceof Error?error.message:String(error);throw new Error(`Could not parse Anthropic SSE event ${sse.event}: ${message}; data=${sse.data}; raw=${sse.raw.join("\\n")}`)}}if(sawMessageStart&&!sawMessageEnd)throw new Error("Anthropic stream ended before message_stop")}var stream=(model,context,options)=>{let stream2=new AssistantMessageEventStream,normalizedContext=resolveTranscript(context,supportsMidConvoSystemMessages(model)),currentTools=getCurrentTools(normalizedContext.messages);return(async()=>{let providerThinkingLevel=managedEffortForRequest(model,options),output={role:"assistant",content:[],api:model.api,provider:model.provider,model:model.id,...providerThinkingLevel===void 0?{}:{providerThinkingLevel},usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"pending",timestamp:Date.now()},serverFallbackAbort=new AbortController,serverFallbackReceipt,combinedAbort=combineAbortSignals([options?.signal,serverFallbackAbort.signal]),requestSignal=combinedAbort.signal;try{let client,isOAuth=!1,advertisedClaudeCodeVersion,usageModel=model,inputTransformations,openClient;if(options?.client)client=options.client;else{let apiKey=options?.apiKey,optionsHeaders=providerHeadersToRecord(options?.headers),federation=getAnthropicFederation(model,apiKey,optionsHeaders,options?.env);federation||assertRequestAuth(model.provider,apiKey,optionsHeaders);let copilotDynamicHeaders;if(model.provider==="github-copilot"){let hasImages=hasCopilotVisionInput(normalizedContext.messages);copilotDynamicHeaders=buildCopilotDynamicHeaders({messages:normalizedContext.messages,hasImages})}let cacheSessionId=resolveCacheRetention(options?.cacheRetention??model.cacheRetention,options?.env,"short")==="none"?void 0:options?.sessionId;openClient=()=>{let created=createClient(model,apiKey,options?.interleavedThinking??!0,shouldUseFineGrainedToolStreamingBeta(model,normalizedContext),options?.refusalFallbacks!==void 0&&configuredBetaHeader(model,options)!==null,optionsHeaders,options?.fetch,copilotDynamicHeaders,cacheSessionId,options?.env,federation);client=created.client,isOAuth=created.isOAuthToken,advertisedClaudeCodeVersion=created.claudeCodeVersion},openClient()}let claudeCodeVersionRetried=!1,retryWithNewerClaudeCode=async error=>claudeCodeVersionRetried||openClient===void 0||advertisedClaudeCodeVersion===void 0||!isClaudeCodeVersionTooOldError(error)||await recoverClaudeCodeVersion(error,claudeCodeVersion,advertisedClaudeCodeVersion,options?.env)===void 0?!1:(claudeCodeVersionRetried=!0,openClient(),!0),noteTooOldClaudeCode=error=>{advertisedClaudeCodeVersion!==void 0&&isClaudeCodeVersionTooOldError(error)&&(error.message=`${error.message}
9
- ${claudeCodeVersionTooOldHint(advertisedClaudeCodeVersion)}`)},fallbackKey=unsignedThinkingFallbackKey(model,options?.sessionId),unsignedThinkingReplay=fallbackKey&&unsignedThinkingTextReplayFallbacks.has(fallbackKey)?"text":getAnthropicCompat(model).unsignedThinkingReplay,demoteReferenceReplay=fallbackKey!==void 0&&toolReferenceReplayFallbacks.has(fallbackKey),requestReplaysReferences=!1,createRequest=async()=>{let params=buildParams(model,normalizedContext,isOAuth,options,unsignedThinkingReplay),nextParams=await options?.onPayload?.(params,model);nextParams!==void 0&&(params=nextParams),params=sanitizeAdaptiveThinkingPayload(model,params,options),params=sanitizeUnsupportedNativeTools(model,params),params=demoteUnavailableToolReferences(params);let withoutReferenceReplay=demoteToolReferenceReplay(params);requestReplaysReferences=withoutReferenceReplay!==params,demoteReferenceReplay&&(params=withoutReferenceReplay),params=sanitizeAnthropicToolPairs(params);let payloadRequestMetadata=extractPayloadRequestMetadata(params);params=payloadRequestMetadata.params;let limitedTools=limitGitHubCopilotTools(model.provider,params.tools,params.tool_choice);limitedTools.omittedCount>0&&(params={...params,tools:limitedTools.tools},recordGitHubCopilotToolLimit(output,limitedTools.omittedCount));let requestOptions={...requestSignal?{signal:requestSignal}:{},...options?.timeoutMs!==void 0?{timeout:options.timeoutMs}:{},maxRetries:0,...payloadRequestMetadata.headers?{headers:payloadRequestMetadata.headers}:{}},send=body=>awaitProviderTransport(()=>client.beta.messages.create({...body,stream:!0},requestOptions).asResponse(),anthropicProviderDiagnosticFromError),sent=await sendWithForcedToolChoiceFallback({target:model,params,acceptsForcedToolChoice:getAnthropicCompat(model).supportsForcedToolChoice,isForced:isForcedAnthropicToolChoice,send});return{params:sent.params,response:sent.result}},requestOutcome;try{requestOutcome=await retryProviderRequest(async()=>{try{return await createRequest()}catch(error){if(unsignedThinkingReplay!=="text"&&isInvalidUnsignedThinkingSignatureError(error))return unsignedThinkingReplay="text",fallbackKey&&unsignedThinkingTextReplayFallbacks.add(fallbackKey),createRequest();if(!demoteReferenceReplay&&requestReplaysReferences&&isToolReferenceNotFoundError(error))return demoteReferenceReplay=!0,fallbackKey&&toolReferenceReplayFallbacks.add(fallbackKey),createRequest();if(await retryWithNewerClaudeCode(error))try{return await createRequest()}catch(retryError){throw noteTooOldClaudeCode(retryError),retryError}throw noteTooOldClaudeCode(error),error}},{maxRetries:options?.maxRetries,maxRetryDelayMs:options?.maxRetryDelayMs,signal:requestSignal})}catch(error){let status=httpStatusOfError(error);throw status!==void 0&&await options?.onResponse?.({status,headers:{}},model),error}let{params:sentParams,response}=requestOutcome;await options?.onResponse?.({status:response.status,headers:headersToRecord(response.headers)},model),stream2.push({type:"start",partial:output});let blocks=output.content;for await(let event of iterateAnthropicEvents(response,requestSignal))if(await options?.onProviderStreamEvent?.(event,model),event.type==="message_start"){output.responseId=event.message.id;let transformations=event.message.input_transformations;Array.isArray(transformations)&&(inputTransformations=transformations);let responseModel=event.message.model;responseModel!==model.id&&(output.responseModel=responseModel);let fallback=responseModel===model.id?void 0:model.compat?.allowedFallbackModels?.find(candidate=>typeof candidate=="string"?candidate===responseModel:candidate.provider===model.provider&&candidate.model===responseModel);fallback!==void 0&&(output.model=responseModel);let fallbackCost=typeof fallback=="string"?void 0:fallback?.cost;usageModel=fallbackCost?{...model,id:responseModel,cost:fallbackCost}:model,output.usage.input=event.message.usage.input_tokens||0,output.usage.output=event.message.usage.output_tokens||0,output.usage.cacheRead=event.message.usage.cache_read_input_tokens||0,output.usage.cacheWrite=event.message.usage.cache_creation_input_tokens||0,output.usage.cacheWrite1h=event.message.usage.cache_creation?.ephemeral_1h_input_tokens||0,output.usage.totalTokens=output.usage.input+output.usage.output+output.usage.cacheRead+output.usage.cacheWrite,calculateCost(model,output.usage);let stickyReceipt=options?.abortServerSideFallback===!0?parseStickyFallbackReceipt(event.message.usage,sentParams.model,event.message.model):void 0;if(stickyReceipt!==void 0){serverFallbackReceipt=stickyReceipt,serverFallbackAbort.abort();break}}else if(event.type==="content_block_start"){let receipt=parseServerFallbackReceipt(event.content_block);if(receipt!==void 0){if(options?.abortServerSideFallback===!0){serverFallbackReceipt=receipt,serverFallbackAbort.abort();break}usageModel=applyServerFallbackContinuation(output,model,receipt)}if(event.content_block.type==="text"){let block={type:"text",text:event.content_block.text??"",index:event.index};output.content.push(block),stream2.push({type:"text_start",contentIndex:output.content.length-1,partial:output})}else if(event.content_block.type==="thinking"){let block={type:"thinking",thinking:event.content_block.thinking??"",thinkingSignature:event.content_block.signature??"",index:event.index};output.content.push(block),stream2.push({type:"thinking_start",contentIndex:output.content.length-1,partial:output})}else if(event.content_block.type==="redacted_thinking"){let block={type:"thinking",thinking:"[Reasoning redacted]",thinkingSignature:event.content_block.data,redacted:!0,index:event.index};output.content.push(block),stream2.push({type:"thinking_start",contentIndex:output.content.length-1,partial:output})}else if(event.content_block.type==="tool_use"){let block={type:"toolCall",id:event.content_block.id,name:isOAuth?fromClaudeCodeName(event.content_block.name,currentTools):event.content_block.name,arguments:isRecord3(event.content_block.input)?event.content_block.input:{},partialJson:"",index:event.index};output.content.push(block),stream2.push({type:"toolcall_start",contentIndex:output.content.length-1,partial:output})}else{let block={type:"providerNative",subtype:event.content_block.type,raw:event.content_block,index:event.index};output.content.push(block)}}else if(event.type==="content_block_delta"){if(event.delta.type==="text_delta"){let index=blocks.findIndex(b=>b.index===event.index),block=blocks[index];block&&block.type==="text"&&(block.text+=event.delta.text,stream2.push({type:"text_delta",contentIndex:index,delta:event.delta.text,partial:output}))}else if(event.delta.type==="thinking_delta"){let index=blocks.findIndex(b=>b.index===event.index),block=blocks[index];block&&block.type==="thinking"&&(block.thinking+=event.delta.thinking,stream2.push({type:"thinking_delta",contentIndex:index,delta:event.delta.thinking,partial:output}))}else if(event.delta.type==="input_json_delta"){let index=blocks.findIndex(b=>b.index===event.index),block=blocks[index];block&&block.type==="toolCall"?(block.partialJson+=event.delta.partial_json,block.arguments=parseStreamingJson(block.partialJson),stream2.push({type:"toolcall_delta",contentIndex:index,delta:event.delta.partial_json,partial:output})):block&&block.type==="providerNative"&&isProviderNativeToolUseBlock(block.raw)&&(block.partialJson=(block.partialJson??"")+event.delta.partial_json)}else if(event.delta.type==="signature_delta"){let index=blocks.findIndex(b=>b.index===event.index),block=blocks[index];block&&block.type==="thinking"&&(block.thinkingSignature=block.thinkingSignature||"",block.thinkingSignature+=event.delta.signature)}}else if(event.type==="content_block_stop"){let index=blocks.findIndex(b=>b.index===event.index),block=blocks[index];if(block){if(delete block.index,block.type==="text")stream2.push({type:"text_end",contentIndex:index,content:block.text,partial:output});else if(block.type==="thinking")stream2.push({type:"thinking_end",contentIndex:index,content:block.thinking,partial:output});else if(block.type==="toolCall")block.arguments=parseStreamingJson(block.partialJson),delete block.partialJson,stream2.push({type:"toolcall_end",contentIndex:index,toolCall:block,partial:output});else if(block.type==="providerNative"){let partialJson=block.partialJson;delete block.partialJson,partialJson!==void 0&&isRecord3(block.raw)&&(block.raw={...block.raw,input:parseStreamingJson(partialJson)})}}}else if(event.type==="message_delta"){let transformations=event.input_transformations;if(Array.isArray(transformations)&&(inputTransformations=transformations),event.delta.stop_reason){output.rawStopReason=event.delta.stop_reason;let stopReasonResult=mapStopReason(event.delta.stop_reason,event.delta.stop_details);output.stopReason=stopReasonResult.stopReason,stopReasonResult.errorMessage&&(output.errorMessage=stopReasonResult.errorMessage),stopReasonResult.stopDetails&&(output.stopDetails=stopReasonResult.stopDetails)}if(event.usage){event.usage.input_tokens!=null&&(output.usage.input=event.usage.input_tokens),event.usage.output_tokens!=null&&(output.usage.output=event.usage.output_tokens),event.usage.cache_read_input_tokens!=null&&(output.usage.cacheRead=event.usage.cache_read_input_tokens),event.usage.cache_creation_input_tokens!=null&&(output.usage.cacheWrite=event.usage.cache_creation_input_tokens);let cacheCreation=event.usage.cache_creation;cacheCreation?.ephemeral_1h_input_tokens!=null&&(output.usage.cacheWrite1h=cacheCreation.ephemeral_1h_input_tokens);let thinkingTokens=event.usage.output_tokens_details?.thinking_tokens;thinkingTokens!=null&&(output.usage.reasoning=thinkingTokens)}output.usage.totalTokens=output.usage.input+output.usage.output+output.usage.cacheRead+output.usage.cacheWrite,calculateCost(usageModel,output.usage)}if(options?.signal?.aborted)throw new Error("Request was aborted");if(serverFallbackReceipt!==void 0&&applyServerFallbackAbort(output,serverFallbackReceipt),output.stopReason==="pending")throw new Error("Anthropic stream ended without a stop reason");if(output.stopReason==="aborted"||output.stopReason==="error")throw new Error(output.errorMessage||"An unknown error occurred");inputTransformations&&inputTransformations.length>0&&appendAssistantMessageDiagnostic(output,{type:"anthropic_input_transformations",timestamp:Date.now(),details:{transformations:inputTransformations.map(transformation=>({type:transformation.type??void 0,path:transformation.path??void 0,reason:transformation.reason??void 0}))}}),combinedAbort.cleanup(),stream2.push({type:"done",reason:output.stopReason,message:output}),stream2.end()}catch(error){combinedAbort.cleanup();for(let block of output.content){delete block.index;let scratch=block.partialJson;block.type==="providerNative"&&scratch!==void 0&&isRecord3(block.raw)&&(block.raw={...block.raw,input:parseStreamingJson(scratch)}),delete block.partialJson}output.stopReason=options?.signal?.aborted?"aborted":"error";let errorMessage=error instanceof Error?error.message:JSON.stringify(error);if(error instanceof Error&&error.status===429){let sdkHeaders=error.headers;if(sdkHeaders instanceof Headers){let hintMs=extract429RetryAfterMs({status:429,headers:sdkHeaders,bodyText:errorMessage});hintMs!==void 0&&(errorMessage=appendRetryAfterMsMarker(errorMessage,hintMs))}}let failure=normalizeAnthropicRetryFailure(error);appendAssistantMessageDiagnostic(output,{type:"provider_retry_failure",timestamp:Date.now(),details:{kind:failure.kind,...failure.statusCode!==void 0?{statusCode:failure.statusCode}:{},...failure.providerCodes!==void 0?{providerCodes:failure.providerCodes}:{},...failure.retryAfterMs!==void 0?{retryAfterMs:failure.retryAfterMs}:{},...failure.shouldRetry!==void 0?{shouldRetry:failure.shouldRetry}:{}}});let providerDiagnostic=output.stopReason==="error"?readProviderDiagnostic(error):void 0;providerDiagnostic!==void 0&&(output.providerDiagnostic=providerDiagnostic),output.errorMessage=withGitHubCopilotFailureNote(formatGitHubCopilotToolLimitError(output,errorMessage),model.provider,error),stream2.push({type:"error",reason:output.stopReason,error:output}),stream2.end()}})(),stream2};function getModelMatchCandidates(model){return[model.id,model.name].flatMap(value=>{let lower=value.toLowerCase();return[lower,lower.replace(/[\s_.:]+/g,"-")]})}function matchesModelMarker(model,markers){return getModelMatchCandidates(model).some(candidate=>markers.some(marker=>candidate.includes(marker)))}function supportsNativeXhighEffort(model){return matchesModelMarker(model,NATIVE_XHIGH_EFFORT_MODEL_MARKERS)}function cannotDisableThinking(model,compat){return compat.supportsDisabledThinking?matchesModelMarker(model,DISABLED_THINKING_REJECTING_MODEL_MARKERS):!0}function managedEffortForRequest(model,options){if(model.compat?.supportsMidConvoEffort===!0)return options?.thinkingEnabled===!1?cannotDisableThinking(model,getAnthropicCompat(model))?"low":void 0:options?.effort??"high"}function isEffortMarker(message){return message.role==="system"&&Array.isArray(message.content)&&message.content.length===0&&message.output_config?.effort!==void 0}function disableThinkingForRequest(params,model,compat){if(delete params.output_config,cannotDisableThinking(model,compat)){delete params.thinking,supportsAdaptiveThinking(model)&&(params.output_config={effort:"low"});return}params.thinking={type:"disabled"},params.messages=params.messages.filter(message=>!isEffortMarker(message))}function supportsAdaptiveThinking(model){return model.compat?.forceAdaptiveThinking!==void 0?model.compat.forceAdaptiveThinking:matchesModelMarker(model,ADAPTIVE_THINKING_MODEL_MARKERS)}function mapThinkingLevelToEffort(model,level){let mapped=level?model.thinkingLevelMap?.[level]:void 0;if(typeof mapped=="string")return mapped;switch(level){case"minimal":case"low":return"low";case"medium":return"medium";case"high":return"high";case"xhigh":return supportsNativeXhighEffort(model)?"xhigh":"max";case"max":return"max";default:return"high"}}var streamSimple=(model,context,options)=>{let apiKey=options?.apiKey,optionsHeaders=providerHeadersToRecord(options?.headers);getAnthropicFederation(model,apiKey,optionsHeaders,options?.env)||assertRequestAuth(model.provider,apiKey,optionsHeaders);let base={...buildBaseOptions(model,context,options,options?.apiKey),toolChoice:options?.toolChoice};if(!options?.reasoning)return stream(model,context,{...base,thinkingEnabled:!1});if(supportsAdaptiveThinking(model)){let effort=mapThinkingLevelToEffort(model,options.reasoning);return stream(model,context,{...base,thinkingEnabled:!0,effort})}let adjusted=adjustMaxTokensForThinking(base.maxTokens,model.maxTokens,options.reasoning,options.thinkingBudgets),maxTokens=clampMaxTokensToContext(model,context,adjusted.maxTokens);return stream(model,context,{...base,maxTokens,thinkingEnabled:!0,thinkingBudgetTokens:Math.min(adjusted.thinkingBudget,Math.max(0,maxTokens-1024))})};function isOAuthToken(apiKey){return apiKey.includes("sk-ant-oat")}function createClient(model,apiKey,interleavedThinking,useFineGrainedToolStreamingBeta,useServerSideFallbackBeta,optionsHeaders,fetch,dynamicHeaders,sessionId,env,federation){let needsInterleavedBeta=interleavedThinking&&!supportsAdaptiveThinking(model),betaFeatures=[];if(useFineGrainedToolStreamingBeta&&betaFeatures.push(FINE_GRAINED_TOOL_STREAMING_BETA),needsInterleavedBeta&&betaFeatures.push(INTERLEAVED_THINKING_BETA),useServerSideFallbackBeta&&betaFeatures.push(SERVER_SIDE_FALLBACK_BETA),model.provider==="cloudflare-ai-gateway")return{client:new PiAnthropic({apiKey:null,authToken:null,baseURL:resolveCloudflareBaseUrl(model,env),dangerouslyAllowBrowser:!0,fetch,defaultHeaders:sanitizeAdaptiveThinkingHeaders(model,mergeHeaders({accept:"application/json","anthropic-dangerous-direct-browser-access":"true","cf-aig-authorization":`Bearer ${apiKey}`,"x-api-key":null,Authorization:null,...betaFeatures.length>0?{"anthropic-beta":betaFeatures.join(",")}:{}},model.headers,optionsHeaders))}),isOAuthToken:!1};if(model.provider==="github-copilot")return{client:new PiAnthropic({apiKey:null,authToken:apiKey,baseURL:model.baseUrl,dangerouslyAllowBrowser:!0,fetch,defaultHeaders:sanitizeAdaptiveThinkingHeaders(model,mergeClientHeaders(model,{accept:"application/json","anthropic-dangerous-direct-browser-access":"true",...betaFeatures.length>0?{"anthropic-beta":betaFeatures.join(",")}:{}},model.headers,dynamicHeaders,optionsHeaders))}),isOAuthToken:!1};if(apiKey&&isOAuthToken(apiKey)){let advertisedClaudeCodeVersion=getClaudeCodeVersion(claudeCodeVersion,env);return{client:new PiAnthropic({apiKey:null,authToken:apiKey,baseURL:model.baseUrl,dangerouslyAllowBrowser:!0,fetch,defaultHeaders:sanitizeAdaptiveThinkingHeaders(model,mergeClientHeaders(model,{accept:"application/json","anthropic-dangerous-direct-browser-access":"true","anthropic-beta":["claude-code-20250219","oauth-2025-04-20",...betaFeatures].join(","),"user-agent":`claude-cli/${advertisedClaudeCodeVersion}`,"x-app":"cli"},model.headers,optionsHeaders))}),isOAuthToken:!0,claudeCodeVersion:advertisedClaudeCodeVersion}}let affinityCompat=getAnthropicCompat(model),sessionAffinityHeaders={};if(sessionId&&affinityCompat.sendSessionAffinityHeaders){let header=affinityCompat.sessionAffinityFormat==="openrouter"?"x-session-id":"x-session-affinity";sessionAffinityHeaders[header]=sessionId}let defaultHeaders=sanitizeAdaptiveThinkingHeaders(model,mergeClientHeaders(model,{accept:"application/json","anthropic-dangerous-direct-browser-access":"true",...betaFeatures.length>0?{"anthropic-beta":betaFeatures.join(",")}:{}},sessionAffinityHeaders,model.headers,optionsHeaders));if(federation){let key=JSON.stringify([model.baseUrl,federation]);if(federationClient?.key!==key||federationClient.fetch!==fetch){let client2=new PiAnthropic({apiKey:null,authToken:null,config:federation,baseURL:model.baseUrl,dangerouslyAllowBrowser:!0,fetch});federationClient={key,fetch,client:client2}}return{client:federationClient.client.withOptions({defaultHeaders}),isOAuthToken:!1}}return{client:new PiAnthropic({apiKey:apiKey??null,authToken:null,baseURL:model.baseUrl,dangerouslyAllowBrowser:!0,fetch,defaultHeaders}),isOAuthToken:!1}}function buildAnthropicWarmPromptCacheParams(model,context,options){let transcript=resolveTranscript(normalizeContext(context),supportsMidConvoSystemMessages(model)),params=buildParams(model,transcript,!1,{...options,maxTokens:0,thinkingEnabled:void 0,toolChoice:void 0}),{stream:_stream,thinking:_thinking,output_config:_outputConfig,tool_choice:_toolChoice,...nonStreaming}=params;return sanitizeAnthropicToolPairs({...nonStreaming,max_tokens:0})}function configuredBetaHeader(model,options){let configured;for(let headers of[model.headers,options?.headers])for(let[name,value]of Object.entries(headers??{}))name.toLowerCase()==="anthropic-beta"&&(configured=value);return configured}function getBetaFeatures(model,context,isOAuthToken2,shape,options){let configured=configuredBetaHeader(model,options);if(configured===null)return[];let required=[];isOAuthToken2&&required.push("claude-code-20250219","oauth-2025-04-20"),shape.midConvoEffort&&required.push(MID_CONVERSATION_OUTPUT_CONFIG_BETA),shape.thinkingBinding&&required.push(THINKING_BINDING_CONTROLS_BETA),shape.nativeToolChanges&&required.push(MID_CONVERSATION_TOOL_CHANGES_BETA),shape.refusalFallbacks&&required.push(SERVER_SIDE_FALLBACK_BETA);let optional=configured===void 0?defaultOptionalBetas(model,context,options):configured.split(",").map(feature=>feature.trim()).filter(Boolean).filter(feature=>!(feature===INTERLEAVED_THINKING_BETA&&supportsAdaptiveThinking(model)));return[...new Set([...optional,...required])]}function defaultOptionalBetas(model,context,options){let features=[];return shouldUseFineGrainedToolStreamingBeta(model,context)&&features.push(FINE_GRAINED_TOOL_STREAMING_BETA),model.reasoning&&options?.thinkingEnabled===!0&&(options.interleavedThinking??!0)&&!supportsAdaptiveThinking(model)&&features.push(INTERLEAVED_THINKING_BETA),shouldUseServerSideFallbackBeta(model)&&features.push(SERVER_SIDE_FALLBACK_BETA),features}function buildParams(model,context,isOAuthToken2,options,unsignedThinkingReplay=getAnthropicCompat(model).unsignedThinkingReplay){let compat=getAnthropicCompat(model),{cacheControl}=getCacheControl(model,options?.cacheRetention??model.cacheRetention,options?.env),initialSystemMessage=getInitialSystemMessage(context.messages),initialSystemText=initialSystemMessage?getSystemMessageText(initialSystemMessage):"",transformedMessages=transformMessages(context.messages,model,normalizeToolCallId,{preserveThinking:options?.thinkingEnabled===!0,preserveUnsignedThinking:!0}),conversationMessages=initialSystemMessage?transformedMessages.slice(1):transformedMessages,initialTools=initialSystemMessage?.toolsAdded??[],betasSuppressed=configuredBetaHeader(model,options)===null;if(betasSuppressed&&isOAuthToken2)throw new Error(`The anthropic-beta header is set to null, but ${model.provider}/${model.id} is called with an OAuth token, which needs the claude-code-20250219 and oauth-2025-04-20 betas. Remove the null, or list the betas you want instead; senpi adds the ones a request needs.`);let midConvoEffort=model.compat?.supportsMidConvoEffort===!0&&!betasSuppressed,nativeToolChanges=!betasSuppressed&&supportsMidConvoSystemMessages(model)&&supportsMidConvoToolChanges(model)&&initialTools.length>0&&!hasToolRedefinitions(context.messages),normalizeToolName=isOAuthToken2?toClaudeCodeName:name=>name,discardedFallbackToolCallIds=collectDiscardedFallbackToolCallIds(conversationMessages,model),partitionMessages=conversationMessages.filter(message=>!(message.role==="toolResult"&&discardedFallbackToolCallIds.has(message.toolCallId))),toolPlacement=nativeToolChanges?{immediate:[],deferred:new Map}:splitDeferredTools({tools:getCurrentTools(context.messages),messages:partitionMessages},compat.supportsToolReferences,normalizeToolName),immediateTools=toolPlacement.immediate,deferredTools=[...toolPlacement.deferred.values()];immediateTools.length===0&&deferredTools.length>0&&(immediateTools=deferredTools,deferredTools=[]);let deferredToolNames=new Set(deferredTools.map(tool=>normalizeToolName(tool.name))),activeEffort=managedEffortForRequest(model,options)??"high",sendFallbacks=options?.refusalFallbacks!==void 0&&!betasSuppressed,betaFeatures=getBetaFeatures(model,context,isOAuthToken2,{midConvoEffort,thinkingBinding:midConvoEffort&&options?.thinkingEnabled!==!1,nativeToolChanges,refusalFallbacks:sendFallbacks},options),convertedMessages=convertMessages(conversationMessages,model,isOAuthToken2,cacheControl,unsignedThinkingReplay,deferredToolNames,normalizeToolName,midConvoEffort?model.provider:void 0,nativeToolChanges),messages=midConvoEffort?insertThinkingLevelMessages(convertedMessages,activeEffort):convertedMessages.messages;if(midConvoEffort&&cacheControl)for(let index=messages.length-1;index>=0;index--){let message=messages[index];if(message.role==="system"&&Array.isArray(message.content)&&message.content.length>0)break;if(message.role==="user"){markUserMessageCacheCheckpoint(message,cacheControl);break}}let params={model:model.id,messages,max_tokens:options?.maxTokens??model.maxTokens,stream:!0,...betaFeatures.length>0?{betas:betaFeatures}:{}};isOAuthToken2?(params.system=[{type:"text",text:"You are Claude Code, Anthropic's official CLI for Claude.",...!initialSystemText&&cacheControl?{cache_control:cacheControl}:{}}],initialSystemText&&params.system.push({type:"text",text:sanitizeSurrogates(initialSystemText),...cacheControl?{cache_control:cacheControl}:{}})):initialSystemText&&(params.system=[{type:"text",text:sanitizeSurrogates(initialSystemText),...cacheControl?{cache_control:cacheControl}:{}}]),options?.temperature!==void 0&&!options?.thinkingEnabled&&compat.supportsTemperature&&Object.defineProperty(params,"temperature",{value:options.temperature,writable:!0,enumerable:!0,configurable:!0});let toolCacheControl=compat.supportsCacheControlOnTools?cacheControl:void 0;if(nativeToolChanges){let initialNames=new Set(initialTools.map(tool=>tool.name)),laterTools=getDeclaredTools(context.messages).filter(tool=>!initialNames.has(tool.name));params.tools=[...convertTools(initialTools,isOAuthToken2,compat.supportsEagerToolInputStreaming,compat.supportsStrictTools,toolCacheControl),DEFERRED_TOOL_PLACEHOLDER,...convertTools(laterTools,isOAuthToken2,compat.supportsEagerToolInputStreaming,compat.supportsStrictTools,void 0,!0)]}else(immediateTools.length>0||deferredTools.length>0)&&(params.tools=[...convertTools(immediateTools,isOAuthToken2,compat.supportsEagerToolInputStreaming,compat.supportsStrictTools,toolCacheControl),...convertTools(deferredTools,isOAuthToken2,compat.supportsEagerToolInputStreaming,compat.supportsStrictTools,void 0,!0)]);if(midConvoEffort&&options?.thinkingEnabled!==!1)params.thinking={type:"adaptive",display:options?.thinkingDisplay??"summarized",block_binding:{prefix_mismatch_behavior:"drop_block"}},params.output_config={effort:"high"};else if(model.reasoning)if(options?.thinkingEnabled){let display=options.thinkingDisplay??"summarized";supportsAdaptiveThinking(model)?(params.thinking={type:"adaptive",display},options.effort&&(params.output_config={effort:options.effort})):params.thinking={type:"enabled",budget_tokens:options.thinkingBudgetTokens||1024,display}}else options?.thinkingEnabled===!1&&disableThinkingForRequest(params,model,compat);if(params.thinking?.type==="enabled"&&finalAssistantTurnIsForeign(context.messages)&&finalAssistantTurnStartsWithToolUse(params.messages)&&disableThinkingForRequest(params,model,compat),options?.metadata){let userId=options.metadata.user_id;typeof userId=="string"&&(params.metadata={user_id:userId})}return options?.toolChoice&&compat.supportsToolChoice&&(!(options.toolChoice==="any"||typeof options.toolChoice=="object")||compat.supportsForcedToolChoice)&&(typeof options.toolChoice=="string"?params.tool_choice={type:options.toolChoice}:params.tool_choice=options.toolChoice),applyExtraBodyToAnthropicParams(params,options?.extraBody),sendFallbacks&&options?.refusalFallbacks!==void 0&&(params.fallbacks=options.refusalFallbacks==="default"?"default":[...options.refusalFallbacks]),params}function applyExtraBodyToAnthropicParams(params,extraBody){if(extraBody)for(let[key,value]of Object.entries(extraBody))ANTHROPIC_RESERVED_BODY_KEYS.has(key)||Object.defineProperty(params,key,{value,writable:!0,enumerable:!0,configurable:!0})}function finalAssistantTurnIsForeign(messages){for(let index=messages.length-1;index>=0;index--){let message=messages[index];if(message.role==="assistant")return message.api!=="anthropic-messages"}return!1}function finalAssistantTurnStartsWithToolUse(messages){for(let index=messages.length-1;index>=0;index--){let message=messages[index];if(message.role!=="assistant")continue;if(!Array.isArray(message.content)||message.content.length===0)return!1;let first=message.content[0];return first.type==="thinking"||first.type==="redacted_thinking"?!1:message.content.some(block=>block.type==="tool_use")}return!1}function convertToolResult(msg,isOAuthToken2,deferredToolNames,loadedToolNames,normalizeToolName){let references=[];for(let name of msg.addedToolNames??[]){let normalizedName=normalizeToolName(name);!deferredToolNames.has(normalizedName)||loadedToolNames.has(normalizedName)||(loadedToolNames.add(normalizedName),references.push({type:"tool_reference",tool_name:isOAuthToken2?toClaudeCodeName(name):name}))}let convertedContent=convertContentBlocks(msg.content);return{toolResult:{type:"tool_result",tool_use_id:msg.toolCallId,content:references.length>0?references:convertedContent,is_error:msg.isError},siblingContent:references.length===0?[]:typeof convertedContent=="string"?[{type:"text",text:convertedContent}]:convertedContent}}function convertMessages(transformedMessages,model,isOAuthToken2,cacheControl,unsignedThinkingReplay="text",deferredToolNames=new Set,normalizeToolName=name=>name,managedProvider,nativeToolChanges=!1){let params=[],assistantLevels=new Map,loadedToolNames=new Set,pendingSystemMessages=[],flushPendingSystemMessages=()=>{params.push(...pendingSystemMessages),pendingSystemMessages.length=0},discardedFallbackToolCallIds=collectDiscardedFallbackToolCallIds(transformedMessages,model),rejectsNativeWebSearchReplay=!getAnthropicCompat(model).supportsWebSearch,providerNativeToolPairing=collectProviderNativeToolPairing(transformedMessages,model,deferredToolNames,normalizeToolName,discardedFallbackToolCallIds);for(let i=0;i<transformedMessages.length;i++){let msg=transformedMessages[i];if(msg.role==="system"){let text=renderSystemMessageUpdate(msg),blocks=[];if(text.length>0&&blocks.push({type:"text",text:sanitizeSurrogates(text)}),nativeToolChanges){for(let tool of msg.toolsRemoved??[])blocks.push({type:"tool_removal",tool:{type:"tool_reference",name:isOAuthToken2?toClaudeCodeName(tool.name):tool.name}});for(let tool of msg.toolsAdded??[])blocks.push({type:"tool_addition",tool:{type:"tool_reference",name:isOAuthToken2?toClaudeCodeName(tool.name):tool.name}})}blocks.length>0&&pendingSystemMessages.push({role:"system",content:blocks})}else if(msg.role==="user")if(typeof msg.content=="string"){if(msg.content.trim().length>0){let content=sanitizeSurrogates(msg.content);params[params.length-1]?.role==="user"?appendUserBlocks(params,[{type:"text",text:content}]):params.push({role:"user",content})}}else{let filteredBlocks=msg.content.map(item=>item.type==="text"?{type:"text",text:sanitizeSurrogates(item.text)}:isVideoMimeType(item.mimeType)?{type:"video",source:{type:"base64",media_type:item.mimeType,data:item.data}}:{type:"image",source:{type:"base64",media_type:item.mimeType,data:item.data}}).filter(b=>b.type==="text"?b.text.trim().length>0:!0);if(filteredBlocks.length===0)continue;appendUserBlocks(params,filteredBlocks)}else if(msg.role==="assistant"){let blocks=[],isSameModel=isSameAnthropicModel(msg,model),fallbackBoundary=isSameModel?lastAnthropicFallbackBoundary(msg.content):-1,preBoundaryPairedServerToolUseIds=fallbackBoundary>=0?pairedServerToolUseIdsBeforeBoundary(msg.content,fallbackBoundary):new Set;for(let blockIndex=0;blockIndex<msg.content.length;blockIndex++){let block=msg.content[blockIndex];if(!(fallbackBoundary>=0&&blockIndex<fallbackBoundary&&(block.type==="thinking"||block.type==="toolCall"||block.type==="providerNative"&&isAnthropicServerToolUseBlock(block.raw)&&!preBoundaryPairedServerToolUseIds.has(block.raw.id))))if(block.type==="text"){if(block.text.trim().length===0)continue;blocks.push({type:"text",text:sanitizeSurrogates(block.text)})}else if(block.type==="thinking"){if(block.redacted){blocks.push({type:"redacted_thinking",data:block.thinkingSignature});continue}let thinkingSignature=block.thinkingSignature,hasThinkingSignature=!!thinkingSignature&&thinkingSignature.trim().length>0;if(block.thinking.trim().length===0&&!hasThinkingSignature)continue;hasThinkingSignature?blocks.push({type:"thinking",thinking:block.thinking,signature:thinkingSignature}):blocks.push(unsignedThinkingReplay==="empty-signature"?{type:"thinking",thinking:sanitizeSurrogates(block.thinking),signature:""}:{type:"text",text:sanitizeSurrogates(block.thinking)})}else block.type==="toolCall"?blocks.push({type:"tool_use",id:block.id,name:isOAuthToken2?toClaudeCodeName(block.name):block.name,input:block.arguments??{}}):block.type==="providerNative"&&isSameModel&&isReplayableAnthropicProviderNativeBlock(block.raw)&&!(rejectsNativeWebSearchReplay&&isAnthropicWebSearchReplayBlock(block.raw))&&!isUnpairedProviderNativeToolBlock(block.raw,providerNativeToolPairing)&&blocks.push(block.raw)}if(blocks.length===0)continue;flushPendingSystemMessages();let messageIndex=params.length;params.push({role:"assistant",content:blocks}),managedProvider!==void 0&&msg.api==="anthropic-messages"&&msg.provider===managedProvider&&isAnthropicEffort(msg.providerThinkingLevel)&&assistantLevels.set(messageIndex,msg.providerThinkingLevel)}else if(msg.role==="toolResult"){let toolResults=[],siblingContent=[],j=i;for(;j<transformedMessages.length&&transformedMessages[j].role==="toolResult";){let nextMsg=transformedMessages[j];if(!discardedFallbackToolCallIds.has(nextMsg.toolCallId)){let converted=convertToolResult(nextMsg,isOAuthToken2,deferredToolNames,loadedToolNames,normalizeToolName);toolResults.push(converted.toolResult),siblingContent.push(...converted.siblingContent)}j++}if(i=j-1,toolResults.length===0)continue;appendUserBlocks(params,[...toolResults,...siblingContent])}}flushPendingSystemMessages();let lastParam=params[params.length-1];if(cacheControl&&lastParam?.role==="system")return markSystemMessageCacheCheckpoint(lastParam,cacheControl),{messages:params,assistantLevels};let retainPrecedingCheckpoint=isToolLoopContinuation(params);if(cacheControl&&params.length>0&&markUserMessageCacheCheckpoint(params[params.length-1],cacheControl)&&retainPrecedingCheckpoint)for(let index=params.length-2;index>=0&&!markUserMessageCacheCheckpoint(params[index],cacheControl);index--);return{messages:params,assistantLevels}}function isAnthropicEffort(value){return value==="low"||value==="medium"||value==="high"||value==="xhigh"||value==="max"}function insertThinkingLevelMessages(converted,activeEffort){let messages=[];for(let index=0;index<converted.messages.length;index++){let historicalEffort=converted.assistantLevels.get(index);historicalEffort!==void 0&&messages.push({role:"system",content:[],output_config:{effort:historicalEffort}}),messages.push(converted.messages[index])}return messages.push({role:"system",content:[],output_config:{effort:activeEffort}}),messages}function shouldUseFineGrainedToolStreamingBeta(model,context){return getCurrentTools(context.messages).length>0&&!getAnthropicCompat(model).supportsEagerToolInputStreaming}var ANTHROPIC_STRICT_UNSUPPORTED_KEYWORDS=new Set(["minimum","maximum","exclusiveMinimum","exclusiveMaximum","multipleOf","maxItems","uniqueItems","minContains","maxContains","minProperties","maxProperties"]),ANTHROPIC_STRICT_STRING_FORMATS=new Set(["date-time","time","date","duration","email","hostname","uri","ipv4","ipv6","uuid"]),isAnthropicStrictUnsupportedKeyword=(key,value)=>ANTHROPIC_STRICT_UNSUPPORTED_KEYWORDS.has(key)?!0:key==="minItems"?value!==0&&value!==1:key==="format"?typeof value!="string"||!ANTHROPIC_STRICT_STRING_FORMATS.has(value):!1;function convertTools(tools,isOAuthToken2,supportsEagerToolInputStreaming,supportsStrictTools,cacheControl,deferLoading=!1){return tools?tools.map((tool,index)=>{let strict=resolveJsonSchemaStrictSampling(tool,supportsStrictTools,isAnthropicStrictUnsupportedKeyword),parameters=getJsonSchemaToolParameters(tool,strict),schema=resolveRootObjectSchema(parameters),legacyInputSchema={type:"object",properties:schema.properties??{},required:schema.required??[]},inputSchema=strict===!0?{...parameters,...legacyInputSchema}:legacyInputSchema;return{name:isOAuthToken2?toClaudeCodeName(tool.name):tool.name,description:tool.description,...supportsEagerToolInputStreaming?{eager_input_streaming:!0}:{},...strict===!0?{strict:!0}:{},input_schema:inputSchema,...deferLoading?{defer_loading:!0}:{},...cacheControl&&index===tools.length-1?{cache_control:cacheControl}:{}}}):[]}function mapStopReason(reason,stopDetails){let explanation=stopDetails?.explanation;switch(reason){case"end_turn":return{stopReason:"stop"};case"max_tokens":return{stopReason:"length"};case"tool_use":return{stopReason:"toolUse"};case"refusal":return{stopReason:"error",errorMessage:explanation||"The model refused to complete the request",stopDetails:explanation==null?{type:"refusal"}:{type:"refusal",explanation}};case"pause_turn":return{stopReason:"stop"};case"stop_sequence":return{stopReason:"stop"};case"sensitive":return{stopReason:"error",errorMessage:"Provider stopped with: sensitive",stopDetails:{type:"sensitive"}};default:throw new Error(`Unhandled stop reason: ${reason}`)}}export{buildAnthropicWarmPromptCacheParams,fromClaudeCodeName,getAnthropicCompat,stream,streamSimple,toClaudeCodeName};
@@ -1,8 +0,0 @@
1
- import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{RPC_ERROR_UNKNOWN_COMMAND,unknownCommandErrorFromWire}from"./chunk-QYWXDE47.js";import{clientMessageIdentity}from"./chunk-IRKWZZKD.js";import{socketNeedsHandshake}from"./chunk-QKU6JOA4.js";import{readSocketSecret,resolveSocketTransportAddress,sendSocketHandshake,socketSecretPath}from"./chunk-NEFNNQSV.js";import{attachJsonlLineReader,serializeJsonLine}from"./chunk-Q3R44CGT.js";import{existsSync}from"node:fs";function getMissingSessionCwdIssue(sessionManager,fallbackCwd){let sessionFile=sessionManager.getSessionFile();if(!sessionFile)return;let sessionCwd=sessionManager.getCwd();if(!(!sessionCwd||existsSync(sessionCwd)))return{sessionFile,sessionCwd,fallbackCwd}}function formatMissingSessionCwdError(issue){let sessionFile=issue.sessionFile?`
3
- Session file: ${issue.sessionFile}`:"";return`Stored session working directory does not exist: ${issue.sessionCwd}${sessionFile}
4
- Current working directory: ${issue.fallbackCwd}`}function formatMissingSessionCwdPrompt(issue){return`cwd from session file does not exist
5
- ${issue.sessionCwd}
6
-
7
- continue in current cwd
8
- ${issue.fallbackCwd}`}var MissingSessionCwdError=class extends Error{constructor(issue){super(formatMissingSessionCwdError(issue)),this.name="MissingSessionCwdError",this.issue=issue}};function assertSessionCwdExists(sessionManager,fallbackCwd){let issue=getMissingSessionCwdIssue(sessionManager,fallbackCwd);if(issue)throw new MissingSessionCwdError(issue)}import{spawn}from"node:child_process";import{createConnection}from"node:net";var StreamIdleTimeoutError=class extends Error{constructor(idleTimeoutMs){super(`Summarization stream stalled: no provider events for ${idleTimeoutMs}ms; treating the request as dead`),this.name="StreamIdleTimeoutError",this.idleTimeoutMs=idleTimeoutMs}},StreamDurationBudgetError=class extends Error{constructor(maxDurationMs){super(`Summarization stream exceeded its ${maxDurationMs}ms wall-clock budget; treating the request as too slow to keep the session waiting`),this.name="StreamDurationBudgetError",this.maxDurationMs=maxDurationMs}},DEFAULT_SUMMARIZATION_IDLE_TIMEOUT_MS=3e5,DEFAULT_SUMMARIZATION_MAX_DURATION_MS=12e4,SUMMARIZATION_MAX_DURATION_PER_TOKEN_MS=2,SUMMARIZATION_MAX_DURATION_CAP_MS=18e5,SUMMARIZATION_TOTAL_BUDGET_MS=9e5;function summarizationTotalBudgetMs(attemptOverrideMs){let override=attemptOverrideMs!==void 0&&Number.isFinite(attemptOverrideMs)&&attemptOverrideMs>0?Math.min(SUMMARIZATION_MAX_DURATION_CAP_MS,attemptOverrideMs):0;return Math.max(SUMMARIZATION_TOTAL_BUDGET_MS,override)}var SummarizationTotalBudgetError=class extends Error{constructor(totalBudgetMs){super(`Compaction exceeded its ${totalBudgetMs}ms total wall-clock budget across every summarization attempt and retry`),this.name="SummarizationTotalBudgetError",this.totalBudgetMs=totalBudgetMs}};function createSummarizationDeadline(totalBudgetMs,now=Date.now){let startedMs=now(),remainingMs=()=>Math.max(0,totalBudgetMs-(now()-startedMs));return{totalBudgetMs,remainingMs,attemptBudgetMs:requestedMs=>{let remaining=remainingMs();if(remaining<=0)throw new SummarizationTotalBudgetError(totalBudgetMs);return Math.min(requestedMs,remaining)}}}function summarizationMaxDurationMs(estimatedInputTokens,overrideMs){if(overrideMs!==void 0&&Number.isFinite(overrideMs)&&overrideMs>0)return Math.min(SUMMARIZATION_MAX_DURATION_CAP_MS,overrideMs);let scaled=estimatedInputTokens*SUMMARIZATION_MAX_DURATION_PER_TOKEN_MS;return Math.min(SUMMARIZATION_MAX_DURATION_CAP_MS,Math.max(DEFAULT_SUMMARIZATION_MAX_DURATION_MS,scaled))}var IDLE_TRIP="idle-trip",BUDGET_TRIP="budget-trip",CALLER_ABORTED="caller-aborted";async function consumeStreamWithIdleTimeout(stream,options){let{idleTimeoutMs,maxDurationMs,abort,onEvent,signal,settle}=options,iterator,removeAbortListener,callerAbortPromise,budgetPromise,budgetTimer,budgetMs=0;if(maxDurationMs!==void 0){budgetMs=maxDurationMs;let{promise,resolve}=Promise.withResolvers();budgetTimer=setTimeout(()=>resolve(BUDGET_TRIP),budgetMs),budgetTimer.unref?.(),budgetPromise=promise}if(signal!==void 0&&!signal.aborted){let{promise,resolve}=Promise.withResolvers(),onAbort=()=>resolve(CALLER_ABORTED);signal.addEventListener("abort",onAbort,{once:!0}),removeAbortListener=()=>signal.removeEventListener("abort",onAbort),callerAbortPromise=promise}let settleUnderWatchdogs=async()=>{if(!settle)return;let{promise:idlePromise,resolve:resolveIdle}=Promise.withResolvers(),timer=setTimeout(()=>resolveIdle(IDLE_TRIP),idleTimeoutMs);timer.unref?.();let contenders=[settle().then(value=>({settled:value})),idlePromise];budgetPromise&&contenders.push(budgetPromise);let outcome;try{outcome=await Promise.race(contenders)}finally{clearTimeout(timer)}if(outcome===IDLE_TRIP)throw abort(),new StreamIdleTimeoutError(idleTimeoutMs);if(outcome===BUDGET_TRIP)throw abort(),new StreamDurationBudgetError(budgetMs);return outcome.settled};try{if(signal?.aborted)return await settleUnderWatchdogs();let resolvedStream;if(Symbol.asyncIterator in stream)resolvedStream=stream;else{let streamContenders=[Promise.resolve(stream)];callerAbortPromise&&streamContenders.push(callerAbortPromise),budgetPromise&&streamContenders.push(budgetPromise);let resolution=await Promise.race(streamContenders);if(resolution===BUDGET_TRIP)throw abort(),new StreamDurationBudgetError(budgetMs);if(resolution===CALLER_ABORTED)return await settleUnderWatchdogs();resolvedStream=resolution}for(iterator=resolvedStream[Symbol.asyncIterator]();;){let{promise:idlePromise,resolve:resolveIdle}=Promise.withResolvers(),timer=setTimeout(()=>resolveIdle(IDLE_TRIP),idleTimeoutMs);timer.unref?.();let contenders=[iterator.next(),idlePromise];callerAbortPromise&&contenders.push(callerAbortPromise),budgetPromise&&contenders.push(budgetPromise);let result;try{result=await Promise.race(contenders)}finally{clearTimeout(timer)}if(result===IDLE_TRIP)throw abort(),iterator?.return?.(),new StreamIdleTimeoutError(idleTimeoutMs);if(result===BUDGET_TRIP)throw abort(),iterator?.return?.(),new StreamDurationBudgetError(budgetMs);if(result===CALLER_ABORTED)return iterator?.return?.(),await settleUnderWatchdogs();if(result.done)return await settleUnderWatchdogs();onEvent?.(result.value)}}finally{removeAbortListener?.(),budgetTimer!==void 0&&clearTimeout(budgetTimer)}}var REQUEST_DEADLINE_MS=3e4,PROMPT_COMPACTION_DEADLINE_MS=SUMMARIZATION_TOTAL_BUDGET_MS+SUMMARIZATION_MAX_DURATION_CAP_MS+REQUEST_DEADLINE_MS,PROMPT_ACK_MAX_WAIT_MS=PROMPT_COMPACTION_DEADLINE_MS+REQUEST_DEADLINE_MS,OPEN_AFTER_QUEUED_DEADLINE_MS=10*6e4,PROMPT_AFTER_QUEUED_DEADLINE_MS=5*6e4;function promptStalledMessage(){return`prompt was received by the host but not accepted within ${PROMPT_AFTER_QUEUED_DEADLINE_MS/6e4} minutes`}function openStalledMessage(position){let queued=typeof position=="number"?` at queue position ${position}`:"",minutes=OPEN_AFTER_QUEUED_DEADLINE_MS/6e4;return`open_session was accepted by the host${queued} but not answered within ${minutes} minutes`}function armRequestDeadline(ms,message,expire){let timer=setTimeout(()=>expire(new Error(message())),ms);return{extend(nextMs,nextMessage){clearTimeout(timer),timer=setTimeout(()=>expire(new Error(nextMessage())),nextMs)},clear(){clearTimeout(timer)}}}var RpcCommandError=class extends Error{constructor(message,errorCode,errorData){super(message),this.name="RpcCommandError",this.errorCode=errorCode,this.errorData=errorData}};function isProviderAccountEvent(event){return event.type==="auth_accounts_changed"||event.type==="account_failover"}var RpcTransportGoneError=class extends Error{constructor(message="Shared RPC host is unavailable"){super(message),this.code="rpc_transport_gone",this.name="RpcTransportGoneError"}};function isTransportGoneError(error){return error instanceof RpcTransportGoneError||error instanceof Error&&(error.message==="Client not started"||error.message.startsWith("RPC transport is not writable.")||error.message==="RPC socket closed")}var RpcClientOpenInFlightError=class extends Error{constructor(){super("An open_session request is already in flight"),this.code="open_session_in_flight",this.name="RpcClientOpenInFlightError"}},MAX_PENDING_SESSION_EVENTS=512,MAX_PENDING_SESSION_EVENT_BYTES=1024*1024,RpcClient=class{constructor(options={}){this.process=null,this.socket=null,this.stopReadingStdout=null,this.eventListeners=[],this.pendingRequests=new Map,this.requestId=0,this.compactions=new Map,this.pendingOpenSession=!1,this.pendingSessionEvents=[],this.pendingSessionEventBytes=0,this.stderr="",this.exitError=null,this.disconnectNotified=!1,this.stopping=!1,this.options=options,this.onEvent(event=>{switch(event.type){case"compaction_start":{let key=event.requestId??"";if(this.compactions.has(key))return;this.compactions.set(key,Date.now());break}case"compaction_end":if(!this.compactions.delete(event.requestId??""))return;break;case"session_replaced":this.compactions.clear();break;default:return}for(let pending of this.pendingRequests.values())pending.sessionId===this.sessionId&&pending.onCompaction?.(this.isCompacting())})}async start(){if(this.process||this.socket)throw new Error("Client already started");if(this.exitError=null,this.compactions.clear(),this.stopping=!1,this.disconnectNotified=!1,this.options.socketPath){await this.startSocket(this.options.socketPath);return}let cliPath=this.options.cliPath??"dist/cli.js",args=["--mode","rpc"];this.options.provider&&this.options.model&&args.push("--provider",this.options.provider),this.options.model&&args.push("--model",this.options.model),this.options.args&&args.push(...this.options.args);let childProcess=spawn("node",[cliPath,...args],{cwd:this.options.cwd,env:{...process.env,SENPI_RUNTIME:"node",...this.options.env},stdio:["pipe","pipe","pipe"],windowsHide:!0});if(this.process=childProcess,childProcess.stderr?.on("data",data=>{this.stderr+=data.toString(),process.stderr.write(data)}),childProcess.once("exit",(code,signal)=>{if(this.process!==childProcess)return;let error=this.createProcessExitError(code,signal);this.exitError=error,this.rejectPendingRequests(error)}),childProcess.once("error",error=>{if(this.process!==childProcess)return;let processError=new Error(`Agent process error: ${error.message}. Stderr: ${this.stderr}`);this.exitError=processError,this.rejectPendingRequests(processError)}),childProcess.stdin?.on("error",error=>{if(this.process!==childProcess)return;let stdinError=this.exitError??new Error(`Agent process stdin error: ${error.message}. Stderr: ${this.stderr}`);this.exitError=stdinError,this.rejectPendingRequests(stdinError)}),this.stopReadingStdout=attachJsonlLineReader(childProcess.stdout,line=>{this.handleLine(line)}),await new Promise(resolve=>setTimeout(resolve,100)),this.process.exitCode!==null){let error=this.exitError??this.createProcessExitError(this.process.exitCode,this.process.signalCode);throw this.exitError=error,error}}isCompacting(){let now=Date.now();for(let[key,startedAt]of this.compactions)now-startedAt>=PROMPT_COMPACTION_DEADLINE_MS&&this.compactions.delete(key);return this.compactions.size>0}async stop(){if(this.compactions.clear(),this.pendingOpenSession=!1,this.pendingSessionEvents=[],this.pendingSessionEventBytes=0,this.socket){this.stopping=!0,this.stopReadingStdout?.(),this.stopReadingStdout=null,this.socket.destroy(),this.socket=null,this.sessionId=void 0,this.pendingOpenSession=!1,this.pendingSessionEvents=[],this.notifyDisconnect(new RpcTransportGoneError);return}this.process&&(this.stopReadingStdout?.(),this.stopReadingStdout=null,this.process.kill("SIGTERM"),await new Promise(resolve=>{let timeout=setTimeout(()=>{this.process?.kill("SIGKILL"),resolve()},1e3);this.process?.on("exit",()=>{clearTimeout(timeout),resolve()})}),this.process=null,this.pendingRequests.clear())}async startSocket(path){let secret=socketNeedsHandshake(path)?await readSocketSecret(socketSecretPath(path)):void 0,socket=createConnection(resolveSocketTransportAddress(path,process.platform,secret));this.socket=socket,await new Promise((resolve,reject)=>{let onConnect=()=>{cleanup(),resolve()},onError=error=>{cleanup(),this.socket=null,reject(error)},cleanup=()=>{socket.off("connect",onConnect),socket.off("error",onError)};socket.once("connect",onConnect),socket.once("error",onError)}),secret&&sendSocketHandshake(socket,secret),this.stopReadingStdout=attachJsonlLineReader(socket,line=>this.handleLine(line)),socket.once("close",()=>{this.socket===socket&&(this.socket=null,this.notifyDisconnect(new RpcTransportGoneError))}),socket.once("error",error=>{this.socket===socket&&this.notifyDisconnect(new RpcTransportGoneError)})}onEvent(listener){return this.eventListeners.push(listener),()=>{let index=this.eventListeners.indexOf(listener);index!==-1&&this.eventListeners.splice(index,1)}}getStderr(){return this.stderr}async setClientInfo(width,capabilities){await this.send({type:"set_client_info",width,capabilities},this.sessionId!==void 0)}async openSession(options){if(this.pendingOpenSession)throw new RpcClientOpenInFlightError;this.pendingOpenSession=!0;try{let response=await this.send({type:"open_session",...options},!1),opened=this.getData(response);return this.sessionId=opened.sessionId,this.compactions.clear(),this.pendingOpenSession=!1,this.flushPendingSessionEvents(),opened}catch(error){throw this.pendingOpenSession=!1,this.pendingSessionEvents=[],this.pendingSessionEventBytes=0,error}}async sendExtensionUIResponse(response){await this.send(response,!0,void 0,!1)}async sendExtensionUIProgress(progress){await this.send(progress,!0,void 0,!1)}async closeSession(sessionId=this.sessionId){if(sessionId){try{this.getData(await this.send({type:"close_session",sessionId},!1))}catch(error){if(!isTransportGoneError(error))throw error}this.sessionId===sessionId&&(this.sessionId=void 0,this.compactions.clear())}}async listSessions(options){let response=await this.send({type:"list_sessions",...options},!1);return this.getData(response).sessions}async prompt(message,optionsOrImages){let options=Array.isArray(optionsOrImages)?{images:optionsOrImages}:optionsOrImages??{},response=await this.send({type:"prompt",message,...clientMessageIdentity(options),...options.images?{images:options.images}:{},...options.streamingBehavior?{streamingBehavior:options.streamingBehavior}:{},...options.thinkingLevel?{thinkingLevel:options.thinkingLevel}:{},...options.sessionTitlePrompt!==void 0?{sessionTitlePrompt:options.sessionTitlePrompt}:{},...options.expandPromptTemplates!==void 0?{expandPromptTemplates:options.expandPromptTemplates}:{},...options.unknownCommandAsText?{unknownCommandAsText:!0}:{}},!0,{onResponse:wireResponse=>{if(!wireResponse.success){options?.preflightResult?.(!1);return}let data=wireResponse.data;options?.promptDisposition?.(data?.disposition??"handled"),options?.preflightResult?.(!0)},onReject:()=>{options?.preflightResult?.(!1)}});if(!response.success){let failure=response;throw(failure.errorCode===RPC_ERROR_UNKNOWN_COMMAND?unknownCommandErrorFromWire(failure.errorData):void 0)??new RpcCommandError(failure.error,failure.errorCode,failure.errorData)}return response.data?.disposition??"handled"}async appendUserMessage(content){await this.send({type:"append_user_message",content})}async appendSessionEntry(entry){await this.send({type:"append_session_entry",entry})}async sendCustomMessage(message,options){await this.send({type:"send_custom_message",...message,...options})}async continueFromLeaf(){let response=await this.send({type:"continue_from_leaf"});this.getData(response)}async steer(message,images,recovery){let response=await this.send({type:"steer",message,images,enqueueOrder:recovery?.enqueueOrder,...clientMessageIdentity(recovery)});return this.getData(response)?.disposition??"handled"}async followUp(message,images,recovery){let response=await this.send({type:"follow_up",message,images,enqueueOrder:recovery?.enqueueOrder,...clientMessageIdentity(recovery)});return this.getData(response)?.disposition??"handled"}async abort(){try{await this.send({type:"abort"})}catch(error){if(!isTransportGoneError(error))throw error}}async abortStrict(){this.getData(await this.send({type:"abort"}))}async abortCompaction(){await this.send({type:"abort_compaction"})}async reload(){let response=await this.send({type:"reload"});return this.getData(response)}async checkReloadVeto(){let response=await this.send({type:"check_reload_veto"});return this.getData(response)}async clearQueue(options){let response=await this.send({type:"clear_queue",abortWillFollow:options?.abortWillFollow});return this.getData(response)}async getSteeringMessages(){let response=await this.send({type:"get_steering_messages"});return this.getData(response).messages}async getFollowUpMessages(){let response=await this.send({type:"get_follow_up_messages"});return this.getData(response).messages}async abortBranchSummary(){await this.send({type:"abort_branch_summary"})}async recordBashResult(command,result,excludeFromContext){await this.send({type:"record_bash_result",command,result,excludeFromContext})}async setLabel(entryId,label){await this.send({type:"set_label",entryId,label})}async newSession(parentSession){let response=await this.send({type:"new_session",parentSession});return this.getData(response)}async getState(){let response=await this.send({type:"get_state"});return this.getData(response)}async setModel(provider,modelId){let response=await this.send({type:"set_model",provider,modelId});return this.getData(response)}async setFavoriteModels(models){await this.send({type:"set_favorite_models",models})}async setScopedModels(models){await this.send({type:"set_scoped_models",models})}async cycleModel(direction="forward"){let response=await this.send({type:"cycle_model",direction});return this.getData(response)}async getAvailableModels(){let response=await this.send({type:"get_available_models"});return this.getData(response).models}async setThinkingLevel(level,options){let response=await this.send({type:"set_thinking_level",level,scope:options?.scope});if(!response.success)throw new Error(response.error)}async cycleThinkingLevel(){let response=await this.send({type:"cycle_thinking_level"});return this.getData(response)}async getAvailableThinkingLevels(){let response=await this.send({type:"get_available_thinking_levels"});return this.getData(response).levels}async setFastMode(enabled){let response=await this.send({type:"set_fast_mode",enabled});return this.getData(response)}async getFastMode(){let response=await this.send({type:"get_fast_mode"});return this.getData(response)}async setSteeringMode(mode){await this.send({type:"set_steering_mode",mode})}async setFollowUpMode(mode){await this.send({type:"set_follow_up_mode",mode})}async compact(customInstructions){let response=await this.send({type:"compact",customInstructions});return this.getData(response)}async setAutoCompaction(enabled){await this.send({type:"set_auto_compaction",enabled})}async setAutoRetry(enabled){await this.send({type:"set_auto_retry",enabled})}async abortRetry(){await this.send({type:"abort_retry"})}async setRetryFallback(retryFallback){await this.send({type:"set_retry_fallback",retryFallback})}async bash(command,options){let response=await this.send({type:"bash",command,excludeFromContext:options?.excludeFromContext,executionId:options?.executionId,operations:options?.operations});return this.getData(response)}async navigateTree(targetId,options){let response=await this.send({type:"navigate_tree",targetId,...options});return this.getData(response)}async abortBash(){await this.send({type:"abort_bash"})}async cleanupBashOutput(path){await this.send({type:"cleanup_bash_output",path})}async getSessionStats(){let response=await this.send({type:"get_session_stats"});return this.getData(response)}async exportHtml(outputPath,themeName){let response=await this.send({type:"export_html",outputPath,themeName});return this.getData(response)}async exportJsonl(outputPath){let response=await this.send({type:"export_jsonl",outputPath});return this.getData(response)}async switchSession(sessionPath,options){let response=await this.send({type:"switch_session",sessionPath,cwdOverride:options?.cwdOverride});return this.getData(response)}async fork(entryId,options){let response=await this.send({type:"fork",entryId,position:options?.position});return this.getData(response)}async clone(){let response=await this.send({type:"clone"});return this.getData(response)}async getForkMessages(){let response=await this.send({type:"get_fork_messages"});return this.getData(response).messages}async getEntries(since){let response=await this.send({type:"get_entries",since});return this.getData(response)}async getTree(){let response=await this.send({type:"get_tree"});return this.getData(response)}async editAssistantMessage(entryId,text,options={}){let response=await this.send({type:"edit_assistant_message",entryId,text,expectedLeafId:options.expectedLeafId,summarize:options.summarize,customInstructions:options.customInstructions});return this.getData(response)}async editUserMessage(entryId,text,options={}){let response=await this.send({type:"edit_user_message",entryId,text,expectedLeafId:options.expectedLeafId,summarize:options.summarize,customInstructions:options.customInstructions});return this.getData(response)}async getLastAssistantText(){let response=await this.send({type:"get_last_assistant_text"});return this.getData(response).text}async setSessionName(name){await this.send({type:"set_session_name",name})}async importJsonl(inputPath,cwdOverride){let response=await this.send({type:"import_jsonl",inputPath,cwdOverride});return this.getData(response)}async getMessages(){let response=await this.send({type:"get_messages"});return this.getData(response).messages}async getMedia(toolCallId,contentIndex){let response=await this.send({type:"get_media",toolCallId,contentIndex});return this.getData(response).content}async getCommands(){let response=await this.send({type:"get_commands"});return this.getData(response).commands}async requestExtension(name,data){let response=await this.send({type:"extension_request",name,...data===void 0?{}:{data}});return this.getData(response)}async getProviderAccounts(provider){let response=await this.send({type:"get_provider_accounts",provider});return this.getData(response).accounts}async pinProviderAccount(provider,name){await this.send({type:"account_pin",provider,name})}async removeProviderAccount(provider,name){await this.send({type:"account_remove",provider,name})}waitForIdle(timeout=6e4){return new Promise((resolve,reject)=>{let timer=setTimeout(()=>{unsubscribe(),reject(new Error(`Timeout waiting for agent to become idle. Stderr: ${this.stderr}`))},timeout),unsubscribe=this.onEvent(event=>{event.type==="agent_settled"&&(clearTimeout(timer),unsubscribe(),resolve())})})}collectEvents(timeout=6e4){return new Promise((resolve,reject)=>{let events=[],timer=setTimeout(()=>{unsubscribe(),reject(new Error(`Timeout collecting events. Stderr: ${this.stderr}`))},timeout),unsubscribe=this.onEvent(event=>{isProviderAccountEvent(event)||event.type==="extension_event"||event.type==="bash_start"||event.type==="bash_end"||event.type==="extension_ui_request"||event.type==="session_replaced"||event.type==="session_parked"||event.type==="queued"||(events.push(event),event.type==="agent_settled"&&(clearTimeout(timer),unsubscribe(),resolve(events)))})})}async promptAndWait(message,images,timeout=6e4){let eventsPromise=this.collectEvents(timeout);return await this.prompt(message,images?{images}:void 0),eventsPromise}handleLine(line){try{let data=JSON.parse(line);if(data.type==="response"&&data.id&&this.pendingRequests.has(data.id)){let pending=this.pendingRequests.get(data.id);this.pendingRequests.delete(data.id),pending.onResponse?.(data),pending.resolve(data);return}if(data.type==="queued"&&typeof data.for_request=="string"&&this.pendingRequests.get(data.for_request)?.onQueued?.(data.position),typeof data.sessionId=="string"&&data.sessionId!==this.sessionId){if(this.pendingOpenSession){let bytes=Buffer.byteLength(line);for(this.pendingSessionEvents.push({sessionId:data.sessionId,event:data,bytes}),this.pendingSessionEventBytes+=bytes;this.pendingSessionEvents.length>MAX_PENDING_SESSION_EVENTS||this.pendingSessionEventBytes>MAX_PENDING_SESSION_EVENT_BYTES;){let oldest=this.pendingSessionEvents.shift();if(!oldest)break;this.pendingSessionEventBytes-=oldest.bytes}}return}for(let listener of[...this.eventListeners])listener(data)}catch{}}flushPendingSessionEvents(){let pending=this.pendingSessionEvents;this.pendingSessionEvents=[],this.pendingSessionEventBytes=0;for(let{sessionId,event}of pending)if(sessionId===this.sessionId)for(let listener of[...this.eventListeners])listener(event)}createProcessExitError(code,signal){return new Error(`Agent process exited (code=${code} signal=${signal}). Stderr: ${this.stderr}`)}notifyDisconnect(error){this.rejectPendingRequests(error),!this.disconnectNotified&&!this.stopping&&(this.disconnectNotified=!0,this.options.onDisconnect?.(error))}rejectPendingRequests(error){for(let pending of this.pendingRequests.values())pending.onReject?.(error),pending.reject(error);this.pendingRequests.clear()}async send(command,route=!0,hooks,expectResponse=!0){let childProcess=this.process,stream=this.socket??childProcess?.stdin;if(!stream)throw new RpcTransportGoneError;if(this.exitError)throw this.exitError;if(childProcess?.exitCode!==null&&childProcess?.exitCode!==void 0){let error=this.createProcessExitError(childProcess.exitCode,childProcess.signalCode);throw this.exitError=error,error}if(stream.destroyed||!stream.writable){let error=new RpcTransportGoneError;throw this.notifyDisconnect(error),error}let ownId=command.type==="extension_ui_response"||command.type==="extension_ui_progress"?command.id:void 0,id=ownId??`req_${++this.requestId}`,fullCommand={...command,...route&&this.sessionId&&!("sessionId"in command)?{sessionId:this.sessionId}:{},...ownId===void 0?{id}:{}};if(!expectResponse)return stream.write(serializeJsonLine(fullCommand)),Promise.resolve({type:"response",command:command.type,success:!0});let sessionId="sessionId"in fullCommand?fullCommand.sessionId:void 0;return new Promise((resolve,reject)=>{let timeoutMessage=()=>`Timeout waiting for response to ${command.type}. Stderr: ${this.stderr}`,promptCap,promptReceived=!1,expire=timeoutError=>{clearTimeout(promptCap);let pending=this.pendingRequests.get(id);this.pendingRequests.delete(id),pending?.onReject?.(timeoutError),reject(timeoutError)},deadline=armRequestDeadline(command.type==="prompt"&&sessionId===this.sessionId&&this.isCompacting()?PROMPT_COMPACTION_DEADLINE_MS:REQUEST_DEADLINE_MS,timeoutMessage,expire);command.type==="prompt"&&(promptCap=setTimeout(()=>{deadline.clear(),expire(new Error(timeoutMessage()))},PROMPT_ACK_MAX_WAIT_MS)),this.pendingRequests.set(id,{sessionId,resolve:response=>{deadline.clear(),clearTimeout(promptCap),resolve(response)},reject:error=>{deadline.clear(),clearTimeout(promptCap),reject(error)},...command.type==="prompt"?{onCompaction:compacting=>compacting?deadline.extend(PROMPT_COMPACTION_DEADLINE_MS,timeoutMessage):promptReceived?deadline.extend(PROMPT_AFTER_QUEUED_DEADLINE_MS,promptStalledMessage):deadline.extend(REQUEST_DEADLINE_MS,timeoutMessage),onQueued:()=>{promptReceived=!0,this.isCompacting()||deadline.extend(PROMPT_AFTER_QUEUED_DEADLINE_MS,promptStalledMessage)}}:{},...command.type==="open_session"?{onQueued:position=>deadline.extend(OPEN_AFTER_QUEUED_DEADLINE_MS,()=>openStalledMessage(position))}:{},...hooks?.onResponse?{onResponse:hooks.onResponse}:{},...hooks?.onReject?{onReject:hooks.onReject}:{}});try{stream.write(serializeJsonLine(fullCommand))}catch(error){let writeError=error instanceof Error?error:new Error(String(error)),pending=this.pendingRequests.get(id);this.pendingRequests.delete(id),pending?.onReject?.(writeError),pending?.reject(writeError)}})}getData(response){if(!response.success){let errorResponse=response;throw errorResponse.errorCode==="missing_session_cwd"&&errorResponse.errorData?new MissingSessionCwdError(errorResponse.errorData):new RpcCommandError(errorResponse.error,errorResponse.errorCode,errorResponse.errorData)}return response.data}};export{StreamIdleTimeoutError,StreamDurationBudgetError,DEFAULT_SUMMARIZATION_IDLE_TIMEOUT_MS,DEFAULT_SUMMARIZATION_MAX_DURATION_MS,SUMMARIZATION_MAX_DURATION_PER_TOKEN_MS,SUMMARIZATION_TOTAL_BUDGET_MS,summarizationTotalBudgetMs,SummarizationTotalBudgetError,createSummarizationDeadline,summarizationMaxDurationMs,consumeStreamWithIdleTimeout,getMissingSessionCwdIssue,formatMissingSessionCwdPrompt,MissingSessionCwdError,assertSessionCwdExists,RpcCommandError,RpcTransportGoneError,isTransportGoneError,RpcClientOpenInFlightError,RpcClient};
@@ -1,2 +0,0 @@
1
- import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{engineBuildIdentity}from"./chunk-ZJHRDQCH.js";import{HOST_GENERATION_ENV,HOST_INSTANCE_ID_ENV}from"./chunk-Q3R44CGT.js";import{parseArgs,resolveSessionRuntime}from"./chunk-VE3D74HN.js";import*as crypto from"node:crypto";var CUSTOM_UNSUPPORTED_CAPABILITY="custom_unsupported",EXTENSION_EVENTS_CAPABILITY="extension_events",AUTO_TITLE_SESSIONS_CAPABILITY="auto_title_sessions",CONTINUE_FROM_LEAF_CAPABILITY="continue_from_leaf",SESSION_HELD_CAPABILITY="session_held",MEDIA_PLACEHOLDERS_CAPABILITY="media_placeholders",QUESTION_CAPABILITY="question",RETAIN_ON_DISCONNECT_CAPABILITY="retain_on_disconnect",SESSION_CONTEXT_CAPABILITY="session_context",SESSION_KIND_CAPABILITY="session_kind",AUTO_TITLE_PER_SESSION_CAPABILITY="auto_title_per_session",WARM_CAPABILITY="warm",DURABLE_SESSION_ID_CAPABILITY="durable_session_id",MOVED_PATH_GUARD_CAPABILITY="moved_path_guard",PROMPT_SURFACE_CAPABILITY="prompt_surface",BROWSER_ENGINE_CAPABILITY="browser_engine",RETRY_FALLBACK_PROFILE_CAPABILITY="retry_fallback_profile",RETRY_FALLBACK_COMMAND_CAPABILITY="retry_fallback_command",PROMPT_SURFACE_CHAT_CAPABILITY="prompt_surface_chat",RPC_CLIENT_CAPABILITIES_ENV="SENPI_RPC_CLIENT_CAPABILITIES";function parseClientCapabilities(value){return value?value.split(",").map(part=>part.trim()).filter(part=>part.length>0):[]}var DEFAULT_CUSTOM_EXTENSION_LABEL="custom UI component";function buildCustomUnsupportedRequest(capabilities,extensionName){if(!capabilities?.includes(CUSTOM_UNSUPPORTED_CAPABILITY))return;let name=extensionName.trim()||DEFAULT_CUSTOM_EXTENSION_LABEL;return{type:"extension_ui_request",id:crypto.randomUUID(),method:"custom_unsupported",extensionName:name}}import{createHash,randomUUID as randomUUID2}from"node:crypto";import{resolve}from"node:path";var INSTANCE_ID=resolveInstanceId(process.env[HOST_INSTANCE_ID_ENV]);function resolveInstanceId(value){return value!==void 0&&value.trim()!==""?value:randomUUID2()}function hostInstanceId(){return INSTANCE_ID}var cachedProfile;function hostGeneration(env){let value=env[HOST_GENERATION_ENV];return value!==void 0&&/^\d+$/.test(value)?Number(value):0}function hostLaunchProfile(argv,cwd){let parsed=parseArgs([...argv],{grokNeoEnabled:!1}),core={extensions:[...new Set((parsed.extensions??[]).map(path=>resolve(cwd,path)))].sort(),multi_session:parsed.multiSession===!0,session_runtime:resolveSessionRuntime(parsed)},canonical=JSON.stringify({extensions:core.extensions,multi_session:core.multi_session,session_runtime:core.session_runtime});return{profile_id:createHash("sha256").update(canonical).digest("hex"),core}}function socketHostLaunchProfile(hostArgs,cwd){return hostLaunchProfile(["--mode","rpc","--multi-session","--listen","unix://",...hostArgs],cwd)}function protocolIdentity(){cachedProfile??=hostLaunchProfile(process.argv.slice(2),process.cwd());let build=engineBuildIdentity();return{instanceId:INSTANCE_ID,generation:hostGeneration(process.env),engineVersion:build.text,engineOrdinal:build.ordinal,launch_profile:cachedProfile}}export{CUSTOM_UNSUPPORTED_CAPABILITY,EXTENSION_EVENTS_CAPABILITY,AUTO_TITLE_SESSIONS_CAPABILITY,CONTINUE_FROM_LEAF_CAPABILITY,SESSION_HELD_CAPABILITY,MEDIA_PLACEHOLDERS_CAPABILITY,QUESTION_CAPABILITY,RETAIN_ON_DISCONNECT_CAPABILITY,SESSION_CONTEXT_CAPABILITY,SESSION_KIND_CAPABILITY,AUTO_TITLE_PER_SESSION_CAPABILITY,WARM_CAPABILITY,DURABLE_SESSION_ID_CAPABILITY,MOVED_PATH_GUARD_CAPABILITY,PROMPT_SURFACE_CAPABILITY,BROWSER_ENGINE_CAPABILITY,RETRY_FALLBACK_PROFILE_CAPABILITY,RETRY_FALLBACK_COMMAND_CAPABILITY,PROMPT_SURFACE_CHAT_CAPABILITY,RPC_CLIENT_CAPABILITIES_ENV,parseClientCapabilities,DEFAULT_CUSTOM_EXTENSION_LABEL,buildCustomUnsupportedRequest,hostInstanceId,hostGeneration,hostLaunchProfile,socketHostLaunchProfile,protocolIdentity};
@@ -1,2 +0,0 @@
1
- import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
2
- import{getProviderEnvValue}from"./chunk-5ROMKDLK.js";var PROMPT_CACHE_TTL_SHORT_SECONDS=300,PROMPT_CACHE_TTL_LONG_SECONDS=3600,PROMPT_CACHE_TTL_OPENAI_EXTENDED_SECONDS=1800,NO_PROMPT_CACHE={kind:"none"},BEST_EFFORT_PROMPT_CACHE={kind:"best-effort"};function ttl(ttlSeconds){return{kind:"ttl",ttlSeconds}}function hostnameOf(baseUrl){try{return new URL(baseUrl).hostname.toLowerCase()}catch{return}}function isAnthropicApiBaseUrl(baseUrl){try{return new URL(baseUrl).hostname==="api.anthropic.com"}catch{return!1}}var FORCED_TOOL_CHOICE_REJECTING_MODEL_ID=/^claude-(?:(?:fable|mythos)(?:-|$)|(?:opus|sonnet)-5[.-]5(?:[.-]|$))/i;function defaultSupportsToolReferences(model){if(model.provider!=="anthropic"||model.id.includes("haiku"))return!1;let version=model.id.match(/^claude-(?:opus|sonnet|fable)-(\d+)(?:-(\d+))?(?:-|$)/);if(!version)return!1;let major=Number(version[1]),minor=version[2]&&version[2].length<8?Number(version[2]):0;return major>4||major===4&&minor>=5}function getAnthropicCompat(model){let isFireworks=model.provider==="fireworks",isCloudflareAiGatewayAnthropic=model.provider==="cloudflare-ai-gateway"&&model.baseUrl.includes("anthropic"),isXiaomi=model.provider==="xiaomi"||model.provider.startsWith("xiaomi-token-plan-"),isOpenRouter=model.provider==="openrouter"||model.baseUrl.includes("openrouter.ai");return{supportsEagerToolInputStreaming:model.compat?.supportsEagerToolInputStreaming??!isFireworks,supportsLongCacheRetention:model.compat?.supportsLongCacheRetention??!isFireworks,sendSessionAffinityHeaders:model.compat?.sendSessionAffinityHeaders??!!(isFireworks||isCloudflareAiGatewayAnthropic||isOpenRouter),sessionAffinityFormat:model.compat?.sessionAffinityFormat??(isOpenRouter?"openrouter":void 0),supportsCacheControlOnTools:model.compat?.supportsCacheControlOnTools??!isFireworks,supportsDisabledThinking:model.compat?.supportsDisabledThinking??!isXiaomi,supportsTemperature:model.compat?.supportsTemperature??!0,supportsToolChoice:model.compat?.supportsToolChoice??!0,supportsForcedToolChoice:model.compat?.supportsForcedToolChoice??!FORCED_TOOL_CHOICE_REJECTING_MODEL_ID.test(model.id),allowEmptySignature:model.compat?.allowEmptySignature??!1,unsignedThinkingReplay:model.compat?.unsignedThinkingReplay??(model.compat?.allowEmptySignature?"empty-signature":"text"),allowedFallbackModels:model.compat?.allowedFallbackModels??[],supportsStrictTools:model.compat?.supportsStrictTools??!1,supportsMidConvoSystemMessages:model.compat?.supportsMidConvoSystemMessages??!1,supportsMidConvoToolChanges:model.compat?.supportsMidConvoToolChanges??!1,supportsToolReferences:model.compat?.supportsToolReferences??defaultSupportsToolReferences(model),supportsWebSearch:model.compat?.supportsWebSearch??isAnthropicApiBaseUrl(model.baseUrl)}}function detectOpenAICompletionsCompat(model){let provider=model.provider,baseUrl=model.baseUrl,isZai=provider==="zai"||provider==="zai-coding-cn"||baseUrl.includes("api.z.ai")||baseUrl.includes("open.bigmodel.cn"),isTogether=provider==="together"||baseUrl.includes("api.together.ai")||baseUrl.includes("api.together.xyz"),isMoonshot=provider==="moonshotai"||provider==="moonshotai-cn"||baseUrl.includes("api.moonshot."),isOpenRouter=provider==="openrouter"||baseUrl.includes("openrouter.ai"),isCloudflareWorkersAI=provider==="cloudflare-workers-ai"||baseUrl.includes("api.cloudflare.com"),isCloudflareAiGateway=provider==="cloudflare-ai-gateway"||baseUrl.includes("gateway.ai.cloudflare.com"),isNvidia=provider==="nvidia"||baseUrl.includes("integrate.api.nvidia.com"),isAntLing=provider==="ant-ling"||baseUrl.includes("api.ant-ling.com"),isCerebras=provider==="cerebras"||baseUrl.includes("cerebras.ai"),isDeepSeek=provider==="deepseek"||baseUrl.toLowerCase().includes("deepseek.com"),isNonStandard=isNvidia||isCerebras||provider==="xai"||baseUrl.includes("api.x.ai")||isTogether||baseUrl.includes("chutes.ai")||isDeepSeek||isZai||isMoonshot||provider==="opencode"||baseUrl.includes("opencode.ai")||isCloudflareWorkersAI||isCloudflareAiGateway||isAntLing,useMaxTokens=baseUrl.includes("chutes.ai")||isDeepSeek||isMoonshot||isCloudflareAiGateway||isTogether||isNvidia||isAntLing||isZai,isGrok=provider==="xai"||baseUrl.includes("api.x.ai"),isOpenRouterDeveloperRoleModel=isOpenRouter&&(model.id.startsWith("anthropic/")||model.id.startsWith("openai/")),openRouterCacheControlPrefixes=["anthropic/","qwen/","google/"],cacheControlModelId=model.id.startsWith("~")?model.id.slice(1):model.id,supportsOpenRouterCacheControl=openRouterCacheControlPrefixes.some(prefix=>cacheControlModelId.startsWith(prefix));return{supportsStore:!isNonStandard,supportsDeveloperRole:isOpenRouterDeveloperRoleModel||!isNonStandard&&!isOpenRouter,supportsReasoningEffort:!isGrok&&!isZai&&!isMoonshot&&!isTogether&&!isCloudflareAiGateway&&!isNvidia&&!isAntLing,supportsUsageInStreaming:!0,supportsFinishReason:!0,maxTokensField:useMaxTokens?"max_tokens":"max_completion_tokens",requiresToolResultName:!1,requiresAssistantAfterToolResult:!1,requiresThinkingAsText:!1,requiresReasoningContentOnAssistantMessages:isDeepSeek,thinkingFormat:isDeepSeek?"deepseek":isZai?"zai":isTogether?"together":isAntLing?"ant-ling":isOpenRouter?"openrouter":"openai",openRouterRouting:{},vercelGatewayRouting:{},chatTemplateKwargs:{},zaiToolStream:!1,supportsStrictMode:!1,toolSchemaFlavor:isMoonshot?"moonshot-mfjs":void 0,supportsDisabledThinking:!0,toolCallFormat:void 0,supportsOpenAIGrammarTools:!1,supportsMidConvoSystemMessages:!1,supportsMidConvoToolAdditions:!1,cacheControlFormat:provider==="openrouter"&&supportsOpenRouterCacheControl?"anthropic":void 0,sendSessionAffinityHeaders:isOpenRouter,deferredToolsMode:void 0,sessionAffinityFormat:isOpenRouter?"openrouter":"openai",supportsPromptCacheKey:isMoonshot||baseUrl.includes("api.openai.com"),supportsMaxOutputTokens:!0,supportsLongCacheRetention:!(isTogether||isCloudflareWorkersAI||isCloudflareAiGateway||isNvidia||isAntLing)}}function getOpenAICompletionsCompat(model){let detected=detectOpenAICompletionsCompat(model);return model.compat?{supportsStore:model.compat.supportsStore??detected.supportsStore,supportsDeveloperRole:model.compat.supportsDeveloperRole??detected.supportsDeveloperRole,supportsReasoningEffort:model.compat.supportsReasoningEffort??detected.supportsReasoningEffort,supportsUsageInStreaming:model.compat.supportsUsageInStreaming??detected.supportsUsageInStreaming,supportsFinishReason:model.compat.supportsFinishReason??detected.supportsFinishReason,maxTokensField:model.compat.maxTokensField??detected.maxTokensField,requiresToolResultName:model.compat.requiresToolResultName??detected.requiresToolResultName,requiresAssistantAfterToolResult:model.compat.requiresAssistantAfterToolResult??detected.requiresAssistantAfterToolResult,requiresThinkingAsText:model.compat.requiresThinkingAsText??detected.requiresThinkingAsText,requiresReasoningContentOnAssistantMessages:model.compat.requiresReasoningContentOnAssistantMessages??detected.requiresReasoningContentOnAssistantMessages,thinkingFormat:model.compat.thinkingFormat??detected.thinkingFormat,supportsDisabledThinking:model.compat.supportsDisabledThinking??detected.supportsDisabledThinking,openRouterRouting:model.compat.openRouterRouting??detected.openRouterRouting,vercelGatewayRouting:model.compat.vercelGatewayRouting??detected.vercelGatewayRouting,chatTemplateKwargs:model.compat.chatTemplateKwargs??detected.chatTemplateKwargs,chatTemplateArgs:model.compat.chatTemplateArgs??detected.chatTemplateArgs,zaiToolStream:model.compat.zaiToolStream??detected.zaiToolStream,supportsThinkingTokenBudget:model.compat.supportsThinkingTokenBudget??detected.supportsThinkingTokenBudget,thinkingTokenBudgetField:model.compat.thinkingTokenBudgetField??detected.thinkingTokenBudgetField,supportsStrictMode:model.compat.supportsStrictMode??detected.supportsStrictMode,toolSchemaFlavor:model.compat.toolSchemaFlavor??detected.toolSchemaFlavor,toolCallFormat:model.compat.toolCallFormat??detected.toolCallFormat,supportsOpenAIGrammarTools:model.compat.supportsOpenAIGrammarTools??detected.supportsOpenAIGrammarTools,supportsMidConvoSystemMessages:model.compat.supportsMidConvoSystemMessages??detected.supportsMidConvoSystemMessages,supportsMidConvoToolAdditions:model.compat.supportsMidConvoToolAdditions??detected.supportsMidConvoToolAdditions,cacheControlFormat:model.compat.cacheControlFormat??detected.cacheControlFormat,sendSessionAffinityHeaders:model.compat.sendSessionAffinityHeaders??detected.sendSessionAffinityHeaders,deferredToolsMode:model.compat.deferredToolsMode??detected.deferredToolsMode,sessionAffinityFormat:model.compat.sessionAffinityFormat??detected.sessionAffinityFormat,supportsPromptCacheKey:model.compat.supportsPromptCacheKey??detected.supportsPromptCacheKey,supportsMaxOutputTokens:model.compat.supportsMaxOutputTokens??detected.supportsMaxOutputTokens,supportsForcedToolChoice:model.compat.supportsForcedToolChoice,vllmPriority:model.compat.vllmPriority??detected.vllmPriority,supportsLongCacheRetention:model.compat.supportsLongCacheRetention??detected.supportsLongCacheRetention}:detected}function getBedrockModelMatchCandidates(modelId,modelName){return(modelName?[modelId,modelName]:[modelId]).flatMap(value=>{let lower=value.toLowerCase();return[lower,lower.replace(/[\s_.:]+/g,"-")]})}function supportsOneHourCacheTtl(model){return getBedrockModelMatchCandidates(model.id,model.name).some(candidate=>["opus-4-5","sonnet-4-5","haiku-4-5"].some(modelVersion=>candidate.includes(modelVersion)))}function supportsPromptCaching(model,env){let candidates=getBedrockModelMatchCandidates(model.id,model.name);return candidates.some(s=>s.includes("claude"))?!!(candidates.some(s=>s.includes("fable-5")||s.includes("opus-5")||s.includes("sonnet-5"))||candidates.some(s=>s.includes("-4-"))||candidates.some(s=>s.includes("claude-3-7-sonnet"))||candidates.some(s=>s.includes("claude-3-5-haiku"))):getProviderEnvValue("AWS_BEDROCK_FORCE_CACHE",env)==="1"}function resolveAnthropicCacheRetention(cacheRetention,env,fallback="short"){return cacheRetention||(getProviderEnvValue("PI_CACHE_RETENTION",env)==="long"?"long":typeof process<"u"&&process.env.PI_CACHE_RETENTION!==void 0?"short":fallback)}function resolveOpenAICompletionsCacheRetention(cacheRetention,env){return cacheRetention||(getProviderEnvValue("PI_CACHE_RETENTION",env)==="long"?"long":"short")}function resolveBedrockCacheRetention(cacheRetention,env){return cacheRetention||(getProviderEnvValue("PI_CACHE_RETENTION",env)==="long"?"long":"short")}function resolveOpenAIResponsesCacheRetention(cacheRetention,env){return cacheRetention||(getProviderEnvValue("PI_CACHE_RETENTION",env)==="long"?"long":"short")}function isDirectDeepSeekModel(model){return model.provider==="deepseek"||hostnameOf(model.baseUrl)==="api.deepseek.com"}var OPENAI_EXTENDED_CACHE_MODEL_ID=/^gpt-(?:5\.(?:[6-9]|\d{2,})|(?:[6-9]|\d{2,})(?:\.\d+)?)(?:-|$)/i;function hasOpenAIExtendedPromptCache(model){if(model.api==="openai-responses"){let responsesModel=model;if(responsesModel.compat?.supportsExplicitPromptCacheMode===!0)return!0;if(responsesModel.provider!=="openai"&&hostnameOf(responsesModel.baseUrl)!=="api.openai.com")return!1}return OPENAI_EXTENDED_CACHE_MODEL_ID.test(model.id)}var CLAUDE_CODE_API_BILLING_ENV=["ANTHROPIC_API_KEY","ANTHROPIC_AUTH_TOKEN","ANTHROPIC_BASE_URL","CLAUDE_CODE_USE_BEDROCK","CLAUDE_CODE_USE_VERTEX","CLAUDE_CODE_USE_FOUNDRY"];function isEnabledFlag(value){return value!==void 0&&!/^(?:|0|false|no|off)$/i.test(value.trim())}function claudeCodePromptCacheTtlSeconds(env){let explicit=getProviderEnvValue("CLAUDE_CODE_PROMPT_CACHE_TTL",env)?.trim().toLowerCase();return explicit==="5m"?PROMPT_CACHE_TTL_SHORT_SECONDS:explicit==="1h"?PROMPT_CACHE_TTL_LONG_SECONDS:isEnabledFlag(getProviderEnvValue("FORCE_PROMPT_CACHING_5M",env))?PROMPT_CACHE_TTL_SHORT_SECONDS:isEnabledFlag(getProviderEnvValue("ENABLE_PROMPT_CACHING_1H",env))?PROMPT_CACHE_TTL_LONG_SECONDS:CLAUDE_CODE_API_BILLING_ENV.some(name=>getProviderEnvValue(name,env)!==void 0)?PROMPT_CACHE_TTL_SHORT_SECONDS:PROMPT_CACHE_TTL_LONG_SECONDS}function resolvePromptCacheLifetime(model,env){switch(model.api){case"claude-sdk-oauth":return ttl(claudeCodePromptCacheTtlSeconds(env));case"anthropic-messages":{let anthropicModel=model,retention=resolveAnthropicCacheRetention(anthropicModel.cacheRetention,env,"short");return retention==="none"?NO_PROMPT_CACHE:retention==="long"&&isAnthropicApiBaseUrl(anthropicModel.baseUrl)&&getAnthropicCompat(anthropicModel).supportsLongCacheRetention?ttl(PROMPT_CACHE_TTL_LONG_SECONDS):ttl(PROMPT_CACHE_TTL_SHORT_SECONDS)}case"bedrock-converse-stream":{let bedrockModel=model,retention=resolveBedrockCacheRetention(bedrockModel.cacheRetention,env);return retention==="none"||!supportsPromptCaching(bedrockModel,env)?NO_PROMPT_CACHE:retention==="long"&&supportsOneHourCacheTtl(bedrockModel)?ttl(PROMPT_CACHE_TTL_LONG_SECONDS):ttl(PROMPT_CACHE_TTL_SHORT_SECONDS)}case"openai-completions":{let completionsModel=model,retention=resolveOpenAICompletionsCacheRetention(completionsModel.cacheRetention,env);if(retention==="none")return NO_PROMPT_CACHE;if(isDirectDeepSeekModel(completionsModel))return BEST_EFFORT_PROMPT_CACHE;let compat=getOpenAICompletionsCompat(completionsModel);return compat.cacheControlFormat==="anthropic"&&retention==="long"&&compat.supportsLongCacheRetention?ttl(PROMPT_CACHE_TTL_LONG_SECONDS):ttl(PROMPT_CACHE_TTL_SHORT_SECONDS)}case"openai-responses":case"openai-codex-responses":case"azure-openai-responses":return resolveOpenAIResponsesCacheRetention(model.cacheRetention,env)==="none"?NO_PROMPT_CACHE:hasOpenAIExtendedPromptCache(model)?ttl(PROMPT_CACHE_TTL_OPENAI_EXTENDED_SECONDS):ttl(PROMPT_CACHE_TTL_SHORT_SECONDS);default:return NO_PROMPT_CACHE}}function resolvePromptCacheTtlSeconds(model,env){let lifetime=resolvePromptCacheLifetime(model,env);return lifetime.kind==="ttl"?lifetime.ttlSeconds:void 0}export{PROMPT_CACHE_TTL_SHORT_SECONDS,PROMPT_CACHE_TTL_LONG_SECONDS,PROMPT_CACHE_TTL_OPENAI_EXTENDED_SECONDS,isAnthropicApiBaseUrl,getAnthropicCompat,getOpenAICompletionsCompat,resolvePromptCacheLifetime,resolvePromptCacheTtlSeconds};