@astrosheep/keiyaku 4.6.7 → 4.6.9

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 (336) hide show
  1. package/README.md +46 -16
  2. package/build/plugins/claude/.claude-plugin/plugin.json +1 -1
  3. package/build/plugins/claude/skills/keiyaku/SKILL.md +5 -6
  4. package/build/plugins/claude/skills/keiyaku-akuma/SKILL.md +1 -1
  5. package/build/plugins/claude/skills/keiyaku-akuma/references/automation.md +8 -8
  6. package/build/plugins/claude/skills/keiyaku-babysit/SKILL.md +1 -1
  7. package/build/plugins/claude/skills/keiyaku-bind/SKILL.md +9 -9
  8. package/build/plugins/claude/skills/keiyaku-debt/SKILL.md +91 -0
  9. package/build/plugins/claude/skills/keiyaku-workflow/SKILL.md +2 -2
  10. package/build/plugins/codex/.codex-plugin/plugin.json +1 -1
  11. package/build/plugins/codex/skills/keiyaku/SKILL.md +5 -6
  12. package/build/plugins/codex/skills/keiyaku-akuma/SKILL.md +1 -1
  13. package/build/plugins/codex/skills/keiyaku-akuma/references/automation.md +8 -8
  14. package/build/plugins/codex/skills/keiyaku-babysit/SKILL.md +1 -1
  15. package/build/plugins/codex/skills/keiyaku-bind/SKILL.md +9 -9
  16. package/build/plugins/codex/skills/keiyaku-debt/SKILL.md +91 -0
  17. package/build/plugins/codex/skills/keiyaku-workflow/SKILL.md +2 -2
  18. package/build/plugins/opencode/index.js +1 -1
  19. package/build/plugins/opencode/skills/keiyaku/SKILL.md +5 -6
  20. package/build/plugins/opencode/skills/keiyaku-akuma/SKILL.md +1 -1
  21. package/build/plugins/opencode/skills/keiyaku-akuma/references/automation.md +8 -8
  22. package/build/plugins/opencode/skills/keiyaku-babysit/SKILL.md +1 -1
  23. package/build/plugins/opencode/skills/keiyaku-bind/SKILL.md +9 -9
  24. package/build/plugins/opencode/skills/keiyaku-debt/SKILL.md +91 -0
  25. package/build/plugins/opencode/skills/keiyaku-workflow/SKILL.md +2 -2
  26. package/build/plugins/pi/keiyaku.ts +0 -5
  27. package/build/skills/keiyaku/SKILL.md +5 -6
  28. package/build/skills/keiyaku-akuma/SKILL.md +1 -1
  29. package/build/skills/keiyaku-akuma/references/automation.md +8 -8
  30. package/build/skills/keiyaku-babysit/SKILL.md +1 -1
  31. package/build/skills/keiyaku-bind/SKILL.md +9 -9
  32. package/build/skills/keiyaku-debt/SKILL.md +91 -0
  33. package/build/skills/keiyaku-workflow/SKILL.md +2 -2
  34. package/build/src/akuma/akuma-call.d.ts +2 -0
  35. package/build/src/akuma/akuma-call.js +8 -2
  36. package/build/src/akuma/akuma-instance.d.ts +14 -1
  37. package/build/src/akuma/akuma-instance.js +37 -7
  38. package/build/src/akuma/akuma-observe.d.ts +33 -8
  39. package/build/src/akuma/akuma-observe.js +89 -63
  40. package/build/src/akuma/akuma-owner.d.ts +14 -2
  41. package/build/src/akuma/akuma-owner.js +49 -35
  42. package/build/src/akuma/akuma-selection-execution.js +9 -1
  43. package/build/src/akuma/akuma-stream.d.ts +22 -0
  44. package/build/src/akuma/akuma-stream.js +116 -0
  45. package/build/src/akuma/akuma-wait.d.ts +1 -40
  46. package/build/src/akuma/akuma-wait.js +23 -84
  47. package/build/src/akuma/akuma.d.ts +52 -16
  48. package/build/src/akuma/akuma.js +10 -10
  49. package/build/src/akuma/allowed.d.ts +7 -12
  50. package/build/src/akuma/allowed.js +13 -4
  51. package/build/src/akuma/archetype.d.ts +7 -15
  52. package/build/src/akuma/archetype.js +36 -35
  53. package/build/src/akuma/body-supervisor.d.ts +5 -5
  54. package/build/src/akuma/body-supervisor.js +22 -20
  55. package/build/src/akuma/body.d.ts +5 -3
  56. package/build/src/akuma/body.js +57 -8
  57. package/build/src/akuma/call-request.d.ts +30 -32
  58. package/build/src/akuma/call-request.js +10 -3
  59. package/build/src/akuma/caller.d.ts +39 -0
  60. package/build/src/akuma/caller.js +36 -0
  61. package/build/src/akuma/dispatch-association.d.ts +0 -1
  62. package/build/src/akuma/dispatch-association.js +0 -3
  63. package/build/src/akuma/heart/activity-schema.d.ts +12 -0
  64. package/build/src/akuma/heart/activity-schema.js +6 -0
  65. package/build/src/akuma/heart/facts.d.ts +16 -12
  66. package/build/src/akuma/heart/facts.js +8 -0
  67. package/build/src/akuma/heart/index.d.ts +61 -9
  68. package/build/src/akuma/heart/index.js +89 -24
  69. package/build/src/akuma/heart/rows.d.ts +3 -3
  70. package/build/src/akuma/heart/rows.js +5 -3
  71. package/build/src/akuma/heart/soul.d.ts +10 -1
  72. package/build/src/akuma/heart/soul.js +34 -24
  73. package/build/src/akuma/heart/storage.d.ts +20 -0
  74. package/build/src/akuma/heart/storage.js +62 -3
  75. package/build/src/akuma/heart/timeline.d.ts +7 -0
  76. package/build/src/akuma/heart/timeline.js +10 -0
  77. package/build/src/akuma/identity.d.ts +0 -1
  78. package/build/src/akuma/identity.js +2 -5
  79. package/build/src/akuma/index.d.ts +6 -2
  80. package/build/src/akuma/index.js +1 -0
  81. package/build/src/akuma/nuke.js +6 -28
  82. package/build/src/akuma/projection.d.ts +25 -11
  83. package/build/src/akuma/projection.js +24 -7
  84. package/build/src/akuma/provider-recipe.d.ts +18 -6
  85. package/build/src/akuma/provider-recipe.js +24 -1
  86. package/build/src/akuma/provider.d.ts +31 -10
  87. package/build/src/akuma/provider.js +105 -14
  88. package/build/src/akuma/providers/acp/events.js +29 -19
  89. package/build/src/akuma/providers/acp/index.js +2 -3
  90. package/build/src/akuma/providers/claude/events.js +110 -69
  91. package/build/src/akuma/providers/claude/index.d.ts +2 -2
  92. package/build/src/akuma/providers/claude/index.js +4 -8
  93. package/build/src/akuma/providers/codex-app-server/events.js +17 -2
  94. package/build/src/akuma/providers/codex-app-server/index.js +17 -11
  95. package/build/src/akuma/providers/decode.d.ts +33 -0
  96. package/build/src/akuma/providers/decode.js +65 -0
  97. package/build/src/akuma/providers/execution-environment.d.ts +2 -1
  98. package/build/src/akuma/providers/execution-environment.js +3 -0
  99. package/build/src/akuma/providers/grok-build/index.js +16 -48
  100. package/build/src/akuma/providers/index.js +2 -0
  101. package/build/src/akuma/providers/lifecycle.d.ts +9 -0
  102. package/build/src/akuma/providers/lifecycle.js +10 -0
  103. package/build/src/akuma/providers/opencode-sdk/event-stream.d.ts +3 -3
  104. package/build/src/akuma/providers/opencode-sdk/event-stream.js +2 -25
  105. package/build/src/akuma/providers/opencode-sdk/events.d.ts +7 -43
  106. package/build/src/akuma/providers/opencode-sdk/events.js +146 -296
  107. package/build/src/akuma/providers/opencode-sdk/index.js +270 -431
  108. package/build/src/akuma/providers/opencode-sdk/native-http.d.ts +9 -0
  109. package/build/src/akuma/providers/opencode-sdk/native-http.js +69 -0
  110. package/build/src/akuma/providers/opencode-sdk/session.d.ts +42 -36
  111. package/build/src/akuma/providers/opencode-sdk/session.js +75 -84
  112. package/build/src/akuma/providers/paseo/events.d.ts +33 -0
  113. package/build/src/akuma/providers/paseo/events.js +204 -0
  114. package/build/src/akuma/providers/paseo/index.d.ts +9 -0
  115. package/build/src/akuma/providers/paseo/index.js +357 -0
  116. package/build/src/akuma/providers/pi/events.d.ts +2 -0
  117. package/build/src/akuma/providers/pi/events.js +36 -38
  118. package/build/src/akuma/providers/pi/index.js +21 -35
  119. package/build/src/akuma/publication.d.ts +2 -0
  120. package/build/src/akuma/publication.js +5 -0
  121. package/build/src/akuma/request-lifecycle.d.ts +4 -2
  122. package/build/src/akuma/request-lifecycle.js +27 -12
  123. package/build/src/akuma/request-rendezvous.js +38 -55
  124. package/build/src/akuma/request-serve.d.ts +1 -1
  125. package/build/src/akuma/request-serve.js +77 -113
  126. package/build/src/akuma/requests.d.ts +3 -1
  127. package/build/src/akuma/requests.js +32 -0
  128. package/build/src/akuma/selection-observation.d.ts +129 -53
  129. package/build/src/akuma/selection-observation.js +3 -9
  130. package/build/src/akuma/turn-drive.d.ts +3 -0
  131. package/build/src/akuma/turn-drive.js +28 -10
  132. package/build/src/akuma-body.js +12 -22
  133. package/build/src/cli/akuma-caller.d.ts +3 -0
  134. package/build/src/cli/akuma-caller.js +31 -0
  135. package/build/src/cli/commands/akuma-grammar.js +10 -16
  136. package/build/src/cli/commands/akuma.js +25 -55
  137. package/build/src/cli/commands/contract-grammar.d.ts +9 -7
  138. package/build/src/cli/commands/contract-grammar.js +40 -47
  139. package/build/src/cli/commands/contract-help.d.ts +17 -7
  140. package/build/src/cli/commands/contract-help.js +50 -11
  141. package/build/src/cli/commands/contract.js +34 -63
  142. package/build/src/cli/commands/debt-grammar.d.ts +19 -0
  143. package/build/src/cli/commands/debt-grammar.js +323 -0
  144. package/build/src/cli/commands/debt-query.d.ts +5 -0
  145. package/build/src/cli/commands/{task-query.js → debt-query.js} +9 -9
  146. package/build/src/cli/commands/{task.d.ts → debt.d.ts} +2 -2
  147. package/build/src/cli/commands/{task.js → debt.js} +87 -164
  148. package/build/src/cli/coordinates.d.ts +1 -1
  149. package/build/src/cli/coordinates.js +1 -1
  150. package/build/src/cli/parse.d.ts +5 -5
  151. package/build/src/cli/parse.js +17 -16
  152. package/build/src/cli/render/akuma-activity.d.ts +11 -83
  153. package/build/src/cli/render/akuma-activity.js +20 -382
  154. package/build/src/cli/render/catalog.d.ts +4 -7
  155. package/build/src/cli/render/catalog.js +5 -5
  156. package/build/src/cli/render/contract-history.js +3 -6
  157. package/build/src/cli/render/contract.js +17 -52
  158. package/build/src/cli/render/debt.d.ts +28 -0
  159. package/build/src/cli/render/{task.js → debt.js} +55 -133
  160. package/build/src/cli/render/kanshi.js +28 -28
  161. package/build/src/cli/render/marks.d.ts +5 -5
  162. package/build/src/cli/render/marks.js +4 -10
  163. package/build/src/cli/render/nuke.js +1 -1
  164. package/build/src/cli/render/receipt.js +3 -10
  165. package/build/src/cli/runtime.d.ts +1 -1
  166. package/build/src/cli/runtime.js +14 -20
  167. package/build/src/cli/scan.d.ts +1 -1
  168. package/build/src/cli/selectors.d.ts +3 -6
  169. package/build/src/cli/selectors.js +22 -53
  170. package/build/src/cli/usage.d.ts +1 -1
  171. package/build/src/cli/usage.js +4 -4
  172. package/build/src/contract-worktree.js +3 -3
  173. package/build/src/debt/board.d.ts +160 -0
  174. package/build/src/{task → debt}/board.js +89 -89
  175. package/build/src/debt/catalog.d.ts +11 -0
  176. package/build/src/debt/catalog.js +59 -0
  177. package/build/src/{task → debt}/context.d.ts +1 -1
  178. package/build/src/{task → debt}/context.js +1 -1
  179. package/build/src/{task → debt}/created-observation.d.ts +6 -10
  180. package/build/src/{task → debt}/created-observation.js +7 -7
  181. package/build/src/debt/document.d.ts +37 -0
  182. package/build/src/{task → debt}/document.js +37 -37
  183. package/build/src/debt/identity.d.ts +21 -0
  184. package/build/src/{task → debt}/identity.js +35 -35
  185. package/build/src/debt/index.d.ts +111 -0
  186. package/build/src/debt/index.js +203 -0
  187. package/build/src/{task → debt}/input.d.ts +8 -8
  188. package/build/src/{task → debt}/input.js +21 -21
  189. package/build/src/debt/lifecycle-operations.d.ts +6 -0
  190. package/build/src/{task → debt}/lifecycle-operations.js +27 -31
  191. package/build/src/debt/mutation-result.d.ts +981 -0
  192. package/build/src/debt/mutation-result.js +109 -0
  193. package/build/src/debt/mutation.d.ts +424 -0
  194. package/build/src/debt/mutation.js +223 -0
  195. package/build/src/debt/operation-types.d.ts +71 -0
  196. package/build/src/debt/operations.d.ts +28 -0
  197. package/build/src/{task → debt}/operations.js +59 -60
  198. package/build/src/debt/query.d.ts +76 -0
  199. package/build/src/{task → debt}/query.js +55 -55
  200. package/build/src/{task → debt}/store.d.ts +13 -13
  201. package/build/src/{task → debt}/store.js +58 -49
  202. package/build/src/debt/view.d.ts +4 -0
  203. package/build/src/debt/view.js +7 -0
  204. package/build/src/dispatch/index.d.ts +3 -3
  205. package/build/src/dispatch/index.js +1 -2
  206. package/build/src/git/observe.d.ts +6 -2
  207. package/build/src/git/observe.js +6 -2
  208. package/build/src/identity/coordinates.d.ts +1 -1
  209. package/build/src/index.d.ts +17 -17
  210. package/build/src/index.js +11 -11
  211. package/build/src/kanshi/index.d.ts +2 -2
  212. package/build/src/kanshi/read.js +54 -39
  213. package/build/src/kanshi/report.d.ts +7 -7
  214. package/build/src/kanshi/select.js +4 -4
  215. package/build/src/library/address.js +2 -4
  216. package/build/src/library/akuma-creation.d.ts +5 -1
  217. package/build/src/library/akuma-creation.js +27 -47
  218. package/build/src/library/akumas.d.ts +7 -7
  219. package/build/src/library/akumas.js +13 -9
  220. package/build/src/library/bind.d.ts +17 -17
  221. package/build/src/library/bind.js +16 -12
  222. package/build/src/library/contract-address.d.ts +9 -0
  223. package/build/src/library/contract-address.js +71 -0
  224. package/build/src/library/contract-composition.d.ts +4 -7
  225. package/build/src/library/contract-composition.js +6 -18
  226. package/build/src/library/contract-creation.d.ts +3 -5
  227. package/build/src/library/contract-creation.js +24 -22
  228. package/build/src/library/contract-execution.js +21 -26
  229. package/build/src/library/contract-outcomes.d.ts +2 -14
  230. package/build/src/library/contract-outcomes.js +2 -13
  231. package/build/src/library/contract-types.d.ts +38 -4
  232. package/build/src/library/delivery.d.ts +0 -2
  233. package/build/src/library/delivery.js +2 -5
  234. package/build/src/library/input.d.ts +2 -2
  235. package/build/src/library/input.js +5 -5
  236. package/build/src/library/invocation.js +2 -2
  237. package/build/src/library/keiyaku.d.ts +0 -5
  238. package/build/src/library/keiyaku.js +6 -12
  239. package/build/src/library/nuke.js +3 -3
  240. package/build/src/library/outcome.d.ts +626 -625
  241. package/build/src/library/outcome.js +13 -3
  242. package/build/src/library/reconcile.js +8 -16
  243. package/build/src/library/refusal.d.ts +2 -2
  244. package/build/src/library/repo.d.ts +3 -2
  245. package/build/src/library/repo.js +10 -5
  246. package/build/src/library/selection.d.ts +5 -8
  247. package/build/src/library/selection.js +22 -73
  248. package/build/src/plugin/akuma-signals.d.ts +2 -0
  249. package/build/src/plugin/akuma-signals.js +4 -0
  250. package/build/src/plugin/public.d.ts +32 -2
  251. package/build/src/plugin/runtime.js +5 -3
  252. package/build/src/protocol/amend.js +3 -2
  253. package/build/src/protocol/attempt.js +3 -8
  254. package/build/src/protocol/bind.d.ts +2 -2
  255. package/build/src/protocol/bind.js +1 -1
  256. package/build/src/protocol/deliver.js +3 -3
  257. package/build/src/protocol/operations.d.ts +1 -3
  258. package/build/src/protocol/operations.js +0 -8
  259. package/build/src/protocol/outcome.d.ts +1 -2
  260. package/build/src/protocol/outcome.js +1 -13
  261. package/build/src/protocol/placement.js +3 -10
  262. package/build/src/protocol/read/status.js +31 -70
  263. package/build/src/protocol/reintegrate.js +3 -10
  264. package/build/src/protocol/review.js +3 -3
  265. package/build/src/protocol/run.d.ts +5 -1
  266. package/build/src/protocol/run.js +3 -3
  267. package/build/src/runtime/proc/windows-launch.exe +0 -0
  268. package/build/src/settlement/fence.d.ts +3 -3
  269. package/build/src/settlement/fence.js +4 -4
  270. package/build/src/settlement/holder.d.ts +16 -16
  271. package/build/src/settlement/holder.js +69 -63
  272. package/build/src/settlement/settle.d.ts +5 -5
  273. package/build/src/settlement/settle.js +53 -53
  274. package/package.json +19 -9
  275. package/plugins/paseo/plugin/index.server.ts +17 -0
  276. package/plugins/paseo/plugin/paseo-plugin.json +4 -0
  277. package/plugins/paseo/plugin/server/attach.ts +52 -0
  278. package/plugins/paseo/plugin/server/keiyaku.ts +44 -0
  279. package/plugins/paseo/plugin/server/message.ts +60 -0
  280. package/plugins/paseo/plugin/server/mirror.ts +193 -0
  281. package/plugins/paseo/plugin/server/model.ts +14 -0
  282. package/plugins/paseo/plugin/server/provider.ts +276 -0
  283. package/plugins/paseo/plugin/server/sdk-worker.ts +237 -0
  284. package/plugins/paseo/plugin/server/sdk.ts +289 -0
  285. package/plugins/paseo/plugin/server/stop.ts +26 -0
  286. package/plugins/paseo/plugin/server/transport.ts +35 -0
  287. package/plugins/paseo/plugin/shared/attach-rpc.ts +10 -0
  288. package/plugins/paseo/plugin/shared/refresh-rpc.ts +6 -0
  289. package/plugins/paseo/plugin/tsconfig.json +6 -0
  290. package/plugins/pi/keiyaku.ts +57 -0
  291. package/skills/keiyaku/SKILL.md +43 -0
  292. package/skills/keiyaku-akuma/SKILL.md +130 -0
  293. package/skills/keiyaku-akuma/references/automation.md +269 -0
  294. package/skills/keiyaku-babysit/SKILL.md +65 -0
  295. package/skills/keiyaku-bind/SKILL.md +216 -0
  296. package/skills/keiyaku-bind/agents/openai.yaml +4 -0
  297. package/skills/keiyaku-debt/SKILL.md +91 -0
  298. package/skills/keiyaku-workflow/SKILL.md +129 -0
  299. package/build/plugins/claude/skills/keiyaku-task/SKILL.md +0 -104
  300. package/build/plugins/codex/skills/keiyaku-task/SKILL.md +0 -104
  301. package/build/plugins/opencode/skills/keiyaku-task/SKILL.md +0 -104
  302. package/build/skills/keiyaku-task/SKILL.md +0 -104
  303. package/build/src/cli/commands/amend.d.ts +0 -12
  304. package/build/src/cli/commands/amend.js +0 -10
  305. package/build/src/cli/commands/bind.d.ts +0 -11
  306. package/build/src/cli/commands/bind.js +0 -23
  307. package/build/src/cli/commands/task-grammar.d.ts +0 -19
  308. package/build/src/cli/commands/task-grammar.js +0 -384
  309. package/build/src/cli/commands/task-query.d.ts +0 -5
  310. package/build/src/cli/render/task.d.ts +0 -41
  311. package/build/src/dispatch/association.d.ts +0 -1
  312. package/build/src/dispatch/association.js +0 -1
  313. package/build/src/task/board.d.ts +0 -168
  314. package/build/src/task/catalog.d.ts +0 -11
  315. package/build/src/task/catalog.js +0 -59
  316. package/build/src/task/compose-language.d.ts +0 -57
  317. package/build/src/task/compose-language.js +0 -364
  318. package/build/src/task/compose-parser.d.ts +0 -32
  319. package/build/src/task/compose-parser.js +0 -180
  320. package/build/src/task/compose.d.ts +0 -16
  321. package/build/src/task/compose.js +0 -189
  322. package/build/src/task/document.d.ts +0 -39
  323. package/build/src/task/identity.d.ts +0 -21
  324. package/build/src/task/index.d.ts +0 -138
  325. package/build/src/task/index.js +0 -269
  326. package/build/src/task/lifecycle-operations.d.ts +0 -6
  327. package/build/src/task/mutation-result.d.ts +0 -1726
  328. package/build/src/task/mutation-result.js +0 -198
  329. package/build/src/task/mutation.d.ts +0 -590
  330. package/build/src/task/mutation.js +0 -262
  331. package/build/src/task/operation-types.d.ts +0 -71
  332. package/build/src/task/operations.d.ts +0 -28
  333. package/build/src/task/query.d.ts +0 -76
  334. package/build/src/task/view.d.ts +0 -4
  335. package/build/src/task/view.js +0 -7
  336. /package/build/src/{task → debt}/operation-types.js +0 -0
