pinecall 0.1.0

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 (431) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +134 -0
  3. package/dist/agent/accepts.d.ts +32 -0
  4. package/dist/agent/accepts.d.ts.map +1 -0
  5. package/dist/agent/accepts.js +28 -0
  6. package/dist/agent/accepts.js.map +1 -0
  7. package/dist/agent/agent.d.ts +189 -0
  8. package/dist/agent/agent.d.ts.map +1 -0
  9. package/dist/agent/agent.js +262 -0
  10. package/dist/agent/agent.js.map +1 -0
  11. package/dist/agent/authors.d.ts +12 -0
  12. package/dist/agent/authors.d.ts.map +1 -0
  13. package/dist/agent/authors.js +28 -0
  14. package/dist/agent/authors.js.map +1 -0
  15. package/dist/agent/decorators.d.ts +22 -0
  16. package/dist/agent/decorators.d.ts.map +1 -0
  17. package/dist/agent/decorators.js +49 -0
  18. package/dist/agent/decorators.js.map +1 -0
  19. package/dist/agent/docstrings.d.ts +43 -0
  20. package/dist/agent/docstrings.d.ts.map +1 -0
  21. package/dist/agent/docstrings.js +311 -0
  22. package/dist/agent/docstrings.js.map +1 -0
  23. package/dist/agent/lifecycle.d.ts +29 -0
  24. package/dist/agent/lifecycle.d.ts.map +1 -0
  25. package/dist/agent/lifecycle.js +11 -0
  26. package/dist/agent/lifecycle.js.map +1 -0
  27. package/dist/agent/stages.d.ts +28 -0
  28. package/dist/agent/stages.d.ts.map +1 -0
  29. package/dist/agent/stages.js +32 -0
  30. package/dist/agent/stages.js.map +1 -0
  31. package/dist/agent/state.d.ts +43 -0
  32. package/dist/agent/state.d.ts.map +1 -0
  33. package/dist/agent/state.js +104 -0
  34. package/dist/agent/state.js.map +1 -0
  35. package/dist/agent/tools.d.ts +66 -0
  36. package/dist/agent/tools.d.ts.map +1 -0
  37. package/dist/agent/tools.js +148 -0
  38. package/dist/agent/tools.js.map +1 -0
  39. package/dist/agent/visibility.d.ts +40 -0
  40. package/dist/agent/visibility.d.ts.map +1 -0
  41. package/dist/agent/visibility.js +89 -0
  42. package/dist/agent/visibility.js.map +1 -0
  43. package/dist/call/call.d.ts +55 -0
  44. package/dist/call/call.d.ts.map +1 -0
  45. package/dist/call/call.js +108 -0
  46. package/dist/call/call.js.map +1 -0
  47. package/dist/call/history.d.ts +34 -0
  48. package/dist/call/history.d.ts.map +1 -0
  49. package/dist/call/history.js +38 -0
  50. package/dist/call/history.js.map +1 -0
  51. package/dist/call/room.d.ts +58 -0
  52. package/dist/call/room.d.ts.map +1 -0
  53. package/dist/call/room.js +68 -0
  54. package/dist/call/room.js.map +1 -0
  55. package/dist/cli/browser.d.ts +8 -0
  56. package/dist/cli/browser.d.ts.map +1 -0
  57. package/dist/cli/browser.js +27 -0
  58. package/dist/cli/browser.js.map +1 -0
  59. package/dist/cli/callbacks.d.ts +26 -0
  60. package/dist/cli/callbacks.d.ts.map +1 -0
  61. package/dist/cli/callbacks.js +68 -0
  62. package/dist/cli/callbacks.js.map +1 -0
  63. package/dist/cli/chat.d.ts +21 -0
  64. package/dist/cli/chat.d.ts.map +1 -0
  65. package/dist/cli/chat.js +214 -0
  66. package/dist/cli/chat.js.map +1 -0
  67. package/dist/cli/config.d.ts +16 -0
  68. package/dist/cli/config.d.ts.map +1 -0
  69. package/dist/cli/config.js +94 -0
  70. package/dist/cli/config.js.map +1 -0
  71. package/dist/cli/connected.d.ts +30 -0
  72. package/dist/cli/connected.d.ts.map +1 -0
  73. package/dist/cli/connected.js +32 -0
  74. package/dist/cli/connected.js.map +1 -0
  75. package/dist/cli/credentials.d.ts +41 -0
  76. package/dist/cli/credentials.d.ts.map +1 -0
  77. package/dist/cli/credentials.js +98 -0
  78. package/dist/cli/credentials.js.map +1 -0
  79. package/dist/cli/ear.d.ts +3 -0
  80. package/dist/cli/ear.d.ts.map +1 -0
  81. package/dist/cli/ear.js +59 -0
  82. package/dist/cli/ear.js.map +1 -0
  83. package/dist/cli/env.d.ts +40 -0
  84. package/dist/cli/env.d.ts.map +1 -0
  85. package/dist/cli/env.js +45 -0
  86. package/dist/cli/env.js.map +1 -0
  87. package/dist/cli/eval.d.ts +37 -0
  88. package/dist/cli/eval.d.ts.map +1 -0
  89. package/dist/cli/eval.js +83 -0
  90. package/dist/cli/eval.js.map +1 -0
  91. package/dist/cli/groups.d.ts +17 -0
  92. package/dist/cli/groups.d.ts.map +1 -0
  93. package/dist/cli/groups.js +38 -0
  94. package/dist/cli/groups.js.map +1 -0
  95. package/dist/cli/index.d.ts +16 -0
  96. package/dist/cli/index.d.ts.map +1 -0
  97. package/dist/cli/index.js +169 -0
  98. package/dist/cli/index.js.map +1 -0
  99. package/dist/cli/keys.d.ts +28 -0
  100. package/dist/cli/keys.d.ts.map +1 -0
  101. package/dist/cli/keys.js +137 -0
  102. package/dist/cli/keys.js.map +1 -0
  103. package/dist/cli/knowledge.d.ts +35 -0
  104. package/dist/cli/knowledge.d.ts.map +1 -0
  105. package/dist/cli/knowledge.js +174 -0
  106. package/dist/cli/knowledge.js.map +1 -0
  107. package/dist/cli/line.d.ts +33 -0
  108. package/dist/cli/line.d.ts.map +1 -0
  109. package/dist/cli/line.js +134 -0
  110. package/dist/cli/line.js.map +1 -0
  111. package/dist/cli/listening.d.ts +38 -0
  112. package/dist/cli/listening.d.ts.map +1 -0
  113. package/dist/cli/listening.js +124 -0
  114. package/dist/cli/listening.js.map +1 -0
  115. package/dist/cli/load.d.ts +38 -0
  116. package/dist/cli/load.d.ts.map +1 -0
  117. package/dist/cli/load.js +99 -0
  118. package/dist/cli/load.js.map +1 -0
  119. package/dist/cli/login.d.ts +30 -0
  120. package/dist/cli/login.d.ts.map +1 -0
  121. package/dist/cli/login.js +158 -0
  122. package/dist/cli/login.js.map +1 -0
  123. package/dist/cli/machine.d.ts +8 -0
  124. package/dist/cli/machine.d.ts.map +1 -0
  125. package/dist/cli/machine.js +41 -0
  126. package/dist/cli/machine.js.map +1 -0
  127. package/dist/cli/memory.d.ts +26 -0
  128. package/dist/cli/memory.d.ts.map +1 -0
  129. package/dist/cli/memory.js +148 -0
  130. package/dist/cli/memory.js.map +1 -0
  131. package/dist/cli/numbers.d.ts +25 -0
  132. package/dist/cli/numbers.d.ts.map +1 -0
  133. package/dist/cli/numbers.js +132 -0
  134. package/dist/cli/numbers.js.map +1 -0
  135. package/dist/cli/personas.d.ts +5 -0
  136. package/dist/cli/personas.d.ts.map +1 -0
  137. package/dist/cli/personas.js +94 -0
  138. package/dist/cli/personas.js.map +1 -0
  139. package/dist/cli/pipeline.d.ts +52 -0
  140. package/dist/cli/pipeline.d.ts.map +1 -0
  141. package/dist/cli/pipeline.js +184 -0
  142. package/dist/cli/pipeline.js.map +1 -0
  143. package/dist/cli/profiles.d.ts +70 -0
  144. package/dist/cli/profiles.d.ts.map +1 -0
  145. package/dist/cli/profiles.js +210 -0
  146. package/dist/cli/profiles.js.map +1 -0
  147. package/dist/cli/prompt.d.ts +20 -0
  148. package/dist/cli/prompt.d.ts.map +1 -0
  149. package/dist/cli/prompt.js +58 -0
  150. package/dist/cli/prompt.js.map +1 -0
  151. package/dist/cli/providers.d.ts +14 -0
  152. package/dist/cli/providers.d.ts.map +1 -0
  153. package/dist/cli/providers.js +116 -0
  154. package/dist/cli/providers.js.map +1 -0
  155. package/dist/cli/remember.d.ts +29 -0
  156. package/dist/cli/remember.d.ts.map +1 -0
  157. package/dist/cli/remember.js +112 -0
  158. package/dist/cli/remember.js.map +1 -0
  159. package/dist/cli/run.d.ts +20 -0
  160. package/dist/cli/run.d.ts.map +1 -0
  161. package/dist/cli/run.js +347 -0
  162. package/dist/cli/run.js.map +1 -0
  163. package/dist/cli/runs/candidate.d.ts +51 -0
  164. package/dist/cli/runs/candidate.d.ts.map +1 -0
  165. package/dist/cli/runs/candidate.js +127 -0
  166. package/dist/cli/runs/candidate.js.map +1 -0
  167. package/dist/cli/runs/drift.d.ts +75 -0
  168. package/dist/cli/runs/drift.d.ts.map +1 -0
  169. package/dist/cli/runs/drift.js +151 -0
  170. package/dist/cli/runs/drift.js.map +1 -0
  171. package/dist/cli/runs/index.d.ts +5 -0
  172. package/dist/cli/runs/index.d.ts.map +1 -0
  173. package/dist/cli/runs/index.js +99 -0
  174. package/dist/cli/runs/index.js.map +1 -0
  175. package/dist/cli/runs/suites.d.ts +16 -0
  176. package/dist/cli/runs/suites.d.ts.map +1 -0
  177. package/dist/cli/runs/suites.js +63 -0
  178. package/dist/cli/runs/suites.js.map +1 -0
  179. package/dist/cli/secret.d.ts +18 -0
  180. package/dist/cli/secret.d.ts.map +1 -0
  181. package/dist/cli/secret.js +41 -0
  182. package/dist/cli/secret.js.map +1 -0
  183. package/dist/cli/sessions.d.ts +21 -0
  184. package/dist/cli/sessions.d.ts.map +1 -0
  185. package/dist/cli/sessions.js +174 -0
  186. package/dist/cli/sessions.js.map +1 -0
  187. package/dist/cli/signup.d.ts +25 -0
  188. package/dist/cli/signup.d.ts.map +1 -0
  189. package/dist/cli/signup.js +122 -0
  190. package/dist/cli/signup.js.map +1 -0
  191. package/dist/cli/simulate.d.ts +45 -0
  192. package/dist/cli/simulate.d.ts.map +1 -0
  193. package/dist/cli/simulate.js +320 -0
  194. package/dist/cli/simulate.js.map +1 -0
  195. package/dist/cli/supervise.d.ts +18 -0
  196. package/dist/cli/supervise.d.ts.map +1 -0
  197. package/dist/cli/supervise.js +134 -0
  198. package/dist/cli/supervise.js.map +1 -0
  199. package/dist/cli/test.d.ts +12 -0
  200. package/dist/cli/test.d.ts.map +1 -0
  201. package/dist/cli/test.js +128 -0
  202. package/dist/cli/test.js.map +1 -0
  203. package/dist/cli/testing/caller.d.ts +28 -0
  204. package/dist/cli/testing/caller.d.ts.map +1 -0
  205. package/dist/cli/testing/caller.js +30 -0
  206. package/dist/cli/testing/caller.js.map +1 -0
  207. package/dist/cli/testing/gateway.d.ts +172 -0
  208. package/dist/cli/testing/gateway.d.ts.map +1 -0
  209. package/dist/cli/testing/gateway.js +96 -0
  210. package/dist/cli/testing/gateway.js.map +1 -0
  211. package/dist/cli/testing/goldens.d.ts +61 -0
  212. package/dist/cli/testing/goldens.d.ts.map +1 -0
  213. package/dist/cli/testing/goldens.js +54 -0
  214. package/dist/cli/testing/goldens.js.map +1 -0
  215. package/dist/cli/testing/latency.d.ts +15 -0
  216. package/dist/cli/testing/latency.d.ts.map +1 -0
  217. package/dist/cli/testing/latency.js +44 -0
  218. package/dist/cli/testing/latency.js.map +1 -0
  219. package/dist/cli/testing/matrix.d.ts +12 -0
  220. package/dist/cli/testing/matrix.d.ts.map +1 -0
  221. package/dist/cli/testing/matrix.js +103 -0
  222. package/dist/cli/testing/matrix.js.map +1 -0
  223. package/dist/cli/testing/progress.d.ts +26 -0
  224. package/dist/cli/testing/progress.d.ts.map +1 -0
  225. package/dist/cli/testing/progress.js +185 -0
  226. package/dist/cli/testing/progress.js.map +1 -0
  227. package/dist/cli/testing/reproduction.d.ts +19 -0
  228. package/dist/cli/testing/reproduction.d.ts.map +1 -0
  229. package/dist/cli/testing/reproduction.js +65 -0
  230. package/dist/cli/testing/reproduction.js.map +1 -0
  231. package/dist/cli/testing/score.d.ts +11 -0
  232. package/dist/cli/testing/score.d.ts.map +1 -0
  233. package/dist/cli/testing/score.js +54 -0
  234. package/dist/cli/testing/score.js.map +1 -0
  235. package/dist/cli/testing/seeding.d.ts +32 -0
  236. package/dist/cli/testing/seeding.d.ts.map +1 -0
  237. package/dist/cli/testing/seeding.js +44 -0
  238. package/dist/cli/testing/seeding.js.map +1 -0
  239. package/dist/cli/testing/suite.d.ts +40 -0
  240. package/dist/cli/testing/suite.d.ts.map +1 -0
  241. package/dist/cli/testing/suite.js +103 -0
  242. package/dist/cli/testing/suite.js.map +1 -0
  243. package/dist/cli/testing/voice.d.ts +37 -0
  244. package/dist/cli/testing/voice.d.ts.map +1 -0
  245. package/dist/cli/testing/voice.js +53 -0
  246. package/dist/cli/testing/voice.js.map +1 -0
  247. package/dist/cli/ui/admin/assets/index-C3WMXdfL.css +1 -0
  248. package/dist/cli/ui/admin/assets/index-DR1mxoAh.js +58 -0
  249. package/dist/cli/ui/admin/index.html +20 -0
  250. package/dist/cli/ui/asked.d.ts +16 -0
  251. package/dist/cli/ui/asked.d.ts.map +1 -0
  252. package/dist/cli/ui/asked.js +53 -0
  253. package/dist/cli/ui/asked.js.map +1 -0
  254. package/dist/cli/ui/browser.d.ts +10 -0
  255. package/dist/cli/ui/browser.d.ts.map +1 -0
  256. package/dist/cli/ui/browser.js +30 -0
  257. package/dist/cli/ui/browser.js.map +1 -0
  258. package/dist/cli/ui/chatting.d.ts +62 -0
  259. package/dist/cli/ui/chatting.d.ts.map +1 -0
  260. package/dist/cli/ui/chatting.js +171 -0
  261. package/dist/cli/ui/chatting.js.map +1 -0
  262. package/dist/cli/ui/console/assets/index-DCTnou52.css +1 -0
  263. package/dist/cli/ui/console/assets/index-dOcE4usU.js +99 -0
  264. package/dist/cli/ui/console/index.html +20 -0
  265. package/dist/cli/ui/console/logo-mark.png +0 -0
  266. package/dist/cli/ui/doors.d.ts +37 -0
  267. package/dist/cli/ui/doors.d.ts.map +1 -0
  268. package/dist/cli/ui/doors.js +70 -0
  269. package/dist/cli/ui/doors.js.map +1 -0
  270. package/dist/cli/ui/drifting.d.ts +23 -0
  271. package/dist/cli/ui/drifting.d.ts.map +1 -0
  272. package/dist/cli/ui/drifting.js +33 -0
  273. package/dist/cli/ui/drifting.js.map +1 -0
  274. package/dist/cli/ui/index.d.ts +15 -0
  275. package/dist/cli/ui/index.d.ts.map +1 -0
  276. package/dist/cli/ui/index.js +117 -0
  277. package/dist/cli/ui/index.js.map +1 -0
  278. package/dist/cli/ui/knowing.d.ts +36 -0
  279. package/dist/cli/ui/knowing.d.ts.map +1 -0
  280. package/dist/cli/ui/knowing.js +86 -0
  281. package/dist/cli/ui/knowing.js.map +1 -0
  282. package/dist/cli/ui/promoting.d.ts +26 -0
  283. package/dist/cli/ui/promoting.d.ts.map +1 -0
  284. package/dist/cli/ui/promoting.js +44 -0
  285. package/dist/cli/ui/promoting.js.map +1 -0
  286. package/dist/cli/ui/refusal.d.ts +18 -0
  287. package/dist/cli/ui/refusal.d.ts.map +1 -0
  288. package/dist/cli/ui/refusal.js +26 -0
  289. package/dist/cli/ui/refusal.js.map +1 -0
  290. package/dist/cli/ui/refused.d.ts +8 -0
  291. package/dist/cli/ui/refused.d.ts.map +1 -0
  292. package/dist/cli/ui/refused.js +11 -0
  293. package/dist/cli/ui/refused.js.map +1 -0
  294. package/dist/cli/ui/remembering.d.ts +38 -0
  295. package/dist/cli/ui/remembering.d.ts.map +1 -0
  296. package/dist/cli/ui/remembering.js +87 -0
  297. package/dist/cli/ui/remembering.js.map +1 -0
  298. package/dist/cli/ui/reproducing.d.ts +23 -0
  299. package/dist/cli/ui/reproducing.d.ts.map +1 -0
  300. package/dist/cli/ui/reproducing.js +52 -0
  301. package/dist/cli/ui/reproducing.js.map +1 -0
  302. package/dist/cli/ui/server.d.ts +22 -0
  303. package/dist/cli/ui/server.d.ts.map +1 -0
  304. package/dist/cli/ui/server.js +211 -0
  305. package/dist/cli/ui/server.js.map +1 -0
  306. package/dist/cli/ui/simulating.d.ts +47 -0
  307. package/dist/cli/ui/simulating.d.ts.map +1 -0
  308. package/dist/cli/ui/simulating.js +86 -0
  309. package/dist/cli/ui/simulating.js.map +1 -0
  310. package/dist/cli/ui/testing.d.ts +49 -0
  311. package/dist/cli/ui/testing.d.ts.map +1 -0
  312. package/dist/cli/ui/testing.js +104 -0
  313. package/dist/cli/ui/testing.js.map +1 -0
  314. package/dist/cli/view.d.ts +43 -0
  315. package/dist/cli/view.d.ts.map +1 -0
  316. package/dist/cli/view.js +137 -0
  317. package/dist/cli/view.js.map +1 -0
  318. package/dist/cli/whoami.d.ts +37 -0
  319. package/dist/cli/whoami.d.ts.map +1 -0
  320. package/dist/cli/whoami.js +78 -0
  321. package/dist/cli/whoami.js.map +1 -0
  322. package/dist/cli/world.d.ts +33 -0
  323. package/dist/cli/world.d.ts.map +1 -0
  324. package/dist/cli/world.js +48 -0
  325. package/dist/cli/world.js.map +1 -0
  326. package/dist/client/agent.d.ts +87 -0
  327. package/dist/client/agent.d.ts.map +1 -0
  328. package/dist/client/agent.js +209 -0
  329. package/dist/client/agent.js.map +1 -0
  330. package/dist/client/calls.d.ts +77 -0
  331. package/dist/client/calls.d.ts.map +1 -0
  332. package/dist/client/calls.js +153 -0
  333. package/dist/client/calls.js.map +1 -0
  334. package/dist/client/client.d.ts +58 -0
  335. package/dist/client/client.d.ts.map +1 -0
  336. package/dist/client/client.js +146 -0
  337. package/dist/client/client.js.map +1 -0
  338. package/dist/client/connection.d.ts +47 -0
  339. package/dist/client/connection.d.ts.map +1 -0
  340. package/dist/client/connection.js +141 -0
  341. package/dist/client/connection.js.map +1 -0
  342. package/dist/client/endpoints.d.ts +7 -0
  343. package/dist/client/endpoints.d.ts.map +1 -0
  344. package/dist/client/endpoints.js +21 -0
  345. package/dist/client/endpoints.js.map +1 -0
  346. package/dist/client/frames.d.ts +24 -0
  347. package/dist/client/frames.d.ts.map +1 -0
  348. package/dist/client/frames.js +49 -0
  349. package/dist/client/frames.js.map +1 -0
  350. package/dist/client/index.d.ts +15 -0
  351. package/dist/client/index.d.ts.map +1 -0
  352. package/dist/client/index.js +14 -0
  353. package/dist/client/index.js.map +1 -0
  354. package/dist/client/listeners.d.ts +36 -0
  355. package/dist/client/listeners.d.ts.map +1 -0
  356. package/dist/client/listeners.js +61 -0
  357. package/dist/client/listeners.js.map +1 -0
  358. package/dist/client/observe.d.ts +44 -0
  359. package/dist/client/observe.d.ts.map +1 -0
  360. package/dist/client/observe.js +122 -0
  361. package/dist/client/observe.js.map +1 -0
  362. package/dist/client/testing/gateway.d.ts +39 -0
  363. package/dist/client/testing/gateway.d.ts.map +1 -0
  364. package/dist/client/testing/gateway.js +129 -0
  365. package/dist/client/testing/gateway.js.map +1 -0
  366. package/dist/client/testing/index.d.ts +4 -0
  367. package/dist/client/testing/index.d.ts.map +1 -0
  368. package/dist/client/testing/index.js +4 -0
  369. package/dist/client/testing/index.js.map +1 -0
  370. package/dist/client/testing/log.d.ts +26 -0
  371. package/dist/client/testing/log.d.ts.map +1 -0
  372. package/dist/client/testing/log.js +111 -0
  373. package/dist/client/testing/log.js.map +1 -0
  374. package/dist/client/testing/loopback.d.ts +3 -0
  375. package/dist/client/testing/loopback.d.ts.map +1 -0
  376. package/dist/client/testing/loopback.js +3 -0
  377. package/dist/client/testing/loopback.js.map +1 -0
  378. package/dist/index.d.ts +22 -0
  379. package/dist/index.d.ts.map +1 -0
  380. package/dist/index.js +35 -0
  381. package/dist/index.js.map +1 -0
  382. package/dist/runtime/channels.d.ts +16 -0
  383. package/dist/runtime/channels.d.ts.map +1 -0
  384. package/dist/runtime/channels.js +30 -0
  385. package/dist/runtime/channels.js.map +1 -0
  386. package/dist/runtime/connect.d.ts +51 -0
  387. package/dist/runtime/connect.d.ts.map +1 -0
  388. package/dist/runtime/connect.js +284 -0
  389. package/dist/runtime/connect.js.map +1 -0
  390. package/dist/runtime/dispatch.d.ts +37 -0
  391. package/dist/runtime/dispatch.d.ts.map +1 -0
  392. package/dist/runtime/dispatch.js +52 -0
  393. package/dist/runtime/dispatch.js.map +1 -0
  394. package/dist/runtime/grounding.d.ts +15 -0
  395. package/dist/runtime/grounding.d.ts.map +1 -0
  396. package/dist/runtime/grounding.js +72 -0
  397. package/dist/runtime/grounding.js.map +1 -0
  398. package/dist/runtime/recall.d.ts +10 -0
  399. package/dist/runtime/recall.d.ts.map +1 -0
  400. package/dist/runtime/recall.js +13 -0
  401. package/dist/runtime/recall.js.map +1 -0
  402. package/dist/runtime/run-tool.d.ts +26 -0
  403. package/dist/runtime/run-tool.d.ts.map +1 -0
  404. package/dist/runtime/run-tool.js +82 -0
  405. package/dist/runtime/run-tool.js.map +1 -0
  406. package/dist/views/components.d.ts +17 -0
  407. package/dist/views/components.d.ts.map +1 -0
  408. package/dist/views/components.js +33 -0
  409. package/dist/views/components.js.map +1 -0
  410. package/dist/views/jsx-dev-runtime.d.ts +3 -0
  411. package/dist/views/jsx-dev-runtime.d.ts.map +1 -0
  412. package/dist/views/jsx-dev-runtime.js +5 -0
  413. package/dist/views/jsx-dev-runtime.js.map +1 -0
  414. package/dist/views/jsx-runtime.d.ts +49 -0
  415. package/dist/views/jsx-runtime.d.ts.map +1 -0
  416. package/dist/views/jsx-runtime.js +67 -0
  417. package/dist/views/jsx-runtime.js.map +1 -0
  418. package/dist/views/lang.d.ts +17 -0
  419. package/dist/views/lang.d.ts.map +1 -0
  420. package/dist/views/lang.js +46 -0
  421. package/dist/views/lang.js.map +1 -0
  422. package/dist/views/layout.d.ts +19 -0
  423. package/dist/views/layout.d.ts.map +1 -0
  424. package/dist/views/layout.js +62 -0
  425. package/dist/views/layout.js.map +1 -0
  426. package/dist/views/render.d.ts +19 -0
  427. package/dist/views/render.d.ts.map +1 -0
  428. package/dist/views/render.js +26 -0
  429. package/dist/views/render.js.map +1 -0
  430. package/package.json +76 -0
  431. package/tsconfig.tenant.json +24 -0
