@adecore/agents 0.0.1 → 0.17.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (348) hide show
  1. package/LICENSE +110 -0
  2. package/README.md +48 -0
  3. package/dist/async.d.ts +2 -0
  4. package/dist/async.js +31 -0
  5. package/dist/chat/attachment-store.d.ts +10 -0
  6. package/dist/chat/attachment-store.js +93 -0
  7. package/dist/chat/backend.d.ts +214 -0
  8. package/dist/chat/backend.js +1 -0
  9. package/dist/chat/background-work.d.ts +8 -0
  10. package/dist/chat/background-work.js +33 -0
  11. package/dist/chat/bookmark-store.d.ts +25 -0
  12. package/dist/chat/bookmark-store.js +141 -0
  13. package/dist/chat/chat-core.d.ts +311 -0
  14. package/dist/chat/chat-core.js +1025 -0
  15. package/dist/chat/chat-log.d.ts +33 -0
  16. package/dist/chat/chat-log.js +163 -0
  17. package/dist/chat/chat-process.d.ts +46 -0
  18. package/dist/chat/chat-process.js +190 -0
  19. package/dist/chat/chat-session.d.ts +209 -0
  20. package/dist/chat/chat-session.js +1511 -0
  21. package/dist/chat/chat-store.d.ts +37 -0
  22. package/dist/chat/chat-store.js +202 -0
  23. package/dist/chat/chat-title.d.ts +10 -0
  24. package/dist/chat/chat-title.js +74 -0
  25. package/dist/chat/claude-backend.d.ts +35 -0
  26. package/dist/chat/claude-backend.js +214 -0
  27. package/dist/chat/claude-protocol.d.ts +41 -0
  28. package/dist/chat/claude-protocol.js +642 -0
  29. package/dist/chat/claude-title.d.ts +11 -0
  30. package/dist/chat/claude-title.js +97 -0
  31. package/dist/chat/claude-transcript.d.ts +28 -0
  32. package/dist/chat/claude-transcript.js +211 -0
  33. package/dist/chat/codex-backend.d.ts +51 -0
  34. package/dist/chat/codex-backend.js +364 -0
  35. package/dist/chat/codex-protocol.d.ts +56 -0
  36. package/dist/chat/codex-protocol.js +767 -0
  37. package/dist/chat/codex-thread.d.ts +32 -0
  38. package/dist/chat/codex-thread.js +131 -0
  39. package/dist/chat/codex-transport.d.ts +42 -0
  40. package/dist/chat/codex-transport.js +188 -0
  41. package/dist/chat/composer-preferences.d.ts +15 -0
  42. package/dist/chat/composer-preferences.js +46 -0
  43. package/dist/chat/context-breakdown.d.ts +2 -0
  44. package/dist/chat/context-breakdown.js +74 -0
  45. package/dist/chat/delta-coalescer.d.ts +12 -0
  46. package/dist/chat/delta-coalescer.js +55 -0
  47. package/dist/chat/errors.d.ts +4 -0
  48. package/dist/chat/errors.js +4 -0
  49. package/dist/chat/fake-claude.d.ts +3 -0
  50. package/dist/chat/fake-claude.js +982 -0
  51. package/dist/chat/fake-cli.d.ts +25 -0
  52. package/dist/chat/fake-cli.js +157 -0
  53. package/dist/chat/fake-codex.d.ts +10 -0
  54. package/dist/chat/fake-codex.js +502 -0
  55. package/dist/chat/fixtures/claude-2.1.285-auto-fallback.json +24 -0
  56. package/dist/chat/fixtures/claude-2.1.285-native-children.json +6600 -0
  57. package/dist/chat/fixtures/claude-2.1.285-resume-direct-compact.json +202 -0
  58. package/dist/chat/fixtures/claude-2.1.285-resume-task-notification.json +57 -0
  59. package/dist/chat/fixtures/claude-projects/-work-demo/5f1c2a9e-0b7d-4c1e-9a53-3e2f8d6b7a10/subagents/agent-a4c2e8f10b3d5a7e9.jsonl +10 -0
  60. package/dist/chat/fixtures/claude-projects/-work-demo/5f1c2a9e-0b7d-4c1e-9a53-3e2f8d6b7a10/subagents/agent-a4c2e8f10b3d5a7e9.meta.json +1 -0
  61. package/dist/chat/fixtures/claude-projects/-work-demo/5f1c2a9e-0b7d-4c1e-9a53-3e2f8d6b7a10/subagents/agent-a9b8c7d6e5f4a3b21.jsonl +2 -0
  62. package/dist/chat/fixtures/claude-projects/-work-demo/5f1c2a9e-0b7d-4c1e-9a53-3e2f8d6b7a10/subagents/agent-a9b8c7d6e5f4a3b21.meta.json +1 -0
  63. package/dist/chat/fixtures/codex-0.159.2-native-approval.json +119 -0
  64. package/dist/chat/fixtures/codex-0.159.2-native-file-approval.json +136 -0
  65. package/dist/chat/fixtures/codex-0.159.2-native-interacted.json +220 -0
  66. package/dist/chat/fixtures/codex-0.159.2-usage-windows.json +74 -0
  67. package/dist/chat/input.d.ts +19 -0
  68. package/dist/chat/input.js +71 -0
  69. package/dist/chat/limit-resume.d.ts +11 -0
  70. package/dist/chat/limit-resume.js +68 -0
  71. package/dist/chat/projector.d.ts +60 -0
  72. package/dist/chat/projector.js +860 -0
  73. package/dist/chat/request-summary.d.ts +3 -0
  74. package/dist/chat/request-summary.js +143 -0
  75. package/dist/chat/subagent-projection.d.ts +8 -0
  76. package/dist/chat/subagent-projection.js +40 -0
  77. package/dist/chat/subagent-reader.d.ts +66 -0
  78. package/dist/chat/subagent-reader.js +396 -0
  79. package/dist/chat/subagent-settlement.d.ts +6 -0
  80. package/dist/chat/subagent-settlement.js +103 -0
  81. package/dist/chat/thread.d.ts +30 -0
  82. package/dist/chat/thread.js +147 -0
  83. package/dist/chat/wake-chat.d.ts +20 -0
  84. package/dist/chat/wake-chat.js +27 -0
  85. package/dist/client-sinks.d.ts +9 -0
  86. package/dist/client-sinks.js +34 -0
  87. package/dist/coded-error.d.ts +5 -0
  88. package/dist/coded-error.js +17 -0
  89. package/dist/context/argv.d.ts +11 -0
  90. package/dist/context/argv.js +58 -0
  91. package/dist/context/refusal.d.ts +9 -0
  92. package/dist/context/refusal.js +38 -0
  93. package/dist/context/verb.d.ts +85 -0
  94. package/dist/context/verb.js +233 -0
  95. package/dist/error-text.d.ts +5 -0
  96. package/dist/error-text.js +24 -0
  97. package/dist/events.d.ts +12 -0
  98. package/dist/events.js +1 -0
  99. package/dist/fs.d.ts +9 -0
  100. package/dist/fs.js +107 -0
  101. package/dist/host/agent-host.d.ts +28 -0
  102. package/dist/host/agent-host.js +105 -0
  103. package/dist/host/environment.d.ts +7 -0
  104. package/dist/host/environment.js +22 -0
  105. package/dist/host/handlers.d.ts +30 -0
  106. package/dist/host/handlers.js +111 -0
  107. package/dist/host/memory-port.d.ts +2 -0
  108. package/dist/host/memory-port.js +25 -0
  109. package/dist/host/wiring.d.ts +40 -0
  110. package/dist/host/wiring.js +120 -0
  111. package/dist/lineage.d.ts +44 -0
  112. package/dist/lineage.js +134 -0
  113. package/dist/messages/deliver-message.d.ts +21 -0
  114. package/dist/messages/deliver-message.js +42 -0
  115. package/dist/messages/deliver-notice.d.ts +25 -0
  116. package/dist/messages/deliver-notice.js +75 -0
  117. package/dist/messages/notice-notes.d.ts +15 -0
  118. package/dist/messages/notice-notes.js +26 -0
  119. package/dist/messages/notice-store.d.ts +30 -0
  120. package/dist/messages/notice-store.js +120 -0
  121. package/dist/modes.d.ts +11 -0
  122. package/dist/modes.js +28 -0
  123. package/dist/outbox/manual-clock.d.ts +10 -0
  124. package/dist/outbox/manual-clock.js +25 -0
  125. package/dist/outbox/outbox-worker.d.ts +44 -0
  126. package/dist/outbox/outbox-worker.js +173 -0
  127. package/dist/outbox/outbox.d.ts +37 -0
  128. package/dist/outbox/outbox.js +76 -0
  129. package/dist/providers/accounts/accounts.d.ts +20 -0
  130. package/dist/providers/accounts/accounts.js +158 -0
  131. package/dist/providers/accounts/launch.d.ts +17 -0
  132. package/dist/providers/accounts/launch.js +30 -0
  133. package/dist/providers/accounts/service.d.ts +87 -0
  134. package/dist/providers/accounts/service.js +538 -0
  135. package/dist/providers/accounts/shadow-home.d.ts +8 -0
  136. package/dist/providers/accounts/shadow-home.js +70 -0
  137. package/dist/providers/accounts/status.d.ts +12 -0
  138. package/dist/providers/accounts/status.js +85 -0
  139. package/dist/providers/accounts/store.d.ts +14 -0
  140. package/dist/providers/accounts/store.js +112 -0
  141. package/dist/providers/accounts/test-accounts.d.ts +12 -0
  142. package/dist/providers/accounts/test-accounts.js +38 -0
  143. package/dist/providers/accounts/variables.d.ts +27 -0
  144. package/dist/providers/accounts/variables.js +94 -0
  145. package/dist/providers/catalog.d.ts +17 -0
  146. package/dist/providers/catalog.js +76 -0
  147. package/dist/providers/claude-models.json +114 -0
  148. package/dist/providers/claude-provider.d.ts +4 -0
  149. package/dist/providers/claude-provider.js +29 -0
  150. package/dist/providers/claude.d.ts +15 -0
  151. package/dist/providers/claude.js +105 -0
  152. package/dist/providers/codex-models.json +135 -0
  153. package/dist/providers/codex-provider.d.ts +4 -0
  154. package/dist/providers/codex-provider.js +27 -0
  155. package/dist/providers/codex-rules.d.ts +9 -0
  156. package/dist/providers/codex-rules.js +35 -0
  157. package/dist/providers/codex.d.ts +14 -0
  158. package/dist/providers/codex.js +52 -0
  159. package/dist/providers/detect.d.ts +6 -0
  160. package/dist/providers/detect.js +30 -0
  161. package/dist/providers/provider.d.ts +25 -0
  162. package/dist/providers/provider.js +1 -0
  163. package/dist/providers/registry.d.ts +28 -0
  164. package/dist/providers/registry.js +118 -0
  165. package/dist/record-directory.d.ts +27 -0
  166. package/dist/record-directory.js +114 -0
  167. package/dist/run-process.d.ts +13 -0
  168. package/dist/run-process.js +42 -0
  169. package/dist/serializer.d.ts +9 -0
  170. package/dist/serializer.js +34 -0
  171. package/dist/skills.d.ts +21 -0
  172. package/dist/skills.js +174 -0
  173. package/dist/tasks/background-limit.d.ts +16 -0
  174. package/dist/tasks/background-limit.js +55 -0
  175. package/dist/tasks/end-children.d.ts +34 -0
  176. package/dist/tasks/end-children.js +53 -0
  177. package/dist/tasks/give-task.d.ts +14 -0
  178. package/dist/tasks/give-task.js +33 -0
  179. package/dist/tasks/task-coordinator.d.ts +52 -0
  180. package/dist/tasks/task-coordinator.js +323 -0
  181. package/dist/tasks/task-store.d.ts +49 -0
  182. package/dist/tasks/task-store.js +197 -0
  183. package/dist/tasks/task-work.d.ts +47 -0
  184. package/dist/tasks/task-work.js +28 -0
  185. package/dist/tasks/waiting-child.d.ts +51 -0
  186. package/dist/tasks/waiting-child.js +143 -0
  187. package/dist/tasks/wake-parent.d.ts +19 -0
  188. package/dist/tasks/wake-parent.js +109 -0
  189. package/dist/tasks/wiring.d.ts +51 -0
  190. package/dist/tasks/wiring.js +151 -0
  191. package/dist/title-file.d.ts +2 -0
  192. package/dist/title-file.js +55 -0
  193. package/dist/usage/accounts.d.ts +15 -0
  194. package/dist/usage/accounts.js +64 -0
  195. package/dist/usage/aggregate.d.ts +12 -0
  196. package/dist/usage/aggregate.js +154 -0
  197. package/dist/usage/exchange.d.ts +16 -0
  198. package/dist/usage/exchange.js +84 -0
  199. package/dist/usage/index-file.d.ts +15 -0
  200. package/dist/usage/index-file.js +123 -0
  201. package/dist/usage/limits/monitor.d.ts +50 -0
  202. package/dist/usage/limits/monitor.js +179 -0
  203. package/dist/usage/limits/normalize.d.ts +21 -0
  204. package/dist/usage/limits/normalize.js +160 -0
  205. package/dist/usage/limits/probe.d.ts +9 -0
  206. package/dist/usage/limits/probe.js +113 -0
  207. package/dist/usage/prices-snapshot.json +1071 -0
  208. package/dist/usage/pricing.d.ts +34 -0
  209. package/dist/usage/pricing.js +186 -0
  210. package/dist/usage/projects.d.ts +17 -0
  211. package/dist/usage/projects.js +49 -0
  212. package/dist/usage/readers/claude.d.ts +3 -0
  213. package/dist/usage/readers/claude.js +59 -0
  214. package/dist/usage/readers/codex.d.ts +23 -0
  215. package/dist/usage/readers/codex.js +155 -0
  216. package/dist/usage/record.d.ts +15 -0
  217. package/dist/usage/record.js +39 -0
  218. package/dist/usage/roots.d.ts +12 -0
  219. package/dist/usage/roots.js +29 -0
  220. package/dist/usage/scanner.d.ts +30 -0
  221. package/dist/usage/scanner.js +234 -0
  222. package/dist/usage/usage-service.d.ts +35 -0
  223. package/dist/usage/usage-service.js +130 -0
  224. package/dist/watch-seam.d.ts +29 -0
  225. package/dist/watch-seam.js +78 -0
  226. package/dist/watch-test-helpers.d.ts +28 -0
  227. package/dist/watch-test-helpers.js +86 -0
  228. package/package.json +42 -3
  229. package/src/async.ts +40 -0
  230. package/src/chat/attachment-store.ts +108 -0
  231. package/src/chat/backend.ts +199 -0
  232. package/src/chat/background-work.ts +42 -0
  233. package/src/chat/bookmark-store.ts +166 -0
  234. package/src/chat/chat-core.ts +1228 -0
  235. package/src/chat/chat-log.ts +187 -0
  236. package/src/chat/chat-process.ts +237 -0
  237. package/src/chat/chat-session.ts +1723 -0
  238. package/src/chat/chat-store.ts +261 -0
  239. package/src/chat/chat-title.ts +90 -0
  240. package/src/chat/claude-backend.ts +235 -0
  241. package/src/chat/claude-protocol.ts +684 -0
  242. package/src/chat/claude-title.ts +106 -0
  243. package/src/chat/claude-transcript.ts +233 -0
  244. package/src/chat/codex-backend.ts +397 -0
  245. package/src/chat/codex-protocol.ts +872 -0
  246. package/src/chat/codex-thread.ts +162 -0
  247. package/src/chat/codex-transport.ts +224 -0
  248. package/src/chat/composer-preferences.ts +67 -0
  249. package/src/chat/context-breakdown.ts +80 -0
  250. package/src/chat/delta-coalescer.ts +62 -0
  251. package/src/chat/errors.ts +25 -0
  252. package/src/chat/fake-claude.ts +1006 -0
  253. package/src/chat/fake-cli.ts +199 -0
  254. package/src/chat/fake-codex.ts +534 -0
  255. package/src/chat/fixtures/claude-2.1.285-auto-fallback.json +24 -0
  256. package/src/chat/fixtures/claude-2.1.285-native-children.json +6600 -0
  257. package/src/chat/fixtures/claude-2.1.285-resume-direct-compact.json +202 -0
  258. package/src/chat/fixtures/claude-2.1.285-resume-task-notification.json +57 -0
  259. package/src/chat/fixtures/claude-projects/-work-demo/5f1c2a9e-0b7d-4c1e-9a53-3e2f8d6b7a10/subagents/agent-a4c2e8f10b3d5a7e9.jsonl +10 -0
  260. package/src/chat/fixtures/claude-projects/-work-demo/5f1c2a9e-0b7d-4c1e-9a53-3e2f8d6b7a10/subagents/agent-a4c2e8f10b3d5a7e9.meta.json +1 -0
  261. package/src/chat/fixtures/claude-projects/-work-demo/5f1c2a9e-0b7d-4c1e-9a53-3e2f8d6b7a10/subagents/agent-a9b8c7d6e5f4a3b21.jsonl +2 -0
  262. package/src/chat/fixtures/claude-projects/-work-demo/5f1c2a9e-0b7d-4c1e-9a53-3e2f8d6b7a10/subagents/agent-a9b8c7d6e5f4a3b21.meta.json +1 -0
  263. package/src/chat/fixtures/codex-0.159.2-native-approval.json +119 -0
  264. package/src/chat/fixtures/codex-0.159.2-native-file-approval.json +136 -0
  265. package/src/chat/fixtures/codex-0.159.2-native-interacted.json +220 -0
  266. package/src/chat/fixtures/codex-0.159.2-usage-windows.json +74 -0
  267. package/src/chat/input.ts +89 -0
  268. package/src/chat/limit-resume.ts +74 -0
  269. package/src/chat/projector.ts +969 -0
  270. package/src/chat/request-summary.ts +168 -0
  271. package/src/chat/subagent-projection.ts +45 -0
  272. package/src/chat/subagent-reader.ts +469 -0
  273. package/src/chat/subagent-settlement.ts +111 -0
  274. package/src/chat/thread.ts +167 -0
  275. package/src/chat/wake-chat.ts +45 -0
  276. package/src/client-sinks.ts +39 -0
  277. package/src/coded-error.ts +18 -0
  278. package/src/context/argv.ts +61 -0
  279. package/src/context/refusal.ts +50 -0
  280. package/src/context/verb.ts +392 -0
  281. package/src/error-text.ts +28 -0
  282. package/src/events.ts +9 -0
  283. package/src/fs.ts +118 -0
  284. package/src/host/agent-host.ts +124 -0
  285. package/src/host/environment.ts +31 -0
  286. package/src/host/handlers.ts +142 -0
  287. package/src/host/memory-port.ts +27 -0
  288. package/src/host/wiring.ts +164 -0
  289. package/src/lineage.ts +159 -0
  290. package/src/messages/deliver-message.ts +61 -0
  291. package/src/messages/deliver-notice.ts +120 -0
  292. package/src/messages/notice-notes.ts +34 -0
  293. package/src/messages/notice-store.ts +142 -0
  294. package/src/modes.ts +38 -0
  295. package/src/outbox/manual-clock.ts +31 -0
  296. package/src/outbox/outbox-worker.ts +214 -0
  297. package/src/outbox/outbox.ts +106 -0
  298. package/src/providers/accounts/accounts.ts +192 -0
  299. package/src/providers/accounts/launch.ts +55 -0
  300. package/src/providers/accounts/service.ts +632 -0
  301. package/src/providers/accounts/shadow-home.ts +85 -0
  302. package/src/providers/accounts/status.ts +106 -0
  303. package/src/providers/accounts/store.ts +158 -0
  304. package/src/providers/accounts/test-accounts.ts +48 -0
  305. package/src/providers/accounts/variables.ts +132 -0
  306. package/src/providers/catalog.ts +90 -0
  307. package/src/providers/claude-models.json +114 -0
  308. package/src/providers/claude-provider.ts +32 -0
  309. package/src/providers/claude.ts +123 -0
  310. package/src/providers/codex-models.json +135 -0
  311. package/src/providers/codex-provider.ts +30 -0
  312. package/src/providers/codex-rules.ts +54 -0
  313. package/src/providers/codex.ts +69 -0
  314. package/src/providers/detect.ts +40 -0
  315. package/src/providers/provider.ts +46 -0
  316. package/src/providers/registry.ts +150 -0
  317. package/src/record-directory.ts +136 -0
  318. package/src/run-process.ts +61 -0
  319. package/src/serializer.ts +41 -0
  320. package/src/skills.ts +199 -0
  321. package/src/tasks/background-limit.ts +72 -0
  322. package/src/tasks/end-children.ts +100 -0
  323. package/src/tasks/give-task.ts +52 -0
  324. package/src/tasks/task-coordinator.ts +384 -0
  325. package/src/tasks/task-store.ts +236 -0
  326. package/src/tasks/task-work.ts +62 -0
  327. package/src/tasks/waiting-child.ts +203 -0
  328. package/src/tasks/wake-parent.ts +142 -0
  329. package/src/tasks/wiring.ts +231 -0
  330. package/src/title-file.ts +57 -0
  331. package/src/usage/accounts.ts +86 -0
  332. package/src/usage/aggregate.ts +220 -0
  333. package/src/usage/exchange.ts +93 -0
  334. package/src/usage/index-file.ts +178 -0
  335. package/src/usage/limits/monitor.ts +239 -0
  336. package/src/usage/limits/normalize.ts +188 -0
  337. package/src/usage/limits/probe.ts +120 -0
  338. package/src/usage/prices-snapshot.json +1071 -0
  339. package/src/usage/pricing.ts +236 -0
  340. package/src/usage/projects.ts +65 -0
  341. package/src/usage/readers/claude.ts +60 -0
  342. package/src/usage/readers/codex.ts +196 -0
  343. package/src/usage/record.ts +60 -0
  344. package/src/usage/roots.ts +39 -0
  345. package/src/usage/scanner.ts +265 -0
  346. package/src/usage/usage-service.ts +161 -0
  347. package/src/watch-seam.ts +111 -0
  348. package/src/watch-test-helpers.ts +102 -0