@@ -0,0 +1,9 @@
1
+ import { type OpenCodeClient } from "@opencode/client";
2
+ /** The matching native SDK owns the dialect; this attempt owns its HTTP connections. */
3
+ export declare function createNativeClient(baseUrl: string, password: string): Readonly<{
4
+ sdk: OpenCodeClient;
5
+ subscribe(signal: AbortSignal): Promise<Readonly<{
6
+ stream: AsyncIterable<unknown>;
7
+ }>>;
8
+ close(): Promise<void>;
9
+ }>;
@@ -0,0 +1,69 @@
1
+ import { OpenCode } from "@opencode/client";
2
+ import { Agent } from "undici";
3
+ import { object } from "../decode.js";
4
+ /** The matching native SDK owns the dialect; this attempt owns its HTTP connections. */
5
+ export function createNativeClient(baseUrl, password) {
6
+ const dispatcher = new Agent();
7
+ const controller = new AbortController();
8
+ // Node's fetch accepts an Undici dispatcher in addition to standard RequestInit.
9
+ // Keep that native extension at this one SDK seam.
10
+ const ownedFetch = (input, init) => {
11
+ controller.signal.throwIfAborted();
12
+ const options = {
13
+ ...init,
14
+ dispatcher,
15
+ signal: init?.signal == null ? controller.signal : AbortSignal.any([controller.signal, init.signal]),
16
+ };
17
+ return globalThis.fetch(input, options);
18
+ };
19
+ const sdk = OpenCode.make({
20
+ baseUrl,
21
+ fetch: ownedFetch,
22
+ headers: { authorization: `Basic ${Buffer.from(`opencode:${password}`).toString("base64")}` },
23
+ });
24
+ const subscribe = async (signal) => {
25
+ const iterator = sdk.event.subscribe({ signal })[Symbol.asyncIterator]();
26
+ try {
27
+ // The producer subscribes before emitting this frame. Headers alone are
28
+ // not a barrier against losing the opening native admission broadcast.
29
+ const connected = await iterator.next();
30
+ if (connected.done || object(connected.value)?.type !== "server.connected") {
31
+ throw new Error("OpenCode event feed did not confirm subscription");
32
+ }
33
+ }
34
+ catch (error) {
35
+ await iterator.return?.();
36
+ throw error;
37
+ }
38
+ return {
39
+ stream: {
40
+ [Symbol.asyncIterator]: () => ({
41
+ next: async () => {
42
+ const next = await iterator.next();
43
+ // Effect stream-failure frames are not native events. The generated
44
+ // SDK parser can yield their payload; never drop that into narration.
45
+ if (!next.done && typeof object(next.value)?.type !== "string") {
46
+ throw new Error("OpenCode native event feed failed");
47
+ }
48
+ return next;
49
+ },
50
+ return: () => iterator.return?.() ?? Promise.resolve({ done: true, value: undefined }),
51
+ }),
52
+ },
53
+ };
54
+ };
55
+ let closing;
56
+ return {
57
+ sdk,
58
+ subscribe,
59
+ close: () => {
60
+ closing ??= (async () => {
61
+ controller.abort();
62
+ // SDK iterator retirement is logical. Dispatcher destruction separately
63
+ // awaits closure of every socket, including requests aborted during setup.
64
+ await dispatcher.destroy();
65
+ })();
66
+ return closing;
67
+ },
68
+ };
69
+ }
@@ -1,24 +1,49 @@
1
- import type { OpencodeClient } from "@opencode-ai/sdk";
1
+ import type { SessionCreateInput, SessionSwitchModelInput } from "@opencode/client";
2
2
  import type { ResumeCoordinate } from "../../heart/index.js";
