@qvac/harness 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (299) hide show
  1. package/CHANGELOG.md +740 -141
  2. package/README.md +75 -7
  3. package/dist/harness.bundle +72 -50
  4. package/dist-lib/index.d.ts +49 -39
  5. package/dist-lib/index.js +448 -161
  6. package/dist-lib/lib/audio-transcode-bare.d.ts +2 -2
  7. package/dist-lib/lib/audio-transcode-bare.js +28 -18
  8. package/dist-lib/lib/audio-transcode-node.d.ts +2 -2
  9. package/dist-lib/lib/capabilities/audio-resample.d.ts +7 -6
  10. package/dist-lib/lib/capabilities/audio-resample.js +30 -18
  11. package/dist-lib/lib/capabilities/completion.d.ts +20 -19
  12. package/dist-lib/lib/capabilities/completion.js +193 -132
  13. package/dist-lib/lib/capabilities/download.d.ts +6 -6
  14. package/dist-lib/lib/capabilities/download.js +15 -8
  15. package/dist-lib/lib/capabilities/embed.js +2 -1
  16. package/dist-lib/lib/capabilities/enhance.d.ts +6 -1
  17. package/dist-lib/lib/capabilities/enhance.js +7 -4
  18. package/dist-lib/lib/capabilities/invoke.js +7 -4
  19. package/dist-lib/lib/capabilities/kv-cache.js +2 -1
  20. package/dist-lib/lib/capabilities/preview-model-source.d.ts +9 -7
  21. package/dist-lib/lib/capabilities/preview-model-source.js +80 -28
  22. package/dist-lib/lib/capabilities/speech-text.js +5 -4
  23. package/dist-lib/lib/capabilities/tool-selection.js +10 -9
  24. package/dist-lib/lib/capabilities/tool-turns.js +30 -16
  25. package/dist-lib/lib/capabilities/usage-breakdown.js +2 -1
  26. package/dist-lib/lib/capabilities/voice.d.ts +5 -1
  27. package/dist-lib/lib/capabilities/voice.js +22 -12
  28. package/dist-lib/lib/connect.d.ts +13 -32
  29. package/dist-lib/lib/connect.js +170 -112
  30. package/dist-lib/lib/context-window.js +25 -21
  31. package/dist-lib/lib/contract-types.d.ts +35 -15
  32. package/dist-lib/lib/diagram-repair.d.ts +4 -4
  33. package/dist-lib/lib/diagram-repair.js +6 -3
  34. package/dist-lib/lib/docx/index.d.ts +3 -2
  35. package/dist-lib/lib/{error-fields.d.ts → guards.d.ts} +1 -0
  36. package/dist-lib/lib/{error-fields.js → guards.js} +3 -0
  37. package/dist-lib/lib/hardware/capability-probe.js +20 -10
  38. package/dist-lib/lib/hardware/gpu-classify.js +6 -3
  39. package/dist-lib/lib/hardware/gpu-probe-addon.js +8 -4
  40. package/dist-lib/lib/hardware/gpu-probe.js +4 -2
  41. package/dist-lib/lib/hardware/gpu-stats.native.cjs +8 -9
  42. package/dist-lib/lib/hardware/parsers.js +8 -4
  43. package/dist-lib/lib/helpers/buffer-burst.js +4 -2
  44. package/dist-lib/lib/helpers/control-tokens.js +4 -2
  45. package/dist-lib/lib/helpers/join-guard.d.ts +2 -2
  46. package/dist-lib/lib/helpers/join-guard.js +4 -2
  47. package/dist-lib/lib/helpers/load-stall.js +4 -2
  48. package/dist-lib/lib/helpers/markup-stream-filter.d.ts +2 -2
  49. package/dist-lib/lib/helpers/markup-stream-filter.js +6 -3
  50. package/dist-lib/lib/helpers/race-abort.js +2 -1
  51. package/dist-lib/lib/helpers/race-timeout.d.ts +5 -0
  52. package/dist-lib/lib/helpers/race-timeout.js +14 -0
  53. package/dist-lib/lib/helpers/run-outcome.d.ts +6 -8
  54. package/dist-lib/lib/helpers/run-outcome.js +36 -20
  55. package/dist-lib/lib/helpers/spawn-path.js +6 -3
  56. package/dist-lib/lib/helpers/text-coalescer.js +6 -3
  57. package/dist-lib/lib/helpers/thinking.js +38 -45
  58. package/dist-lib/lib/helpers/tool-call-markup.d.ts +9 -7
  59. package/dist-lib/lib/helpers/tool-call-markup.js +36 -20
  60. package/dist-lib/lib/helpers/tool-intent.d.ts +3 -2
  61. package/dist-lib/lib/helpers/tool-intent.js +4 -2
  62. package/dist-lib/lib/helpers/tool-label.js +18 -9
  63. package/dist-lib/lib/hooks/built-in/arg-repair.js +23 -13
  64. package/dist-lib/lib/hooks/built-in/egress.js +2 -1
  65. package/dist-lib/lib/hooks/built-in/skill-catalog.js +2 -1
  66. package/dist-lib/lib/hooks/pipeline.d.ts +5 -4
  67. package/dist-lib/lib/hooks/pipeline.js +6 -3
  68. package/dist-lib/lib/hooks/run.js +12 -8
  69. package/dist-lib/lib/model-download-progress.js +10 -8
  70. package/dist-lib/lib/models/context.d.ts +1 -1
  71. package/dist-lib/lib/models/context.js +5 -1
  72. package/dist-lib/lib/models/custom-model-cache.d.ts +10 -1
  73. package/dist-lib/lib/models/custom-model-cache.js +43 -15
  74. package/dist-lib/lib/models/gguf-header.d.ts +3 -2
  75. package/dist-lib/lib/models/gguf-header.js +44 -22
  76. package/dist-lib/lib/models/idle-unload.d.ts +14 -0
  77. package/dist-lib/lib/models/idle-unload.js +51 -0
  78. package/dist-lib/lib/models/kv-cache.d.ts +3 -2
  79. package/dist-lib/lib/models/kv-cache.js +4 -3
  80. package/dist-lib/lib/models/llm-presets.d.ts +2 -2
  81. package/dist-lib/lib/models/llm-presets.js +4 -2
  82. package/dist-lib/lib/models/model-catalog-constants.js +3 -2
  83. package/dist-lib/lib/models/model-catalog.d.ts +15 -20
  84. package/dist-lib/lib/models/model-catalog.js +66 -31
  85. package/dist-lib/lib/models/model-delete.js +18 -8
  86. package/dist-lib/lib/models/model-handle.js +2 -1
  87. package/dist-lib/lib/models/model-list.d.ts +8 -3
  88. package/dist-lib/lib/models/model-list.js +11 -6
  89. package/dist-lib/lib/models/model-pool.d.ts +48 -10
  90. package/dist-lib/lib/models/model-pool.js +106 -45
  91. package/dist-lib/lib/models/model-source.js +10 -5
  92. package/dist-lib/lib/models/music-catalog.d.ts +2 -2
  93. package/dist-lib/lib/models/nmt-catalog.d.ts +4 -3
  94. package/dist-lib/lib/models/nmt-catalog.js +10 -5
  95. package/dist-lib/lib/models/opencl-cache.d.ts +6 -1
  96. package/dist-lib/lib/models/opencl-cache.js +5 -3
  97. package/dist-lib/lib/models/sdk-faults.d.ts +11 -8
  98. package/dist-lib/lib/models/sdk-faults.js +9 -6
  99. package/dist-lib/lib/models/shards.d.ts +11 -0
  100. package/dist-lib/lib/models/shards.js +15 -0
  101. package/dist-lib/lib/models/tool-dialect.js +10 -5
  102. package/dist-lib/lib/no-redirect-fetch-bare.d.ts +3 -3
  103. package/dist-lib/lib/no-redirect-fetch-bare.js +1 -1
  104. package/dist-lib/lib/no-redirect-fetch-impl.js +6 -3
  105. package/dist-lib/lib/no-redirect-fetch-node.d.ts +1 -1
  106. package/dist-lib/lib/no-redirect-fetch-node.js +9 -9
  107. package/dist-lib/lib/office/index.d.ts +3 -2
  108. package/dist-lib/lib/office/python.d.ts +3 -2
  109. package/dist-lib/lib/office/python.js +2 -1
  110. package/dist-lib/lib/prompt.d.ts +5 -4
  111. package/dist-lib/lib/prompt.js +8 -4
  112. package/dist-lib/lib/queue.js +10 -5
  113. package/dist-lib/lib/resolution-detector.js +21 -11
  114. package/dist-lib/lib/rpc-session.js +2 -1
  115. package/dist-lib/lib/sdk-loader.js +2 -1
  116. package/dist-lib/lib/sdk-storage.js +4 -2
  117. package/dist-lib/lib/serve.js +122 -66
  118. package/dist-lib/lib/spawn.js +7 -4
  119. package/dist-lib/lib/tmp-path.d.ts +7 -6
  120. package/dist-lib/lib/tool-call-display.d.ts +2 -2
  121. package/dist-lib/lib/tools/create-documents.js +18 -10
  122. package/dist-lib/lib/tools/edit-documents.js +23 -13
  123. package/dist-lib/lib/tools/edit-image.d.ts +2 -2
  124. package/dist-lib/lib/tools/edit-image.js +60 -36
  125. package/dist-lib/lib/tools/exec/adapters/adapter.d.ts +10 -10
  126. package/dist-lib/lib/tools/exec/adapters/python/attachments.d.ts +17 -11
  127. package/dist-lib/lib/tools/exec/adapters/python/attachments.js +53 -40
  128. package/dist-lib/lib/tools/exec/adapters/python/create-effect.d.ts +2 -2
  129. package/dist-lib/lib/tools/exec/adapters/python/create-effect.js +60 -32
  130. package/dist-lib/lib/tools/exec/adapters/python/guarded-fetch.d.ts +33 -22
  131. package/dist-lib/lib/tools/exec/adapters/python/guarded-fetch.js +58 -29
  132. package/dist-lib/lib/tools/exec/adapters/python/interrupt-timer.d.ts +2 -2
  133. package/dist-lib/lib/tools/exec/adapters/python/loader.js +23 -12
  134. package/dist-lib/lib/tools/exec/adapters/python/memfs.d.ts +13 -11
  135. package/dist-lib/lib/tools/exec/adapters/python/memfs.js +10 -5
  136. package/dist-lib/lib/tools/exec/adapters/python/net-shim.js +3 -1
  137. package/dist-lib/lib/tools/exec/adapters/python/output-policy.d.ts +6 -4
  138. package/dist-lib/lib/tools/exec/adapters/python/output-policy.js +20 -10
  139. package/dist-lib/lib/tools/exec/adapters/python/pyodide.d.ts +2 -2
  140. package/dist-lib/lib/tools/exec/adapters/python/pyodide.js +14 -7
  141. package/dist-lib/lib/tools/exec/adapters/python/python-adapter.d.ts +41 -34
  142. package/dist-lib/lib/tools/exec/adapters/python/python-adapter.js +316 -166
  143. package/dist-lib/lib/tools/exec/adapters/python/run-session.d.ts +9 -8
  144. package/dist-lib/lib/tools/exec/adapters/python/run-session.js +56 -28
  145. package/dist-lib/lib/tools/exec/adapters/python/wheels.d.ts +8 -10
  146. package/dist-lib/lib/tools/exec/adapters/python/wheels.js +22 -11
  147. package/dist-lib/lib/tools/exec/adapters/python/worker/client.d.ts +3 -2
  148. package/dist-lib/lib/tools/exec/adapters/python/worker/client.js +41 -26
  149. package/dist-lib/lib/tools/exec/adapters/python/worker/entry.js +27 -18
  150. package/dist-lib/lib/tools/exec/adapters/python/worker/protocol.d.ts +2 -2
  151. package/dist-lib/lib/tools/exec/adapters/python/worker/protocol.js +14 -13
  152. package/dist-lib/lib/tools/exec/adapters/python/worker/spawn-node.d.ts +4 -4
  153. package/dist-lib/lib/tools/exec/adapters/python/worker/spawn-node.js +10 -5
  154. package/dist-lib/lib/tools/exec/adapters/shell/shell-adapter.d.ts +4 -4
  155. package/dist-lib/lib/tools/exec/adapters/shell/shell-adapter.js +2 -1
  156. package/dist-lib/lib/tools/exec/obsidian/cli-process.d.ts +6 -1
  157. package/dist-lib/lib/tools/exec/obsidian/cli-process.js +8 -5
  158. package/dist-lib/lib/tools/exec/obsidian/cli.d.ts +6 -6
  159. package/dist-lib/lib/tools/exec/obsidian/cli.js +4 -4
  160. package/dist-lib/lib/tools/exec/obsidian/command.d.ts +3 -2
  161. package/dist-lib/lib/tools/exec/obsidian/command.js +6 -3
  162. package/dist-lib/lib/tools/exec/obsidian/output.js +2 -1
  163. package/dist-lib/lib/tools/exec/obsidian/route.d.ts +4 -6
  164. package/dist-lib/lib/tools/exec/obsidian/route.js +17 -11
  165. package/dist-lib/lib/tools/exec/obsidian/safe-path.js +2 -1
  166. package/dist-lib/lib/tools/exec/obsidian/vault-create.js +15 -7
  167. package/dist-lib/lib/tools/exec/obsidian/vault-paths.d.ts +2 -2
  168. package/dist-lib/lib/tools/exec/obsidian/vault-paths.js +20 -10
  169. package/dist-lib/lib/tools/exec/obsidian/vault-read.js +20 -13
  170. package/dist-lib/lib/tools/exec/obsidian/vault-write.js +24 -12
  171. package/dist-lib/lib/tools/exec/runner.d.ts +14 -14
  172. package/dist-lib/lib/tools/exec/runner.js +5 -3
  173. package/dist-lib/lib/tools/exec/scope.js +52 -28
  174. package/dist-lib/lib/tools/exec/shell-argv.js +31 -18
  175. package/dist-lib/lib/tools/exec/shell-guidance.d.ts +6 -1
  176. package/dist-lib/lib/tools/exec/shell-guidance.js +35 -20
  177. package/dist-lib/lib/tools/exec/video-tools.js +2 -2
  178. package/dist-lib/lib/tools/exec.d.ts +6 -8
  179. package/dist-lib/lib/tools/exec.js +113 -54
  180. package/dist-lib/lib/tools/file-glob.d.ts +4 -5
  181. package/dist-lib/lib/tools/file-glob.js +16 -11
  182. package/dist-lib/lib/tools/fs/glob.js +13 -18
  183. package/dist-lib/lib/tools/fs/remote-protocol.d.ts +10 -10
  184. package/dist-lib/lib/tools/fs/remote.d.ts +3 -2
  185. package/dist-lib/lib/tools/fs/remote.js +13 -7
  186. package/dist-lib/lib/tools/fs/scope.d.ts +8 -3
  187. package/dist-lib/lib/tools/fs/scope.js +20 -12
  188. package/dist-lib/lib/tools/fs/walk.js +6 -3
  189. package/dist-lib/lib/tools/fs/write.d.ts +3 -2
  190. package/dist-lib/lib/tools/generate-image.d.ts +11 -9
  191. package/dist-lib/lib/tools/generate-image.js +73 -37
  192. package/dist-lib/lib/tools/generate-music.d.ts +22 -11
  193. package/dist-lib/lib/tools/generate-music.js +79 -48
  194. package/dist-lib/lib/tools/grep.js +66 -41
  195. package/dist-lib/lib/tools/http-request/encode-fields.js +18 -9
  196. package/dist-lib/lib/tools/http-request/{utils.js → request.js} +20 -11
  197. package/dist-lib/lib/tools/http-request/truncate-response.js +57 -46
  198. package/dist-lib/lib/tools/http-request.d.ts +1 -1
  199. package/dist-lib/lib/tools/http-request.js +33 -18
  200. package/dist-lib/lib/tools/mcp/protocol.d.ts +53 -0
  201. package/dist-lib/lib/tools/mcp/{utils.js → protocol.js} +45 -23
  202. package/dist-lib/lib/tools/mcp-call.d.ts +1 -1
  203. package/dist-lib/lib/tools/mcp-call.js +37 -16
  204. package/dist-lib/lib/tools/operations/builders.js +10 -6
  205. package/dist-lib/lib/tools/operations/compile.js +20 -10
  206. package/dist-lib/lib/tools/operations/decoders.js +12 -6
  207. package/dist-lib/lib/tools/operations/gmail-message.js +3 -2
  208. package/dist-lib/lib/tools/outbound-guard.d.ts +4 -3
  209. package/dist-lib/lib/tools/outbound-guard.js +14 -8
  210. package/dist-lib/lib/tools/private-ip.js +8 -7
  211. package/dist-lib/lib/tools/rag-search.js +14 -7
  212. package/dist-lib/lib/tools/read-files.js +23 -20
  213. package/dist-lib/lib/tools/skill.js +19 -10
  214. package/dist-lib/lib/tools/skills/auth-resolver.d.ts +11 -18
  215. package/dist-lib/lib/tools/skills/auth-resolver.js +30 -18
  216. package/dist-lib/lib/tools/skills/bin-check.d.ts +3 -2
  217. package/dist-lib/lib/tools/skills/bin-check.js +10 -3
  218. package/dist-lib/lib/tools/skills/bundled-dir.js +20 -10
  219. package/dist-lib/lib/tools/skills/bundled-hash.d.ts +3 -2
  220. package/dist-lib/lib/tools/skills/bundled-hash.js +6 -1
  221. package/dist-lib/lib/tools/skills/catalog.d.ts +3 -2
  222. package/dist-lib/lib/tools/skills/catalog.js +33 -28
  223. package/dist-lib/lib/tools/skills/cli-argv.d.ts +3 -2
  224. package/dist-lib/lib/tools/skills/cli-argv.js +55 -52
  225. package/dist-lib/lib/tools/skills/cli-schema-check.js +21 -10
  226. package/dist-lib/lib/tools/skills/cli-schema-load.js +28 -20
  227. package/dist-lib/lib/tools/skills/cli-schema-types.d.ts +6 -6
  228. package/dist-lib/lib/tools/skills/cli-schema.js +2 -1
  229. package/dist-lib/lib/tools/skills/credential-check.d.ts +6 -3
  230. package/dist-lib/lib/tools/skills/credential-check.js +24 -12
  231. package/dist-lib/lib/tools/skills/credential-grants.js +1 -6
  232. package/dist-lib/lib/tools/skills/credential-health.d.ts +5 -1
  233. package/dist-lib/lib/tools/skills/credential-health.js +5 -3
  234. package/dist-lib/lib/tools/skills/frontmatter-parser.js +10 -5
  235. package/dist-lib/lib/tools/skills/manifest-parse.js +84 -64
  236. package/dist-lib/lib/tools/skills/mention.js +7 -6
  237. package/dist-lib/lib/tools/skills/obsidian-readiness.d.ts +2 -2
  238. package/dist-lib/lib/tools/skills/obsidian-readiness.js +11 -3
  239. package/dist-lib/lib/tools/skills/overlay-crud.d.ts +6 -4
  240. package/dist-lib/lib/tools/skills/overlay-crud.js +12 -6
  241. package/dist-lib/lib/tools/skills/overlay-dir.js +4 -2
  242. package/dist-lib/lib/tools/skills/overlay-watch.d.ts +3 -2
  243. package/dist-lib/lib/tools/skills/overlay-watch.js +8 -4
  244. package/dist-lib/lib/tools/skills/setup-routes.js +1 -3
  245. package/dist-lib/lib/tools/skills/skill-settings.js +4 -1
  246. package/dist-lib/lib/tools/skills/skill-state.d.ts +6 -11
  247. package/dist-lib/lib/tools/skills/skill-state.js +48 -29
  248. package/dist-lib/lib/tools/skills/tool-grants.js +6 -3
  249. package/dist-lib/lib/tools/toolsets.js +2 -1
  250. package/dist-lib/lib/tools/translate.d.ts +4 -5
  251. package/dist-lib/lib/tools/translate.js +31 -14
  252. package/dist-lib/lib/tools/url-guard.js +2 -1
  253. package/dist-lib/lib/tools/weather-lookup/place.js +8 -4
  254. package/dist-lib/lib/tools/weather-lookup/report.d.ts +7 -1
  255. package/dist-lib/lib/tools/weather-lookup/report.js +46 -9
  256. package/dist-lib/lib/tools/weather-lookup.js +18 -12
  257. package/dist-lib/lib/tools/web-fetch.js +47 -24
  258. package/dist-lib/lib/tools/web-search.js +8 -3
  259. package/dist-lib/lib/validating-lookup.d.ts +4 -4
  260. package/dist-lib/lib/wav-encode.d.ts +1 -1
  261. package/dist-lib/lib/wav-encode.js +11 -10
  262. package/dist-lib/lib/web-fetch/embedded-state.js +24 -12
  263. package/dist-lib/lib/web-fetch/extract.js +4 -2
  264. package/dist-lib/lib/web-fetch/images.js +8 -4
  265. package/dist-lib/lib/web-fetch/video.d.ts +2 -2
  266. package/dist-lib/lib/web-fetch/video.js +8 -4
  267. package/dist-lib/lib/web-search/engine-registry.d.ts +2 -2
  268. package/dist-lib/lib/web-search/engines/aol.js +1 -1
  269. package/dist-lib/lib/web-search/engines/bing.js +1 -1
  270. package/dist-lib/lib/web-search/engines/brave.js +4 -1
  271. package/dist-lib/lib/web-search/engines/duckduckgo.js +3 -2
  272. package/dist-lib/lib/web-search/engines/google.js +7 -3
  273. package/dist-lib/lib/web-search/engines/wikipedia.js +5 -4
  274. package/dist-lib/lib/web-search/engines/yahoo.js +1 -1
  275. package/dist-lib/lib/web-search/fetch-html.d.ts +5 -4
  276. package/dist-lib/lib/web-search/fetch-html.js +13 -7
  277. package/dist-lib/lib/web-search/orchestrator.d.ts +9 -5
  278. package/dist-lib/lib/web-search/orchestrator.js +3 -3
  279. package/dist-lib/lib/wire.d.ts +3 -2
  280. package/dist-lib/lib/wire.js +23 -15
  281. package/dist-lib/schema/baseline.js +10 -5
  282. package/dist-lib/schema/build.js +2 -1
  283. package/dist-lib/schema/harness.d.ts +15 -2
  284. package/dist-lib/schema/harness.js +39 -2
  285. package/dist-lib/schema/release-tags.d.ts +3 -2
  286. package/dist-lib/schema/release-tags.js +6 -3
  287. package/dist-lib/spec/bind.js +9 -0
  288. package/dist-lib/spec/calls.js +3 -0
  289. package/dist-lib/spec/hrpc/hrpc.json +39 -0
  290. package/dist-lib/spec/hrpc/index.js +39 -3
  291. package/dist-lib/spec/hrpc/messages.js +105 -8
  292. package/dist-lib/spec/hyperschema/index.js +105 -8
  293. package/dist-lib/spec/hyperschema/schema.json +77 -1
  294. package/dist-lib/spec/hyperschema/types.d.ts +25 -1
  295. package/package.json +14 -14
  296. package/worker/harness-sidecar.mjs +15 -22
  297. package/worker/stow-entry.mjs +7 -4
  298. package/dist-lib/lib/tools/mcp/utils.d.ts +0 -47
  299. /package/dist-lib/lib/tools/http-request/{utils.d.ts → request.d.ts} +0 -0