@@ -0,0 +1,61 @@
1
+ // Who is listening for what. One registry, used for a whole agent and for a single call alike.
2
+ import { toCamel } from "@pinecall/protocol";
3
+ /** The decoded event with its keys as the app reads them. */
4
+ export function camelEvent(event) {
5
+ return { type: event.type, data: toCamel(event.data) };
6
+ }
7
+ /**
8
+ * Every listener registered against one thing — an agent, or a call — and the dispatch to them.
9
+ *
10
+ * A listener that throws is a bug in the app, not a reason to stop reading the socket: it is
11
+ * handed to `onError` and the next listener still runs.
12
+ */
13
+ export class Listeners {
14
+ onError;
15
+ #byType = new Map();
16
+ #any = new Set();
17
+ constructor(onError) {
18
+ this.onError = onError;
19
+ }
20
+ /** Listen for one event type. The returned function stops listening. */
21
+ on(type, listener) {
22
+ const listeners = this.#byType.get(type) ?? new Set();
23
+ this.#byType.set(type, listeners);
24
+ listeners.add(listener);
25
+ return () => {
26
+ listeners.delete(listener);
27
+ };
28
+ }
29
+ /** Listen for every event. The returned function stops listening. */
30
+ onAny(listener) {
31
+ this.#any.add(listener);
32
+ return () => {
33
+ this.#any.delete(listener);
34
+ };
35
+ }
36
+ /** Hand one event to everybody waiting for it, then to everybody waiting for anything. */
37
+ emit(event, context) {
38
+ for (const listener of this.#byType.get(event.type) ?? []) {
39
+ this.#run(() => listener(event.data, context));
40
+ }
41
+ for (const listener of this.#any) {
42
+ this.#run(() => listener(event, context));
43
+ }
44
+ }
45
+ #run(listener) {
46
+ try {
47
+ const running = listener();
48
+ if (running instanceof Promise) {
49
+ running.catch((failed) => this.onError(asError(failed)));
50
+ }
51
+ }
52
+ catch (failed) {
53
+ this.onError(asError(failed));
54
+ }
55
+ }
56
+ }
57
+ /** Whatever was thrown, as an Error: `catch` gives `unknown` and a listener may throw a string. */
58
+ export function asError(thrown) {
59
+ return thrown instanceof Error ? thrown : new Error(String(thrown));
60
+ }
61
+ //# sourceMappingURL=listeners.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listeners.js","sourceRoot":"","sources":["../../src/client/listeners.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAE/F,OAAO,EAAE,OAAO,EAA0D,MAAM,oBAAoB,CAAC;AAgBrG,6DAA6D;AAC7D,MAAM,UAAU,UAAU,CAAC,KAAY;IACrC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAgB,CAAC;AACvE,CAAC;AAED;;;;;GAKG;AACH,MAAM,OAAO,SAAS;IAIS,OAAO;IAH3B,OAAO,GAAG,IAAI,GAAG,EAAgC,CAAC;IAClD,IAAI,GAAG,IAAI,GAAG,EAAwB,CAAC;IAEhD,YAA6B,OAA+B;uBAA/B,OAAO;IAA2B,CAAC;IAEhE,wEAAwE;IACxE,EAAE,CAAsB,IAAO,EAAE,QAA8B;QAC7D,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,EAAmB,CAAC;QACvE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAClC,SAAS,CAAC,GAAG,CAAC,QAA2B,CAAC,CAAC;QAC3C,OAAO,GAAG,EAAE;YACV,SAAS,CAAC,MAAM,CAAC,QAA2B,CAAC,CAAC;QAChD,CAAC,CAAC;IACJ,CAAC;IAED,qEAAqE;IACrE,KAAK,CAAC,QAA8B;QAClC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACxB,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC7B,CAAC,CAAC;IACJ,CAAC;IAED,0FAA0F;IAC1F,IAAI,CAAC,KAAiB,EAAE,OAAgB;QACtC,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YAC1D,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAE,QAAyD,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;QACnG,CAAC;QACD,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACjC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAED,IAAI,CAAC,QAAuB;QAC1B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,QAAQ,EAAE,CAAC;YAC3B,IAAI,OAAO,YAAY,OAAO,EAAE,CAAC;gBAC/B,OAAO,CAAC,KAAK,CAAC,CAAC,MAAe,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACpE,CAAC;QACH,CAAC;QAAC,OAAO,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;CACF;AAED,mGAAmG;AACnG,MAAM,UAAU,OAAO,CAAC,MAAe;IACrC,OAAO,MAAM,YAAY,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;AACtE,CAAC"}
@@ -0,0 +1,44 @@
1
+ import { type Entry, type State } from "@pinecall/protocol";
2
+ import { type CamelEvent } from "./listeners.js";
3
+ /** Whose log: one call's, or an agent's own. */
4
+ export type LogTarget = {
5
+ call: string;
6
+ agent?: never;
7
+ } | {
8
+ agent: string;
9
+ call?: never;
10
+ };
11
+ /** Where to read from and from which cursor. */
12
+ export interface ReadOptions {
13
+ url: string;
14
+ apiKey: string;
15
+ after?: number;
16
+ signal?: AbortSignal;
17
+ }
18
+ /** One page of a log: the entries after the cursor, what they fold to, and where to go next. */
19
+ export interface Page {
20
+ entries: Entry[];
21
+ state: State;
22
+ /** True while the log is still open: more will follow, and the stream is how to get it. */
23
+ live: boolean;
24
+ /** The cursor to ask from next, or null when nothing follows this page. */
25
+ next: number | null;
26
+ }
27
+ /** One entry, what it means, and the state the log has folded to including it. */
28
+ export interface Observation {
29
+ entry: Entry;
30
+ event: CamelEvent;
31
+ state: State;
32
+ }
33
+ /**
34
+ * A log as it happens: every entry after the cursor, then everything that follows, forever.
35
+ *
36
+ * The cursor is the whole protocol. A stream that drops is the same URL again with a fresher
37
+ * `Last-Event-ID`, and the platform answers a reader that fell behind with `log.gap` — carrying a
38
+ * snapshot when it has one — then `log.caught_up` when what follows is live. The reducer is
39
+ * `@pinecall/protocol`'s, so a client and the platform never disagree about what a log means.
40
+ */
41
+ export declare function observe(target: LogTarget, options: ReadOptions): AsyncGenerator<Observation>;
42
+ /** The log as it stands: one page after the cursor, what it folds to, and whether more follows. */
43
+ export declare function history(target: LogTarget, options: ReadOptions): Promise<Page>;
44
+ //# sourceMappingURL=observe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observe.d.ts","sourceRoot":"","sources":["../../src/client/observe.ts"],"names":[],"mappings":"AAEA,OAAO,EAA6C,KAAK,KAAK,EAAE,KAAK,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAGvG,OAAO,EAAc,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE7D,gDAAgD;AAChD,MAAM,MAAM,SAAS,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAE1F,gDAAgD;AAChD,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,gGAAgG;AAChG,MAAM,WAAW,IAAI;IACnB,OAAO,EAAE,KAAK,EAAE,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;IACb,2FAA2F;IAC3F,IAAI,EAAE,OAAO,CAAC;IACd,2EAA2E;IAC3E,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED,kFAAkF;AAClF,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,KAAK,CAAC;CACd;AAKD;;;;;;;GAOG;AACH,wBAAuB,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,GAAG,cAAc,CAAC,WAAW,CAAC,CA2BnG;AAID,mGAAmG;AACnG,wBAAsB,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAcpF"}
@@ -0,0 +1,122 @@
1
+ // Reading a log: the same URL as a JSON page and as SSE, folded by the protocol's own reducer.
2
+ import { apply, decodeEntry, eventOf, initialState } from "@pinecall/protocol";
3
+ import { agentLogUrl, callLogUrl } from "./endpoints.js";
4
+ import { PinecallError } from "./frames.js";
5
+ import { camelEvent } from "./listeners.js";
6
+ const RETRY_MS = 1_000;
7
+ const RETRY_CAP_MS = 30_000;
8
+ /**
9
+ * A log as it happens: every entry after the cursor, then everything that follows, forever.
10
+ *
11
+ * The cursor is the whole protocol. A stream that drops is the same URL again with a fresher
12
+ * `Last-Event-ID`, and the platform answers a reader that fell behind with `log.gap` — carrying a
13
+ * snapshot when it has one — then `log.caught_up` when what follows is live. The reducer is
14
+ * `@pinecall/protocol`'s, so a client and the platform never disagree about what a log means.
15
+ */
16
+ export async function* observe(target, options) {
17
+ let state = initialState();
18
+ let after = options.after ?? 0;
19
+ let attempt = 0;
20
+ let opened = false;
21
+ while (!aborted(options.signal)) {
22
+ try {
23
+ for await (const entry of stream(target, { ...options, after })) {
24
+ attempt = 0;
25
+ opened = true;
26
+ after = entry.seq;
27
+ state = apply(state, entry);
28
+ yield { entry, event: camelEvent(eventOf(entry)), state };
29
+ }
30
+ }
31
+ catch (failed) {
32
+ if (aborted(options.signal)) {
33
+ return;
34
+ }
35
+ // A stream that never opened is a misconfiguration — a wrong key, a call nobody has — and
36
+ // the reader hears it now. One that dropped after it worked is what the cursor is for.
37
+ if (!opened) {
38
+ throw failed;
39
+ }
40
+ }
41
+ attempt += 1;
42
+ await pause(Math.min(RETRY_CAP_MS, RETRY_MS * 2 ** (attempt - 1)) * Math.random(), options.signal);
43
+ }
44
+ }
45
+ // The page says where to go next itself, rather than leaving the reader to infer a cursor from
46
+ // the last entry it happened to receive: an empty page of a live log still has a next.
47
+ /** The log as it stands: one page after the cursor, what it folds to, and whether more follows. */
48
+ export async function history(target, options) {
49
+ const response = await read(target, options, "application/json");
50
+ const page = await response.json();
51
+ if (page === null || typeof page !== "object" || !Array.isArray(page.entries)) {
52
+ throw new PinecallError("the log page is not { entries, live, next }");
53
+ }
54
+ const { entries: raw, live, next } = page;
55
+ const entries = raw.map((one) => decodeEntry(one));
56
+ return {
57
+ entries,
58
+ state: entries.reduce(apply, initialState()),
59
+ live: live === true,
60
+ next: typeof next === "number" ? next : null,
61
+ };
62
+ }
63
+ /** One SSE connection: entries until the server closes it or the reader is aborted. */
64
+ async function* stream(target, options) {
65
+ const response = await read(target, options, "text/event-stream");
66
+ if (response.body === null) {
67
+ throw new PinecallError("the event stream came back with no body");
68
+ }
69
+ let buffered = "";
70
+ const decoder = new TextDecoder();
71
+ for await (const chunk of response.body) {
72
+ buffered += decoder.decode(chunk, { stream: true });
73
+ let cut = buffered.indexOf("\n\n");
74
+ while (cut !== -1) {
75
+ const entry = entryIn(buffered.slice(0, cut));
76
+ buffered = buffered.slice(cut + 2);
77
+ cut = buffered.indexOf("\n\n");
78
+ if (entry !== null) {
79
+ yield entry;
80
+ }
81
+ }
82
+ }
83
+ }
84
+ /** One SSE block as an entry, or null for a comment or a keep-alive that carries no data. */
85
+ function entryIn(block) {
86
+ const data = block
87
+ .split("\n")
88
+ .filter((line) => line.startsWith("data:"))
89
+ .map((line) => line.slice("data:".length).trimStart())
90
+ .join("\n");
91
+ return data === "" ? null : decodeEntry(JSON.parse(data));
92
+ }
93
+ async function read(target, options, accept) {
94
+ const url = new URL(target.call === undefined ? agentLogUrl(options.url, target.agent) : callLogUrl(options.url, target.call));
95
+ const after = options.after ?? 0;
96
+ if (after > 0) {
97
+ url.searchParams.set("after", String(after));
98
+ }
99
+ const headers = { accept, authorization: `Bearer ${options.apiKey}` };
100
+ if (after > 0) {
101
+ headers["last-event-id"] = String(after);
102
+ }
103
+ const response = await fetch(url, { headers, ...(options.signal === undefined ? {} : { signal: options.signal }) });
104
+ if (!response.ok) {
105
+ throw new PinecallError(`${url.pathname}: the gateway answered ${response.status}`);
106
+ }
107
+ return response;
108
+ }
109
+ /** True once the reader asked to stop. A function, so no narrowing survives the loop's own check. */
110
+ function aborted(signal) {
111
+ return signal?.aborted === true;
112
+ }
113
+ async function pause(ms, signal) {
114
+ await new Promise((resolve) => {
115
+ const timer = setTimeout(resolve, ms);
116
+ signal?.addEventListener("abort", () => {
117
+ clearTimeout(timer);
118
+ resolve();
119
+ });
120
+ });
121
+ }
122
+ //# sourceMappingURL=observe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observe.js","sourceRoot":"","sources":["../../src/client/observe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { type Command, type Entry, type EventType } from "@pinecall/protocol";
2
+ /** What a fake gateway answers to, and what it hands back. */
3
+ export interface FakeGatewayOptions {
4
+ /** The only key it accepts. Anything else is closed with 1008 and no body, like the real door. */
5
+ apiKey?: string;
6
+ /** Slugs this gateway refuses to register at all: the real one refuses a door another agent
7
+ * already answers, or a slug another fleet is holding. */
8
+ taken?: string[];
9
+ }
10
+ /** One command the fake gateway received, as it arrived. */
11
+ export type Received = Command;
12
+ /**
13
+ * A gateway with no session, no store and no model: it numbers entries, answers the three
14
+ * commands the app socket answers itself, and lets a test push any entry it likes down the wire.
15
+ *
16
+ * It exists because the client's promise is that an app can be tested without a gateway, and a
17
+ * promise like that has to be shipped, not re-written in every app's test folder.
18
+ */
19
+ export declare class FakeGateway {
20
+ #private;
21
+ private readonly options;
22
+ readonly received: Received[];
23
+ private constructor();
24
+ /** Start one on a port nobody chose. Close it when the test is over. */
25
+ static start(options?: FakeGatewayOptions): Promise<FakeGateway>;
26
+ /** What a client should be given as its PINECALL_URL. */
27
+ get url(): string;
28
+ /** How many apps are connected right now. */
29
+ get connections(): number;
30
+ /** Every command of one type, in the order it arrived. */
31
+ commandsOf(type: string): Received[];
32
+ /** Push one entry to every connected app, numbered as a store would number it. */
33
+ emit(agent: string, call: string | null, type: EventType, data: Record<string, unknown>): Entry;
34
+ /** Drop every open socket without closing the door: what a gateway restart looks like. */
35
+ cut(): void;
36
+ /** Stop listening and hang up on everybody. */
37
+ close(): Promise<void>;
38
+ }
39
+ //# sourceMappingURL=gateway.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../../../src/client/testing/gateway.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmC,KAAK,OAAO,EAAE,KAAK,KAAK,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAQ/G,8DAA8D;AAC9D,MAAM,WAAW,kBAAkB;IACjC,kGAAkG;IAClG,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;8DAC0D;IAC1D,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,4DAA4D;AAC5D,MAAM,MAAM,QAAQ,GAAG,OAAO,CAAC;AAE/B;;;;;;GAMG;AACH,qBAAa,WAAW;;IASuB,OAAO,CAAC,QAAQ,CAAC,OAAO;IARrE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAM;IAQnC,OAAO,eAGN;IAID,wEAAwE;IACxE,OAAa,KAAK,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,WAAW,CAAC,CAgBzE;IAED,yDAAyD;IACzD,IAAI,GAAG,IAAI,MAAM,CAEhB;IAED,6CAA6C;IAC7C,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,0DAA0D;IAC1D,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,EAAE,CAEnC;IAED,kFAAkF;IAClF,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,KAAK,CAM9F;IAED,0FAA0F;IAC1F,GAAG,IAAI,IAAI,CAKV;IAED,+CAA+C;IACzC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAG3B;CAuDF"}
@@ -0,0 +1,129 @@
1
+ // A gateway that is not there: enough of the app socket to test an app's own agents, in process.
2
+ import { CommandSchema, EPHEMERAL_EVENTS } from "@pinecall/protocol";
3
+ import { WebSocket, WebSocketServer } from "ws";
4
+ import { LOOPBACK } from "./loopback.js";
5
+ // The gateway answers a key nothing knows during the handshake, so the upgrade never happens.
6
+ const FORBIDDEN = 403;
7
+ /**
8
+ * A gateway with no session, no store and no model: it numbers entries, answers the three
9
+ * commands the app socket answers itself, and lets a test push any entry it likes down the wire.
10
+ *
11
+ * It exists because the client's promise is that an app can be tested without a gateway, and a
12
+ * promise like that has to be shipped, not re-written in every app's test folder.
13
+ */
14
+ export class FakeGateway {
15
+ options;
16
+ received = [];
17
+ #server;
18
+ #sockets = new Set();
19
+ #refused;
20
+ #seq = 0;
21
+ #apps = 0;
22
+ #port = 0;
23
+ constructor(server, options) {
24
+ this.options = options;
25
+ this.#server = server;
26
+ this.#refused = new Set(options.taken ?? []);
27
+ }
28
+ // The key is checked during the handshake, the way the real door checks it: a socket that never
29
+ // opens is what a wrong key looks like from the app's side, not one that opens and shuts.
30
+ /** Start one on a port nobody chose. Close it when the test is over. */
31
+ static async start(options = {}) {
32
+ const server = new WebSocketServer({
33
+ port: 0,
34
+ // The address `url` hands out, and nothing wider. Without it the listener takes the IPv6
35
+ // wildcard, which the kernel will grant on a port another program already holds on IPv4 —
36
+ // and then the client's `127.0.0.1` connection is served by that program instead of by us.
37
+ host: LOOPBACK,
38
+ path: "/v1/apps",
39
+ verifyClient: ({ req }, done) => done(options.apiKey === undefined || req.headers.authorization === `Bearer ${options.apiKey}`, FORBIDDEN),
40
+ });
41
+ await new Promise((resolve) => server.once("listening", resolve));
42
+ const gateway = new FakeGateway(server, options);
43
+ const address = server.address();
44
+ gateway.#port = typeof address === "object" && address !== null ? address.port : 0;
45
+ server.on("connection", (socket) => gateway.#accept(socket));
46
+ return gateway;
47
+ }
48
+ /** What a client should be given as its PINECALL_URL. */
49
+ get url() {
50
+ return `http://${LOOPBACK}:${this.#port}`;
51
+ }
52
+ /** How many apps are connected right now. */
53
+ get connections() {
54
+ return this.#sockets.size;
55
+ }
56
+ /** Every command of one type, in the order it arrived. */
57
+ commandsOf(type) {
58
+ return this.received.filter((command) => command.type === type);
59
+ }
60
+ /** Push one entry to every connected app, numbered as a store would number it. */
61
+ emit(agent, call, type, data) {
62
+ const entry = { seq: (this.#seq += 1), ts: Date.now() / 1000, call, agent, type, ephemeral: EPHEMERAL_EVENTS.has(type), data };
63
+ for (const socket of this.#sockets) {
64
+ socket.send(JSON.stringify(entry));
65
+ }
66
+ return entry;
67
+ }
68
+ /** Drop every open socket without closing the door: what a gateway restart looks like. */
69
+ cut() {
70
+ for (const socket of this.#sockets) {
71
+ socket.terminate();
72
+ }
73
+ this.#sockets.clear();
74
+ }
75
+ /** Stop listening and hang up on everybody. */
76
+ async close() {
77
+ this.cut();
78
+ await new Promise((resolve, reject) => this.#server.close((failed) => (failed ? reject(failed) : resolve())));
79
+ }
80
+ #accept(socket) {
81
+ this.#sockets.add(socket);
82
+ // The id the real gateway mints per connection and hands back in `agent.registered`.
83
+ const app = `app_${(this.#apps += 1)}`;
84
+ socket.on("message", (raw) => this.#take(socket, app, raw));
85
+ socket.on("close", () => this.#sockets.delete(socket));
86
+ // Node THROWS an `error` event nobody listens for, and `ws` raises one on this socket for any
87
+ // frame it cannot parse — a confused client, or whatever else found the port. Without this
88
+ // line one bad connection ends the whole test run instead of just itself.
89
+ socket.on("error", () => this.#sockets.delete(socket));
90
+ }
91
+ #take(socket, app, raw) {
92
+ const command = CommandSchema.parse(JSON.parse(raw.toString()));
93
+ this.received.push(command);
94
+ switch (command.type) {
95
+ case "agent.register":
96
+ return this.#register(socket, app, command);
97
+ case "agent.configure":
98
+ return this.#answer(socket, command, "agent.configured", { changed: Object.keys((command.data["config"] ?? {})) });
99
+ case "ping":
100
+ return this.#answer(socket, command, "pong", { ts: Date.now() / 1000 });
101
+ default:
102
+ return;
103
+ }
104
+ }
105
+ // Many sockets may hold one agent, so a second register is answered like the first: what the
106
+ // real registry refuses is a door another agent answers. `taken` is how a test asks for that.
107
+ #register(socket, app, command) {
108
+ if (this.#refused.has(command.agent)) {
109
+ this.#refuse(socket, command, "refused", `${command.agent} answers at a door somebody else has`);
110
+ return;
111
+ }
112
+ const { routes, sdk } = command.data;
113
+ this.#answer(socket, command, "agent.registered", sdk === undefined ? { routes, app } : { routes, app, sdk });
114
+ }
115
+ #answer(socket, command, type, data) {
116
+ socket.send(JSON.stringify(this.#entry(command.agent, null, type, data)));
117
+ }
118
+ #refuse(socket, command, code, message) {
119
+ const data = { code, message, recoverable: true, command: command.type };
120
+ if (command.id !== undefined) {
121
+ data["id"] = command.id;
122
+ }
123
+ socket.send(JSON.stringify(this.#entry(command.agent, null, "error", data)));
124
+ }
125
+ #entry(agent, call, type, data) {
126
+ return { seq: (this.#seq += 1), ts: Date.now() / 1000, call, agent, type, ephemeral: EPHEMERAL_EVENTS.has(type), data };
127
+ }
128
+ }
129
+ //# sourceMappingURL=gateway.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway.js","sourceRoot":"","sources":["../../../src/client/testing/gateway.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { FakeGateway } from "./gateway.js";
2
+ export type { FakeGatewayOptions, Received } from "./gateway.js";
3
+ export { FakeLog } from "./log.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/testing/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,YAAY,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,4 @@
1
+ // pinecall/client/testing: a gateway and a log that are not there, so an app's tests need neither.
2
+ export { FakeGateway } from "./gateway.js";
3
+ export { FakeLog } from "./log.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/testing/index.ts"],"names":[],"mappings":"AAAA,mGAAmG;AAEnG,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { type Entry, type EventType } from "@pinecall/protocol";
2
+ /**
3
+ * `GET /v1/calls/{id}/events` and `GET /v1/agents/{slug}/calls`, as a JSON page and as SSE.
4
+ *
5
+ * The cursor is the whole protocol, so this is the piece worth faking: `after` and
6
+ * `Last-Event-ID` are the same number, and a reader that reconnects with a fresher one gets
7
+ * exactly what it missed.
8
+ */
9
+ export declare class FakeLog {
10
+ #private;
11
+ readonly entries: Entry[];
12
+ private constructor();
13
+ /** Start one on a port nobody chose. Close it when the test is over. */
14
+ static start(): Promise<FakeLog>;
15
+ /** What a client should be given as its PINECALL_URL. */
16
+ get url(): string;
17
+ /** Append one entry, numbered as a store would number it, and push it to everybody attached. */
18
+ append(agent: string, call: string | null, type: EventType, data: Record<string, unknown>): Entry;
19
+ /** Drop every attached reader mid-stream: what a deploy looks like to somebody reading. */
20
+ cut(): void;
21
+ /** How many readers are attached right now. */
22
+ get readers(): number;
23
+ /** Stop listening and hang up on everybody. */
24
+ close(): Promise<void>;
25
+ }
26
+ //# sourceMappingURL=log.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../../src/client/testing/log.ts"],"names":[],"mappings":"AAGA,OAAO,EAAoB,KAAK,KAAK,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAUlF;;;;;;GAMG;AACH,qBAAa,OAAO;;IAClB,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,CAAM;IAK/B,OAAO,eAEN;IAED,wEAAwE;IACxE,OAAa,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC,CAQrC;IAED,yDAAyD;IACzD,IAAI,GAAG,IAAI,MAAM,CAEhB;IAED,gGAAgG;IAChG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,KAAK,CAOhG;IAED,2FAA2F;IAC3F,GAAG,IAAI,IAAI,CAKV;IAED,+CAA+C;IAC/C,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,+CAA+C;IACzC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAG3B;CA2CF"}
@@ -0,0 +1,111 @@
1
+ // A log nobody stored: the two reading doors, over a list of entries a test appends to.
2
+ import { createServer } from "node:http";
3
+ import { EPHEMERAL_EVENTS } from "@pinecall/protocol";
4
+ import { LOOPBACK } from "./loopback.js";
5
+ /**
6
+ * `GET /v1/calls/{id}/events` and `GET /v1/agents/{slug}/calls`, as a JSON page and as SSE.
7
+ *
8
+ * The cursor is the whole protocol, so this is the piece worth faking: `after` and
9
+ * `Last-Event-ID` are the same number, and a reader that reconnects with a fresher one gets
10
+ * exactly what it missed.
11
+ */
12
+ export class FakeLog {
13
+ entries = [];
14
+ #server;
15
+ #readers = new Set();
16
+ #port = 0;
17
+ constructor(server) {
18
+ this.#server = server;
19
+ }
20
+ /** Start one on a port nobody chose. Close it when the test is over. */
21
+ static async start() {
22
+ const server = createServer();
23
+ const log = new FakeLog(server);
24
+ server.on("request", (request, response) => log.#serve(request, response));
25
+ await new Promise((resolve) => server.listen(0, LOOPBACK, resolve));
26
+ const address = server.address();
27
+ log.#port = typeof address === "object" && address !== null ? address.port : 0;
28
+ return log;
29
+ }
30
+ /** What a client should be given as its PINECALL_URL. */
31
+ get url() {
32
+ return `http://${LOOPBACK}:${this.#port}`;
33
+ }
34
+ /** Append one entry, numbered as a store would number it, and push it to everybody attached. */
35
+ append(agent, call, type, data) {
36
+ const entry = { seq: this.entries.length + 1, ts: Date.now() / 1000, call, agent, type, ephemeral: EPHEMERAL_EVENTS.has(type), data };
37
+ this.entries.push(entry);
38
+ for (const reader of this.#readers) {
39
+ this.#push(reader, entry);
40
+ }
41
+ return entry;
42
+ }
43
+ /** Drop every attached reader mid-stream: what a deploy looks like to somebody reading. */
44
+ cut() {
45
+ for (const reader of this.#readers) {
46
+ reader.response.end();
47
+ }
48
+ this.#readers.clear();
49
+ }
50
+ /** How many readers are attached right now. */
51
+ get readers() {
52
+ return this.#readers.size;
53
+ }
54
+ /** Stop listening and hang up on everybody. */
55
+ async close() {
56
+ this.cut();
57
+ await new Promise((resolve, reject) => this.#server.close((failed) => (failed ? reject(failed) : resolve())));
58
+ }
59
+ #serve(request, response) {
60
+ const url = new URL(request.url ?? "/", this.url);
61
+ const of = matched(url.pathname);
62
+ if (of === null) {
63
+ response.writeHead(404).end();
64
+ return;
65
+ }
66
+ const after = Number(request.headers["last-event-id"] ?? url.searchParams.get("after") ?? 0);
67
+ const mine = this.entries.filter((entry) => entry.seq > after && of(entry));
68
+ if ((request.headers.accept ?? "").includes("text/event-stream")) {
69
+ this.#attach(response, mine, after);
70
+ return;
71
+ }
72
+ // A call's log is open until call.ended; an agent's never closes. The cursor is the last seq
73
+ // this page carried, or the one the reader asked from when the page is empty and more follows.
74
+ const live = !this.entries.some((entry) => of(entry) && entry.type === "call.ended");
75
+ const last = mine.at(-1);
76
+ const next = last !== undefined ? last.seq : live ? after : null;
77
+ response.writeHead(200, { "content-type": "application/json" }).end(JSON.stringify({ entries: mine, live, next }));
78
+ }
79
+ #attach(response, replay, after) {
80
+ response.writeHead(200, { "content-type": "text/event-stream", "cache-control": "no-cache", connection: "keep-alive" });
81
+ const reader = { after, response };
82
+ for (const entry of replay) {
83
+ this.#push(reader, entry);
84
+ }
85
+ this.#readers.add(reader);
86
+ // No `error` listener here, unlike the gateway's socket, and that asymmetry is deliberate: a
87
+ // broken reader destroys its `ServerResponse` first, and node drops an error on a destroyed
88
+ // message instead of emitting it. `close` is the only event this door ever gets. See sdk.md.
89
+ response.on("close", () => this.#readers.delete(reader));
90
+ }
91
+ #push(reader, entry) {
92
+ if (entry.seq <= reader.after) {
93
+ return;
94
+ }
95
+ reader.after = entry.seq;
96
+ reader.response.write(`id: ${entry.seq}\ndata: ${JSON.stringify(entry)}\n\n`);
97
+ }
98
+ }
99
+ /** Which entries a path is asking for, or null when it is not one of the two doors. */
100
+ function matched(pathname) {
101
+ const call = /^\/v1\/calls\/([^/]+)\/events$/.exec(pathname);
102
+ if (call !== null) {
103
+ return (entry) => entry.call === decodeURIComponent(call[1]);
104
+ }
105
+ const agent = /^\/v1\/agents\/([^/]+)\/calls$/.exec(pathname);
106
+ if (agent !== null) {
107
+ return (entry) => entry.agent === decodeURIComponent(agent[1]);
108
+ }
109
+ return null;
110
+ }
111
+ //# sourceMappingURL=log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.js","sourceRoot":"","sources":["../../../src/client/testing/log.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** The one address a fake listens on and hands out, so it is served by itself and by nothing else. */
2
+ export declare const LOOPBACK = "127.0.0.1";
3
+ //# sourceMappingURL=loopback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loopback.d.ts","sourceRoot":"","sources":["../../../src/client/testing/loopback.ts"],"names":[],"mappings":"AAAA,sGAAsG;AAEtG,eAAO,MAAM,QAAQ,cAAc,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** The one address a fake listens on and hands out, so it is served by itself and by nothing else. */
2
+ export const LOOPBACK = "127.0.0.1";
3
+ //# sourceMappingURL=loopback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loopback.js","sourceRoot":"","sources":["../../../src/client/testing/loopback.ts"],"names":[],"mappings":"AAAA,sGAAsG;AAEtG,MAAM,CAAC,MAAM,QAAQ,GAAG,WAAW,CAAC"}