@@ -0,0 +1,233 @@
1
+ import { z } from 'zod';
2
+ import { CodedError } from '../coded-error.js';
3
+ import { parseArgv } from './argv.js';
4
+ /* A verb said no. The code is for a script, the message for the agent, the lines for what it can pick instead. */
5
+ export class VerbRefusal extends CodedError {
6
+ }
7
+ export const DRY_RUN_FLAG = 'dry-run';
8
+ export const REVISION_FLAG = 'revision';
9
+ /* Agents dry-run every call before the real one to be safe, which doubles what each costs them. */
10
+ export const DRY_RUN_PREVIEW = 'a refused call makes nothing either, so it is only a preview and never needed for safety';
11
+ function flagsOf(spec) {
12
+ return {
13
+ values: [...Object.keys(spec.flags.shape), ...(spec.revision === true ? [REVISION_FLAG] : [])],
14
+ switches: [...(spec.switches ?? []), ...(spec.dryRun === true ? [DRY_RUN_FLAG] : [])]
15
+ };
16
+ }
17
+ function flagSpelled(usage, flag) {
18
+ return new RegExp(`(^|[^\\w-])${flag}(?![\\w-])`).test(usage);
19
+ }
20
+ /*
21
+ * The synopsis with every flag the detail documents: what the hand-written one leaves out is added
22
+ * from its detail line, bracketed unless that line says it is required, so the two never drift.
23
+ */
24
+ function usageWithFlags(usage, detail) {
25
+ const missing = detail
26
+ .filter((line) => line.startsWith('flag\t--'))
27
+ .map((line) => line.split('\t'))
28
+ .filter(([, syntax]) => !flagSpelled(usage, syntax.split(' ')[0]))
29
+ .map(([, syntax, need]) => (need === 'required' ? syntax : `[${syntax}]`));
30
+ return [usage, ...missing].filter((part) => part !== '').join(' ');
31
+ }
32
+ /*
33
+ * Every schema in the registry carries a sentence of its own, because zod's default ("Too small:
34
+ * expected array to have >=1 items") names neither what is missing nor what may go there.
35
+ */
36
+ function issueMessage(error, what) {
37
+ return error.issues[0]?.message ?? `Bad ${what}`;
38
+ }
39
+ /*
40
+ * Every row says what it is in its first field, so the lines under the list are never read as verbs.
41
+ * A noun names its actions and not their arguments, which keeps the root short; `help <noun>` has those.
42
+ */
43
+ export function summaryLines(entries) {
44
+ return entries.map((entry) => entry.served === 'noun'
45
+ ? `noun\t${entry.name}\t${entry.actions.map((action) => action.word).join('|')}\t${entry.summary}`
46
+ : `verb\t${entry.name}\t${entry.usage}\t${entry.summary}`);
47
+ }
48
+ /* The signatures of every action of a noun, for `help <noun>` and a refusal about one. */
49
+ function actionLines(noun) {
50
+ return noun.actions.map((action) => `action\t${action.name}\t${action.usage}\t${action.summary}`);
51
+ }
52
+ /* `cli` is the command an agent runs, such as `app-context`, which every pointer to `help` names. */
53
+ export function createVerbRegistry(options) {
54
+ const { cli } = options;
55
+ /*
56
+ * What takes `--dry-run`, filled as each is defined. Everything else refuses the flag by name and
57
+ * points at these, so an agent never gets a silent nothing from a dry run that was never dry.
58
+ */
59
+ const dryRunVerbs = [];
60
+ /* What a refusal over arguments points at; for an action `name` is both words, which is what `help` takes. */
61
+ const usageLinesOf = (name, usage) => [`usage\t${name}\t${usage}`, `detail\t${cli} help ${name}`];
62
+ /* One set of arguments parsed and run. `name` is what a refusal calls it, so `view new` refuses under both its words. */
63
+ const runArgs = async (name, usage, spec, argv, call) => {
64
+ const usageLines = usageLinesOf(name, usage);
65
+ const { values, switches } = flagsOf(spec);
66
+ const parsed = parseArgv(argv, values, switches);
67
+ if (!parsed.ok) {
68
+ const dryRunAsked = argv.some((word) => word === `--${DRY_RUN_FLAG}` || word.startsWith(`--${DRY_RUN_FLAG}=`));
69
+ if (parsed.code === 'unknown-flag' && spec.dryRun !== true && dryRunAsked) {
70
+ throw new VerbRefusal('no-dry-run', `${name} takes no --${DRY_RUN_FLAG}; only the verbs that make something do`, dryRunVerbs.map((verb) => `verb\t${verb}\ttakes --${DRY_RUN_FLAG}`));
71
+ }
72
+ throw new VerbRefusal(parsed.code, parsed.message, usageLines);
73
+ }
74
+ const positionals = spec.positionals.safeParse(parsed.positionals);
75
+ if (!positionals.success) {
76
+ throw new VerbRefusal('bad-arguments', issueMessage(positionals.error, 'argument'), usageLines);
77
+ }
78
+ const { [REVISION_FLAG]: revision, ...given } = parsed.flags;
79
+ const flags = spec.flags.safeParse(given);
80
+ if (!flags.success) {
81
+ throw new VerbRefusal('bad-arguments', issueMessage(flags.error, 'flag'), usageLines);
82
+ }
83
+ if (revision !== undefined && !/^\d+$/.test(revision)) {
84
+ throw new VerbRefusal('bad-arguments', `--${REVISION_FLAG} takes the whole number a list printed as revision`, usageLines);
85
+ }
86
+ return spec.run({ positionals: positionals.data, flags: flags.data, switches: parsed.switches, dryRun: parsed.switches.has(DRY_RUN_FLAG) }, revision === undefined ? call : { ...call, expectedRevision: Number(revision) });
87
+ };
88
+ /* What a verb and an action share: the synopsis beside the schemas its arguments are checked against. */
89
+ const defineArgs = (name, spec) => {
90
+ const { values, switches } = flagsOf(spec);
91
+ if (spec.dryRun === true) {
92
+ dryRunVerbs.push(name);
93
+ }
94
+ const usage = usageWithFlags(spec.usage, spec.detail);
95
+ return {
96
+ name,
97
+ usage,
98
+ summary: spec.summary,
99
+ detail: spec.detail,
100
+ flagNames: [...new Set([...values, ...switches])],
101
+ dryRun: spec.dryRun === true,
102
+ run: (argv, call) => runArgs(name, usage, spec, argv, call)
103
+ };
104
+ };
105
+ const defineVerb = (spec) => ({
106
+ served: 'verb',
107
+ ...defineArgs(spec.name, spec)
108
+ });
109
+ const defineAction = (noun, spec) => ({
110
+ word: spec.name,
111
+ ...defineArgs(`${noun} ${spec.name}`, spec)
112
+ });
113
+ const defineNoun = (spec) => {
114
+ const words = spec.actions.map((action) => action.word);
115
+ return {
116
+ served: 'noun',
117
+ name: spec.name,
118
+ usage: `<${words.join('|')}> ...`,
119
+ summary: spec.summary,
120
+ detail: spec.detail,
121
+ actions: spec.actions,
122
+ async run(argv, call) {
123
+ const [word, ...rest] = argv;
124
+ const action = spec.actions.find((candidate) => candidate.word === word);
125
+ if (!action) {
126
+ throw new VerbRefusal('unknown-action', `${spec.name} needs one of ${words.join(', ')}${word === undefined ? '' : `, and ${word} is not one`}`, [...spec.actions.map((candidate) => `usage\t${candidate.name}\t${candidate.usage}`), `detail\t${cli} help ${spec.name}`]);
127
+ }
128
+ return action.run(rest, call);
129
+ }
130
+ };
131
+ };
132
+ const defineHelp = (spec) => {
133
+ const detailLines = (entry) => [`usage\t${entry.name}\t${entry.usage}`, `about\t${entry.summary}`, ...entry.detail, spec.refusal];
134
+ const nounLines = (noun) => [
135
+ `usage\t${noun.name}\t${noun.usage}`,
136
+ `about\t${noun.summary}`,
137
+ ...noun.detail,
138
+ ...actionLines(noun),
139
+ `detail\t${cli} help ${noun.name} <action>\tone action in full`,
140
+ spec.refusal
141
+ ];
142
+ const topics = spec.topics ?? [];
143
+ const topicLines = topics.map((topic) => `topic\t${topic.name}\t${topic.summary}`);
144
+ const topicPointer = topics.length > 0 ? [`detail\t${cli} help <topic>\tone topic in full`] : [];
145
+ return defineVerb({
146
+ name: 'help',
147
+ usage: '[noun] [action]',
148
+ summary: 'Lists every verb and noun; with a noun the signature of each of its actions, with a noun and an action or with a verb everything that one takes',
149
+ detail: [
150
+ topics.length > 0
151
+ ? 'argument\t<noun>\toptional\tThe noun, verb or topic to detail; without one every verb, noun and topic is listed'
152
+ : 'argument\t<noun>\toptional\tThe noun or verb to detail; without one every verb and noun is listed',
153
+ 'argument\t<action>\toptional\tOne action of that noun, in full',
154
+ 'prints\tverb\tname\targuments\tsummary\tone row per verb',
155
+ 'prints\tnoun\tname\tactions\tsummary\tone row per noun, its actions separated by |; a row that starts with neither is not one',
156
+ ...(topics.length > 0 ? ['prints\ttopic\tname\tsummary\tone row per topic, after the verbs and nouns'] : [])
157
+ ],
158
+ positionals: z.array(z.string()).max(2, 'help takes a verb, or a noun and one of its actions, and nothing else'),
159
+ flags: z.object({}),
160
+ run: async ({ positionals: [name, actionWord] }) => {
161
+ const entries = spec.entries();
162
+ if (name === undefined) {
163
+ return [
164
+ ...summaryLines(entries),
165
+ ...topicLines,
166
+ ...spec.root(),
167
+ `detail\t${cli} help <noun>\tthe signature of every action of a noun`,
168
+ `detail\t${cli} help <noun> <action>\tone action in full`,
169
+ `detail\t${cli} help <verb>\tone verb in full`,
170
+ ...topicPointer,
171
+ spec.refusal
172
+ ];
173
+ }
174
+ const entry = entries.find((candidate) => candidate.name === name);
175
+ const topic = entry ? undefined : topics.find((candidate) => candidate.name === name);
176
+ if (topic) {
177
+ if (actionWord !== undefined) {
178
+ throw new VerbRefusal('bad-arguments', `${name} is a topic and has no actions; ${cli} help ${name} prints it`, [
179
+ `detail\t${cli} help ${name}\tthe topic in full`
180
+ ]);
181
+ }
182
+ return [`about\t${topic.summary}`, ...topic.body];
183
+ }
184
+ if (!entry) {
185
+ throw new VerbRefusal('unknown-verb', topics.length > 0 ? `${name} is not a verb, a noun or a topic` : `${name} is not a verb or a noun`, [
186
+ `detail\t${cli} help\tevery verb and noun, with what each takes`,
187
+ ...summaryLines(entries),
188
+ ...topicLines
189
+ ]);
190
+ }
191
+ if (entry.served !== 'noun') {
192
+ if (actionWord !== undefined) {
193
+ throw new VerbRefusal('bad-arguments', `${name} is a verb and has no actions; ${cli} help ${name} details it`, [
194
+ `detail\t${cli} help ${name}\tone verb in full`
195
+ ]);
196
+ }
197
+ return detailLines(entry);
198
+ }
199
+ if (actionWord === undefined) {
200
+ return nounLines(entry);
201
+ }
202
+ const action = entry.actions.find((candidate) => candidate.word === actionWord);
203
+ if (!action) {
204
+ throw new VerbRefusal('unknown-action', `${actionWord} is not an action of ${name}`, actionLines(entry));
205
+ }
206
+ return detailLines(action);
207
+ }
208
+ });
209
+ };
210
+ const dryRunVerbNames = () => dryRunVerbs;
211
+ const dryRunLine = () => `dry run\t--${DRY_RUN_FLAG}\t${dryRunVerbs.join(', ')}\tsame checks, nothing made; ${DRY_RUN_PREVIEW}; every other verb refuses the flag`;
212
+ return { defineVerb, defineAction, defineNoun, defineHelp, dryRunVerbNames, dryRunLine };
213
+ }
214
+ /* How much came in, for a refusal that counts: zod hands its error function the input it rejected. */
215
+ export function lengthOf(input) {
216
+ if (typeof input === 'string' || Array.isArray(input)) {
217
+ return input.length;
218
+ }
219
+ return 0;
220
+ }
221
+ /* A flag a verb cannot do without: the same sentence whether it was left out or left empty, since
222
+ zod's own ("expected string, received undefined") names neither the flag nor what goes in it. */
223
+ export function requiredField(needs) {
224
+ return z.string({ error: needs }).min(1, needs);
225
+ }
226
+ /*
227
+ * What a refusal lists, or one line saying the set is empty. A refusal that promises the groups of a
228
+ * canvas and then prints nothing reads as a daemon that lost them, where the truth is that there are
229
+ * none, which is a different thing to do something about.
230
+ */
231
+ export function orNote(lines, note) {
232
+ return lines.length === 0 ? [`note\t${note}`] : lines;
233
+ }
@@ -0,0 +1,5 @@
1
+ /** The message of an error, or its whole stack with `debug` set. */
2
+ export declare function describeError(error: unknown, debug: boolean): string;
3
+ export declare function setErrorStacks(on: boolean): void;
4
+ /** `describeError` as the host set it, for a log line or a note. */
5
+ export declare function errorText(error: unknown): string;
@@ -0,0 +1,24 @@
1
+ /*
2
+ * How an error reaches a log, a note or a reply. Bun prints an Error object handed to the console with a
3
+ * code frame of the bundle it came from, which in a compiled binary is a few lines of minified source,
4
+ * so an error is always turned into a string first.
5
+ */
6
+ /** The message of an error, or its whole stack with `debug` set. */
7
+ export function describeError(error, debug) {
8
+ if (!(error instanceof Error)) {
9
+ return String(error);
10
+ }
11
+ if (debug) {
12
+ return error.stack ?? `${error.name}: ${error.message}`;
13
+ }
14
+ return error.message === '' ? error.name : error.message;
15
+ }
16
+ // The host decides once whether a stack is worth showing; the package reads no variable of its own.
17
+ let showStacks = false;
18
+ export function setErrorStacks(on) {
19
+ showStacks = on;
20
+ }
21
+ /** `describeError` as the host set it, for a log line or a note. */
22
+ export function errorText(error) {
23
+ return describeError(error, showStacks);
24
+ }
@@ -0,0 +1,12 @@
1
+ import type { AGENT_EVENT_SCHEMAS, AgentEventType } from '@adecore/agent-contracts';
2
+ import type { z } from 'zod';
3
+ export type AgentEventMap = {
4
+ [E in AgentEventType]: z.infer<(typeof AGENT_EVENT_SCHEMAS)[E]>;
5
+ };
6
+ export type AgentEvent = {
7
+ [E in AgentEventType]: {
8
+ event: E;
9
+ payload: AgentEventMap[E];
10
+ };
11
+ }[AgentEventType];
12
+ export type AgentSink = (event: AgentEvent) => void;
package/dist/events.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/dist/fs.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ export declare function tempNameFor(target: string): string;
2
+ export interface WriteAtomicOptions {
3
+ durable?: boolean;
4
+ }
5
+ export declare function writeAtomic(target: string, content: string | Uint8Array, mode?: number, options?: WriteAtomicOptions): Promise<void>;
6
+ export declare function replaceSync(temp: string, target: string): void;
7
+ export declare function writeAtomicSync(target: string, content: string | Uint8Array, mode?: number): void;
8
+ export declare function isNotFound(e: unknown): boolean;
9
+ export declare function fileExists(path: string): Promise<boolean>;
package/dist/fs.js ADDED
@@ -0,0 +1,107 @@
1
+ import { renameSync, writeFileSync } from 'node:fs';
2
+ import { open, rename, stat, writeFile } from 'node:fs/promises';
3
+ import { dirname } from 'node:path';
4
+ // Windows can refuse a rename while a watcher or an indexer holds the target; a few short retries cover it.
5
+ const RENAME_RETRIES = 5;
6
+ const RENAME_RETRY_MS = 40;
7
+ // Node has no synchronous sleep; a wait on a value nobody changes is one.
8
+ function sleepSync(ms) {
9
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
10
+ }
11
+ function isTransient(e) {
12
+ return typeof e === 'object' && e !== null && 'code' in e && (e.code === 'EPERM' || e.code === 'EBUSY' || e.code === 'EACCES');
13
+ }
14
+ // Two writes of the same file in flight at once (a fire-and-forget save next to an awaited one) must not share a temp name.
15
+ let nextTemp = 0;
16
+ /* Where a file waits while it is being written; the pid keeps two hosts over one home apart. */
17
+ export function tempNameFor(target) {
18
+ return `${target}.${process.pid}-${nextTemp++}.tmp`;
19
+ }
20
+ async function writeFlushed(path, content, mode) {
21
+ const handle = await open(path, 'w', mode);
22
+ try {
23
+ await handle.writeFile(content);
24
+ await handle.sync();
25
+ }
26
+ finally {
27
+ await handle.close();
28
+ }
29
+ }
30
+ // Windows cannot open a directory to flush it, and NTFS journals the rename itself.
31
+ async function syncDirectory(path) {
32
+ if (process.platform === 'win32') {
33
+ return;
34
+ }
35
+ const handle = await open(path, 'r');
36
+ try {
37
+ await handle.sync();
38
+ }
39
+ finally {
40
+ await handle.close();
41
+ }
42
+ }
43
+ /*
44
+ * A crash between the two steps leaves a stray temp file, never a half-written file. That holds for
45
+ * a process that dies; after a power cut APFS and ext4 can still hold an empty target, unless the
46
+ * write is durable.
47
+ */
48
+ export async function writeAtomic(target, content, mode = 0o600, options = {}) {
49
+ const temp = tempNameFor(target);
50
+ if (options.durable) {
51
+ await writeFlushed(temp, content, mode);
52
+ }
53
+ else {
54
+ await writeFile(temp, content, { mode });
55
+ }
56
+ for (let attempt = 0;; attempt++) {
57
+ try {
58
+ await rename(temp, target);
59
+ break;
60
+ }
61
+ catch (e) {
62
+ if (!isTransient(e) || attempt >= RENAME_RETRIES) {
63
+ throw e;
64
+ }
65
+ await new Promise((resolve) => setTimeout(resolve, RENAME_RETRY_MS));
66
+ }
67
+ }
68
+ if (options.durable) {
69
+ await syncDirectory(dirname(target));
70
+ }
71
+ }
72
+ /*
73
+ * The same rename, without a turn of the event loop. A `bun --watch` reload restarts a module before
74
+ * an awaited write comes back, and an exit path is gone before one lands, so what has to be on disk
75
+ * before the process turns around goes through here.
76
+ */
77
+ export function replaceSync(temp, target) {
78
+ for (let attempt = 0;; attempt++) {
79
+ try {
80
+ renameSync(temp, target);
81
+ return;
82
+ }
83
+ catch (e) {
84
+ if (!isTransient(e) || attempt >= RENAME_RETRIES) {
85
+ throw e;
86
+ }
87
+ sleepSync(RENAME_RETRY_MS);
88
+ }
89
+ }
90
+ }
91
+ export function writeAtomicSync(target, content, mode = 0o600) {
92
+ const temp = tempNameFor(target);
93
+ writeFileSync(temp, content, { mode });
94
+ replaceSync(temp, target);
95
+ }
96
+ export function isNotFound(e) {
97
+ return typeof e === 'object' && e !== null && 'code' in e && e.code === 'ENOENT';
98
+ }
99
+ export async function fileExists(path) {
100
+ try {
101
+ await stat(path);
102
+ return true;
103
+ }
104
+ catch {
105
+ return false;
106
+ }
107
+ }
@@ -0,0 +1,28 @@
1
+ import { type FramePort } from '@adecore/agent-contracts';
2
+ import type { ChatCore } from '../chat/chat-core.ts';
3
+ import type { ProviderAccountsService } from '../providers/accounts/service.ts';
4
+ import type { ProviderRegistry } from '../providers/registry.ts';
5
+ import type { UsageMonitor } from '../usage/limits/monitor.ts';
6
+ import type { UsageService } from '../usage/usage-service.ts';
7
+ import { type AgentWiringOptions } from './wiring.ts';
8
+ export interface AgentHostOptions<Core extends ChatCore = ChatCore> extends AgentWiringOptions<Core> {
9
+ background?: boolean;
10
+ }
11
+ export declare class AgentHost<Core extends ChatCore = ChatCore> {
12
+ readonly chats: Core;
13
+ readonly providers: ProviderRegistry;
14
+ readonly accounts: ProviderAccountsService;
15
+ readonly usage: UsageService;
16
+ readonly limits: UsageMonitor;
17
+ private readonly wiring;
18
+ private readonly background;
19
+ private readonly connections;
20
+ private nextClient;
21
+ private closing;
22
+ private constructor();
23
+ static open<Core extends ChatCore = ChatCore>(options: AgentHostOptions<Core>): Promise<AgentHost<Core>>;
24
+ connect(port: FramePort): () => void;
25
+ close(): Promise<void>;
26
+ private shutDown;
27
+ private receive;
28
+ }
@@ -0,0 +1,105 @@
1
+ import { AGENT_REQUEST_SCHEMAS, parseRequest } from '@adecore/agent-contracts';
2
+ import { CodedError } from '../coded-error.js';
3
+ import { errorText } from '../error-text.js';
4
+ import { wireAgents } from './wiring.js';
5
+ function errorReply(id, code, message) {
6
+ return { id, ok: false, error: { code, message } };
7
+ }
8
+ function isAgentRequest(type) {
9
+ return Object.hasOwn(AGENT_REQUEST_SCHEMAS, type);
10
+ }
11
+ /*
12
+ * The chats of an app that has no daemon: it answers the agent requests over any `FramePort` and
13
+ * sends the agent events back on it, frames checked on arrival. One port is one client. Closing the host writes every thread and ends every CLI; a chat
14
+ * goes on at the next start through its CLI's own session.
15
+ */
16
+ export class AgentHost {
17
+ chats;
18
+ providers;
19
+ accounts;
20
+ usage;
21
+ limits;
22
+ wiring;
23
+ background;
24
+ connections = new Set();
25
+ nextClient = 1;
26
+ closing = null;
27
+ constructor(options) {
28
+ this.wiring = wireAgents(options);
29
+ this.chats = this.wiring.chats;
30
+ this.providers = this.wiring.providers;
31
+ this.accounts = this.wiring.accounts;
32
+ this.usage = this.wiring.usage;
33
+ this.limits = this.wiring.limits;
34
+ this.background = options.background ?? true;
35
+ }
36
+ /* A host with its accounts read; its clocks run from here unless `background` is off. */
37
+ static async open(options) {
38
+ const host = new AgentHost(options);
39
+ await host.accounts.load();
40
+ if (host.background) {
41
+ host.wiring.start();
42
+ }
43
+ return host;
44
+ }
45
+ /* Serves one client over `port` until the returned function or `close` lets go of it. */
46
+ connect(port) {
47
+ const clientId = `port-${this.nextClient++}`;
48
+ const releases = [
49
+ port.onFrame((frame) => void this.receive(port, clientId, frame)),
50
+ this.wiring.connect(clientId, (event) => port.send({ type: 'event', event: event.event, payload: event.payload }))
51
+ ];
52
+ const disconnect = () => {
53
+ if (!this.connections.delete(disconnect)) {
54
+ return;
55
+ }
56
+ for (const release of releases) {
57
+ release();
58
+ }
59
+ };
60
+ this.connections.add(disconnect);
61
+ return disconnect;
62
+ }
63
+ /* Lets go of every client, writes every thread and ends every CLI; settles once they exited. */
64
+ close() {
65
+ this.closing ??= this.shutDown();
66
+ return this.closing;
67
+ }
68
+ async shutDown() {
69
+ for (const disconnect of [...this.connections]) {
70
+ disconnect();
71
+ }
72
+ await this.wiring.stop();
73
+ }
74
+ async receive(port, clientId, frame) {
75
+ const parsed = parseRequest(frame);
76
+ if (!parsed.ok) {
77
+ // The id when the frame carried a usable one, so the client can settle its promise.
78
+ const id = typeof frame === 'object' && frame !== null && 'id' in frame && typeof frame.id === 'string' && frame.id !== '' ? frame.id : null;
79
+ port.send(errorReply(id, 'bad-request', parsed.message));
80
+ return;
81
+ }
82
+ const { id, type, payload } = parsed.value;
83
+ if (!isAgentRequest(type)) {
84
+ port.send(errorReply(id, 'unknown-request', `Unknown request type: ${type}`));
85
+ return;
86
+ }
87
+ const checked = AGENT_REQUEST_SCHEMAS[type].payload.safeParse(payload);
88
+ if (!checked.success) {
89
+ port.send(errorReply(id, 'bad-request', `Invalid payload for ${type}`));
90
+ return;
91
+ }
92
+ try {
93
+ const handler = this.wiring.handlers[type];
94
+ port.send({ id, ok: true, result: await handler(checked.data, clientId) });
95
+ }
96
+ catch (e) {
97
+ if (e instanceof CodedError) {
98
+ port.send(errorReply(id, e.code, e.message));
99
+ return;
100
+ }
101
+ console.error(`Handler for ${type} failed:`, errorText(e));
102
+ port.send(errorReply(id, 'internal', 'Request failed'));
103
+ }
104
+ }
105
+ }
@@ -0,0 +1,7 @@
1
+ export declare const RUIMTE_SESSION_VARIABLES: readonly ['RUIMTE_HOOK_URL', 'RUIMTE_HOOK_TOKEN', 'RUIMTE_CONTEXT_URL', 'RUIMTE_CONTEXT_TOKEN', 'RUIMTE_SESSION_ID'];
2
+ export interface CliEnvironmentPolicy {
3
+ variables?: readonly string[];
4
+ prefixes?: readonly string[];
5
+ sessionPrefixes?: readonly string[];
6
+ }
7
+ export declare function cliEnvironment(env?: Record<string, string | undefined>, policy?: CliEnvironmentPolicy): Record<string, string>;
@@ -0,0 +1,22 @@
1
+ // These inherited hooks must remain blocked while older hosts are still in use.
2
+ export const RUIMTE_SESSION_VARIABLES = ['RUIMTE_HOOK_URL', 'RUIMTE_HOOK_TOKEN', 'RUIMTE_CONTEXT_URL', 'RUIMTE_CONTEXT_TOKEN', 'RUIMTE_SESSION_ID'];
3
+ const COMPATIBILITY_PREFIXES = ['RUIMTE_HOOK_', 'RUIMTE_CONTEXT_'];
4
+ export function cliEnvironment(env = process.env, policy = {}) {
5
+ const variables = new Set([...RUIMTE_SESSION_VARIABLES, ...(policy.variables ?? [])]);
6
+ const prefixes = [...COMPATIBILITY_PREFIXES, ...(policy.prefixes ?? [])];
7
+ for (const host of policy.sessionPrefixes ?? []) {
8
+ const prefix = host.replace(/_+$/, '');
9
+ if (prefix === '') {
10
+ throw new Error('A session environment prefix must not be empty');
11
+ }
12
+ variables.add(`${prefix}_SESSION_ID`);
13
+ prefixes.push(`${prefix}_HOOK_`, `${prefix}_CONTEXT_`);
14
+ }
15
+ const clean = {};
16
+ for (const [name, value] of Object.entries(env)) {
17
+ if (value !== undefined && !variables.has(name) && !prefixes.some((prefix) => name.startsWith(prefix))) {
18
+ clean[name] = value;
19
+ }
20
+ }
21
+ return clean;
22
+ }
@@ -0,0 +1,30 @@
1
+ import type { AGENT_REQUEST_SCHEMAS, AgentRequestType } from '@adecore/agent-contracts';
2
+ import type { z } from 'zod';
3
+ import type { ChatCore } from '../chat/chat-core.ts';
4
+ import type { ProviderAccountsService } from '../providers/accounts/service.ts';
5
+ import type { ProviderRegistry } from '../providers/registry.ts';
6
+ import type { UsageMonitor } from '../usage/limits/monitor.ts';
7
+ import type { UsageService } from '../usage/usage-service.ts';
8
+ export type AgentRequestMap = {
9
+ [T in AgentRequestType]: {
10
+ payload: z.infer<(typeof AGENT_REQUEST_SCHEMAS)[T]['payload']>;
11
+ result: z.infer<(typeof AGENT_REQUEST_SCHEMAS)[T]['result']>;
12
+ };
13
+ };
14
+ export type AgentHandler<T extends AgentRequestType> = (payload: AgentRequestMap[T]['payload'], clientId: string) => AgentRequestMap[T]['result'] | Promise<AgentRequestMap[T]['result']>;
15
+ export type AgentHandlers = {
16
+ [T in AgentRequestType]: AgentHandler<T>;
17
+ };
18
+ type AccountRequestType = Extract<AgentRequestType, `accounts.${string}`>;
19
+ type UsageRequestType = Extract<AgentRequestType, `usage.${string}`>;
20
+ export type ChatRequestType = Exclude<AgentRequestType, AccountRequestType | UsageRequestType>;
21
+ export declare function chatHandlers(chats: ChatCore, providers: ProviderRegistry): {
22
+ [T in ChatRequestType]: AgentHandler<T>;
23
+ };
24
+ export declare function accountHandlers(accounts: ProviderAccountsService): {
25
+ [T in AccountRequestType]: AgentHandler<T>;
26
+ };
27
+ export declare function usageHandlers(usage: UsageService, limits: UsageMonitor): {
28
+ [T in UsageRequestType]: AgentHandler<T>;
29
+ };
30
+ export {};