3
3
  import type { ProviderExecution } from "../../provider-recipe.js";
4
- export type OpencodeSdkSession = Pick<OpencodeClient["session"], "create" | "get" | "fork" | "abort" | "promptAsync" | "messages">;
5
- /**
6
- * The adapter's own event subscription port. It carries the cancellation signal
7
- * and the cancellable retry backoff the installed client honors at runtime,
8
- * without naming the SDK's generated request type at the call site.
9
- */
4
+ export type OpencodeSdkSession = Readonly<{
5
+ create(input: {
6
+ body: SessionCreateInput;
7
+ }): Promise<unknown>;
8
+ get(input: {
9
+ id: string;
10
+ }): Promise<unknown>;
11
+ switchModel(input: {
12
+ id: string;
13
+ model: SessionSwitchModelInput["model"];
14
+ }): Promise<unknown>;
15
+ instructions(input: {
16
+ id: string;
17
+ text: string;
18
+ }): Promise<unknown>;
19
+ active(): Promise<unknown>;
20
+ fork(input: {
21
+ id: string;
22
+ before: string;
23
+ }): Promise<unknown>;
24
+ interrupt(input: {
25
+ id: string;
26
+ }): Promise<unknown>;
27
+ prompt(input: {
28
+ id: string;
29
+ body: {
30
+ id: string;
31
+ text: string;
32
+ };
33
+ }): Promise<unknown>;
34
+ message(input: {
35
+ id: string;
36
+ messageID: string;
37
+ }): Promise<unknown>;
38
+ }>;
10
39
  export type OpencodeEventSubscriptionRequest = Readonly<{
11
40
  directory: string;
12
- /** Cancels the subscription's fetch, reader, and retry waiting. */
13
41
  signal: AbortSignal;
14
- /** Resolves without rejecting when `signal` aborts, and always clears its timer. */
15
- sleep(milliseconds: number): Promise<void>;
16
- }>;
17
- type OpencodeEventSubscription = Readonly<{
18
- stream: AsyncIterable<unknown>;
19
42
  }>;
