@qvac/harness 1.0.0-rc.1 → 1.0.0-rc.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 (796) hide show
  1. package/CHANGELOG.md +1168 -1
  2. package/NOTICE.md +16 -0
  3. package/README.md +278 -471
  4. package/dist-lib/index.d.ts +101 -169
  5. package/dist-lib/index.js +423 -1506
  6. package/dist-lib/lib/addon-seal.bare.d.ts +1 -0
  7. package/dist-lib/lib/addon-seal.bare.js +3 -0
  8. package/dist-lib/lib/addon-seal.node.d.ts +1 -0
  9. package/dist-lib/lib/addon-seal.node.js +1 -0
  10. package/dist-lib/lib/agent/delegate.d.ts +83 -0
  11. package/dist-lib/lib/agent/delegate.js +261 -0
  12. package/dist-lib/lib/agent/follow.d.ts +32 -0
  13. package/dist-lib/lib/agent/follow.js +162 -0
  14. package/dist-lib/lib/agent/index.d.ts +37 -0
  15. package/dist-lib/lib/agent/index.js +42 -0
  16. package/dist-lib/lib/agent/plan.d.ts +6 -0
  17. package/dist-lib/lib/agent/plan.js +74 -0
  18. package/dist-lib/lib/agent/resolve.d.ts +3 -0
  19. package/dist-lib/lib/agent/resolve.js +78 -0
  20. package/dist-lib/lib/{capabilities → agent}/tool-names.d.ts +0 -1
  21. package/dist-lib/lib/{capabilities → agent}/tool-names.js +0 -1
  22. package/dist-lib/lib/{capabilities → agent}/tool-selection.d.ts +3 -6
  23. package/dist-lib/lib/{capabilities → agent}/tool-selection.js +9 -1
  24. package/dist-lib/lib/agent/tools.d.ts +14 -0
  25. package/dist-lib/lib/agent/tools.js +16 -0
  26. package/dist-lib/lib/agent/transfer.d.ts +7 -0
  27. package/dist-lib/lib/agent/transfer.js +26 -0
  28. package/dist-lib/lib/capabilities/agent-ports.d.ts +3 -0
  29. package/dist-lib/lib/capabilities/agent-ports.js +9 -0
  30. package/dist-lib/lib/capabilities/completion-engine/actors/answering.d.ts +1 -1
  31. package/dist-lib/lib/capabilities/completion-engine/actors/answering.js +25 -9
  32. package/dist-lib/lib/capabilities/completion-engine/actors/batching.d.ts +3 -0
  33. package/dist-lib/lib/capabilities/completion-engine/actors/batching.js +90 -0
  34. package/dist-lib/lib/capabilities/completion-engine/actors/direct-search.d.ts +2 -1
  35. package/dist-lib/lib/capabilities/completion-engine/actors/direct-search.js +14 -5
  36. package/dist-lib/lib/capabilities/completion-engine/actors/execute.d.ts +5 -3
  37. package/dist-lib/lib/capabilities/completion-engine/actors/execute.js +8 -3
  38. package/dist-lib/lib/capabilities/completion-engine/actors/executing.d.ts +29 -2
  39. package/dist-lib/lib/capabilities/completion-engine/actors/executing.js +100 -40
  40. package/dist-lib/lib/capabilities/completion-engine/actors/execution-plan.d.ts +11 -10
  41. package/dist-lib/lib/capabilities/completion-engine/actors/execution-plan.js +28 -21
  42. package/dist-lib/lib/capabilities/completion-engine/actors/finishing.js +2 -2
  43. package/dist-lib/lib/capabilities/completion-engine/actors/inspect-prepare.d.ts +4 -0
  44. package/dist-lib/lib/capabilities/completion-engine/actors/inspect-prepare.js +67 -0
  45. package/dist-lib/lib/capabilities/completion-engine/actors/inspecting.d.ts +10 -3
  46. package/dist-lib/lib/capabilities/completion-engine/actors/inspecting.js +14 -11
  47. package/dist-lib/lib/capabilities/completion-engine/actors/loading-skill.d.ts +7 -3
  48. package/dist-lib/lib/capabilities/completion-engine/actors/loading-skill.js +30 -31
  49. package/dist-lib/lib/capabilities/completion-engine/actors/preparing.d.ts +3 -2
  50. package/dist-lib/lib/capabilities/completion-engine/actors/preparing.js +86 -102
  51. package/dist-lib/lib/capabilities/completion-engine/actors/rejecting.d.ts +1 -1
  52. package/dist-lib/lib/capabilities/completion-engine/actors/rejecting.js +24 -7
  53. package/dist-lib/lib/capabilities/completion-engine/actors/rejection.d.ts +4 -2
  54. package/dist-lib/lib/capabilities/completion-engine/actors/rejection.js +8 -8
  55. package/dist-lib/lib/capabilities/completion-engine/actors/resolving.d.ts +1 -1
  56. package/dist-lib/lib/capabilities/completion-engine/actors/resolving.js +73 -15
  57. package/dist-lib/lib/capabilities/completion-engine/actors/retrieving.d.ts +10 -0
  58. package/dist-lib/lib/capabilities/completion-engine/actors/retrieving.js +56 -0
  59. package/dist-lib/lib/capabilities/completion-engine/actors/run-prepare.d.ts +4 -0
  60. package/dist-lib/lib/capabilities/completion-engine/actors/run-prepare.js +74 -0
  61. package/dist-lib/lib/capabilities/completion-engine/actors/skill-step.d.ts +2 -0
  62. package/dist-lib/lib/capabilities/completion-engine/actors/skill-step.js +76 -0
  63. package/dist-lib/lib/capabilities/completion-engine/actors/stream.d.ts +2 -2
  64. package/dist-lib/lib/capabilities/completion-engine/actors/stream.js +2 -1
  65. package/dist-lib/lib/capabilities/completion-engine/actors/streaming.d.ts +1 -1
  66. package/dist-lib/lib/capabilities/completion-engine/actors/streaming.js +84 -26
  67. package/dist-lib/lib/capabilities/completion-engine/actors/wrap-up.d.ts +1 -1
  68. package/dist-lib/lib/capabilities/completion-engine/actors/wrap-up.js +16 -6
  69. package/dist-lib/lib/capabilities/completion-engine/actors.d.ts +11 -0
  70. package/dist-lib/lib/capabilities/completion-engine/actors.js +216 -0
  71. package/dist-lib/lib/capabilities/completion-engine/driver.d.ts +12 -5
  72. package/dist-lib/lib/capabilities/completion-engine/driver.js +118 -33
  73. package/dist-lib/lib/capabilities/completion-engine/durable.d.ts +2 -1
  74. package/dist-lib/lib/capabilities/completion-engine/durable.js +6 -4
  75. package/dist-lib/lib/capabilities/completion-engine/engine.d.ts +65 -0
  76. package/dist-lib/lib/{machine → capabilities/completion-engine}/engine.js +67 -130
  77. package/dist-lib/lib/capabilities/completion-engine/index.d.ts +30 -0
  78. package/dist-lib/lib/capabilities/completion-engine/index.js +44 -0
  79. package/dist-lib/lib/capabilities/completion-engine/loop.d.ts +58 -0
  80. package/dist-lib/lib/capabilities/completion-engine/loop.js +62 -0
  81. package/dist-lib/lib/capabilities/completion-engine/metrics.d.ts +4 -0
  82. package/dist-lib/lib/capabilities/completion-engine/metrics.js +46 -0
  83. package/dist-lib/lib/capabilities/completion-engine/operations.d.ts +5 -2
  84. package/dist-lib/lib/capabilities/completion-engine/operations.js +84 -15
  85. package/dist-lib/lib/capabilities/completion-engine/ports.d.ts +25 -2
  86. package/dist-lib/lib/capabilities/completion-engine/ports.js +25 -16
  87. package/dist-lib/lib/capabilities/completion-engine/prepare-step.d.ts +26 -0
  88. package/dist-lib/lib/{machine → capabilities/completion-engine}/replay-output.d.ts +1 -1
  89. package/dist-lib/lib/{machine → capabilities/completion-engine}/replay-output.js +1 -1
  90. package/dist-lib/lib/capabilities/{completion-loop → completion-engine}/round.d.ts +24 -4
  91. package/dist-lib/lib/capabilities/{completion-loop → completion-engine}/round.js +242 -27
  92. package/dist-lib/lib/capabilities/completion-engine/session.d.ts +19 -12
  93. package/dist-lib/lib/capabilities/completion-engine/session.js +12 -6
  94. package/dist-lib/lib/capabilities/completion-engine/splice.d.ts +2 -0
  95. package/dist-lib/lib/capabilities/completion-engine/splice.js +7 -0
  96. package/dist-lib/lib/capabilities/completion-engine/stages.d.ts +23 -0
  97. package/dist-lib/lib/capabilities/completion-engine/tool-caller.d.ts +10 -0
  98. package/dist-lib/lib/capabilities/completion-engine/tool-caller.js +151 -0
  99. package/dist-lib/lib/capabilities/completion-engine/tool-execution.d.ts +77 -0
  100. package/dist-lib/lib/capabilities/{completion-loop → completion-engine}/tool-execution.js +74 -25
  101. package/dist-lib/lib/capabilities/{completion-loop → completion-engine}/turns.d.ts +8 -4
  102. package/dist-lib/lib/capabilities/completion-engine/turns.js +225 -0
  103. package/dist-lib/lib/capabilities/enhance.d.ts +1 -1
  104. package/dist-lib/lib/capabilities/enhance.js +3 -2
  105. package/dist-lib/lib/capabilities/invoke.d.ts +1 -1
  106. package/dist-lib/lib/capabilities/preview-model-source.d.ts +1 -10
  107. package/dist-lib/lib/capabilities/preview-model-source.js +3 -1
  108. package/dist-lib/lib/capabilities/sdk-tool.d.ts +10 -0
  109. package/dist-lib/lib/capabilities/sdk-tool.js +130 -0
  110. package/dist-lib/lib/capabilities/skill-entry.d.ts +8 -0
  111. package/dist-lib/lib/capabilities/skill-entry.js +14 -0
  112. package/dist-lib/lib/capabilities/tool-plan.d.ts +6 -5
  113. package/dist-lib/lib/capabilities/tool-plan.js +16 -10
  114. package/dist-lib/lib/capabilities/tool-turns.d.ts +29 -4
  115. package/dist-lib/lib/capabilities/tool-turns.js +120 -10
  116. package/dist-lib/lib/capabilities/usage-breakdown.d.ts +1 -1
  117. package/dist-lib/lib/capabilities/usage-breakdown.js +4 -1
  118. package/dist-lib/lib/connect.d.ts +6 -0
  119. package/dist-lib/lib/connect.js +153 -65
  120. package/dist-lib/lib/context-window.d.ts +4 -2
  121. package/dist-lib/lib/context-window.js +27 -16
  122. package/dist-lib/lib/contract/agent.d.ts +65 -0
  123. package/dist-lib/lib/{capabilities/types.d.ts → contract/completion.d.ts} +140 -26
  124. package/dist-lib/lib/contract/exec.d.ts +134 -0
  125. package/dist-lib/lib/{hooks/types.d.ts → contract/hooks.d.ts} +62 -10
  126. package/dist-lib/lib/contract/index.d.ts +5 -0
  127. package/dist-lib/lib/contract/knowledge.d.ts +60 -0
  128. package/dist-lib/lib/contract/knowledge.js +1 -0
  129. package/dist-lib/lib/contract/models.d.ts +56 -0
  130. package/dist-lib/lib/contract/models.js +1 -0
  131. package/dist-lib/lib/contract/run.d.ts +142 -0
  132. package/dist-lib/lib/contract/run.js +1 -0
  133. package/dist-lib/lib/contract/sandbox.d.ts +29 -0
  134. package/dist-lib/lib/contract/sandbox.js +1 -0
  135. package/dist-lib/lib/contract/skill-readiness.d.ts +14 -0
  136. package/dist-lib/lib/contract/skill-readiness.js +1 -0
  137. package/dist-lib/lib/{capabilities/voice.d.ts → contract/speech.d.ts} +11 -16
  138. package/dist-lib/lib/contract/speech.js +1 -0
  139. package/dist-lib/lib/contract-types.d.ts +43 -16
  140. package/dist-lib/lib/docx/index.d.ts +0 -1
  141. package/dist-lib/lib/docx/index.js +15 -24
  142. package/dist-lib/lib/embeddings/index.d.ts +63 -0
  143. package/dist-lib/lib/embeddings/index.js +267 -0
  144. package/dist-lib/lib/fold/index.d.ts +50 -0
  145. package/dist-lib/lib/fold/index.js +123 -0
  146. package/dist-lib/lib/{tools/exec/adapters/python/guarded-fetch.d.ts → guarded-fetch.d.ts} +5 -12
  147. package/dist-lib/lib/{tools/exec/adapters/python/guarded-fetch.js → guarded-fetch.js} +12 -34
  148. package/dist-lib/lib/helpers/completion-params.d.ts +3 -0
  149. package/dist-lib/lib/helpers/completion-params.js +12 -0
  150. package/dist-lib/lib/helpers/copy.d.ts +1 -0
  151. package/dist-lib/lib/helpers/copy.js +5 -0
  152. package/dist-lib/lib/helpers/drain.d.ts +5 -0
  153. package/dist-lib/lib/helpers/drain.js +19 -0
  154. package/dist-lib/lib/{machine/errors.d.ts → helpers/engine-error.d.ts} +6 -9
  155. package/dist-lib/lib/{machine/errors.js → helpers/engine-error.js} +9 -25
  156. package/dist-lib/lib/helpers/failure-result.d.ts +21 -0
  157. package/dist-lib/lib/helpers/failure-result.js +39 -0
  158. package/dist-lib/lib/helpers/head-tail.d.ts +7 -0
  159. package/dist-lib/lib/helpers/head-tail.js +19 -0
  160. package/dist-lib/lib/helpers/image-settings.d.ts +2 -0
  161. package/dist-lib/lib/helpers/image-settings.js +19 -0
  162. package/dist-lib/lib/helpers/mcp-methods.d.ts +2 -0
  163. package/dist-lib/lib/helpers/mcp-methods.js +14 -0
  164. package/dist-lib/lib/helpers/race-abort.d.ts +1 -1
  165. package/dist-lib/lib/helpers/race-abort.js +1 -1
  166. package/dist-lib/lib/helpers/repeated-reply.d.ts +2 -0
  167. package/dist-lib/lib/helpers/repeated-reply.js +63 -0
  168. package/dist-lib/lib/helpers/run-outcome.d.ts +5 -4
  169. package/dist-lib/lib/helpers/run-outcome.js +11 -9
  170. package/dist-lib/lib/{machine → helpers}/stable-stringify.js +1 -1
  171. package/dist-lib/lib/helpers/tool-call-markup.d.ts +1 -0
  172. package/dist-lib/lib/helpers/tool-call-markup.js +9 -5
  173. package/dist-lib/lib/helpers/tool-label.d.ts +2 -2
  174. package/dist-lib/lib/helpers/tool-label.js +3 -3
  175. package/dist-lib/lib/hooks/built-in/arg-repair.d.ts +1 -1
  176. package/dist-lib/lib/hooks/built-in/arg-repair.js +109 -19
  177. package/dist-lib/lib/hooks/built-in/egress.d.ts +1 -1
  178. package/dist-lib/lib/hooks/built-in/egress.js +13 -21
  179. package/dist-lib/lib/hooks/built-in/sandbox.d.ts +1 -1
  180. package/dist-lib/lib/hooks/built-in/skill-catalog.d.ts +1 -1
  181. package/dist-lib/lib/hooks/index.d.ts +48 -0
  182. package/dist-lib/lib/hooks/index.js +130 -0
  183. package/dist-lib/lib/hooks/run.d.ts +9 -6
  184. package/dist-lib/lib/hooks/run.js +113 -48
  185. package/dist-lib/lib/{completion-lifecycle.d.ts → lifecycle/completion-run.d.ts} +1 -1
  186. package/dist-lib/lib/{completion-lifecycle.js → lifecycle/completion-run.js} +1 -1
  187. package/dist-lib/lib/lifecycle/index.d.ts +83 -0
  188. package/dist-lib/lib/lifecycle/index.js +335 -0
  189. package/dist-lib/lib/{harness-lifecycle.js → lifecycle/machine.js} +2 -2
  190. package/dist-lib/lib/machine/completion/actions/completion.d.ts +11 -2
  191. package/dist-lib/lib/machine/completion/actions/completion.js +98 -14
  192. package/dist-lib/lib/machine/completion/actions/prepare.d.ts +9 -0
  193. package/dist-lib/lib/machine/completion/actions/prepare.js +30 -0
  194. package/dist-lib/lib/machine/completion/actions/tools.d.ts +10 -1
  195. package/dist-lib/lib/machine/completion/actions/tools.js +79 -7
  196. package/dist-lib/lib/machine/completion/context.d.ts +7 -2
  197. package/dist-lib/lib/machine/completion/context.js +29 -5
  198. package/dist-lib/lib/machine/completion/guards/retry.d.ts +1 -0
  199. package/dist-lib/lib/machine/completion/guards/retry.js +6 -3
  200. package/dist-lib/lib/machine/completion/implementations.d.ts +38 -12
  201. package/dist-lib/lib/machine/completion/implementations.js +81 -31
  202. package/dist-lib/lib/machine/completion/machine.d.ts +140 -63
  203. package/dist-lib/lib/machine/completion/machine.js +194 -58
  204. package/dist-lib/lib/machine/completion/ports.d.ts +7 -55
  205. package/dist-lib/lib/machine/completion/ports.js +1 -224
  206. package/dist-lib/lib/machine/completion/rules.d.ts +20 -19
  207. package/dist-lib/lib/machine/completion/rules.js +73 -52
  208. package/dist-lib/lib/machine/completion/types.d.ts +110 -187
  209. package/dist-lib/lib/machine/completion/version.d.ts +1 -0
  210. package/dist-lib/lib/machine/completion/version.js +1 -0
  211. package/dist-lib/lib/machine/definition.d.ts +23 -0
  212. package/dist-lib/lib/machine/definition.js +76 -0
  213. package/dist-lib/lib/machine/index.d.ts +463 -20
  214. package/dist-lib/lib/machine/index.js +15 -11
  215. package/dist-lib/lib/models/llm-presets.d.ts +1 -0
  216. package/dist-lib/lib/models/model-catalog-constants.d.ts +3 -1
  217. package/dist-lib/lib/models/model-catalog-constants.js +9 -1
  218. package/dist-lib/lib/models/model-catalog.d.ts +31 -4
  219. package/dist-lib/lib/models/model-catalog.js +89 -8
  220. package/dist-lib/lib/models/model-fit.d.ts +55 -0
  221. package/dist-lib/lib/models/model-fit.js +102 -0
  222. package/dist-lib/lib/models/model-handle.d.ts +4 -0
  223. package/dist-lib/lib/models/model-handle.js +8 -1
  224. package/dist-lib/lib/models/model-list.d.ts +4 -0
  225. package/dist-lib/lib/models/model-pool.d.ts +35 -10
  226. package/dist-lib/lib/models/model-pool.js +63 -14
  227. package/dist-lib/lib/models/music-catalog.d.ts +1 -1
  228. package/dist-lib/lib/models/music-catalog.js +8 -1
  229. package/dist-lib/lib/models/sdk-faults.d.ts +2 -0
  230. package/dist-lib/lib/models/sdk-faults.js +18 -0
  231. package/dist-lib/lib/models/tts-model-default.js +3 -3
  232. package/dist-lib/lib/office/engine/codes.d.ts +62 -0
  233. package/dist-lib/lib/office/engine/codes.js +61 -0
  234. package/dist-lib/lib/office/engine/docx/document.d.ts +216 -0
  235. package/dist-lib/lib/office/engine/docx/document.js +1152 -0
  236. package/dist-lib/lib/office/engine/docx/index.d.ts +7 -0
  237. package/dist-lib/lib/office/engine/docx/index.js +8 -0
  238. package/dist-lib/lib/office/engine/docx/styles.d.ts +31 -0
  239. package/dist-lib/lib/office/engine/docx/styles.js +173 -0
  240. package/dist-lib/lib/office/engine/docx/template.d.ts +18 -0
  241. package/dist-lib/lib/office/engine/docx/template.js +133 -0
  242. package/dist-lib/lib/office/engine/docx/text.d.ts +55 -0
  243. package/dist-lib/lib/office/engine/docx/text.js +538 -0
  244. package/dist-lib/lib/office/engine/drawingml/chart.d.ts +63 -0
  245. package/dist-lib/lib/office/engine/drawingml/chart.js +539 -0
  246. package/dist-lib/lib/office/engine/drawingml/text.d.ts +35 -0
  247. package/dist-lib/lib/office/engine/drawingml/text.js +352 -0
  248. package/dist-lib/lib/office/engine/errors.d.ts +6 -0
  249. package/dist-lib/lib/office/engine/errors.js +12 -0
  250. package/dist-lib/lib/office/engine/image.d.ts +8 -0
  251. package/dist-lib/lib/office/engine/image.js +48 -0
  252. package/dist-lib/lib/office/engine/index.d.ts +12 -0
  253. package/dist-lib/lib/office/engine/index.js +7 -0
  254. package/dist-lib/lib/office/engine/opc/content-types.d.ts +17 -0
  255. package/dist-lib/lib/office/engine/opc/content-types.js +74 -0
  256. package/dist-lib/lib/office/engine/opc/media.d.ts +13 -0
  257. package/dist-lib/lib/office/engine/opc/media.js +11 -0
  258. package/dist-lib/lib/office/engine/opc/package.d.ts +51 -0
  259. package/dist-lib/lib/office/engine/opc/package.js +324 -0
  260. package/dist-lib/lib/office/engine/opc/paths.d.ts +7 -0
  261. package/dist-lib/lib/office/engine/opc/paths.js +46 -0
  262. package/dist-lib/lib/office/engine/opc/properties.d.ts +7 -0
  263. package/dist-lib/lib/office/engine/opc/properties.js +75 -0
  264. package/dist-lib/lib/office/engine/opc/relationships.d.ts +23 -0
  265. package/dist-lib/lib/office/engine/opc/relationships.js +65 -0
  266. package/dist-lib/lib/office/engine/opc/zip.d.ts +15 -0
  267. package/dist-lib/lib/office/engine/opc/zip.js +264 -0
  268. package/dist-lib/lib/office/engine/pptx/fit.d.ts +12 -0
  269. package/dist-lib/lib/office/engine/pptx/fit.js +37 -0
  270. package/dist-lib/lib/office/engine/pptx/index.d.ts +8 -0
  271. package/dist-lib/lib/office/engine/pptx/index.js +8 -0
  272. package/dist-lib/lib/office/engine/pptx/inherit.d.ts +29 -0
  273. package/dist-lib/lib/office/engine/pptx/inherit.js +155 -0
  274. package/dist-lib/lib/office/engine/pptx/notes.d.ts +5 -0
  275. package/dist-lib/lib/office/engine/pptx/notes.js +85 -0
  276. package/dist-lib/lib/office/engine/pptx/presentation.d.ts +54 -0
  277. package/dist-lib/lib/office/engine/pptx/presentation.js +749 -0
  278. package/dist-lib/lib/office/engine/pptx/read.d.ts +9 -0
  279. package/dist-lib/lib/office/engine/pptx/read.js +66 -0
  280. package/dist-lib/lib/office/engine/pptx/shapes.d.ts +52 -0
  281. package/dist-lib/lib/office/engine/pptx/shapes.js +276 -0
  282. package/dist-lib/lib/office/engine/pptx/slides.d.ts +27 -0
  283. package/dist-lib/lib/office/engine/pptx/slides.js +123 -0
  284. package/dist-lib/lib/office/engine/pptx/template.d.ts +20 -0
  285. package/dist-lib/lib/office/engine/pptx/template.js +391 -0
  286. package/dist-lib/lib/office/engine/pptx/types.d.ts +120 -0
  287. package/dist-lib/lib/office/engine/pptx/types.js +1 -0
  288. package/dist-lib/lib/office/engine/units.d.ts +3 -0
  289. package/dist-lib/lib/office/engine/units.js +12 -0
  290. package/dist-lib/lib/office/engine/utf8.d.ts +2 -0
  291. package/dist-lib/lib/office/engine/utf8.js +103 -0
  292. package/dist-lib/lib/office/engine/xlsx/formula.d.ts +49 -0
  293. package/dist-lib/lib/office/engine/xlsx/formula.js +381 -0
  294. package/dist-lib/lib/office/engine/xlsx/index.d.ts +8 -0
  295. package/dist-lib/lib/office/engine/xlsx/index.js +8 -0
  296. package/dist-lib/lib/office/engine/xlsx/refs.d.ts +22 -0
  297. package/dist-lib/lib/office/engine/xlsx/refs.js +82 -0
  298. package/dist-lib/lib/office/engine/xlsx/reshape.d.ts +21 -0
  299. package/dist-lib/lib/office/engine/xlsx/reshape.js +424 -0
  300. package/dist-lib/lib/office/engine/xlsx/sheet.d.ts +108 -0
  301. package/dist-lib/lib/office/engine/xlsx/sheet.js +662 -0
  302. package/dist-lib/lib/office/engine/xlsx/strings.d.ts +15 -0
  303. package/dist-lib/lib/office/engine/xlsx/strings.js +93 -0
  304. package/dist-lib/lib/office/engine/xlsx/styles.d.ts +38 -0
  305. package/dist-lib/lib/office/engine/xlsx/styles.js +369 -0
  306. package/dist-lib/lib/office/engine/xlsx/template.d.ts +7 -0
  307. package/dist-lib/lib/office/engine/xlsx/template.js +54 -0
  308. package/dist-lib/lib/office/engine/xlsx/workbook.d.ts +161 -0
  309. package/dist-lib/lib/office/engine/xlsx/workbook.js +850 -0
  310. package/dist-lib/lib/office/engine/xlsx/write.d.ts +2 -0
  311. package/dist-lib/lib/office/engine/xlsx/write.js +42 -0
  312. package/dist-lib/lib/office/engine/xml.d.ts +45 -0
  313. package/dist-lib/lib/office/engine/xml.js +258 -0
  314. package/dist-lib/lib/office/extract.d.ts +9 -0
  315. package/dist-lib/lib/office/extract.js +19 -0
  316. package/dist-lib/lib/office/index.d.ts +1 -1
  317. package/dist-lib/lib/office/index.js +74 -19
  318. package/dist-lib/lib/plugins/addons.d.ts +2 -0
  319. package/dist-lib/lib/plugins/addons.js +12 -0
  320. package/dist-lib/lib/plugins/context.d.ts +16 -0
  321. package/dist-lib/lib/plugins/context.js +48 -0
  322. package/dist-lib/lib/plugins/index.d.ts +3 -0
  323. package/dist-lib/lib/plugins/index.js +1 -0
  324. package/dist-lib/lib/plugins/registry.d.ts +116 -0
  325. package/dist-lib/lib/plugins/registry.js +505 -0
  326. package/dist-lib/lib/plugins/runtime.d.ts +27 -0
  327. package/dist-lib/lib/plugins/runtime.js +143 -0
  328. package/dist-lib/lib/plugins/scope.d.ts +17 -0
  329. package/dist-lib/lib/plugins/scope.js +55 -0
  330. package/dist-lib/lib/prompt.d.ts +2 -5
  331. package/dist-lib/lib/prompt.js +9 -0
  332. package/dist-lib/lib/residency/completion-runtime.d.ts +52 -0
  333. package/dist-lib/lib/{capabilities → residency}/completion-runtime.js +22 -15
  334. package/dist-lib/lib/residency/index.d.ts +148 -0
  335. package/dist-lib/lib/residency/index.js +539 -0
  336. package/dist-lib/lib/run-log/boundary.d.ts +17 -0
  337. package/dist-lib/lib/run-log/boundary.js +58 -0
  338. package/dist-lib/lib/run-log/history-codec.d.ts +7 -6
  339. package/dist-lib/lib/run-log/history-codec.js +175 -46
  340. package/dist-lib/lib/run-log/index.d.ts +46 -0
  341. package/dist-lib/lib/run-log/index.js +40 -0
  342. package/dist-lib/lib/run-log/inspect.d.ts +53 -0
  343. package/dist-lib/lib/{run-log-inspect.js → run-log/inspect.js} +196 -139
  344. package/dist-lib/lib/run-log/live.d.ts +37 -0
  345. package/dist-lib/lib/run-log/live.js +195 -0
  346. package/dist-lib/lib/run-log/persisted-actor.d.ts +1 -6
  347. package/dist-lib/lib/run-log/persisted-actor.js +4 -3
  348. package/dist-lib/lib/run-log/protocol-types.d.ts +37 -14
  349. package/dist-lib/lib/run-log/protocol.d.ts +1 -2
  350. package/dist-lib/lib/run-log/protocol.js +45 -40
  351. package/dist-lib/lib/{run-log-redact.d.ts → run-log/redact.d.ts} +3 -2
  352. package/dist-lib/lib/{run-log-redact.js → run-log/redact.js} +101 -16
  353. package/dist-lib/lib/run-log/replay.d.ts +3 -2
  354. package/dist-lib/lib/run-log/replay.js +7 -6
  355. package/dist-lib/lib/run-log/request-codec.d.ts +17 -0
  356. package/dist-lib/lib/run-log/request-codec.js +87 -0
  357. package/dist-lib/lib/run-log/run-journal.d.ts +14 -8
  358. package/dist-lib/lib/run-log/run-journal.js +100 -75
  359. package/dist-lib/lib/sdk-loader.d.ts +2 -7
  360. package/dist-lib/lib/sdk-loader.js +8 -15
  361. package/dist-lib/lib/sdk-storage.js +3 -1
  362. package/dist-lib/lib/serve.js +139 -38
  363. package/dist-lib/lib/skills-host/index.d.ts +59 -0
  364. package/dist-lib/lib/skills-host/index.js +268 -0
  365. package/dist-lib/lib/spawn.d.ts +37 -3
  366. package/dist-lib/lib/spawn.js +7 -3
  367. package/dist-lib/lib/spill.d.ts +11 -0
  368. package/dist-lib/lib/spill.js +82 -0
  369. package/dist-lib/lib/tools/{exec/adapters/python → attachments}/output-policy.d.ts +2 -3
  370. package/dist-lib/lib/tools/{exec/adapters/python/attachments.d.ts → attachments/staging.d.ts} +2 -2
  371. package/dist-lib/lib/tools/{exec/adapters/python/attachments.js → attachments/staging.js} +3 -3
  372. package/dist-lib/lib/tools/catalog.d.ts +1 -1
  373. package/dist-lib/lib/tools/catalog.js +1 -1
  374. package/dist-lib/lib/tools/create-documents.d.ts +1 -1
  375. package/dist-lib/lib/tools/edit-documents.d.ts +1 -1
  376. package/dist-lib/lib/tools/exec/adapters/shell/shell-adapter.d.ts +5 -7
  377. package/dist-lib/lib/tools/exec/adapters/shell/shell-adapter.js +3 -2
  378. package/dist-lib/lib/tools/exec/bare-runtime.js +2 -4
  379. package/dist-lib/lib/tools/exec/python-source.d.ts +6 -0
  380. package/dist-lib/lib/tools/exec/python-source.js +243 -0
  381. package/dist-lib/lib/tools/exec/runner.d.ts +24 -45
  382. package/dist-lib/lib/tools/exec/runner.js +68 -34
  383. package/dist-lib/lib/tools/exec/scope.d.ts +2 -0
  384. package/dist-lib/lib/tools/exec/scope.js +33 -2
  385. package/dist-lib/lib/tools/exec/shell-guidance.d.ts +11 -9
  386. package/dist-lib/lib/tools/exec/shell-guidance.js +28 -57
  387. package/dist-lib/lib/tools/exec/video-tools.d.ts +0 -1
  388. package/dist-lib/lib/tools/exec/video-tools.js +0 -5
  389. package/dist-lib/lib/tools/exec.d.ts +7 -14
  390. package/dist-lib/lib/tools/exec.js +181 -457
  391. package/dist-lib/lib/tools/file-glob.d.ts +1 -1
  392. package/dist-lib/lib/tools/file-glob.js +1 -0
  393. package/dist-lib/lib/tools/fs/scope.d.ts +1 -0
  394. package/dist-lib/lib/tools/fs/scope.js +8 -3
  395. package/dist-lib/lib/tools/grep.d.ts +1 -1
  396. package/dist-lib/lib/tools/grep.js +1 -0
  397. package/dist-lib/lib/tools/http-request.d.ts +1 -1
  398. package/dist-lib/lib/tools/http-request.js +1 -0
  399. package/dist-lib/lib/tools/index.d.ts +21 -0
  400. package/dist-lib/lib/tools/index.js +46 -0
  401. package/dist-lib/lib/tools/office/ops.d.ts +13 -0
  402. package/dist-lib/lib/tools/office/ops.js +100 -0
  403. package/dist-lib/lib/tools/office.d.ts +12 -0
  404. package/dist-lib/lib/tools/office.js +486 -0
  405. package/dist-lib/lib/tools/operations/compile.d.ts +3 -3
  406. package/dist-lib/lib/tools/operations/compile.js +2 -1
  407. package/dist-lib/lib/tools/operations/decoders.js +1 -1
  408. package/dist-lib/lib/tools/operations/manifest.d.ts +1 -1
  409. package/dist-lib/lib/tools/outbound-guard.d.ts +3 -1
  410. package/dist-lib/lib/tools/outbound-guard.js +4 -0
  411. package/dist-lib/lib/tools/pdf/build.d.ts +43 -0
  412. package/dist-lib/lib/tools/pdf/build.js +150 -0
  413. package/dist-lib/lib/tools/pdf/images.d.ts +7 -0
  414. package/dist-lib/lib/tools/pdf/images.js +82 -0
  415. package/dist-lib/lib/tools/pdf/request.d.ts +63 -0
  416. package/dist-lib/lib/tools/pdf/request.js +335 -0
  417. package/dist-lib/lib/tools/pdf.d.ts +6 -0
  418. package/dist-lib/lib/tools/pdf.js +303 -0
  419. package/dist-lib/lib/tools/read-files.d.ts +1 -1
  420. package/dist-lib/lib/tools/read-files.js +5 -1
  421. package/dist-lib/lib/tools/skill.d.ts +2 -4
  422. package/dist-lib/lib/tools/skill.js +20 -22
  423. package/dist-lib/lib/tools/skills/auth-resolver.d.ts +1 -1
  424. package/dist-lib/lib/tools/skills/catalog.d.ts +9 -2
  425. package/dist-lib/lib/tools/skills/catalog.js +7 -7
  426. package/dist-lib/lib/tools/skills/cli-schema.js +1 -1
  427. package/dist-lib/lib/tools/skills/frontmatter-parser.d.ts +1 -0
  428. package/dist-lib/lib/tools/skills/frontmatter-parser.js +1 -0
  429. package/dist-lib/lib/tools/skills/mention.d.ts +1 -2
  430. package/dist-lib/lib/tools/skills/mention.js +0 -3
  431. package/dist-lib/lib/tools/skills/scope-key.d.ts +2 -1
  432. package/dist-lib/lib/tools/skills/scope-key.js +2 -3
  433. package/dist-lib/lib/tools/skills/skill-state.d.ts +2 -2
  434. package/dist-lib/lib/tools/skills/skill-state.js +11 -28
  435. package/dist-lib/lib/tools/toolsets.d.ts +3 -7
  436. package/dist-lib/lib/tools/toolsets.js +5 -9
  437. package/dist-lib/lib/tools/web-fetch.d.ts +1 -1
  438. package/dist-lib/lib/tools/web-fetch.js +42 -6
  439. package/dist-lib/lib/web-fetch/embedded-state.js +1 -1
  440. package/dist-lib/lib/web-fetch/extract.js +1 -1
  441. package/dist-lib/lib/web-fetch/images.js +1 -1
  442. package/dist-lib/lib/web-fetch/video.js +1 -1
  443. package/dist-lib/lib/wire.d.ts +8 -0
  444. package/dist-lib/lib/wire.js +112 -2
  445. package/dist-lib/plugins/code-mode/index.d.ts +16 -0
  446. package/dist-lib/plugins/code-mode/index.js +43 -0
  447. package/dist-lib/plugins/coding/index.d.ts +15 -0
  448. package/dist-lib/plugins/coding/index.js +42 -0
  449. package/dist-lib/plugins/coding/jobs.d.ts +24 -0
  450. package/dist-lib/plugins/coding/jobs.js +144 -0
  451. package/dist-lib/plugins/coding/session.d.ts +51 -0
  452. package/dist-lib/plugins/coding/session.js +263 -0
  453. package/dist-lib/plugins/coding/write-file.d.ts +3 -0
  454. package/dist-lib/plugins/coding/write-file.js +52 -0
  455. package/dist-lib/plugins/command-hooks/index.d.ts +88 -0
  456. package/dist-lib/plugins/command-hooks/index.js +338 -0
  457. package/dist-lib/plugins/external-agents/acp.d.ts +27 -0
  458. package/dist-lib/plugins/external-agents/acp.js +264 -0
  459. package/dist-lib/plugins/external-agents/cli.d.ts +3 -0
  460. package/dist-lib/plugins/external-agents/cli.js +199 -0
  461. package/dist-lib/plugins/external-agents/index.d.ts +25 -0
  462. package/dist-lib/plugins/external-agents/index.js +54 -0
  463. package/dist-lib/plugins/external-agents/process.d.ts +19 -0
  464. package/dist-lib/plugins/external-agents/process.js +92 -0
  465. package/dist-lib/plugins/external-agents/targets.d.ts +32 -0
  466. package/dist-lib/plugins/external-agents/targets.js +66 -0
  467. package/dist-lib/{lib/tools → plugins/image}/edit-image.d.ts +3 -2
  468. package/dist-lib/{lib/tools → plugins/image}/edit-image.js +7 -2
  469. package/dist-lib/{lib/tools → plugins/image}/generate-image.d.ts +6 -12
  470. package/dist-lib/{lib/tools → plugins/image}/generate-image.js +6 -7
  471. package/dist-lib/plugins/image/index.d.ts +25 -0
  472. package/dist-lib/plugins/image/index.js +76 -0
  473. package/dist-lib/plugins/knowledge/index.d.ts +21 -0
  474. package/dist-lib/plugins/knowledge/index.js +47 -0
  475. package/dist-lib/plugins/knowledge/search-tool.d.ts +4 -0
  476. package/dist-lib/plugins/knowledge/search-tool.js +38 -0
  477. package/dist-lib/plugins/knowledge/store.d.ts +42 -0
  478. package/dist-lib/plugins/knowledge/store.js +332 -0
  479. package/dist-lib/plugins/lsp/index.d.ts +32 -0
  480. package/dist-lib/plugins/lsp/index.js +77 -0
  481. package/dist-lib/plugins/lsp/pool.d.ts +24 -0
  482. package/dist-lib/plugins/lsp/pool.js +73 -0
  483. package/dist-lib/plugins/lsp/rpc.d.ts +37 -0
  484. package/dist-lib/plugins/lsp/rpc.js +145 -0
  485. package/dist-lib/plugins/lsp/server.d.ts +55 -0
  486. package/dist-lib/plugins/lsp/server.js +192 -0
  487. package/dist-lib/plugins/lsp/tool.d.ts +12 -0
  488. package/dist-lib/plugins/lsp/tool.js +366 -0
  489. package/dist-lib/plugins/mcp/call.d.ts +17 -0
  490. package/dist-lib/{lib/tools/mcp-call.js → plugins/mcp/call.js} +92 -84
  491. package/dist-lib/plugins/mcp/index.d.ts +21 -0
  492. package/dist-lib/plugins/mcp/index.js +85 -0
  493. package/dist-lib/{lib/tools → plugins}/mcp/protocol.d.ts +9 -16
  494. package/dist-lib/{lib/tools → plugins}/mcp/protocol.js +3 -16
  495. package/dist-lib/plugins/mcp/server.d.ts +23 -0
  496. package/dist-lib/plugins/mcp/server.js +108 -0
  497. package/dist-lib/{lib/tools → plugins/music}/generate-music.d.ts +6 -15
  498. package/dist-lib/{lib/tools → plugins/music}/generate-music.js +7 -8
  499. package/dist-lib/plugins/music/index.d.ts +24 -0
  500. package/dist-lib/plugins/music/index.js +48 -0
  501. package/dist-lib/{lib/tools/exec → plugins}/obsidian/cli-process.d.ts +2 -2
  502. package/dist-lib/{lib/tools/exec → plugins}/obsidian/cli-process.js +2 -2
  503. package/dist-lib/{lib/tools/exec → plugins}/obsidian/cli.d.ts +1 -1
  504. package/dist-lib/{lib/tools/exec → plugins}/obsidian/cli.js +7 -7
  505. package/dist-lib/{lib/tools/exec → plugins}/obsidian/command.js +1 -1
  506. package/dist-lib/{lib/tools/exec → plugins}/obsidian/guidance.d.ts +0 -1
  507. package/dist-lib/{lib/tools/exec → plugins}/obsidian/guidance.js +0 -7
  508. package/dist-lib/plugins/obsidian/index.d.ts +26 -0
  509. package/dist-lib/plugins/obsidian/index.js +138 -0
  510. package/dist-lib/{lib/tools/skills/obsidian-readiness.d.ts → plugins/obsidian/readiness.d.ts} +1 -0
  511. package/dist-lib/{lib/tools/skills/obsidian-readiness.js → plugins/obsidian/readiness.js} +7 -0
  512. package/dist-lib/plugins/python/guarded-fetch.d.ts +13 -0
  513. package/dist-lib/plugins/python/guarded-fetch.js +32 -0
  514. package/dist-lib/plugins/python/index.d.ts +18 -0
  515. package/dist-lib/plugins/python/index.js +19 -0
  516. package/dist-lib/{lib/tools/exec/adapters → plugins}/python/interrupt-timer.js +2 -2
  517. package/dist-lib/plugins/python/language.d.ts +8 -0
  518. package/dist-lib/plugins/python/language.js +377 -0
  519. package/dist-lib/{lib/tools/exec/adapters → plugins}/python/loader.d.ts +1 -0
  520. package/dist-lib/{lib/tools/exec/adapters → plugins}/python/loader.js +8 -1
  521. package/dist-lib/{lib/tools/exec/adapters → plugins}/python/memfs.js +3 -3
  522. package/dist-lib/{lib/tools/exec/adapters → plugins}/python/module-distributions.js +0 -3
  523. package/dist-lib/{lib/tools/exec/adapters → plugins}/python/pyodide.js +4 -4
  524. package/dist-lib/plugins/python/python-adapter.d.ts +41 -0
  525. package/dist-lib/plugins/python/python-adapter.js +515 -0
  526. package/dist-lib/{lib/tools/exec/adapters → plugins}/python/run-session.d.ts +1 -2
  527. package/dist-lib/{lib/tools/exec/adapters → plugins}/python/run-session.js +10 -99
  528. package/dist-lib/plugins/python/shell-redirect.d.ts +8 -0
  529. package/dist-lib/plugins/python/shell-redirect.js +25 -0
  530. package/dist-lib/{lib/tools/exec/adapters → plugins}/python/wheels.js +4 -3
  531. package/dist-lib/{lib/tools/exec/adapters → plugins}/python/worker/active.js +1 -1
  532. package/dist-lib/{lib/tools/exec/adapters → plugins}/python/worker/client.d.ts +1 -0
  533. package/dist-lib/{lib/tools/exec/adapters → plugins}/python/worker/client.js +6 -3
  534. package/dist-lib/plugins/python/worker/entry.d.ts +1 -0
  535. package/dist-lib/plugins/python/worker/entry.js +9 -0
  536. package/dist-lib/plugins/python/worker/interrupt-deadline.d.ts +1 -0
  537. package/dist-lib/{lib/tools/exec/adapters → plugins}/python/worker/interrupt-deadline.js +1 -1
  538. package/dist-lib/{lib/tools/exec/adapters → plugins}/python/worker/serve.js +2 -2
  539. package/dist-lib/{lib/tools/exec/adapters → plugins}/python/worker/spawn.d.ts +1 -0
  540. package/dist-lib/{lib/tools/exec/adapters → plugins}/python/worker/spawn.js +7 -0
  541. package/dist-lib/plugins/quickjs/index.d.ts +20 -0
  542. package/dist-lib/plugins/quickjs/index.js +25 -0
  543. package/dist-lib/plugins/quickjs/language.d.ts +3 -0
  544. package/dist-lib/plugins/quickjs/language.js +59 -0
  545. package/dist-lib/plugins/quickjs/runtime.d.ts +38 -0
  546. package/dist-lib/plugins/quickjs/runtime.js +421 -0
  547. package/dist-lib/plugins/quickjs/text-decoder.d.ts +1 -0
  548. package/dist-lib/plugins/quickjs/text-decoder.js +15 -0
  549. package/dist-lib/plugins/run-report/brand.d.ts +1 -0
  550. package/dist-lib/plugins/run-report/brand.js +1 -0
  551. package/dist-lib/plugins/run-report/flow-view.d.ts +6 -0
  552. package/dist-lib/plugins/run-report/flow-view.js +53 -0
  553. package/dist-lib/plugins/run-report/flow.d.ts +33 -0
  554. package/dist-lib/plugins/run-report/flow.js +201 -0
  555. package/dist-lib/plugins/run-report/index.d.ts +17 -0
  556. package/dist-lib/plugins/run-report/index.js +27 -0
  557. package/dist-lib/plugins/run-report/layout.d.ts +39 -0
  558. package/dist-lib/plugins/run-report/layout.js +175 -0
  559. package/dist-lib/plugins/run-report/meaning.d.ts +6 -0
  560. package/dist-lib/plugins/run-report/meaning.js +43 -0
  561. package/dist-lib/plugins/run-report/model.d.ts +86 -0
  562. package/dist-lib/plugins/run-report/model.js +387 -0
  563. package/dist-lib/plugins/run-report/page.d.ts +13 -0
  564. package/dist-lib/plugins/run-report/page.js +234 -0
  565. package/dist-lib/plugins/run-report/script.d.ts +1 -0
  566. package/dist-lib/plugins/run-report/script.js +661 -0
  567. package/dist-lib/plugins/run-report/story.d.ts +48 -0
  568. package/dist-lib/plugins/run-report/story.js +188 -0
  569. package/dist-lib/plugins/run-report/style.d.ts +1 -0
  570. package/dist-lib/plugins/run-report/style.js +410 -0
  571. package/dist-lib/plugins/run-report/why.d.ts +28 -0
  572. package/dist-lib/plugins/run-report/why.js +170 -0
  573. package/dist-lib/plugins/sandbox-macos/index.d.ts +48 -0
  574. package/dist-lib/plugins/sandbox-macos/index.js +175 -0
  575. package/dist-lib/plugins/sandbox-vm/index.d.ts +24 -0
  576. package/dist-lib/plugins/sandbox-vm/index.js +27 -0
  577. package/dist-lib/plugins/sandbox-vm/vm-shell.d.ts +46 -0
  578. package/dist-lib/plugins/sandbox-vm/vm-shell.js +106 -0
  579. package/dist-lib/{lib → plugins/speech}/audio-transcode-bare.js +2 -2
  580. package/dist-lib/plugins/speech/index.d.ts +17 -0
  581. package/dist-lib/plugins/speech/index.js +24 -0
  582. package/dist-lib/plugins/speech/speech-engine.d.ts +23 -0
  583. package/dist-lib/plugins/speech/speech-engine.js +55 -0
  584. package/dist-lib/plugins/speech/speech-runtime.d.ts +22 -0
  585. package/dist-lib/plugins/speech/speech-runtime.js +212 -0
  586. package/dist-lib/{lib/capabilities → plugins/speech}/speech-text.d.ts +1 -0
  587. package/dist-lib/{lib/capabilities → plugins/speech}/speech-text.js +10 -3
  588. package/dist-lib/plugins/speech/voice-lane.d.ts +2 -0
  589. package/dist-lib/plugins/speech/voice-lane.js +9 -0
  590. package/dist-lib/plugins/speech/voice.d.ts +17 -0
  591. package/dist-lib/{lib/capabilities → plugins/speech}/voice.js +27 -25
  592. package/dist-lib/plugins/translation/index.d.ts +22 -0
  593. package/dist-lib/plugins/translation/index.js +63 -0
  594. package/dist-lib/{lib/models → plugins/translation}/nmt-catalog.d.ts +0 -1
  595. package/dist-lib/{lib/models → plugins/translation}/nmt-catalog.js +0 -3
  596. package/dist-lib/{lib/tools → plugins/translation}/translate.d.ts +14 -6
  597. package/dist-lib/{lib/tools → plugins/translation}/translate.js +14 -8
  598. package/dist-lib/plugins/walkie-talkie/crew.d.ts +27 -0
  599. package/dist-lib/plugins/walkie-talkie/crew.js +103 -0
  600. package/dist-lib/plugins/walkie-talkie/index.d.ts +127 -0
  601. package/dist-lib/plugins/walkie-talkie/index.js +340 -0
  602. package/dist-lib/plugins/walkie-talkie/wire.d.ts +67 -0
  603. package/dist-lib/plugins/walkie-talkie/wire.js +136 -0
  604. package/dist-lib/plugins/weather/geocode.d.ts +25 -0
  605. package/dist-lib/plugins/weather/geocode.js +101 -0
  606. package/dist-lib/plugins/weather/index.d.ts +15 -0
  607. package/dist-lib/plugins/weather/index.js +17 -0
  608. package/dist-lib/plugins/weather/lookup.d.ts +6 -0
  609. package/dist-lib/plugins/weather/lookup.js +169 -0
  610. package/dist-lib/{lib/tools/weather-lookup → plugins/weather}/place.js +5 -1
  611. package/dist-lib/plugins/web-search/engine-registry.d.ts +44 -0
  612. package/dist-lib/plugins/web-search/engine-registry.js +17 -0
  613. package/dist-lib/{lib → plugins}/web-search/engines/aol.d.ts +1 -0
  614. package/dist-lib/{lib → plugins}/web-search/engines/aol.js +5 -3
  615. package/dist-lib/{lib → plugins}/web-search/engines/bing.d.ts +1 -0
  616. package/dist-lib/{lib → plugins}/web-search/engines/bing.js +9 -4
  617. package/dist-lib/{lib → plugins}/web-search/engines/brave.d.ts +1 -0
  618. package/dist-lib/{lib → plugins}/web-search/engines/brave.js +5 -3
  619. package/dist-lib/{lib → plugins}/web-search/engines/duckduckgo.d.ts +1 -0
  620. package/dist-lib/{lib → plugins}/web-search/engines/duckduckgo.js +5 -2
  621. package/dist-lib/{lib → plugins}/web-search/engines/google.d.ts +1 -0
  622. package/dist-lib/{lib → plugins}/web-search/engines/google.js +6 -4
  623. package/dist-lib/{lib → plugins}/web-search/engines/wikipedia.d.ts +1 -0
  624. package/dist-lib/{lib → plugins}/web-search/engines/wikipedia.js +5 -3
  625. package/dist-lib/{lib → plugins}/web-search/engines/yahoo.d.ts +1 -0
  626. package/dist-lib/{lib → plugins}/web-search/engines/yahoo.js +5 -3
  627. package/dist-lib/{lib → plugins}/web-search/fetch-html.js +1 -1
  628. package/dist-lib/plugins/web-search/index.d.ts +18 -0
  629. package/dist-lib/plugins/web-search/index.js +33 -0
  630. package/dist-lib/{lib → plugins}/web-search/orchestrator.d.ts +3 -1
  631. package/dist-lib/{lib → plugins}/web-search/orchestrator.js +5 -5
  632. package/dist-lib/plugins/web-search/tool.d.ts +3 -0
  633. package/dist-lib/{lib/tools/web-search.js → plugins/web-search/tool.js} +18 -14
  634. package/dist-lib/plugins/web-search/types.js +1 -0
  635. package/dist-lib/schema/generate.js +5 -2
  636. package/dist-lib/schema/harness.js +158 -7
  637. package/dist-lib/spec/bind.js +20 -4
  638. package/dist-lib/spec/calls.js +4 -0
  639. package/dist-lib/spec/hrpc/hrpc.json +52 -0
  640. package/dist-lib/spec/hrpc/index.js +51 -3
  641. package/dist-lib/spec/hrpc/messages.js +595 -17
  642. package/dist-lib/spec/hyperschema/index.js +595 -17
  643. package/dist-lib/spec/hyperschema/schema.json +464 -1
  644. package/dist-lib/spec/hyperschema/types.d.ts +113 -2
  645. package/package.json +261 -484
  646. package/patches/{@qvac%2Finference@0.20.0.patch → @qvac%2Finference@0.21.0.patch} +8 -8
  647. package/scripts/addon-externals.cjs +386 -0
  648. package/scripts/addon-externals.d.ts +30 -0
  649. package/wheels/manifest.json +1 -160
  650. package/worker/harness-sidecar.mjs +80 -59
  651. package/dist-lib/lib/capabilities/completion-engine/actors/inspect-preload.d.ts +0 -3
  652. package/dist-lib/lib/capabilities/completion-engine/actors/inspect-preload.js +0 -75
  653. package/dist-lib/lib/capabilities/completion-engine/actors/preload-failure.d.ts +0 -9
  654. package/dist-lib/lib/capabilities/completion-engine/actors/preload-failure.js +0 -11
  655. package/dist-lib/lib/capabilities/completion-engine/actors/preloading.d.ts +0 -3
  656. package/dist-lib/lib/capabilities/completion-engine/actors/preloading.js +0 -114
  657. package/dist-lib/lib/capabilities/completion-loop/index.d.ts +0 -80
  658. package/dist-lib/lib/capabilities/completion-loop/index.js +0 -158
  659. package/dist-lib/lib/capabilities/completion-loop/metrics.d.ts +0 -5
  660. package/dist-lib/lib/capabilities/completion-loop/metrics.js +0 -29
  661. package/dist-lib/lib/capabilities/completion-loop/tool-execution.d.ts +0 -60
  662. package/dist-lib/lib/capabilities/completion-loop/turns.js +0 -112
  663. package/dist-lib/lib/capabilities/completion-runtime.d.ts +0 -46
  664. package/dist-lib/lib/capabilities/completion.d.ts +0 -18
  665. package/dist-lib/lib/capabilities/completion.js +0 -22
  666. package/dist-lib/lib/helpers/recovery-required.d.ts +0 -1
  667. package/dist-lib/lib/helpers/recovery-required.js +0 -1
  668. package/dist-lib/lib/hooks/built-in/index.d.ts +0 -4
  669. package/dist-lib/lib/hooks/built-in/index.js +0 -4
  670. package/dist-lib/lib/hooks/pipeline.d.ts +0 -24
  671. package/dist-lib/lib/hooks/pipeline.js +0 -74
  672. package/dist-lib/lib/hooks/registry.d.ts +0 -2
  673. package/dist-lib/lib/hooks/registry.js +0 -7
  674. package/dist-lib/lib/machine/completion/actions/skills.d.ts +0 -9
  675. package/dist-lib/lib/machine/completion/actions/skills.js +0 -83
  676. package/dist-lib/lib/machine/engine.d.ts +0 -93
  677. package/dist-lib/lib/machine/guards.d.ts +0 -2
  678. package/dist-lib/lib/machine/guards.js +0 -6
  679. package/dist-lib/lib/office/pptx.d.ts +0 -1
  680. package/dist-lib/lib/office/pptx.js +0 -26
  681. package/dist-lib/lib/office/python.d.ts +0 -8
  682. package/dist-lib/lib/office/python.js +0 -32
  683. package/dist-lib/lib/office/xlsx.d.ts +0 -1
  684. package/dist-lib/lib/office/xlsx.js +0 -26
  685. package/dist-lib/lib/run-log-inspect.d.ts +0 -25
  686. package/dist-lib/lib/run-log-protocol.d.ts +0 -2
  687. package/dist-lib/lib/run-log-protocol.js +0 -1
  688. package/dist-lib/lib/tool-call-display.d.ts +0 -1
  689. package/dist-lib/lib/tools/exec/adapters/adapter.d.ts +0 -31
  690. package/dist-lib/lib/tools/exec/adapters/python/create-effect.d.ts +0 -7
  691. package/dist-lib/lib/tools/exec/adapters/python/create-effect.js +0 -318
  692. package/dist-lib/lib/tools/exec/adapters/python/python-adapter.d.ts +0 -89
  693. package/dist-lib/lib/tools/exec/adapters/python/python-adapter.js +0 -1371
  694. package/dist-lib/lib/tools/exec/adapters/python/worker/entry.js +0 -3
  695. package/dist-lib/lib/tools/exec/obsidian/route.d.ts +0 -17
  696. package/dist-lib/lib/tools/exec/obsidian/route.js +0 -91
  697. package/dist-lib/lib/tools/mcp-call.d.ts +0 -14
  698. package/dist-lib/lib/tools/rag-search.d.ts +0 -2
  699. package/dist-lib/lib/tools/rag-search.js +0 -105
  700. package/dist-lib/lib/tools/weather-lookup.d.ts +0 -8
  701. package/dist-lib/lib/tools/weather-lookup.js +0 -122
  702. package/dist-lib/lib/tools/web-search.d.ts +0 -6
  703. package/dist-lib/lib/web-search/engine-registry.d.ts +0 -7
  704. package/dist-lib/lib/web-search/engine-registry.js +0 -17
  705. package/wheels/cffi-2.0.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl +0 -0
  706. package/wheels/cryptography-47.0.0-cp314-abi3-pyemscripten_2026_0_wasm32.whl +0 -0
  707. package/wheels/defusedxml-0.7.1-py2.py3-none-any.whl +0 -0
  708. package/wheels/et_xmlfile-2.0.0-py3-none-any.whl +0 -0
  709. package/wheels/fonttools-4.62.1-py3-none-any.whl +0 -0
  710. package/wheels/fpdf2-2.8.8-py3-none-any.whl +0 -0
  711. package/wheels/lxml-6.0.2-cp314-cp314-pyemscripten_2026_0_wasm32.whl +0 -0
  712. package/wheels/openpyxl-3.1.5-py2.py3-none-any.whl +0 -0
  713. package/wheels/pillow-12.2.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl +0 -0
  714. package/wheels/pycparser-3.0-py3-none-any.whl +0 -0
  715. package/wheels/pypdf-6.15.0-py3-none-any.whl +0 -0
  716. package/wheels/python_docx-1.2.0-py3-none-any.whl +0 -0
  717. package/wheels/python_pptx-1.0.2-py3-none-any.whl +0 -0
  718. package/wheels/six-1.17.0-py2.py3-none-any.whl +0 -0
  719. package/wheels/typing_extensions-4.15.0-py3-none-any.whl +0 -0
  720. package/wheels/xlsxwriter-3.2.9-py3-none-any.whl +0 -0
  721. /package/dist-lib/lib/{tools/skills → agent}/tool-grants.d.ts +0 -0
  722. /package/dist-lib/lib/{tools/skills → agent}/tool-grants.js +0 -0
  723. /package/dist-lib/lib/capabilities/{types.js → completion-engine/prepare-step.js} +0 -0
  724. /package/dist-lib/lib/{hooks/types.js → capabilities/completion-engine/stages.js} +0 -0
  725. /package/dist-lib/lib/{tool-call-display.js → contract/agent.js} +0 -0
  726. /package/dist-lib/lib/{tools/exec/adapters/adapter.js → contract/completion.js} +0 -0
  727. /package/dist-lib/lib/{tools/exec/adapters/python/worker/entry.d.ts → contract/exec.js} +0 -0
  728. /package/dist-lib/lib/{tools/exec/adapters/python/worker/interrupt-deadline.d.ts → contract/hooks.js} +0 -0
  729. /package/dist-lib/lib/{web-search/types.js → contract/index.js} +0 -0
  730. /package/dist-lib/lib/{capabilities/completion-engine → helpers}/abort-polyfill.d.ts +0 -0
  731. /package/dist-lib/lib/{capabilities/completion-engine → helpers}/abort-polyfill.js +0 -0
  732. /package/dist-lib/lib/{web-search → helpers}/html-helpers.d.ts +0 -0
  733. /package/dist-lib/lib/{web-search → helpers}/html-helpers.js +0 -0
  734. /package/dist-lib/lib/{tools → helpers}/model-args.d.ts +0 -0
  735. /package/dist-lib/lib/{tools → helpers}/model-args.js +0 -0
  736. /package/dist-lib/lib/{machine → helpers}/stable-stringify.d.ts +0 -0
  737. /package/dist-lib/lib/{web-search → helpers}/user-agents.d.ts +0 -0
  738. /package/dist-lib/lib/{web-search → helpers}/user-agents.js +0 -0
  739. /package/dist-lib/lib/{harness-lifecycle.d.ts → lifecycle/machine.d.ts} +0 -0
  740. /package/dist-lib/lib/tools/{exec/adapters/python → attachments}/output-policy.js +0 -0
  741. /package/dist-lib/{lib/tools/exec → plugins}/obsidian/command.d.ts +0 -0
  742. /package/dist-lib/{lib/tools/exec → plugins}/obsidian/note-name.d.ts +0 -0
  743. /package/dist-lib/{lib/tools/exec → plugins}/obsidian/note-name.js +0 -0
  744. /package/dist-lib/{lib/tools/exec → plugins}/obsidian/output.d.ts +0 -0
  745. /package/dist-lib/{lib/tools/exec → plugins}/obsidian/output.js +0 -0
  746. /package/dist-lib/{lib/tools/exec → plugins}/obsidian/safe-path.d.ts +0 -0
  747. /package/dist-lib/{lib/tools/exec → plugins}/obsidian/safe-path.js +0 -0
  748. /package/dist-lib/{lib/tools/exec → plugins}/obsidian/vault-create.d.ts +0 -0
  749. /package/dist-lib/{lib/tools/exec → plugins}/obsidian/vault-create.js +0 -0
  750. /package/dist-lib/{lib/tools/exec → plugins}/obsidian/vault-fs.d.ts +0 -0
  751. /package/dist-lib/{lib/tools/exec → plugins}/obsidian/vault-fs.js +0 -0
  752. /package/dist-lib/{lib/tools/exec → plugins}/obsidian/vault-paths.d.ts +0 -0
  753. /package/dist-lib/{lib/tools/exec → plugins}/obsidian/vault-paths.js +0 -0
  754. /package/dist-lib/{lib/tools/exec → plugins}/obsidian/vault-read.d.ts +0 -0
  755. /package/dist-lib/{lib/tools/exec → plugins}/obsidian/vault-read.js +0 -0
  756. /package/dist-lib/{lib/tools/exec → plugins}/obsidian/vault-write.d.ts +0 -0
  757. /package/dist-lib/{lib/tools/exec → plugins}/obsidian/vault-write.js +0 -0
  758. /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/deadline-state.d.ts +0 -0
  759. /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/deadline-state.js +0 -0
  760. /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/distributions.d.ts +0 -0
  761. /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/distributions.js +0 -0
  762. /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/interrupt-timer.d.ts +0 -0
  763. /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/memfs.d.ts +0 -0
  764. /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/module-distributions.d.ts +0 -0
  765. /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/named-hosts.d.ts +0 -0
  766. /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/named-hosts.js +0 -0
  767. /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/net-shim.d.ts +0 -0
  768. /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/net-shim.js +0 -0
  769. /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/pyodide.d.ts +0 -0
  770. /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/wheels.d.ts +0 -0
  771. /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/worker/active.d.ts +0 -0
  772. /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/worker/protocol.d.ts +0 -0
  773. /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/worker/protocol.js +0 -0
  774. /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/worker/serve.d.ts +0 -0
  775. /package/dist-lib/{lib/capabilities → plugins/speech}/audio-resample.d.ts +0 -0
  776. /package/dist-lib/{lib/capabilities → plugins/speech}/audio-resample.js +0 -0
  777. /package/dist-lib/{lib → plugins/speech}/audio-transcode-bare.d.ts +0 -0
  778. /package/dist-lib/{lib → plugins/speech}/audio-transcode-node.d.ts +0 -0
  779. /package/dist-lib/{lib → plugins/speech}/audio-transcode-node.js +0 -0
  780. /package/dist-lib/{lib/capabilities → plugins/speech}/speech-lexicon.d.ts +0 -0
  781. /package/dist-lib/{lib/capabilities → plugins/speech}/speech-lexicon.js +0 -0
  782. /package/dist-lib/{lib → plugins/speech}/wav-encode.d.ts +0 -0
  783. /package/dist-lib/{lib → plugins/speech}/wav-encode.js +0 -0
  784. /package/dist-lib/{lib/tools/weather-lookup → plugins/weather}/place.d.ts +0 -0
  785. /package/dist-lib/{lib/tools/weather-lookup → plugins/weather}/report.d.ts +0 -0
  786. /package/dist-lib/{lib/tools/weather-lookup → plugins/weather}/report.js +0 -0
  787. /package/dist-lib/{lib → plugins}/web-search/fetch-html.d.ts +0 -0
  788. /package/dist-lib/{lib → plugins}/web-search/format-results.d.ts +0 -0
  789. /package/dist-lib/{lib → plugins}/web-search/format-results.js +0 -0
  790. /package/dist-lib/{lib → plugins}/web-search/merge-results.d.ts +0 -0
  791. /package/dist-lib/{lib → plugins}/web-search/merge-results.js +0 -0
  792. /package/dist-lib/{lib → plugins}/web-search/types.d.ts +0 -0
  793. /package/dist-lib/{lib → plugins}/web-search/url-helpers.d.ts +0 -0
  794. /package/dist-lib/{lib → plugins}/web-search/url-helpers.js +0 -0
  795. /package/dist-lib/{lib → plugins}/web-search/url-normalize.d.ts +0 -0
  796. /package/dist-lib/{lib → plugins}/web-search/url-normalize.js +0 -0