@@ -37,7 +37,8 @@ function buildInit(options, signal) {
37
37
  }
38
38
  return init;
39
39
  }
40
- async function fetchWithTimeout(fetcher, url, options, callerSignal) {
40
+ async function fetchWithTimeout(fetcher, url, options) {
41
+ const callerSignal = options?.signal;
41
42
  if (callerSignal?.aborted) {
42
43
  throw new AbortError();
43
44
  }
@@ -57,10 +58,12 @@ async function fetchWithTimeout(fetcher, url, options, callerSignal) {
57
58
  return { ok: resp.ok, status: resp.status, text };
58
59
  }
59
60
  catch (err) {
60
- if (timedOut)
61
+ if (timedOut) {
61
62
  throw new TimeoutError(timeoutMs);
62
- if (callerSignal?.aborted)
63
+ }
64
+ if (callerSignal?.aborted) {
63
65
  throw new AbortError();
66
+ }
64
67
  throw err;
65
68
  }
66
69
  finally {
@@ -68,8 +71,8 @@ async function fetchWithTimeout(fetcher, url, options, callerSignal) {
68
71
  callerSignal?.removeEventListener('abort', onCallerAbort);
69
72
  }
70
73
  }
71
- export async function fetchHtml(fetcher, url, options, signal) {
72
- const { ok, status, text } = await fetchWithTimeout(fetcher, url, options, signal);
74
+ export async function fetchHtml(fetcher, url, options) {
75
+ const { ok, status, text } = await fetchWithTimeout(fetcher, url, options);
73
76
  if (!ok) {
74
77
  throw new Error(`HTTP ${status}`);
75
78
  }
@@ -83,8 +86,11 @@ export class JsonParseError extends Error {
83
86
  this.name = 'JsonParseError';
84
87
  }
85
88
  }
86
- export async function fetchJson(fetcher, url, options, signal) {
87
- const { ok, status, text } = await fetchWithTimeout(fetcher, url, { ...options, accept: options?.accept ?? 'application/json' }, signal);
89
+ export async function fetchJson(fetcher, url, options) {
90
+ const { ok, status, text } = await fetchWithTimeout(fetcher, url, {
91
+ ...options,
92
+ accept: options?.accept ?? 'application/json'
93
+ });
88
94
  if (!ok) {
89
95
  throw new Error(`HTTP ${status}`);
90
96
  }
@@ -1,14 +1,18 @@
1
1
  import type { AbortSignal as BareAbortSignal } from 'bare-abort-controller';
2
2
  import type { Fetcher, WebSearchResult } from './types.ts';
3
- export type EngineSummaryEntry = {
3
+ export interface EngineSummaryEntry {
4
4
  readonly engine: string;
5
5
  readonly status: 'ok' | 'timeout' | 'error';
6
6
  readonly resultCount: number;
7
7
  readonly durationMs: number;
8
- };
9
- export type SearchWebResult = {
8
+ }
9
+ export interface SearchWebResult {
10
10
  readonly results: ReadonlyArray<WebSearchResult>;
11
11
  readonly engineSummary: ReadonlyArray<EngineSummaryEntry>;
12
- };
12
+ }
13
13
  export declare function classifyEngineError(reason: unknown): 'timeout' | 'error';
14
- export declare function searchWeb(fetcher: Fetcher, query: string, maxResults?: number, signal?: BareAbortSignal): Promise<SearchWebResult>;
14
+ export interface SearchWebOptions {
15
+ readonly maxResults?: number;
16
+ readonly signal?: BareAbortSignal;
17
+ }
18
+ export declare function searchWeb(fetcher: Fetcher, query: string, { maxResults, signal }?: SearchWebOptions): Promise<SearchWebResult>;
@@ -4,7 +4,7 @@ import { mergeResults } from './merge-results.js';
4
4
  export function classifyEngineError(reason) {
5
5
  return reason instanceof TimeoutError ? 'timeout' : 'error';
6
6
  }
7
- function processSettledResult(engineName, result, outcomes, engineSummary) {
7
+ function processSettledResult(engineName, result, { outcomes, engineSummary }) {
8
8
  if (result.status === 'fulfilled') {
9
9
  outcomes.push(result.value);
10
10
  engineSummary.push({
@@ -23,7 +23,7 @@ function processSettledResult(engineName, result, outcomes, engineSummary) {
23
23
  });
24
24
  }
25
25
  }
26
- export async function searchWeb(fetcher, query, maxResults = DEFAULT_MAX_RESULTS, signal) {
26
+ export async function searchWeb(fetcher, query, { maxResults = DEFAULT_MAX_RESULTS, signal } = {}) {
27
27
  const settled = await Promise.allSettled(ENGINES.map(async ({ name, fn }) => {
28
28
  const start = Date.now();
29
29
  const results = await fn(query, fetcher, signal);
@@ -41,7 +41,7 @@ export async function searchWeb(fetcher, query, maxResults = DEFAULT_MAX_RESULTS
41
41
  if (!engine || !settledResult) {
42
42
  continue;
43
43
  }
44
- processSettledResult(engine.name, settledResult, outcomes, engineSummary);
44
+ processSettledResult(engine.name, settledResult, { outcomes, engineSummary });
45
45
  }
46
46
  if (outcomes.length === 0) {
47
47
  return { results: [], engineSummary };
@@ -44,8 +44,9 @@ export declare function toWire(event: HarnessEvent): WireEvent;
44
44
  export declare function fromWire(event: WireEvent): HarnessEvent;
45
45
  export declare function toDownloadWire(event: HarnessEvent): WireDownloadEvent;
46
46
  export declare function fromDownloadWire(event: WireDownloadEvent): HarnessEvent;
47
- export declare function packVectors(vectors: number[][]): {
47
+ export interface PackedVectors {
48
48
  dimensions: number;
49
49
  vectors: Buffer;
50
- };
50
+ }
51
+ export declare function packVectors(vectors: number[][]): PackedVectors;
51
52
  export declare function unpackVectors(dimensions: number, bytes: Buffer): number[][];
@@ -1,4 +1,14 @@
1
1
  import b4a from 'b4a';
2
+ import { isRecord } from './guards.js';
3
+ function stringField(value) {
4
+ return typeof value === 'string' ? value : undefined;
5
+ }
6
+ function objectField(value) {
7
+ return isRecord(value) ? value : {};
8
+ }
9
+ function isResource(value) {
10
+ return isRecord(value) && typeof value.kind === 'string' && typeof value.label === 'string';
11
+ }
2
12
  export function toWire(event) {
3
13
  switch (event.type) {
4
14
  case 'content':
@@ -7,26 +17,26 @@ export function toWire(event) {
7
17
  case 'tool-call':
8
18
  return {
9
19
  type: 'tool-call',
10
- name: event.name,
20
+ name: stringField(event.name),
11
21
  arguments: event.args,
12
- rawCall: event.rawCall ?? null,
13
- effect: event.effect ?? null,
22
+ rawCall: stringField(event.rawCall) ?? null,
23
+ effect: stringField(event.effect) ?? null,
14
24
  display: event.display
15
25
  };
16
26
  case 'tool-result':
17
27
  return {
18
28
  type: 'tool-result',
19
- name: event.name,
29
+ name: stringField(event.name),
20
30
  result: event.result
21
31
  };
22
32
  case 'tool-activity':
23
33
  return {
24
34
  type: 'tool-activity',
25
- name: event.name,
35
+ name: stringField(event.name),
26
36
  arguments: event.args,
27
- resource: event.resource ?? null,
28
- effect: event.effect,
29
- decision: event.decision
37
+ resource: isResource(event.resource) ? event.resource : null,
38
+ effect: stringField(event.effect),
39
+ decision: stringField(event.decision)
30
40
  };
31
41
  case 'metrics': {
32
42
  const { type, ...metrics } = event;
@@ -64,9 +74,7 @@ export function fromWire(event) {
64
74
  type: 'tool-call',
65
75
  name: event.name ?? '',
66
76
  args: event.arguments ?? {},
67
- ...(event.rawCall === null || event.rawCall === undefined
68
- ? {}
69
- : { rawCall: event.rawCall }),
77
+ rawCall: event.rawCall ?? undefined,
70
78
  effect: event.effect === 'read' ? 'read' : 'write',
71
79
  display: event.display ?? undefined
72
80
  };
@@ -86,11 +94,11 @@ export function fromWire(event) {
86
94
  decision: event.decision || 'blocked'
87
95
  };
88
96
  case 'metrics':
89
- return { type: 'metrics', ...event.metrics };
97
+ return { type: 'metrics', ...objectField(event.metrics) };
90
98
  case 'inference-call':
91
99
  return { type: 'inference-call', call: event.payload };
92
100
  case 'inference-sent': {
93
- const sent = (event.payload ?? {});
101
+ const sent = objectField(event.payload);
94
102
  return {
95
103
  type: 'inference-sent',
96
104
  messages: sent.messages,
@@ -118,7 +126,7 @@ export function toDownloadWire(event) {
118
126
  case 'complete':
119
127
  return {
120
128
  type: 'complete',
121
- assetId: event.assetId,
129
+ assetId: stringField(event.assetId),
122
130
  downloaded: typeof event.downloaded === 'boolean' ? event.downloaded : undefined
123
131
  };
124
132
  case 'error':
@@ -132,7 +140,7 @@ export function toDownloadWire(event) {
132
140
  export function fromDownloadWire(event) {
133
141
  switch (event.type) {
134
142
  case 'progress':
135
- return { type: 'progress', ...(event.progress ?? {}) };
143
+ return { type: 'progress', ...objectField(event.progress) };
136
144
  case 'complete':
137
145
  return { type: 'complete', assetId: event.assetId ?? '', downloaded: event.downloaded };
138
146
  case 'error':
@@ -7,28 +7,33 @@ export function rewindSpec(root, dirs, { carries, keep }) {
7
7
  if (process.env.SCHEMA_NO_BASELINE)
8
8
  return [];
9
9
  const baselines = previousReleaseTags(root, { carries });
10
- if (baselines.length === 0)
10
+ if (baselines.length === 0) {
11
11
  return [];
12
+ }
12
13
  const held = keep.map((file) => {
13
14
  const target = path.join(root, file);
14
15
  return { target, contents: fs.readFileSync(target) };
15
16
  });
16
- for (const dir of dirs)
17
+ for (const dir of dirs) {
17
18
  checkoutSpec(root, dir, baselines[0]);
18
- for (const { target, contents } of held)
19
+ }
20
+ for (const { target, contents } of held) {
19
21
  fs.writeFileSync(target, contents);
22
+ }
20
23
  return baselines;
21
24
  }
22
25
  function checkoutSpec(root, dir, tag) {
23
26
  console.log(`rewinding ${path.relative(root, dir)} to ${tag}`);
24
27
  const done = spawnSync('git', ['checkout', tag, '--', dir], { cwd: root });
25
- if (done.status !== 0)
28
+ if (done.status !== 0) {
26
29
  throw new Error(`checkout ${tag} failed: ${done.stderr ?? ''}`);
30
+ }
27
31
  }
28
32
  export function unstageSpec(root, dirs) {
29
33
  const done = spawnSync('git', ['reset', '--quiet', 'HEAD', '--', ...dirs], { cwd: root });
30
- if (done.status !== 0)
34
+ if (done.status !== 0) {
31
35
  throw new Error(`git reset -- spec failed: ${done.stderr ?? ''}`);
36
+ }
32
37
  }
33
38
  export function resetHrpcIds(hrpcDir) {
34
39
  fs.rmSync(path.join(hrpcDir, 'hrpc.json'), { force: true });
@@ -34,6 +34,7 @@ registerHarnessApi(builder.namespace('harness'));
34
34
  HRPCBuilder.toDisk(builder);
35
35
  writeBind(builder, path.join(SPEC_DIR, 'bind.js'));
36
36
  writeClient(builder, path.join(SPEC_DIR, 'calls.js'), 'harnessClient');
37
- if (baselines.length > 0)
37
+ if (baselines.length > 0) {
38
38
  unstageSpec(ROOT, BASELINE_DIRS);
39
+ }
39
40
  console.log('harness contract spec generated under spec/');
@@ -1,2 +1,15 @@
1
- export declare function registerHarnessTypes(ns: any): void;
2
- export declare function registerHarnessApi(api: any): void;
1
+ import type Hyperschema from 'hyperschema';
2
+ interface HrpcRoute {
3
+ name: string;
4
+ stream: boolean;
5
+ }
6
+ interface HrpcNamespace {
7
+ register(description: {
8
+ name: string;
9
+ request: HrpcRoute;
10
+ response: HrpcRoute;
11
+ }): void;
12
+ }
13
+ export declare function registerHarnessTypes(ns: Hyperschema.Namespace): void;
14
+ export declare function registerHarnessApi(api: HrpcNamespace): void;
15
+ export {};
@@ -338,7 +338,8 @@ export function registerHarnessTypes(ns) {
338
338
  { name: 'isLoaded', type: 'bool', required: true },
339
339
  { name: 'supportsImages', type: 'bool', required: true },
340
340
  { name: 'expectedSize', type: 'uint', required: true },
341
- { name: 'actualSize', type: 'uint' }
341
+ { name: 'actualSize', type: 'uint' },
342
+ { name: 'label', type: 'string' }
342
343
  ]
343
344
  });
344
345
  ns.register({
@@ -566,7 +567,9 @@ export function registerHarnessTypes(ns) {
566
567
  { name: 'src', type: 'string', required: true },
567
568
  { name: 'projectionSrc', type: 'string' },
568
569
  { name: 'taskType', type: 'string' },
569
- { name: 'expectedSize', type: 'uint' }
570
+ { name: 'expectedSize', type: 'uint' },
571
+ { name: 'label', type: 'string' },
572
+ { name: 'contextLength', type: 'uint' }
570
573
  ]
571
574
  });
572
575
  ns.register({
@@ -714,6 +717,25 @@ export function registerHarnessTypes(ns) {
714
717
  { name: 'mmprojSrc', type: 'string' }
715
718
  ]
716
719
  });
720
+ ns.register({
721
+ name: 'set-model-idle-timeout-request',
722
+ fields: [{ name: 'ms', type: 'uint', required: true }]
723
+ });
724
+ ns.register({
725
+ name: 'load-model-response',
726
+ fields: [
727
+ { name: 'loaded', type: 'bool', required: true },
728
+ { name: 'reason', type: 'string' }
729
+ ]
730
+ });
731
+ ns.register({
732
+ name: 'unload-model-request',
733
+ fields: [{ name: 'model', type: 'string', required: true }]
734
+ });
735
+ ns.register({
736
+ name: 'unload-model-response',
737
+ fields: [{ name: 'unloaded', type: 'bool', required: true }]
738
+ });
717
739
  }
718
740
  export function registerHarnessApi(api) {
719
741
  api.register({
@@ -866,4 +888,19 @@ export function registerHarnessApi(api) {
866
888
  request: { name: '@harness/preview-model-source-request', stream: false },
867
889
  response: { name: '@harness/preview-model-source-response', stream: false }
868
890
  });
891
+ api.register({
892
+ name: 'set-model-idle-timeout',
893
+ request: { name: '@harness/set-model-idle-timeout-request', stream: false },
894
+ response: { name: '@harness/ok-response', stream: false }
895
+ });
896
+ api.register({
897
+ name: 'load-model',
898
+ request: { name: '@harness/warm-model-request', stream: false },
899
+ response: { name: '@harness/load-model-response', stream: false }
900
+ });
901
+ api.register({
902
+ name: 'unload-model',
903
+ request: { name: '@harness/unload-model-request', stream: false },
904
+ response: { name: '@harness/unload-model-response', stream: false }
905
+ });
869
906
  }
@@ -1,6 +1,7 @@
1
1
  import { Version } from 'bare-semver';
2
2
  export declare function currentReleaseVersion(root: string): Version;
3
- export declare function previousReleaseTags(root: string, { count, carries }: {
3
+ export interface PreviousReleaseTagsOptions {
4
4
  count?: number;
5
5
  carries: string;
6
- }): string[];
6
+ }
7
+ export declare function previousReleaseTags(root: string, { count, carries }: PreviousReleaseTagsOptions): string[];
@@ -16,13 +16,15 @@ const TAG_PREFIX = 'v';
16
16
  export function previousReleaseTags(root, { count = 3, carries }) {
17
17
  const current = currentReleaseVersion(root);
18
18
  const listed = spawnSync('git', ['tag', '-l', `${TAG_PREFIX}*`], { cwd: root });
19
- if (listed.status !== 0)
19
+ if (listed.status !== 0) {
20
20
  throw new Error(`git tag -l failed: ${listed.stderr ?? ''}`);
21
+ }
21
22
  const newestPerLine = new Map();
22
23
  for (const line of (listed.stdout?.toString() ?? '').split('\n')) {
23
24
  const parsed = parseTag(line.trim());
24
- if (!parsed || Version.compare(parsed.version, current) > 0)
25
+ if (!parsed || Version.compare(parsed.version, current) > 0) {
25
26
  continue;
27
+ }
26
28
  const winner = newestPerLine.get(parsed.line);
27
29
  if (!winner || Version.compare(parsed.version, winner.version) > 0) {
28
30
  newestPerLine.set(parsed.line, parsed);
@@ -46,8 +48,9 @@ function parseTag(name) {
46
48
  return null;
47
49
  try {
48
50
  const version = Version.parse(name.slice(TAG_PREFIX.length));
49
- if (version.prerelease.length > 0)
51
+ if (version.prerelease.length > 0) {
50
52
  return null;
53
+ }
51
54
  return { tag: name, version, line: `${version.major}.${version.minor}` };
52
55
  }
53
56
  catch {
@@ -130,4 +130,13 @@ export function bindApi(rpc, api) {
130
130
  if (api.previewModelSource) {
131
131
  rpc.onPreviewModelSource((req) => api.previewModelSource(req));
132
132
  }
133
+ if (api.setModelIdleTimeout) {
134
+ rpc.onSetModelIdleTimeout((req) => api.setModelIdleTimeout(req));
135
+ }
136
+ if (api.loadModel) {
137
+ rpc.onLoadModel((req) => api.loadModel(req));
138
+ }
139
+ if (api.unloadModel) {
140
+ rpc.onUnloadModel((req) => api.unloadModel(req));
141
+ }
133
142
  }
@@ -40,5 +40,8 @@ export function harnessClient(rpc) {
40
40
  deleteKvCache: (input) => rpc.deleteKvCache(input),
41
41
  detectLanguage: (input) => rpc.detectLanguage(input),
42
42
  previewModelSource: (input) => rpc.previewModelSource(input),
43
+ setModelIdleTimeout: (input) => rpc.setModelIdleTimeout(input),
44
+ loadModel: (input) => rpc.loadModel(input),
45
+ unloadModel: (input) => rpc.unloadModel(input),
43
46
  };
44
47
  }
@@ -390,6 +390,45 @@
390
390
  "stream": false
391
391
  },
392
392
  "version": 1
393
+ },
394
+ {
395
+ "id": 30,
396
+ "name": "@harness/set-model-idle-timeout",
397
+ "request": {
398
+ "name": "@harness/set-model-idle-timeout-request",
399
+ "stream": false
400
+ },
401
+ "response": {
402
+ "name": "@harness/ok-response",
403
+ "stream": false
404
+ },
405
+ "version": 1
406
+ },
407
+ {
408
+ "id": 31,
409
+ "name": "@harness/load-model",
410
+ "request": {
411
+ "name": "@harness/warm-model-request",
412
+ "stream": false
413
+ },
414
+ "response": {
415
+ "name": "@harness/load-model-response",
416
+ "stream": false
417
+ },
418
+ "version": 1
419
+ },
420
+ {
421
+ "id": 32,
422
+ "name": "@harness/unload-model",
423
+ "request": {
424
+ "name": "@harness/unload-model-request",
425
+ "stream": false
426
+ },
427
+ "response": {
428
+ "name": "@harness/unload-model-response",
429
+ "stream": false
430
+ },
431
+ "version": 1
393
432
  }
394
433
  ]
395
434
  }
@@ -65,7 +65,13 @@ const methods = new Map([
65
65
  ['@harness/detect-language', 28],
66
66
  [28, '@harness/detect-language'],
67
67
  ['@harness/preview-model-source', 29],
68
- [29, '@harness/preview-model-source']
68
+ [29, '@harness/preview-model-source'],
69
+ ['@harness/set-model-idle-timeout', 30],
70
+ [30, '@harness/set-model-idle-timeout'],
71
+ ['@harness/load-model', 31],
72
+ [31, '@harness/load-model'],
73
+ ['@harness/unload-model', 32],
74
+ [32, '@harness/unload-model']
69
75
  ])
70
76
 
71
77
  class HRPC {
@@ -102,7 +108,10 @@ class HRPC {
102
108
  ['@harness/delete-overlay-skill', getEncoding('@harness/skill-name-request')],
103
109
  ['@harness/delete-kv-cache', getEncoding('@harness/kv-cache-delete-request')],
104
110
  ['@harness/detect-language', getEncoding('@harness/detect-language-request')],
105
- ['@harness/preview-model-source', getEncoding('@harness/preview-model-source-request')]
111
+ ['@harness/preview-model-source', getEncoding('@harness/preview-model-source-request')],
112
+ ['@harness/set-model-idle-timeout', getEncoding('@harness/set-model-idle-timeout-request')],
113
+ ['@harness/load-model', getEncoding('@harness/warm-model-request')],
114
+ ['@harness/unload-model', getEncoding('@harness/unload-model-request')]
106
115
  ])
107
116
  this._responseEncodings = new Map([
108
117
  ['@harness/completion', getEncoding('@harness/completion-event')],
@@ -134,7 +143,10 @@ class HRPC {
134
143
  ['@harness/delete-overlay-skill', getEncoding('@harness/delete-skill-response')],
135
144
  ['@harness/delete-kv-cache', getEncoding('@harness/kv-cache-deletion-response')],
136
145
  ['@harness/detect-language', getEncoding('@harness/detect-language-response')],
137
- ['@harness/preview-model-source', getEncoding('@harness/preview-model-source-response')]
146
+ ['@harness/preview-model-source', getEncoding('@harness/preview-model-source-response')],
147
+ ['@harness/set-model-idle-timeout', getEncoding('@harness/ok-response')],
148
+ ['@harness/load-model', getEncoding('@harness/load-model-response')],
149
+ ['@harness/unload-model', getEncoding('@harness/unload-model-response')]
138
150
  ])
139
151
  this._rpc = new RPC(stream, async (req) => {
140
152
  const command = methods.get(req.command)
@@ -352,6 +364,18 @@ class HRPC {
352
364
  return this._call('@harness/preview-model-source', args)
353
365
  }
354
366
 
367
+ async setModelIdleTimeout(args) {
368
+ return this._call('@harness/set-model-idle-timeout', args)
369
+ }
370
+
371
+ async loadModel(args) {
372
+ return this._call('@harness/load-model', args)
373
+ }
374
+
375
+ async unloadModel(args) {
376
+ return this._call('@harness/unload-model', args)
377
+ }
378
+
355
379
  onCompletion(responseFn) {
356
380
  this._handlers['@harness/completion'] = responseFn
357
381
  }
@@ -472,6 +496,18 @@ class HRPC {
472
496
  this._handlers['@harness/preview-model-source'] = responseFn
473
497
  }
474
498
 
499
+ onSetModelIdleTimeout(responseFn) {
500
+ this._handlers['@harness/set-model-idle-timeout'] = responseFn
501
+ }
502
+
503
+ onLoadModel(responseFn) {
504
+ this._handlers['@harness/load-model'] = responseFn
505
+ }
506
+
507
+ onUnloadModel(responseFn) {
508
+ this._handlers['@harness/unload-model'] = responseFn
509
+ }
510
+
475
511
  _requestIsStream(command) {
476
512
  return [
477
513
  '@harness/completion',