20
43
  export type OpencodeSdkEvent = Readonly<{
21
- subscribe(request: OpencodeEventSubscriptionRequest): Promise<OpencodeEventSubscription>;
44
+ subscribe(request: OpencodeEventSubscriptionRequest): Promise<Readonly<{
45
+ stream: AsyncIterable<unknown>;
46
+ }>>;
22
47
  }>;
23
48
  export type OpencodeSdkLoader = (cwd: string, execution: ProviderExecution, signal: AbortSignal) => Promise<Readonly<{
24
49
  client: {
@@ -29,31 +54,11 @@ export type OpencodeSdkLoader = (cwd: string, execution: ProviderExecution, sign
29
54
  ready?: Promise<void>;
30
55
  }>>;
31
56
  export declare const OPENCODE_SDK_PROVIDER: "opencode-sdk";
32
- /**
33
- * Adapt the installed client's generated event endpoint to the adapter's
34
- * subscription port.
35
- *
36
- * The generated per-endpoint `Options` type omits the SDK's runtime
37
- * `sseSleepFn` option even though the client forwards every per-request key
38
- * into `createSseClient`, so a caller cannot express a cancellable backoff
39
- * through the published type. Declaring the port here keeps that one typing gap
40
- * and its single adaptation at the SDK seam: no other module repeats a cast,
41
- * the SDK's own parser and retry policy stay untouched, and an injected loader
42
- * supplies the same port shape.
43
- */
44
- export declare function opencodeEventPort(event: OpencodeClient["event"]): OpencodeSdkEvent;
45
57
  export declare function messageId(sequence?: number): string;
46
58
  export declare function parseModel(model: string): Readonly<{
47
59
  providerID: string;
48
- modelID: string;
60
+ id: string;
49
61
  }>;
50
- /**
51
- * Compose the config handed to a headless opencode server. The permission base
52
- * layer fills only the classes the caller leaves unspecified: an explicit caller
53
- * permission key wins per key and every non-permission key passes through
54
- * untouched. A caller that supplies a non-object `permission` shorthand states
55
- * the whole policy and keeps it.
56
- */
57
62
  export declare function composeHeadlessPermissionConfig(config?: Readonly<Record<string, unknown>>): Record<string, unknown>;
58
63
  export type OpencodeRuntime = Readonly<{
59
64
  client: {
@@ -62,6 +67,8 @@ export type OpencodeRuntime = Readonly<{
62
67
  };
63
68
  close: () => Promise<void>;
64
69
  }>;
70
+ /** A successful HTML fallback, or a JSON response from another API, is not readiness. */
71
+ export declare function waitReady(json: (path: string) => Promise<unknown>, signal: AbortSignal): Promise<void>;
65
72
  export declare function loadOpencode(input: Readonly<{
66
73
  execution: ProviderExecution;
67
74
  cwd: string;
@@ -71,4 +78,3 @@ export declare function loadOpencode(input: Readonly<{
71
78
  requests?: string;
72
79
  }>): Promise<OpencodeRuntime>;
73
80
  export declare function coordinate(sessionId: string): ResumeCoordinate;
74
- export {};
@@ -3,92 +3,59 @@ import { randomBytes } from "node:crypto";
3
3
  import { abortable } from "../../abort.js";
4
4
  import { akumaExecutionEnvironment } from "../execution-environment.js";
5
5
  import { spawnDetachedProcess } from "../../../runtime/proc/run.js";
6
+ import { object } from "../decode.js";
7
+ import { createNativeClient } from "./native-http.js";
6
8
  export const OPENCODE_SDK_PROVIDER = "opencode-sdk";
7
- /**
8
- * Adapt the installed client's generated event endpoint to the adapter's
9
- * subscription port.
10
- *
11
- * The generated per-endpoint `Options` type omits the SDK's runtime
12
- * `sseSleepFn` option even though the client forwards every per-request key
13
- * into `createSseClient`, so a caller cannot express a cancellable backoff
14
- * through the published type. Declaring the port here keeps that one typing gap
15
- * and its single adaptation at the SDK seam: no other module repeats a cast,
16
- * the SDK's own parser and retry policy stay untouched, and an injected loader
17
- * supplies the same port shape.
18
- */
19
- export function opencodeEventPort(event) {
20
- return {
21
- subscribe: (request) => {
22
- const adapted = {
23
- query: { directory: request.directory },
24
- signal: request.signal,
25
- };
26
- // Runtime-only key omitted from the generated Options type; the installed
27
- // client forwards it to createSseClient unchanged.
28
- adapted.sseSleepFn = request.sleep;
29
- return event.subscribe(adapted);
30
- },
31
- };
32
- }
33
9
  export function messageId(sequence = 0) {
34
- const timestamp = BigInt(new Date().getTime()) * 0x1000n + BigInt(sequence);
35
- const bytes = Buffer.alloc(6);
36
- bytes.writeUIntBE(Number(timestamp & 0xffffffffffffn), 0, 6);
37
- const alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
38
- const suffix = [...randomBytes(14)].map((byte) => alphabet[byte % alphabet.length]).join("");
39
- return `msg_${bytes.toString("hex")}${suffix}`;
10
+ const timestamp = BigInt(Date.now()) * 0x1000n + BigInt(sequence);
11
+ return `msg_${timestamp.toString(16)}${randomBytes(14).toString("hex")}`;
40
12
  }
41
13
  export function parseModel(model) {
42
14
  const slash = model.indexOf("/");
43
15
  if (slash <= 0 || slash === model.length - 1)
44
16
  throw new Error("OpenCode model must be <provider>/<model>");
45
- return { providerID: model.slice(0, slash), modelID: model.slice(slash + 1) };
46
- }
47
- /**
48
- * Permission classes whose upstream defaults can await a human reply. A headless
49
- * server has no reply channel, so such a pending ask never settles.
50
- *
51
- * Verified against the installed opencode 1.18.33 agent permission ruleset: the
52
- * primary agents start from `{"*":"allow"}` with `external_directory` and
53
- * `doom_loop` set to ask, `read` set to ask for `.env` files, and `question`
54
- * allowed (the question tool awaits an answer by semantics). Every other class
55
- * matches the allow-all rule and cannot await.
56
- */
57
- const HEADLESS_PERMISSION_BASE = Object.freeze({
58
- external_directory: "allow",
59
- doom_loop: "allow",
60
- read: "allow",
61
- question: "deny",
62
- });
63
- function isRecord(value) {
64
- return value !== null && typeof value === "object" && !Array.isArray(value);
17
+ return { providerID: model.slice(0, slash), id: model.slice(slash + 1) };
65
18
  }
66
- /**
67
- * Compose the config handed to a headless opencode server. The permission base
68
- * layer fills only the classes the caller leaves unspecified: an explicit caller
69
- * permission key wins per key and every non-permission key passes through
70
- * untouched. A caller that supplies a non-object `permission` shorthand states
71
- * the whole policy and keeps it.
72
- */
19
+ // v2.0.20 Agent.Info.default asks only for external_directory and env reads;
20
+ // question separately requests permission before awaiting its form reply.
21
+ const HEADLESS_PERMISSION_BASE = [
22
+ { action: "external_directory", resource: "*", effect: "allow" },
23
+ { action: "read", resource: "*", effect: "allow" },
24
+ { action: "question", resource: "*", effect: "deny" },
25
+ ];
73
26
  export function composeHeadlessPermissionConfig(config) {
74
- const permission = config?.permission;
75
- if (permission !== undefined && !isRecord(permission))
76
- return { ...config };
77
- return { ...config, permission: { ...HEADLESS_PERMISSION_BASE, ...permission } };
27
+ const permissions = config?.permissions;
28
+ if (permissions !== undefined && !Array.isArray(permissions))
29
+ throw new Error("OpenCode v2 permissions must be a ruleset");
30
+ const actions = new Set((permissions ?? []).map((rule) => object(rule)?.action));
31
+ return {
32
+ ...config,
33
+ permissions: [...HEADLESS_PERMISSION_BASE.filter((rule) => !actions.has(rule.action)), ...(permissions ?? [])],
34
+ };
78
35
  }
79
- async function waitReady(client, cwd, signal) {
36
+ /** A successful HTML fallback, or a JSON response from another API, is not readiness. */
37
+ export async function waitReady(json, signal) {
38
+ let last;
80
39
  for (let attempt = 0; attempt < 100; attempt += 1) {
81
- if (signal.aborted)
82
- throw new Error("OpenCode startup aborted");
40
+ signal.throwIfAborted();
83
41
  try {
84
- await abortable(client.session.list({ query: { directory: cwd }, throwOnError: true }), signal);
42
+ const info = object(await abortable(json("/api/info"), signal));
43
+ if (typeof info?.version !== "string" ||
44
+ !info.version.startsWith("2.") ||
45
+ typeof info.pid !== "number" ||
46
+ !Array.isArray(info.urls) ||
47
+ typeof object(info.paths)?.tmp !== "string") {
48
+ throw new Error("OpenCode readiness requires native v2 server identity");
49
+ }
85
50
  return;
86
51
  }
87
- catch {
52
+ catch (error) {
53
+ last = error;
54
+ signal.throwIfAborted();
88
55
  await new Promise((resolve) => setTimeout(resolve, 100));
89
56
  }
90
57
  }
91
- throw new Error("OpenCode server did not become ready within 10000ms");
58
+ throw new Error(`OpenCode server did not become ready within 10000ms: ${String(last)}`);
92
59
  }
93
60
  async function availablePort() {
94
61
  return await new Promise((resolve, reject) => {
@@ -107,15 +74,17 @@ async function availablePort() {
107
74
  }
108
75
  export async function loadOpencode(input) {
109
76
  const { execution, cwd, signal, loader, onRuntime, requests } = input;
110
- if (loader) {
111
- const loaded = await abortable(loader(cwd, { ...execution, env: akumaExecutionEnvironment(process.env, execution.env, requests) }, signal), signal);
77
+ if (loader !== undefined) {
78
+ const loaded = await abortable(loader(cwd, {
79
+ ...execution,
80
+ env: akumaExecutionEnvironment(process.env, execution.env, requests),
81
+ }, signal), signal);
112
82
  let closing;
113
83
  const runtime = {
114
84
  client: loaded.client,
115
- close: async () => {
116
- closing ??= Promise.resolve(loaded.close?.()).then(() => undefined);
117
- await closing;
118
- },
85
+ close: () => (closing ??= Promise.resolve()
86
+ .then(() => loaded.close?.())
87
+ .then(() => undefined)),
119
88
  };
120
89
  onRuntime?.(runtime);
121
90
  try {
@@ -130,34 +99,56 @@ export async function loadOpencode(input) {
130
99
  }
131
100
  }
132
101
  const port = await availablePort();
102
+ signal.throwIfAborted();
103
+ const password = execution.env?.OPENCODE_PASSWORD ??
104
+ execution.env?.OPENCODE_SERVER_PASSWORD ??
105
+ randomBytes(32).toString("base64url");
106
+ const config = composeHeadlessPermissionConfig(execution.config);
133
107
  const owned = await spawnDetachedProcess({
134
108
  argv: [execution.executable ?? "opencode", "serve", "--hostname", "127.0.0.1", "--port", String(port)],
135
109
  cwd,
136
110
  env: akumaExecutionEnvironment(process.env, {
137
- OPENCODE_CONFIG_CONTENT: JSON.stringify(composeHeadlessPermissionConfig(execution.config)),
111
+ OPENCODE_CONFIG_CONTENT: JSON.stringify(config),
138
112
  ...execution.env,
113
+ OPENCODE_PASSWORD: password,
114
+ OPENCODE_SERVER_PASSWORD: password,
139
115
  }, requests),
140
116
  log: `${cwd}/.opencode.log`,
141
117
  });
142
- const { createOpencodeClient } = await import("@opencode-ai/sdk");
143
- const client = createOpencodeClient({ baseUrl: `http://127.0.0.1:${port}`, directory: cwd });
118
+ const native = createNativeClient(`http://127.0.0.1:${port}`, password);
144
119
  let closing;
120
+ const options = { signal };
145
121
  const runtime = {
146
- client: { session: client.session, event: opencodeEventPort(client.event) },
147
- close: async () => {
148
- closing ??= owned.terminate();
149
- await closing;
122
+ client: {
123
+ session: {
124
+ create: async ({ body }) => ({ data: await native.sdk.session.create(body, options) }),
125
+ get: async ({ id }) => ({ data: await native.sdk.session.get({ sessionID: id }, options) }),
126
+ switchModel: ({ id, model }) => native.sdk.session.switchModel({ sessionID: id, model }, options),
127
+ instructions: ({ id, text }) => native.sdk.session.instructions.entry.put({ sessionID: id, key: "keiyaku.system", value: text }, options),
128
+ active: async () => ({ data: await native.sdk.session.active(options) }),
129
+ fork: async ({ id, before }) => ({ data: await native.sdk.session.fork({ sessionID: id, before }, options) }),
130
+ interrupt: ({ id }) => native.sdk.session.interrupt({ sessionID: id, resume: false }),
131
+ prompt: async ({ id, body }) => ({
132
+ data: await native.sdk.session.prompt({ sessionID: id, ...body }, options),
133
+ }),
134
+ message: async ({ id, messageID }) => ({
135
+ data: await native.sdk.session.message.get({ sessionID: id, messageID }, options),
136
+ }),
137
+ },
138
+ event: { subscribe: ({ signal }) => native.subscribe(signal) },
150
139
  },
140
+ close: () => (closing ??= Promise.all([native.close(), owned.terminate()]).then(() => undefined)),
151
141
  };
152
142
  onRuntime?.(runtime);
153
143
  try {
154
- await waitReady(client, cwd, signal);
144
+ await waitReady(() => native.sdk.server.info({ signal }), signal);
145
+ signal.throwIfAborted();
146
+ return runtime;
155
147
  }
156
148
  catch (error) {
157
149
  await runtime.close();
158
150
  throw error;
159
151
  }
160
- return runtime;
161
152
  }
162
153
  export function coordinate(sessionId) {
163
154
  return { sessionId };
@@ -0,0 +1,33 @@
1
+ import type { AgentStreamEventPayload } from "@getpaseo/protocol/messages";
2
+ import type { AgentRuntimeInfo } from "@getpaseo/protocol/agent-types";
3
+ import { AgentEventChannel, type TurnResult } from "../../provider.js";
4
+ /**
5
+ * The runtime's own confirmation at establishment, reported as a native
6
+ * provider model id. The installed Paseo wire carries no mid-attempt model
7
+ * change on this timeline subscription, so a later re-selection is not
8
+ * observable here and is never invented.
9
+ */
10
+ export declare function paseoRuntimeModel(info: AgentRuntimeInfo | undefined): string | undefined;
11
+ /** Live fragments belong to a canonical admitted turn, not agent-wide status. */
12
+ export declare class PaseoTurn {
13
+ readonly messageId: string;
14
+ readonly events: AgentEventChannel;
15
+ readonly admission: Promise<string>;
16
+ readonly completion: Promise<TurnResult>;
17
+ private admit;
18
+ private rejectAdmission;
19
+ private finish;
20
+ private rejectCompletion;
21
+ private turnId;
22
+ private readonly messages;
23
+ private readonly messagesById;
24
+ private readonly calls;
25
+ private answer;
26
+ private assistantContiguous;
27
+ settled: boolean;
28
+ terminal: boolean;
29
+ constructor(messageId: string);
30
+ receive(event: AgentStreamEventPayload): void;
31
+ private appendAssistant;
32
+ fail(error: unknown): void;
33
+ }
@@ -0,0 +1,204 @@
1
+ import { AgentEventChannel, otherToolCall } from "../../provider.js";
2
+ import { stringValue } from "../decode.js";
3
+ /**
4
+ * The runtime's own confirmation at establishment, reported as a native
5
+ * provider model id. The installed Paseo wire carries no mid-attempt model
6
+ * change on this timeline subscription, so a later re-selection is not
7
+ * observable here and is never invented.
8
+ */
9
+ export function paseoRuntimeModel(info) {
10
+ const model = info?.model;
11
+ return typeof model === "string" && model.trim().length > 0 ? model : undefined;
12
+ }
13
+ /**
14
+ * The observed result text one native detail carries. A detail that observes no
15
+ * text stays absent; a present empty string remains observed and empty.
16
+ */
17
+ function detailOutput(detail) {
18
+ switch (detail.type) {
19
+ case "shell":
20
+ return stringValue(detail.output);
21
+ case "read":
22
+ case "search":
23
+ return stringValue(detail.content);
24
+ case "fetch":
25
+ return stringValue(detail.result);
26
+ default:
27
+ return undefined;
28
+ }
29
+ }
30
+ /** The verified unified patch a completed edit detail observed, when it supplied one. */
31
+ function detailPatch(detail) {
32
+ return detail.type === "edit" ? stringValue(detail.unifiedDiff) : undefined;
33
+ }
34
+ /** Attach the observed patch to the one change its correlated path already named. */
35
+ function withObservedPatch(call, patch) {
36
+ if (call.kind !== "fileChange")
37
+ return call;
38
+ const change = call.changes[0];
39
+ if (patch === undefined || change === undefined || call.changes.length !== 1)
40
+ return call;
41
+ return { kind: "fileChange", changes: [{ ...change, patch }] };
42
+ }
43
+ function toolCall(item) {
44
+ const detail = item.detail;
45
+ switch (detail.type) {
46
+ case "shell":
47
+ return { kind: "run", command: detail.command };
48
+ case "read":
49
+ return {
50
+ kind: "read",
51
+ path: detail.filePath,
52
+ ...(detail.offset === undefined ? {} : { offset: detail.offset }),
53
+ ...(detail.limit === undefined ? {} : { limit: detail.limit }),
54
+ };
55
+ case "edit":
56
+ case "write":
57
+ return { kind: "fileChange", changes: [{ op: "unspecified", path: detail.filePath }] };
58
+ case "search":
59
+ return { kind: "search", query: detail.query, scope: detail.toolName === "web_search" ? "web" : "content" };
60
+ case "unknown":
61
+ return otherToolCall(item.name, detail.input);
62
+ default:
63
+ return otherToolCall(item.name);
64
+ }
65
+ }
66
+ function timelineNarration(item, calls) {
67
+ switch (item.type) {
68
+ case "tool_call": {
69
+ const base = calls.get(item.callId) ?? (item.status === "running" ? toolCall(item) : otherToolCall(item.name));
70
+ const call = item.status === "running" ? base : withObservedPatch(base, detailPatch(item.detail));
71
+ calls.set(item.callId, call);
72
+ if (item.status === "running") {
73
+ return { type: "tool", phase: "started", id: item.callId, name: item.name, call };
74
+ }
75
+ const output = detailOutput(item.detail);
76
+ return {
77
+ type: "tool",
78
+ phase: "completed",
79
+ id: item.callId,
80
+ name: item.name,
81
+ call,
82
+ result: {
83
+ status: item.status === "completed" ? "ok" : "error",
84
+ ...(output === undefined ? {} : { output }),
85
+ },
86
+ };
87
+ }
88
+ case "error":
89
+ case "notification":
90
+ return { type: "note", text: item.message };
91
+ case "compaction":
92
+ return { type: "note", text: `Context compaction ${item.status}` };
93
+ case "reasoning":
94
+ case "user_message":
95
+ case "assistant_message":
96
+ return undefined;
97
+ default:
98
+ return { type: "unknown", kind: item.type };
99
+ }
100
+ }
101
+ /** Live fragments belong to a canonical admitted turn, not agent-wide status. */
102
+ export class PaseoTurn {
103
+ messageId;
104
+ events = new AgentEventChannel();
105
+ admission;
106
+ completion;
107
+ admit;
108
+ rejectAdmission;
109
+ finish;
110
+ rejectCompletion;
111
+ turnId;
112
+ messages = [];
113
+ messagesById = new Map();
114
+ calls = new Map();
115
+ answer = "";
116
+ assistantContiguous = false;
117
+ settled = false;
118
+ terminal = false;
119
+ constructor(messageId) {
120
+ this.messageId = messageId;
121
+ this.admission = new Promise((resolve, reject) => {
122
+ this.admit = resolve;
123
+ this.rejectAdmission = reject;
124
+ });
125
+ this.completion = new Promise((resolve, reject) => {
126
+ this.finish = resolve;
127
+ this.rejectCompletion = reject;
128
+ });
129
+ void this.admission.catch(() => undefined);
130
+ void this.completion.catch(() => undefined);
131
+ }
132
+ receive(event) {
133
+ if (this.settled)
134
+ return;
135
+ if (event.type === "timeline" &&
136
+ event.item.type === "user_message" &&
137
+ event.item.clientMessageId === this.messageId) {
138
+ if (event.turnId === undefined)
139
+ return this.fail(new Error("Paseo native admission omitted turnId"));
140
+ if (this.turnId !== undefined) {
141
+ if (this.turnId !== event.turnId)
142
+ this.fail(new Error("Paseo canonical admission changed native turn"));
143
+ return;
144
+ }
145
+ this.turnId = event.turnId;
146
+ this.admit(event.turnId);
147
+ return;
148
+ }
149
+ if (!("turnId" in event) || this.turnId === undefined || event.turnId !== this.turnId)
150
+ return;
151
+ if (event.type === "timeline") {
152
+ if (event.item.type === "assistant_message")
153
+ this.appendAssistant(event.item);
154
+ else {
155
+ this.assistantContiguous = false;
156
+ const narration = timelineNarration(event.item, this.calls);
157
+ if (narration !== undefined)
158
+ this.events.emit(narration);
159
+ }
160
+ }
161
+ else if (event.type === "turn_completed") {
162
+ this.settled = true;
163
+ this.finish({
164
+ kind: "answered",
165
+ answer: this.answer,
166
+ historyId: this.turnId,
167
+ });
168
+ }
169
+ else if (event.type === "turn_failed" || event.type === "turn_canceled") {
170
+ this.settled = true;
171
+ this.finish({ kind: "failed", diagnostic: event.type === "turn_failed" ? event.error : event.reason });
172
+ }
173
+ if (this.settled) {
174
+ this.terminal = true;
175
+ for (const message of this.messages)
176
+ this.events.emit({ type: "assistant", text: message.text });
177
+ }
178
+ }
179
+ appendAssistant(item) {
180
+ // Native final text is the last contiguous assistant segment; narration keeps all messages.
181
+ this.answer = this.assistantContiguous ? this.answer + item.text : item.text;
182
+ const previous = item.messageId === undefined
183
+ ? this.assistantContiguous
184
+ ? this.messages.at(-1)
185
+ : undefined
186
+ : this.messagesById.get(item.messageId);
187
+ this.assistantContiguous = true;
188
+ if (previous !== undefined)
189
+ previous.text += item.text;
190
+ else {
191
+ const message = { ...(item.messageId === undefined ? {} : { id: item.messageId }), text: item.text };
192
+ this.messages.push(message);
193
+ if (item.messageId !== undefined)
194
+ this.messagesById.set(item.messageId, message);
195
+ }
196
+ }
197
+ fail(error) {
198
+ if (this.settled)
199
+ return;
200
+ this.settled = true;
201
+ this.rejectAdmission(error);
202
+ this.rejectCompletion(error);
203
+ }
204
+ }
@@ -0,0 +1,9 @@
1
+ import { DaemonClient, type DaemonClientConfig } from "@getpaseo/client/internal/daemon-client";
2
+ import { type ProviderAdapter } from "../../provider.js";
3
+ import type { ProviderExecution } from "../../provider-recipe.js";
4
+ type PaseoClient = Pick<DaemonClient, "connect" | "close" | "createAgent" | "fetchAgent" | "setAgentModel" | "listProviderModels" | "setAgentThinkingOption" | "sendMessage" | "cancelAgent" | "subscribeAgentTimeline" | "subscribeConnectionStatus">;
5
+ export type PaseoDependencies = Readonly<{
6
+ createClient?(config: DaemonClientConfig): PaseoClient;
7
+ }>;
8
+ export declare function createPaseoProvider(execution: ProviderExecution, dependencies?: PaseoDependencies): ProviderAdapter;
9
+ export {};