package/README.md CHANGED
@@ -1,542 +1,349 @@
1
- # @qvac/harness
1
+ <p align="center">
2
+ <img src="docs/assets/ducks.png" alt="" width="200">
3
+ </p>
4
+
5
+ <h1 align="center">@qvac/harness</h1>
6
+
7
+ <p align="center">
8
+ <b>The agent harness for local models</b>
9
+ <br>
10
+ Tools, agents, sandboxes and resumable runs on your own device
11
+ </p>
12
+
13
+ <p align="center">
14
+ on-device GGUF models &middot; Bare and Node &middot; agents that hand off and delegate &middot;
15
+ parallel tools and runs &middot; sandboxed exec &middot; crash-proof sidecar &middot;
16
+ resume after process death
17
+ </p>
18
+
19
+ <p align="center">
20
+ <a href="#how-it-works">How it works</a> &middot;
21
+ <a href="#features">Features</a> &middot;
22
+ <a href="#plugins">Plugins</a> &middot;
23
+ <a href="#examples">Examples</a> &middot;
24
+ <a href="#host-it">Host it</a> &middot;
25
+ <a href="#development">Development</a>
26
+ </p>
2
27
 
3
- The QV.AC inference engine: `generate(context)` over the QVAC SDK — completions,
4
- embeddings, transcription, image and music generation — plus the tool runtime
5
- skills execute in (Python via Pyodide, web search/fetch, MCP, filesystem). It
6
- knows nothing about the app, hyperdb or sync: inference in, events out.
7
-
8
- It runs as a supervised child process (or Bare thread on mobile) that a host
9
- spawns and talks to over hrpc — crash isolation for free, death is the exit
10
- itself. See [bare-supervisor](https://github.com/tetherto/bare-supervisor) for
11
- the supervision contract.
12
-
13
- ## The published package
28
+ ```sh
29
+ npm i @qvac/harness
30
+ ```
14
31
 
15
- The published package ships the library and its runtime content, not a prebuilt
16
- engine:
32
+ ```ts
33
+ import { Harness, QWEN_35_2B } from '@qvac/harness'
17
34
 
18
- - `dist-lib/` — the compiled library and its declarations. The package exports
19
- resolve to it; the TypeScript source stays in the repository.
20
- - `worker/harness-sidecar.mjs` — the sidecar entry a host stows into its own
21
- bundle, and `worker/stow-entry.mjs`, the same entry as a plain file for a
22
- host that spawns it straight from its install
23
- - the hash-pinned Python `wheels/` the tool runtime consumes (skills come from
24
- [`@qvac/skills`](https://github.com/tetherto/qvac-skills), a content-addressed
25
- bundle this package materializes at runtime)
35
+ const harness = new Harness()
36
+ const messages = [{ role: 'user', content: 'Reply with one word: hi' }]
37
+ for await (const event of harness.completion({ model: QWEN_35_2B, messages })) {
38
+ if (event.type === 'content') {
39
+ process.stdout.write(event.text)
40
+ }
41
+ }
26
42
 
27
- A host that stows the harness defers the `@qvac` inference addons
28
- (`scripts/addon-externals.cjs` lists them), so they resolve from real files
29
- beside the bundle, and ships everything stow offloads there: prebuilds, and
30
- pyodide's data and the wheels, which the harness names as assets. A target that
31
- embeds assets instead cannot run python.
43
+ await harness.close()
44
+ ```
32
45
 
33
- ## Spawning
46
+ That is the whole API surface for a chat: **context in, events out.** The model is a GGUF that the
47
+ QVAC SDK runs on this device: no server and no API key, and the prompt never leaves it.
34
48
 
35
- `spawnHarness` spawns an entry as a bare-sidecar process and hands back a
36
- client over hrpc:
49
+ ## How it works
37
50
 
38
- ```js
39
- import { spawnHarness } from '@qvac/harness'
40
-
41
- const harness = spawnHarness({ entry, sdkStorage })
51
+ ```
52
+ your app @qvac/harness (in process, a child process, or a Bare thread)
53
+ ┌────────────┐ completion(context) ┌──────────────────────────────────────────────────────────┐
54
+ │ │ ───────────────────► │ agent ──► prompt ──► model (QVAC SDK, llama.cpp) │
55
+ │ UI │ │ ▲ │ tool calls │
56
+ │ │ ◄─────────────────── │ │ ▼ │
57
+ │ approve() │ content, tool-call │ │ guards ──► approve? ──► tools, plugins, agents │
58
+ └────────────┘ transfer, metrics │ └────────── results ◄───────────┘ (one round) │
59
+ └──────────────────────────────────────────────────────────┘
42
60
  ```
43
61
 
44
- `entry` is the host's own stowed bundle, or `@qvac/harness/worker/stow-entry.mjs`
45
- resolved from its install. The argv slots the entry reads (skills dir, sdk
46
- storage, model config, wheels dir, ...) are the ones
47
- `worker/harness-sidecar.mjs` documents; `harnessChild` does the same under
48
- bare-supervisor.
62
+ A completion is a loop of **rounds**. In each round the model answers or calls tools. Every call is
63
+ checked against its schema and the run's grants, sorted into a read or a write, sent to your
64
+ `approve` if it writes, then run, and its result goes back to the model. The run ends when the model
65
+ answers, a budget runs out, or it hands the conversation to another agent.
49
66
 
50
- ## Custom models
67
+ The loop is a state machine (`lib/machine/`), and every step is journaled. So a run can pause for
68
+ approval, survive the process dying, and pick up where it stopped. `bun run resume` kills a run at
69
+ its approval and resumes it; see [The loop is a state machine](examples/README.md#the-loop-is-a-state-machine).
51
70
 
52
- A host can let its users add a GGUF the catalog does not carry: a Hugging Face
53
- link, a direct link to a `.gguf` file, or a local path. The harness checks the
54
- source, runs it by the name the host registers it under, lists it next to the
55
- catalog and deletes what it downloaded. Which custom models a device has is the
56
- host's state; the harness keeps only the set it was last given.
71
+ **Built for small models.** A 2B model makes mistakes a cloud model does not. The harness repairs
72
+ broken tool-call markup, coerces arguments to their schema, re-asks when the model describes a call
73
+ instead of making it, trims long tool output and spills the rest to a file the model can read, and
74
+ folds old turns into a summary when the context fills. The KV cache is reused across rounds and
75
+ runs, so a long chat does not prefill its whole history again.
57
76
 
58
- The calls below are on the client `spawnHarness` returns (a `RemoteHarness`) and
59
- on an in-process `Harness` alike.
77
+ ## Features
60
78
 
61
- ### Preview a source before adding it
79
+ ### Tools you control
62
80
 
63
- `previewModelSource` reads the source's Hugging Face metadata and the first
64
- megabyte of the file. It never downloads the model.
81
+ A tool is a plain object. You decide what is a read and what is a write; writes go through `approve`.
65
82
 
66
- ```js
67
- const preview = await harness.previewModelSource({
68
- src: 'https://huggingface.co/bartowski/Nanbeige_Nanbeige4.2-3B-GGUF/resolve/main/Nanbeige_Nanbeige4.2-3B-IQ2_M.gguf',
69
- mmprojSrc: undefined // a vision model's projection, checked with it
70
- })
83
+ ```ts
84
+ const stock: ToolDefinition = {
85
+ name: 'stock',
86
+ description: 'Units in stock for one SKU',
87
+ toolset: null,
88
+ parameters: { type: 'object', properties: { sku: { type: 'string' } }, required: ['sku'] },
89
+ effect: () => 'read',
90
+ // reads marked concurrent run side by side in one round
91
+ concurrent: true,
92
+ execute: (args) => Promise.resolve({ content: String(inventory[String(args.sku)] ?? 0) })
93
+ }
71
94
 
72
- // {
73
- // ok: true,
74
- // src: 'https://huggingface.co/.../Nanbeige_Nanbeige4.2-3B-IQ2_M.gguf',
75
- // sizeBytes: 1868506272,
76
- // contextLength: 262144,
77
- // architecture: 'nanbeige',
78
- // sizeLabel: '3B',
79
- // taskType: 'llm',
80
- // license: 'apache-2.0',
81
- // fit: 'unknown',
82
- // fitReasons: ['...why the fit is unknown']
83
- // }
95
+ harness.completion({ model, messages, tools: [stock], approve: (call) => askTheUser(call) })
84
96
  ```
85
97
 
86
- A preview is one of three answers:
87
-
88
- - **A file**: `ok: true` with `src`, the download link to register. A Hugging
89
- Face page link is resolved to its `resolve/` url, and a direct link to one
90
- shard of a split model to its first part, sized as the whole set.
91
- - **A choice**: `ok: true` with `files: [{ src, label, sizeBytes }]` and no
92
- `src`, for a repo that holds several weights. Split shards are one entry and
93
- projections are left out. Preview the chosen `files[i].src` again.
94
- - **A refusal**: `ok: false` with `refusal` and a `reason` ready to show. The
95
- refusals are `invalid-source`, `not-found`, `private`, `gated`, `web-page`,
96
- `unreachable`, `not-gguf`, `not-a-model` (a projection or LoRA adapter),
97
- `no-model-files` and `invalid-projection`.
98
-
99
- ```js
100
- if (!preview.ok) return showError(preview.reason)
101
- if (!preview.src) return pickOneOf(preview.files)
102
- ```
98
+ Built-in tools read and edit files only inside folders you grant (`grantedDirs`,
99
+ `grantedWriteDirs`), and never inside the app's own storage. They also read, edit and create Word,
100
+ Excel, PowerPoint and PDF files on device, in TypeScript, with no Python and no cloud.
101
+
102
+ ### Large tool sets, on demand
103
103
 
104
- `taskType` says what the model does: `llm`, `embeddings`, `speech-to-text`,
105
- `text-to-speech` or `image-generation`. It comes from the Hugging Face pipeline
106
- tag, then the card's and the file's tags, then the architecture. The preview
107
- reports it for any model and refuses none for its task, so the host decides
108
- what may be added. Only an `llm` runs as a custom model today:
104
+ Mark a tool `defer: true` and the model sees only its name, grouped under `group`, until it calls
105
+ `tool_search` to load it. The loaded schema is appended to the history, so the prompt prefix stays
106
+ cached; an MCP server takes `defer: true` for all its tools. A 2B with fifty tools no longer reads
107
+ fifty schemas every round.
109
108
 
110
- ```js
111
- if (preview.taskType !== 'llm') {
112
- return showError(`This is a ${preview.taskType} model. Custom models run as the text model only.`)
109
+ ```ts
110
+ const lookup: ToolDefinition = {
111
+ ...stock,
112
+ name: 'warehouse_lookup',
113
+ defer: true,
114
+ group: 'warehouse'
113
115
  }
114
116
  ```
115
117
 
116
- `fit` is `likely-fits`, `likely-too-large` or `unknown`, and `fitReasons` says
117
- why. It comes only from the SDK, for a file whose sha256 its catalog knows, so
118
- most custom files are `unknown`. It is never a reason to refuse.
119
-
120
- `sizeLabel` is the file's own `general.size_label` as written (`0.6B`, `3B`,
121
- `30B-A3B`), and is absent when the file records none.
118
+ ### Agents that hand off
122
119
 
123
- ### Register the set
120
+ An agent is a prompt, tools and skills, and may name its own `model`. Give it `handoffs` and it can
121
+ pass the conversation on: here a health question goes to an agent on MedPsy, a medical model. Each
122
+ hop is its own run, with its own `runId`, and emits a `transfer` event.
124
123
 
125
- `setCustomModels` replaces the whole set. Send it on start and whenever the
126
- host's store changes; the client sends the last set again after a reconnect.
127
-
128
- ```js
129
- await harness.setCustomModels([
130
- {
131
- name: 'nanbeige-3b',
132
- src: preview.src,
133
- projectionSrc: preview.mmprojSrc,
134
- taskType: preview.taskType, // 'llm'; an entry for another task is not registered
135
- expectedSize: preview.sizeBytes,
136
- label: 'Nanbeige 4.2 3B', // what the user calls it
137
- contextLength: preview.contextLength // the window it was trained on
124
+ ```ts
125
+ const triage = {
126
+ id: 'triage',
127
+ bio: 'You route each request to the right agent.',
128
+ handoffs: [
129
+ { id: 'office', description: 'Word, Excel and PDF documents' },
130
+ { id: 'health', description: 'Symptoms, medicines and wellbeing' }
131
+ ]
132
+ }
133
+ const agents = {
134
+ office: {
135
+ bio: 'You write and edit documents.',
136
+ handoffs: [{ id: 'triage', description: 'Anything that is not a document' }]
137
+ },
138
+ // a medical model of its own; the others run on the run's model
139
+ health: { model: MEDPSY_1_7B, bio: 'You answer health questions clearly.' },
140
+ triage
141
+ }
142
+ for await (const event of harness.completion({ model, agent: triage, agents, messages })) {
143
+ if (event.type === 'transfer') {
144
+ console.log(`${event.from} -> ${event.to}: ${event.reason}`)
145
+ } else {
146
+ render(event)
138
147
  }
139
- ])
140
- ```
141
-
142
- A registered name loads like a catalog model wherever an `llm` name is taken,
143
- and never resolves for another task. A missing `taskType` means `llm`.
144
- `expectedSize` is what `isCached` compares the downloaded files against.
145
- `label` is the name to show. The harness also reads the model family from it
146
- (Qwen, Gemma, LFM and so on) to pick the tool-call format, so a model whose id
147
- and file name don't carry the family still gets the right one.
148
- `contextLength` caps the context a custom model loads with by default, so a
149
- model trained on 40,960 tokens loads with 40,960 rather than the 51,200
150
- default. A context size the caller asks for still wins.
151
-
152
- ### List them
153
-
154
- `list` returns custom models after the catalog rows, under the same `type` and
155
- `cachedOnly` filters:
156
-
157
- ```js
158
- const models = await harness.list({ type: 'llm' })
159
- const custom = models.filter((model) => model.registrySource === 'custom')
160
-
161
- // {
162
- // name: 'nanbeige-3b',
163
- // type: 'llm',
164
- // registryPath: 'https://huggingface.co/.../Nanbeige_Nanbeige4.2-3B-IQ2_M.gguf',
165
- // registrySource: 'custom',
166
- // isCached: false,
167
- // isLoaded: false,
168
- // isLoading: false,
169
- // supportsImages: false,
170
- // expectedSize: 1868506272,
171
- // label: 'Nanbeige 4.2 3B',
172
- // taskType: 'llm'
173
- // }
148
+ }
174
149
  ```
175
150
 
176
- `registryPath` is the model's `src`, and `supportsImages` is true when it has a
177
- projection. `isCached` means every file is on disk and, when `expectedSize` is
178
- known, their sizes add up to it, so a partial download is not cached. A local
179
- path is checked where it is. A downloaded file is looked for at the path the SDK
180
- gives a single-file http download under the models cache dir, which the spawned
181
- sidecar knows from `sdkStorage.models`; an in-process `Harness` needs
182
- `new Harness({ modelsDir })` for it. A sharded download is looked for in the
183
- folder the SDK keeps its shards in, and is cached once every shard is there.
151
+ ### Agents as tools
184
152
 
185
- Every row, catalog or custom, carries `taskType`: what the model is for, in the
186
- vocabulary a preview uses, so a Models screen groups by task rather than by
187
- addon. `whisper` and `parakeet` are both `speech-to-text`, and an addon with no
188
- task of its own is `other`.
153
+ `delegate` lets an agent send several self-contained tasks to subagents and get every answer back.
154
+ They run on the same loaded model, as many at once as `delegateTool` is given `slots` and the
155
+ harness has. A subagent sees only its task, and cannot delegate or hand off.
189
156
 
190
- ### Delete a download
157
+ ```ts
158
+ import { Agent } from '@qvac/harness/agent'
191
159
 
192
- ```js
193
- const { removed, freedBytes } = await harness.deleteModel('nanbeige-3b')
160
+ const explorer = { id: 'explorer', bio: 'You answer one question about the code.' }
161
+ const base = { model, agent: explorer, messages: [], grantedDirs: [projectDir] }
162
+ const delegate = Agent.delegateTool(harness, base)
163
+ harness.completion({ model, messages, tools: [delegate], grantedDirs: [projectDir] })
194
164
  ```
195
165
 
196
- For a custom model this removes the weight and projection it downloaded,
197
- including every shard of a sharded one, and never a local path: those are the
198
- user's files. The model stays registered and
199
- lists as not cached, ready to download again. Like a catalog delete, it does not
200
- unload a model that is running.
201
-
202
- ### Load and unload a model
203
-
204
- ```js
205
- import { QWEN_35_4B } from '@qvac/harness'
166
+ ### Hand the hard parts to Claude Code
206
167
 
207
- const { loaded } = await harness.loadModel({ model: QWEN_35_4B, agent: { ctxSize: 8192 } })
208
- const row = (await harness.list({ cachedOnly: true })).find((model) => model.name === QWEN_35_4B)
209
- // row.isLoaded === true, and the next completion with the same agent reuses it
168
+ The same `delegate` tool can reach agents outside the harness: Claude Code, Codex, or anything that
169
+ speaks ACP. Each task runs in a fresh process in the run's granted folder, and asks your `approve`
170
+ first.
210
171
 
211
- const { unloaded } = await harness.unloadModel({ model: QWEN_35_4B })
172
+ ```ts
173
+ import { ExternalAgents } from '@qvac/harness/plugins/external-agents'
174
+
175
+ const targets = ExternalAgents.targets({
176
+ dir: agentsHome,
177
+ targets: [
178
+ {
179
+ name: 'claude',
180
+ description: 'Claude Code, for a hard change that needs a stronger model',
181
+ protocol: 'claude',
182
+ command: '/usr/local/bin/claude',
183
+ // your own Claude Code sign-in and settings; leave it out to run isolated on an API key
184
+ login: 'user'
185
+ }
186
+ ]
187
+ })
188
+ const delegate = Agent.delegateTool(harness, base, { targets })
212
189
  ```
213
190
 
214
- `loadModel` loads a downloaded model ahead of use, under the key a request for it
215
- would load under, so the first request does not load it again. Pass the agent a
216
- chat model will run for, since its context size and KV cache types are part of
217
- that key. Chat, embedding, speech and transcription models stay loaded; image and
218
- music models load for each generation and are refused.
219
-
220
- A chat model loaded this way is pinned. It does not count against
221
- `completionModelCap`, so several can be loaded at once, and a request loading
222
- another model leaves it in place. A request or a manual load for the same model
223
- under other settings replaces its idle copy rather than loading a second one. A
224
- manual load never unloads another model to fit: `{ loaded: false, reason: 'memory' }` means the
225
- SDK's `assessModelFit` estimate says it would not fit beside what is loaded, so
226
- unload one first. A request always gets its model, though: when that would not
227
- fit, pinned models no reply is using give way, oldest first. Image or music generation and an idle
228
- unload still clear every idle chat model, pinned or not.
229
-
230
- ```js
231
- const big = await harness.loadModel({ model: QWEN_36_27B, agent: { ctxSize: 262144 } })
232
- if (big.reason === 'memory') showNotice('Unload a model first')
233
- ```
191
+ ### Plans and goals
192
+
193
+ `plan: true` gives an agent `update_plan`, a checklist it sees after every round. A `goal` keeps the
194
+ run going until every step is done or a budget runs out. `planMode` refuses writes until the user
195
+ approves the plan.
234
196
 
235
- `unloadModel` waits for any request holding the model to finish, then unloads
236
- every copy of it. `unloaded` is false when a request still held it after the
237
- wait, so a caller that wants the model gone at once stops those requests first.
238
- Both change `isLoaded` in the next `list()`. `isLoading` is true on a row from
239
- the moment a load of its model starts, whoever asked for it (a request,
240
- `warmModel` or `loadModel`), until the model is ready or the load fails; it is
241
- read off the pool, so a host keeps no count of its own. A model loading again
242
- under other settings while a copy of it is resident reads `isLoaded: true` and
243
- `isLoading: true` at once. The `model` event carries `catalogChanged` at each
244
- edge a `list()` re-read would show: the `loading` that starts a load, the
245
- `ready` or `error` that ends it, and `unloaded`. Progress ticks between them do
246
- not. A load that ends without the model in memory reports
247
- `error` with the reason in `message`: it failed, or a suspend or close cancelled it.
248
- An image, music or translation model loads for each generation and never reads
249
- `isLoading: true`; a speech, transcription or embedding model loads under its
250
- source rather than its row name, so its row reads `false` for now. A load or an
251
- unload counts as a call in flight for
252
- [`setModelIdleTimeout`](#freeing-memory-when-idle), and one that lands during an
253
- idle unload waits for it, so a load never loads a second copy and an unload
254
- answers once the memory is free.
255
-
256
- `bun run model-residency` (`bare examples/model-residency/run.ts`, with
257
- `QVAC_MODEL_CACHE_PATH` pointing at the models) runs these calls against the
258
- models already on disk and prints what each step changed. It never downloads.
259
-
260
- ## Freeing memory when idle
261
-
262
- ```js
263
- await harness.setModelIdleTimeout(30 * 60_000)
197
+ ```ts
198
+ const agent = { id: 'lead', bio: 'You are the lead engineer.', plan: true }
199
+ harness.completion({ model, agent, messages, goal: { objective: 'All tests pass', rounds: 30 } })
264
200
  ```
265
201
 
266
- Once no call has been in flight for that long, every idle resident model is
267
- unloaded, and the next call loads what it needs again. The clock covers the
268
- whole device: any call resets it, whichever model it uses. `0`, the default, is
269
- Never.
202
+ ### Steer a run while it works
270
203
 
271
- ## Office extraction
204
+ Send turns into a running completion. A steer lands at the next tool boundary; a follow-up continues
205
+ the run after its answer.
272
206
 
273
- Hosts can supply the bundled Python extractor to their document pipeline:
207
+ ```ts
208
+ async function* input() {
209
+ yield { mode: 'steer' as const, text: 'Use the v2 endpoint instead' }
210
+ }
211
+ harness.completion({ model, messages, input: input() })
212
+ ```
274
213
 
275
- Set `QVAC_PYODIDE_CACHE_DIR` to a writable directory before calling the API,
276
- including from source and compiled-package consumers. The worker seeds this
277
- cache from shipped wheels; without it, Pyodide can try downloading packages.
214
+ ### Parallel
278
215
 
279
- ```js
280
- import { extractOfficeText, closeOfficeWorker } from '@qvac/harness/office'
216
+ Concurrent reads in one round run side by side. `slots` lets one loaded model decode several
217
+ completions at once, each with its own context: on the 2B, four requests at `slots: 4` decode about
218
+ 30% more tokens a second in all, and each starts in about 0.2 s instead of queueing for 2 s.
281
219
 
282
- const text = await extractOfficeText(bytes, 'report.xlsx', { signal, mimeType })
283
- // At host shutdown, after outstanding extractions have settled:
284
- await closeOfficeWorker()
220
+ ```ts
221
+ const harness = new Harness({ slots: 2 })
222
+ const [a, b] = await Promise.all([ask(harness, 'Summarize A'), ask(harness, 'Summarize B')])
285
223
  ```
286
224
 
287
- DOCX preserves paragraph and table order. XLSX includes sheet names, nonempty rows,
288
- cached formula results and formula text when no cached result exists. PPTX includes
289
- slide text, grouped shapes and tables in slide order; speaker notes, images and charts
290
- are not extracted. Legacy XLS/PPT formats are unsupported. File extensions select the
291
- format, with `mimeType` as a fallback when the name has no recognized Office extension.
225
+ ### Sandboxed code
292
226
 
293
- The extractor accepts up to 20 MiB and requires the shipped Python wheels. With the
294
- cache configured, extraction uses those wheels offline. A host that stows the harness ships them
295
- with what stow offloads beside the bundle; `QVAC_PYTHON_WHEELS_DIR` names another directory.
296
- Source checkouts prepare wheels with `bun run vendor:wheels`.
227
+ `exec: true` gives the model a shell, and plugins decide where it runs: under macOS Seatbelt, in a
228
+ VM, or as JavaScript in QuickJS with no files or network. Python runs in Pyodide. For real coding
229
+ work, `CodingPlugin` adds a shell that keeps its place, background jobs and `write_file`, run
230
+ inside Seatbelt on macOS.
297
231
 
298
- The existing `extractDocxText` and `closeDocxWorker` exports from `@qvac/harness/docx`
299
- remain available. Both entry points share the same Python worker and cache.
232
+ ```ts
233
+ const harness = new Harness({
234
+ exec: true,
235
+ plugins: [new SeatbeltSandbox({ preset: 'workspace-write', network: false }), new QuickJs()]
236
+ })
237
+ ```
300
238
 
301
- ## Development
239
+ ### Runs that survive a crash
240
+
241
+ Spawned with `spawnHarness`, the harness runs as a supervised child process, so a llama.cpp crash
242
+ kills the AI and never the app. Every step of a run is journaled; after the process dies, send the
243
+ same `runId` with `resume: true` and the run carries on. See [Resuming a completion](docs/resuming.md).
244
+
245
+ ### Know how fast it is
246
+
247
+ Every completion ends with a `metrics` event: prefill and decode tokens per second, time to first
248
+ token, per round and per run. Each loaded model reports the engine's own fit verdict and its device
249
+ and host bytes in `diagnostics().models`. See [Speed stats](docs/speed-stats.md). Accuracy is measured on real
250
+ benchmarks (BFCL, τ²-bench, Terminal-Bench) in [examples/bench](examples/bench/README.md).
251
+
252
+ ## Plugins
253
+
254
+ A plugin is an instance you pass in `plugins`. Its options are its constructor's argument, and the
255
+ host grants its reads there too: `new Weather({ read: ['weather_lookup'] })`. A plugin never grants
256
+ itself.
257
+
258
+ | Plugin | Adds |
259
+ | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
260
+ | [`ExternalAgents`](plugins/external-agents/README.md) | Claude Code, Codex or any ACP agent as a `delegate` target |
261
+ | [`WalkieTalkie`](plugins/walkie-talkie/README.md) | Two-way comms with agents and people on other machines, over Hyperswarm |
262
+ | [`RunReport`](plugins/run-report/README.md) | A run as a flowchart played back step by step, with why; records through `onStep`, not `plugins` |
263
+ | [`CodingPlugin`](plugins/coding/README.md) | A shell that keeps its place, background jobs, `write_file` |
264
+ | [`LspPlugin`](plugins/lsp/README.md) | Definitions, references, symbols and diagnostics from language servers |
265
+ | [`McpPlugin`](plugins/mcp/README.md) | The tools of any HTTP MCP server |
266
+ | [`CodeMode`](plugins/code-mode/README.md) | `run_code`: a script that calls the other tools |
267
+ | [`QuickJs`](plugins/quickjs/README.md) | JavaScript for `exec`, with no files or network |
268
+ | [`Python`](plugins/python/README.md) | Python for `exec`, in Pyodide |
269
+ | [`SeatbeltSandbox`](plugins/sandbox-macos/README.md) | `exec`'s shell under macOS `sandbox-exec` |
270
+ | [`VmShell`](plugins/sandbox-vm/README.md) | `exec`'s shell in a VM with no network or disk |
271
+ | [`CommandHooks`](plugins/command-hooks/README.md) | The command hooks of a Claude Code `settings.json` |
272
+ | [`Knowledge`](plugins/knowledge/README.md) | Search over the user's documents |
273
+ | [`WebSearchPlugin`](plugins/web-search/README.md) | Web search across several engines |
274
+ | [`Speech`](plugins/speech/README.md) | Transcription, text to speech, and MOSS voice cloning and dialogue |
275
+ | [`Image`](plugins/image/README.md) | Image generation and editing |
276
+ | [`Music`](plugins/music/README.md) | Music generation |
277
+ | [`TranslationPlugin`](plugins/translation/README.md) | Translation on device |
278
+ | [`Weather`](plugins/weather/README.md) | Weather lookup |
279
+ | [`ObsidianRoute`](plugins/obsidian/README.md) | `obsidian …` commands against a vault |
280
+
281
+ Each plugin is imported from `@qvac/harness/plugins/<folder>`. Writing your own takes one object:
302
282
 
303
- ```
304
- bun install
305
- bun run lint # prettier + lunte + tsc
306
- bun run test # brittle, node and bare lanes
307
- bun run build:schema # regenerates spec/ (wire-compat rewind once v* tags exist)
308
- bun run build:bundle # stows the sidecar entry into dist/, to prove it still stows
309
- ```
283
+ ```ts
284
+ import { Harness, PLUGIN_API_VERSION, type HarnessPlugin } from '@qvac/harness'
310
285
 
311
- ## Engine layout
286
+ const clock: HarnessPlugin = {
287
+ name: 'clock',
288
+ api: PLUGIN_API_VERSION,
289
+ setup: () => ({ tools: [timeTool] })
290
+ }
312
291
 
313
- `lib/machine/` contains `completion/**`, `engine.ts`, `errors.ts`, `index.ts`, `replay-output.ts`,
314
- `stable-stringify.ts`, and `guards.ts`. The run-log layer is in `lib/run-log/`:
315
- `protocol.ts`, `protocol-types.ts`, `history-codec.ts`, `run-journal.ts`,
316
- `persisted-actor.ts`, `replay.ts`, and `patch.ts`.
292
+ const harness = new Harness({ plugins: [clock] })
293
+ ```
317
294
 
318
- The completion graph has 24 states and 61 transitions. Reproduce these
319
- counts with `examples/bench/graph-metrics.ts`.
295
+ `setup` returns tools, hooks, services and `exec` contributions. See the
296
+ [plugin framework](lib/plugins/README.md) and a [custom plugin](examples/custom-plugin/README.md).
320
297
 
321
- The schema baseline rewinds `spec/` against this repo's `v*` release tags and
322
- skips loudly while none exist. Dependency `overrides` pin the resolutions the
323
- engine is validated against — keep them aligned with direct specs, npm refuses
324
- a mismatch on publish.
298
+ ## Examples
325
299
 
326
- ## License
300
+ Each runs on a local model under `QVAC_MODEL_CACHE_PATH` (`~/.qvac/models` by default).
301
+ `test/examples.ts` proves code-assistant, subagents, handoffs, parallel and custom-plugin on a
302
+ scripted model; host needs a spawned Bare child and a model, so it has no test. More in
303
+ [examples/](examples/README.md).
327
304
 
328
- See [LICENSE](./LICENSE.md).
305
+ | Run | Shows |
306
+ | ------------------------ | ---------------------------------------------------------------------------------------- |
307
+ | `bun run code-assistant` | [A coding team](examples/code-assistant/README.md): plan, subagents, review, Claude Code |
308
+ | `bun run subagents` | A lead handing one file to each subagent, four reading at once |
309
+ | `bun run handoffs` | A triage agent handing a memo to an office agent, and a health question to one on MedPsy |
310
+ | `bun run parallel` | Three tools in one round, and two runs on one model |
311
+ | `bun run custom-plugin` | [A third-party plugin](examples/custom-plugin/README.md): tools, a hook, a service |
312
+ | `bun run host` | Hosting the harness as a sidecar, the way a desktop app does |
329
313
 
330
- ## Resuming a completion
314
+ ## Host it
331
315
 
332
- The harness emits resumable steps to a host-owned log. Direct `Harness.completion()` runs without
333
- that host log work normally, but cannot recover after process death. For remote runs, pass a
334
- `HostRunLog` to `connectHarness(...).completion()` and reuse the same `runId` when reconnecting.
335
- The peer must advertise `hostRunLogVersion: 1`.
316
+ Run it in your process with `new Harness()`, or as a supervised sidecar, so a model crash never
317
+ takes down your app:
336
318
 
337
319
  ```ts
338
- const request = { runId: 'draft-42', model, messages, agent, runLog }
339
- for await (const event of remote.completion(request)) {
340
- // Save the run ID and render completion events.
341
- }
320
+ import { spawnHarness } from '@qvac/harness'
342
321
 
343
- // begin() returns the saved boot for this run. connectHarness resumes from it and sends the
344
- // same request identity; supply current callbacks, tool configs, and filesystem grants again.
345
- for await (const event of remote.completion({ runId: 'draft-42', resume: true, runLog, approve })) {
346
- // Handle run-resumed, round-reset, content, tool activity, and paused.
347
- }
322
+ const harness = spawnHarness({ entry, sdkStorage })
348
323
  ```
349
324
 
350
- `HostRunLog.begin(runId)` acquires one exclusive generation and returns its compact boot, if the
351
- run already exists, plus a 32-byte `digestKey`. Each `append(runId, generation, step)` must durably
352
- commit the whole `EngineStep`—its `seq`, expected logical record length, and records—in one
353
- transaction. The client waits for that commit before continuing. `release(runId, generation)` fences
354
- late appends from the ended connection. A host may export its authenticated records for inspection;
355
- the harness does not fetch storage or decrypt a host's log itself.
356
-
357
- `hostAppendTimeoutMs` (default 5000) bounds that wait; it applies in full even to a resume issued
358
- after the run's own deadline has passed. A spawned host raises it via the `runLog` start payload
359
- when its appends (e.g. a large first append on resume) can take longer than the default.
360
-
361
- Cancellation, iterator disposal, suspension, shutdown, and remote disconnect pause a run. A
362
- `paused` event ends that stream without making the run terminal. Resume retains completed tool
363
- results; time spent paused does not count against the run's deadline. A `round-reset` event identifies
364
- the unfinished round. Ordinary resets carry no `replacedTypes`; only the terminal replay reset
365
- (when resuming) lists the output kinds to replace. Both replace content and thinking. Text and
366
- tool events carry run/round identities; tool events also carry their call identity. Completed runs
367
- replay their final answer and metrics without loading a model.
368
-
369
- An unfinished write produces `recovery-required` with an `operation` containing its ID, name,
370
- resolved arguments, and effect. A write that the pause stopped before it started runs again. Reconcile the external result, then supply exactly that operation's
371
- resolution on resume:
325
+ The sidecar speaks the same `completion(context)` over hrpc. [`@qvac/core`](https://github.com/tetherto/qvac-core)
326
+ takes it unchanged to run agents across your devices; see its
327
+ [Integrating a harness](https://github.com/tetherto/qvac-core#integrating-a-harness).
372
328
 
373
- ```ts
374
- remote.completion({
375
- runId: 'draft-42',
376
- resume: true,
377
- model,
378
- messages,
379
- agent,
380
- recovery: [{ operationId: operation.id, decision: 'result', result: confirmedResult }],
381
- runLog,
382
- approve
383
- })
329
+ ## Reference
384
330
 
385
- // If re-execution is appropriate, explicitly authorize it instead:
386
- // recovery: [{ operationId: operation.id, decision: 'retry' }]
387
- ```
331
+ - [Hosting](docs/hosting.md): what the package ships, spawning, freeing memory, office extraction.
332
+ - [Architecture](docs/architecture.md): the engine layout and each module's API.
333
+ - [Resuming a completion](docs/resuming.md): the host run log, process death, the tool-call grammar.
334
+ - [Custom models](docs/custom-models.md): run a GGUF the catalog does not carry.
335
+ - [Speed stats](docs/speed-stats.md) and [benchmarks](examples/bench/README.md).
336
+ - [Decisions](docs/decisions/INDEX.md): why the harness is built the way it is.
388
337
 
389
- A retry can repeat an external effect. Receipts prevent replay of completed operations; they do
390
- not provide transactions or exactly-once effects in external systems. Missing runtime callbacks or
391
- a model that cannot load leave the run paused with a recovery reason. For these runtime/read
392
- reasons, restore the dependencies and resume without a `recovery` resolution. A tool that is gone
393
- or whose schema changed since the pause ends the run with an error, because no resolution can
394
- bring the old tool back. Stale resolutions and attempts to change the original conversation or
395
- model are rejected.
396
-
397
- A round can pause with one call's arguments redacted, whether or not a sibling call in the same
398
- round already landed or was already dispatched. Resuming refuses with `PENDING_ARGS_REDACTED`
399
- instead of replaying the redacted call. Its `recoveryOperationIds` lists every call the round still
400
- needs settled before it can proceed: a dispatched write not yet resolved (redacted or not), or a
401
- call whose real arguments exist only in the redacted snapshot, whether dispatched as a read or
402
- never dispatched at all. A plain call that was never redacted and never dispatched is not listed;
403
- it simply runs when the round resumes. Settle any listed operation with `decision: 'result'` and
404
- the known outcome. `decision: 'skip'` is also available when the host knows a redacted operation
405
- did not land, or for a read; it records a readable placeholder body,
406
- `{ skipped: true, reason: 'not executed; arguments unavailable after resume' }`, never the literal
407
- `undefined`. For a dispatched redacted write, `skip` asserts the call never landed; if the host
408
- skips a write that did land, the model sees "not executed" and may issue it again. It remains
409
- refused for a dispatched write whose arguments are available. The `retry` decision re-dispatches a
410
- call still pending; it is refused once that call already has a settled result, for a call never
411
- dispatched at all, and for a dispatched call whose arguments were redacted, which re-raises
412
- `PENDING_ARGS_REDACTED` instead of retrying blind. Settling every listed operation finishes the
413
- round; the landed write is never repeated, though a redacted read may run again. When no operation
414
- can be reconciled this way, the error's `forkAt` gives the last log length that never held redacted
415
- arguments as real ones, and `forkSafe` says whether forking there is actually safe: `false` means a
416
- write whose intent starts at or after `forkAt` has an unknown outcome — its result already landed, or it was dispatched
417
- and never resolved — so a fork could repeat it and the host should resolve `recoveryOperationIds`
418
- instead. `forkRun(sourceCore, targetCore, { at: forkAt, runId })` copies the log up to that point
419
- under a new `runId`, and the round reruns from there.
420
-
421
- Tool definitions are checked again on resume, including their function source. A tool whose
422
- behavior depends on values captured in a closure must supply and update `policyVersion` when
423
- those values change; function source cannot reveal them. The `exec` and `http_request` factories
424
- accept this value as an option; `exec` also fingerprints its static path and Python settings.
425
-
426
- Tool configuration values are not stored in the log; a digest verifies that the caller supplies
427
- the same configuration on resume. Credentials embedded in those values must currently remain
428
- unchanged. Credentials managed through `setCredentials()` or runtime callbacks can be refreshed
429
- without changing the request.
430
-
431
- For host-owned logs, resume uses the boot returned by `begin()` and does not require the peer's
432
- local `completionRecovery` capability. A transport `done` frame only means the stream ended; it
433
- does not mean the run succeeded. Run-log and machine versions must match. XState restore accepts
434
- older stable patches in the installed minor; future patches, other minors, and prereleases are
435
- rejected. The first checkpoint and child actor snapshots are trusted inputs; diagnostic replay does
436
- not verify actor effects or the initial context.
437
-
438
- `connectHarness(transport, { runLogReleaseTimeoutMs })` bounds host lease cleanup to 5 seconds
439
- by default. A rejected, throwing, or timed-out release is logged without replacing the completion
440
- outcome. The host must keep generation fencing active until release actually settles; a cleanup
441
- timeout does not authorize another writer.
442
-
443
- Each run's metadata contains a JSON-only definition of the machine, including state hierarchy,
444
- initial states, tags, invoked actors, and named transition guards/actions. Checkpoints and deltas
445
- also carry the exact event, source/target state IDs, fired guard names, and action names observed in
446
- XState's transition trace. The inspector displays these recorded traces and can replay state/context
447
- at the same machine and XState versions; event-triggered guard/action traces are re-evaluated and
448
- must match the recorded trace exactly, or replay reports a divergence. Eventless traces (no
449
- triggering event, e.g. `always` transitions) are not replay-verified; the inspector marks each such
450
- line `[eventless; not replay-verified]`. A version mismatch, legacy log, or prefix selection skips
451
- replay and leaves the stored snapshot and trace authoritative. The checked-in [completion
452
- graph](./docs/statecharts/completion-machine.mmd) is generated from the same machine definition and
453
- CI rejects a stale artifact.
454
-
455
- Export records from the host, then inspect a selected logical record or physical core length:
338
+ ## Development
456
339
 
457
340
  ```sh
458
- bare examples/run-log/inspect.ts <records.json> --context <recordIndex>
459
- bare examples/run-log/view.ts <records.json> report.html --limit <recordIndex>
341
+ bun install
342
+ bun run lint # prettier + lunte + tsc
343
+ bun run test # brittle, node and bare lanes
344
+ bun run build:schema # regenerates spec/
460
345
  ```
461
346
 
462
- Logical record index, engine step sequence, and physical storage length are different positions;
463
- host exports can include the mapping. The CLI reads exported records only. The host remains
464
- responsible for remote lookup, authentication, decryption, and sharing access.
465
-
466
- `@qvac/harness/run-log-inspect` is the library behind that CLI: `inspectRun(core, opts)` yields the
467
- same lines the `inspect.ts` example prints, and `renderRunLogHtml(core, opts)` renders the HTML
468
- report `view.ts` writes. A host imports either directly instead of shelling out to the examples,
469
- passing a `MachineLog` adapter or an envelope whose `records()` method returns an async iterable
470
- of `{ recordIndex, stepSeq, physicalLength, record }` entries. A raw records array or parsed JSON
471
- envelope must first be adapted; the CLI's `recordsCore` helper shows this conversion. Options are
472
- `recordLimit` (an exclusive logical index), `contextRecord`, `physicalLength`, and
473
- `contextPhysicalLength`.
474
-
475
- The completion machine is internal: its state names are part of the run-log format, not the API.
476
- Hook consumers observe `runPause` and `runResume` for a run that can resume. A run with no run-log
477
- store cannot resume, so a pause ends it and `runEnd` reports `aborted` (the caller aborted) or
478
- `abandoned` (the consumer stopped iterating).
479
-
480
- ## Tool-call markup grammar
481
-
482
- A tool-call block opens with `<function`, up to 64 ASCII whitespace characters, `=`, up to 64
483
- more ASCII whitespace characters, a name, up to 64 ASCII whitespace characters, and `>`. Tags are
484
- case-insensitive, except in the legacy nested reading below. An executable name is 1–64
485
- non-whitespace characters other than `<` or `>`; persistence also recognizes longer names so an
486
- oversized call cannot bypass redaction. A parameter uses the same form with `parameter` in place
487
- of `function`, and ends at the first case-insensitive
488
- `</parameter>`. A function block ends at the first case-insensitive `</function>`. Anything after
489
- that closer is prose and cannot extend the call, including more parameters or closers.
490
-
491
- Text that does not form a complete opener and closed block is prose. In particular, empty names,
492
- overlong executable names, bare parameter tags, and function-tag examples without a matching
493
- closer are neither executed nor hidden from the displayed answer. Stray function closers, including
494
- `</FUNCTION>`, also stay visible. A function opener inside a function block or a parameter opener
495
- inside a parameter value makes that block ambiguous, and persistence redacts it conservatively.
496
- A block with a nested function opener keeps the legacy recovery reading: the first lowercase
497
- `<function=` with no whitespace before `=` names the call. The text between `=` and `>` is limited
498
- to 64 characters before the name is trimmed. It runs with complete lowercase
499
- parameters up to the first lowercase `</function>` within that block. That reading ignores other
500
- function openers, so `<function=a><function=login>…` runs `a`,
501
- `<FUNCTION=a><function=login>…` and `<function =a><function=login>…` run `login`, and
502
- `<FUNCTION=a><FUNCTION=login>…` runs nothing. Likewise,
503
- `<function=x><function= login ><parameter=path>p</parameter></function>` runs `x` with `path: "p"`
504
- when `x` is a known tool. An unclosed parameter, such as `<parameter=key>S</function>`, contributes
505
- no argument and does not itself make the function block ambiguous. Persistence still redacts its
506
- value when the name is a credential field or a registered sensitive parameter, including in prose.
507
-
508
- ## Run-log data and privacy
509
-
510
- The harness redacts structured values before it sends a durable step to the host. String or object
511
- values under exact credential field names are redacted. Numeric values under known credential
512
- names are also redacted; generic `token` counts and `secret` flags are preserved. Registered tool
513
- parameters marked `sensitive: true` are redacted regardless of name or value type. Known names include `db_password`, `GITHUB_TOKEN`,
514
- `openai_api_key`, `client_password`, and `client_passphrase` (case, underscores, and hyphens
515
- are normalized).
516
- Name-based redaction is best effort: provider key names such as `ANTHROPIC_API_KEY`, `GH_TOKEN`,
517
- and `PGPASSWORD` are not covered, and a bare `token` argument (e.g. a pagination cursor) is
518
- redacted and lost on resume just like a real secret. The durable way to mark a value as a secret,
519
- regardless of its name, is the schema's `sensitive: true` annotation.
520
- Encoded assistant tool calls are redacted when history crosses persistence. Within one live process,
521
- a model's next request still sees its own prior call's real arguments, because that history lives
522
- only in the actor's memory. A **resumed** run has no such memory: its context is rebuilt from the
523
- persisted (redacted) log, so the model's first request after resume sees `[redacted]` for any tool
524
- call it made before the run was interrupted, not the original argument; that argument cannot be
525
- recovered. The model sees that prior call as well-formed markup with the literal `"[redacted]"`
526
- value, not an error; a model that re-issues such a call runs it with that literal placeholder.
527
- A persisted `raw` or `rawCall` of 4,096 characters or more is rebuilt from its (redacted) arguments
528
- even when nothing is sensitive, so it may differ byte-for-byte from the live call's `rawCall`.
529
- Shorter unchanged text stays identical to the original.
530
- Other arbitrary strings, tool results, and prose are preserved. Persisted machine
531
- history can reference matching original request messages by index and materializes to the same
532
- messages on resume and inspection — this applies to the caller-supplied conversation the run
533
- started from, which is never redacted, not to arguments the model generated mid-run. Hosts must
534
- treat free text and results as confidential and
535
- protect their log with encryption and access control. The host's `digestKey` verifies request
536
- identity and never enters a run record.
537
-
538
- A pending tool call whose arguments were redacted cannot be executed on resume and is rejected.
539
- A literal `[redacted]` supplied by the user is not enough to trigger that check. Tool configuration
540
- values are not stored in the run log; a keyed digest verifies that the caller supplies the same
541
- configuration on resume. Credentials managed through `setCredentials()` or runtime callbacks can
542
- be refreshed without changing the request identity.
347
+ ## License
348
+
349
+ See [LICENSE](./LICENSE.md).