@try-works/dsh-model-as-tool 0.1.2 → 0.3.6

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 (267) hide show
  1. package/bin/dsh-tool-mode-credentials.mjs +20 -0
  2. package/bin/dsh-tool-mode.mjs +202 -0
  3. package/catalog/desert-ant-models.json +693 -693
  4. package/client/client.model-tools.js +592 -0
  5. package/client/index.js +1679 -0
  6. package/lib/adapters/index.d.ts.map +1 -1
  7. package/lib/adapters/index.js +4 -4
  8. package/lib/bindings.d.ts.map +1 -1
  9. package/lib/bindings.js +26 -25
  10. package/lib/capability.d.ts.map +1 -1
  11. package/lib/capability.js +17 -0
  12. package/lib/capture-path.d.ts +97 -0
  13. package/lib/capture-path.d.ts.map +1 -0
  14. package/lib/capture-path.js +152 -0
  15. package/lib/diagnostics.d.ts +166 -0
  16. package/lib/diagnostics.d.ts.map +1 -0
  17. package/lib/diagnostics.js +135 -0
  18. package/lib/extension-dependencies.d.ts +197 -0
  19. package/lib/extension-dependencies.d.ts.map +1 -0
  20. package/lib/extension-dependencies.js +369 -0
  21. package/lib/extension-dispatch.d.ts +117 -0
  22. package/lib/extension-dispatch.d.ts.map +1 -0
  23. package/lib/extension-dispatch.js +124 -0
  24. package/lib/extension-registrar.d.ts +100 -0
  25. package/lib/extension-registrar.d.ts.map +1 -0
  26. package/lib/extension-registrar.js +134 -0
  27. package/lib/extensions-api.d.ts +217 -0
  28. package/lib/extensions-api.d.ts.map +1 -0
  29. package/lib/extensions-api.js +17 -0
  30. package/lib/extensions-remote.d.ts +54 -0
  31. package/lib/extensions-remote.d.ts.map +1 -0
  32. package/lib/extensions-remote.js +66 -0
  33. package/lib/extensions-service.d.ts +334 -0
  34. package/lib/extensions-service.d.ts.map +1 -0
  35. package/lib/extensions-service.js +1351 -0
  36. package/lib/harness-llm.d.ts +138 -0
  37. package/lib/harness-llm.d.ts.map +1 -0
  38. package/lib/harness-llm.js +218 -0
  39. package/lib/harness-serving.d.ts +95 -0
  40. package/lib/harness-serving.d.ts.map +1 -0
  41. package/lib/harness-serving.js +157 -0
  42. package/lib/headless.d.ts +97 -0
  43. package/lib/headless.d.ts.map +1 -0
  44. package/lib/headless.js +349 -0
  45. package/lib/http-acquisition.d.ts +27 -0
  46. package/lib/http-acquisition.d.ts.map +1 -0
  47. package/lib/http-acquisition.js +136 -0
  48. package/lib/index.d.ts +250 -7
  49. package/lib/index.d.ts.map +1 -1
  50. package/lib/index.js +2625 -70
  51. package/lib/invocation-accounting.d.ts +169 -0
  52. package/lib/invocation-accounting.d.ts.map +1 -0
  53. package/lib/invocation-accounting.js +148 -0
  54. package/lib/legacy-migration.d.ts +95 -0
  55. package/lib/legacy-migration.d.ts.map +1 -0
  56. package/lib/legacy-migration.js +429 -0
  57. package/lib/managed-workers.d.ts +151 -0
  58. package/lib/managed-workers.d.ts.map +1 -0
  59. package/lib/managed-workers.js +249 -0
  60. package/lib/mcp/client-grant.d.ts +74 -0
  61. package/lib/mcp/client-grant.d.ts.map +1 -0
  62. package/lib/mcp/client-grant.js +60 -0
  63. package/lib/mcp/credential-cli.d.ts +38 -0
  64. package/lib/mcp/credential-cli.d.ts.map +1 -0
  65. package/lib/mcp/credential-cli.js +148 -0
  66. package/lib/mcp/credential-store.d.ts +143 -0
  67. package/lib/mcp/credential-store.d.ts.map +1 -0
  68. package/lib/mcp/credential-store.js +454 -0
  69. package/lib/mcp/host-binding.d.ts +25 -0
  70. package/lib/mcp/host-binding.d.ts.map +1 -1
  71. package/lib/mcp/host-binding.js +107 -14
  72. package/lib/mcp/http.d.ts +68 -18
  73. package/lib/mcp/http.d.ts.map +1 -1
  74. package/lib/mcp/http.js +390 -62
  75. package/lib/mcp/oauth.d.ts +149 -0
  76. package/lib/mcp/oauth.d.ts.map +1 -0
  77. package/lib/mcp/oauth.js +396 -0
  78. package/lib/mcp/protocol.d.ts +46 -7
  79. package/lib/mcp/protocol.d.ts.map +1 -1
  80. package/lib/mcp/protocol.js +63 -16
  81. package/lib/mcp/rate-limit.d.ts +68 -0
  82. package/lib/mcp/rate-limit.d.ts.map +1 -0
  83. package/lib/mcp/rate-limit.js +114 -0
  84. package/lib/mcp/sdk-v2.d.ts +17 -0
  85. package/lib/mcp/sdk-v2.d.ts.map +1 -0
  86. package/lib/mcp/sdk-v2.js +181 -0
  87. package/lib/mcp/server.d.ts +11 -1
  88. package/lib/mcp/server.d.ts.map +1 -1
  89. package/lib/mcp/server.js +80 -13
  90. package/lib/mcp/stdio.d.ts.map +1 -1
  91. package/lib/mcp/stdio.js +9 -1
  92. package/lib/mcp/subscriptions.d.ts +43 -1
  93. package/lib/mcp/subscriptions.d.ts.map +1 -1
  94. package/lib/mcp/subscriptions.js +90 -9
  95. package/lib/model-qualification.d.ts +192 -0
  96. package/lib/model-qualification.d.ts.map +1 -0
  97. package/lib/model-qualification.js +178 -0
  98. package/lib/planning.d.ts +246 -0
  99. package/lib/planning.d.ts.map +1 -0
  100. package/lib/planning.js +457 -0
  101. package/lib/prepared-assets.d.ts +178 -0
  102. package/lib/prepared-assets.d.ts.map +1 -0
  103. package/lib/prepared-assets.js +286 -0
  104. package/lib/provider-bridge.d.ts +37 -0
  105. package/lib/provider-bridge.d.ts.map +1 -1
  106. package/lib/provider-bridge.js +189 -12
  107. package/lib/ptc-authority.d.ts +140 -0
  108. package/lib/ptc-authority.d.ts.map +1 -0
  109. package/lib/ptc-authority.js +216 -0
  110. package/lib/ptc-runtime.d.ts +156 -0
  111. package/lib/ptc-runtime.d.ts.map +1 -0
  112. package/lib/ptc-runtime.js +191 -0
  113. package/lib/publication.d.ts +2 -1
  114. package/lib/publication.d.ts.map +1 -1
  115. package/lib/publication.js +13 -5
  116. package/lib/receipt.d.ts.map +1 -1
  117. package/lib/receipt.js +8 -0
  118. package/lib/title-proposal.d.ts +194 -0
  119. package/lib/title-proposal.d.ts.map +1 -0
  120. package/lib/title-proposal.js +244 -0
  121. package/lib/tool-mode-run.d.ts +235 -0
  122. package/lib/tool-mode-run.d.ts.map +1 -0
  123. package/lib/tool-mode-run.js +283 -0
  124. package/lib/types.d.ts +3 -1
  125. package/lib/types.d.ts.map +1 -1
  126. package/lib/update-surface.d.ts +79 -0
  127. package/lib/update-surface.d.ts.map +1 -0
  128. package/lib/update-surface.js +224 -0
  129. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/lang-detect.d.ts +16 -0
  130. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/lang-detect.d.ts.map +1 -0
  131. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/lang-detect.js +85 -0
  132. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/standard.d.ts +38 -0
  133. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/standard.d.ts.map +1 -0
  134. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/standard.js +445 -0
  135. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/stt-transcribe.d.ts +20 -0
  136. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/stt-transcribe.d.ts.map +1 -0
  137. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/stt-transcribe.js +112 -0
  138. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-embed.d.ts +14 -0
  139. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-embed.d.ts.map +1 -0
  140. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-embed.js +63 -0
  141. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-rerank.d.ts +14 -0
  142. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-rerank.d.ts.map +1 -0
  143. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-rerank.js +76 -0
  144. package/node_modules/@try-works/tool-mode-contracts/lib/dsh.d.ts +82 -0
  145. package/node_modules/@try-works/tool-mode-contracts/lib/dsh.d.ts.map +1 -0
  146. package/node_modules/@try-works/tool-mode-contracts/lib/dsh.js +274 -0
  147. package/node_modules/@try-works/tool-mode-contracts/lib/index.d.ts +26 -0
  148. package/node_modules/@try-works/tool-mode-contracts/lib/index.d.ts.map +1 -0
  149. package/node_modules/@try-works/tool-mode-contracts/lib/index.js +48 -0
  150. package/node_modules/@try-works/tool-mode-contracts/lib/meta.d.ts +104 -0
  151. package/node_modules/@try-works/tool-mode-contracts/lib/meta.d.ts.map +1 -0
  152. package/node_modules/@try-works/tool-mode-contracts/lib/meta.js +55 -0
  153. package/node_modules/@try-works/tool-mode-contracts/lib/registry.d.ts +107 -0
  154. package/node_modules/@try-works/tool-mode-contracts/lib/registry.d.ts.map +1 -0
  155. package/node_modules/@try-works/tool-mode-contracts/lib/registry.js +246 -0
  156. package/node_modules/@try-works/tool-mode-contracts/package.json +34 -0
  157. package/node_modules/@try-works/tool-mode-extension-sdk/bin/dsh-tool-mode.mjs +20 -0
  158. package/node_modules/@try-works/tool-mode-extension-sdk/lib/cli.d.ts +80 -0
  159. package/node_modules/@try-works/tool-mode-extension-sdk/lib/cli.d.ts.map +1 -0
  160. package/node_modules/@try-works/tool-mode-extension-sdk/lib/cli.js +533 -0
  161. package/node_modules/@try-works/tool-mode-extension-sdk/lib/declarative-recipes.d.ts +83 -0
  162. package/node_modules/@try-works/tool-mode-extension-sdk/lib/declarative-recipes.d.ts.map +1 -0
  163. package/node_modules/@try-works/tool-mode-extension-sdk/lib/declarative-recipes.js +125 -0
  164. package/node_modules/@try-works/tool-mode-extension-sdk/lib/discovery.d.ts +70 -0
  165. package/node_modules/@try-works/tool-mode-extension-sdk/lib/discovery.d.ts.map +1 -0
  166. package/node_modules/@try-works/tool-mode-extension-sdk/lib/discovery.js +201 -0
  167. package/node_modules/@try-works/tool-mode-extension-sdk/lib/errors.d.ts +57 -0
  168. package/node_modules/@try-works/tool-mode-extension-sdk/lib/errors.d.ts.map +1 -0
  169. package/node_modules/@try-works/tool-mode-extension-sdk/lib/errors.js +83 -0
  170. package/node_modules/@try-works/tool-mode-extension-sdk/lib/index.d.ts +31 -0
  171. package/node_modules/@try-works/tool-mode-extension-sdk/lib/index.d.ts.map +1 -0
  172. package/node_modules/@try-works/tool-mode-extension-sdk/lib/index.js +31 -0
  173. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/archive.d.ts +86 -0
  174. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/archive.d.ts.map +1 -0
  175. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/archive.js +185 -0
  176. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/dependencies.d.ts +126 -0
  177. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/dependencies.d.ts.map +1 -0
  178. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/dependencies.js +297 -0
  179. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/lifecycle.d.ts +216 -0
  180. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/lifecycle.d.ts.map +1 -0
  181. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/lifecycle.js +800 -0
  182. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/migration.d.ts +210 -0
  183. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/migration.d.ts.map +1 -0
  184. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/migration.js +368 -0
  185. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/runtime-link.d.ts +63 -0
  186. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/runtime-link.d.ts.map +1 -0
  187. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/runtime-link.js +149 -0
  188. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/source-directory.d.ts +35 -0
  189. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/source-directory.d.ts.map +1 -0
  190. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/source-directory.js +179 -0
  191. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/staged.d.ts +179 -0
  192. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/staged.d.ts.map +1 -0
  193. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/staged.js +235 -0
  194. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/store.d.ts +367 -0
  195. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/store.d.ts.map +1 -0
  196. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/store.js +807 -0
  197. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/update-flow.d.ts +185 -0
  198. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/update-flow.d.ts.map +1 -0
  199. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/update-flow.js +504 -0
  200. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/zip-source.d.ts +17 -0
  201. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/zip-source.d.ts.map +1 -0
  202. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/zip-source.js +80 -0
  203. package/node_modules/@try-works/tool-mode-extension-sdk/lib/load.d.ts +52 -0
  204. package/node_modules/@try-works/tool-mode-extension-sdk/lib/load.d.ts.map +1 -0
  205. package/node_modules/@try-works/tool-mode-extension-sdk/lib/load.js +102 -0
  206. package/node_modules/@try-works/tool-mode-extension-sdk/lib/manifest.d.ts +171 -0
  207. package/node_modules/@try-works/tool-mode-extension-sdk/lib/manifest.d.ts.map +1 -0
  208. package/node_modules/@try-works/tool-mode-extension-sdk/lib/manifest.js +271 -0
  209. package/node_modules/@try-works/tool-mode-extension-sdk/lib/runtime.d.ts +242 -0
  210. package/node_modules/@try-works/tool-mode-extension-sdk/lib/runtime.d.ts.map +1 -0
  211. package/node_modules/@try-works/tool-mode-extension-sdk/lib/runtime.js +58 -0
  212. package/node_modules/@try-works/tool-mode-extension-sdk/lib/state.d.ts +118 -0
  213. package/node_modules/@try-works/tool-mode-extension-sdk/lib/state.d.ts.map +1 -0
  214. package/node_modules/@try-works/tool-mode-extension-sdk/lib/state.js +113 -0
  215. package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker/worker-child.d.ts +2 -0
  216. package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker/worker-child.d.ts.map +1 -0
  217. package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker/worker-child.js +351 -0
  218. package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker.d.ts +150 -0
  219. package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker.d.ts.map +1 -0
  220. package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker.js +670 -0
  221. package/node_modules/@try-works/tool-mode-extension-sdk/package.json +53 -0
  222. package/node_modules/@try-works/tool-mode-extension-sdk/schema/extension-manifest-1.1.0.schema.json +253 -0
  223. package/node_modules/@try-works/tool-mode-recipes/bin/tool-mode-recipe.mjs +15 -0
  224. package/node_modules/@try-works/tool-mode-recipes/lib/broker.d.ts +427 -0
  225. package/node_modules/@try-works/tool-mode-recipes/lib/broker.d.ts.map +1 -0
  226. package/node_modules/@try-works/tool-mode-recipes/lib/broker.js +592 -0
  227. package/node_modules/@try-works/tool-mode-recipes/lib/cli.d.ts +60 -0
  228. package/node_modules/@try-works/tool-mode-recipes/lib/cli.d.ts.map +1 -0
  229. package/node_modules/@try-works/tool-mode-recipes/lib/cli.js +936 -0
  230. package/node_modules/@try-works/tool-mode-recipes/lib/dsh-adapter.d.ts +237 -0
  231. package/node_modules/@try-works/tool-mode-recipes/lib/dsh-adapter.d.ts.map +1 -0
  232. package/node_modules/@try-works/tool-mode-recipes/lib/dsh-adapter.js +200 -0
  233. package/node_modules/@try-works/tool-mode-recipes/lib/fixture-provider.d.ts +85 -0
  234. package/node_modules/@try-works/tool-mode-recipes/lib/fixture-provider.d.ts.map +1 -0
  235. package/node_modules/@try-works/tool-mode-recipes/lib/fixture-provider.js +176 -0
  236. package/node_modules/@try-works/tool-mode-recipes/lib/images.d.ts +105 -0
  237. package/node_modules/@try-works/tool-mode-recipes/lib/images.d.ts.map +1 -0
  238. package/node_modules/@try-works/tool-mode-recipes/lib/images.js +129 -0
  239. package/node_modules/@try-works/tool-mode-recipes/lib/index.d.ts +25 -0
  240. package/node_modules/@try-works/tool-mode-recipes/lib/index.d.ts.map +1 -0
  241. package/node_modules/@try-works/tool-mode-recipes/lib/index.js +25 -0
  242. package/node_modules/@try-works/tool-mode-recipes/lib/recipe-format.d.ts +325 -0
  243. package/node_modules/@try-works/tool-mode-recipes/lib/recipe-format.d.ts.map +1 -0
  244. package/node_modules/@try-works/tool-mode-recipes/lib/recipe-format.js +1310 -0
  245. package/node_modules/@try-works/tool-mode-recipes/lib/templates.d.ts +51 -0
  246. package/node_modules/@try-works/tool-mode-recipes/lib/templates.d.ts.map +1 -0
  247. package/node_modules/@try-works/tool-mode-recipes/lib/templates.js +310 -0
  248. package/node_modules/@try-works/tool-mode-recipes/lib/titles.d.ts +227 -0
  249. package/node_modules/@try-works/tool-mode-recipes/lib/titles.d.ts.map +1 -0
  250. package/node_modules/@try-works/tool-mode-recipes/lib/titles.js +407 -0
  251. package/node_modules/@try-works/tool-mode-recipes/package.json +56 -0
  252. package/node_modules/@try-works/tool-mode-recipes/recipes/describe-image.json +38 -0
  253. package/node_modules/@try-works/tool-mode-recipes/recipes/text-title.json +45 -0
  254. package/node_modules/@try-works/tool-mode-recipes/schema/harness-model-recipe.schema.json +273 -0
  255. package/package.json +50 -17
  256. package/remote/spec.mjs +439 -0
  257. package/remote/typert.host.mjs +14 -0
  258. package/remote/typert.remote-client.mjs +16 -0
  259. package/lib/adapters/tongue.d.ts +0 -31
  260. package/lib/adapters/tongue.d.ts.map +0 -1
  261. package/lib/adapters/tongue.js +0 -93
  262. package/lib/adapters/voz.d.ts +0 -28
  263. package/lib/adapters/voz.d.ts.map +0 -1
  264. package/lib/adapters/voz.js +0 -102
  265. /package/{lib → node_modules/@try-works/tool-mode-extension-sdk/lib}/licensing.d.ts +0 -0
  266. /package/{lib → node_modules/@try-works/tool-mode-extension-sdk/lib}/licensing.d.ts.map +0 -0
  267. /package/{lib → node_modules/@try-works/tool-mode-extension-sdk/lib}/licensing.js +0 -0
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Invocation accounting: timings, outcome class and sizes (OBS-01, OBS-05).
3
+ *
4
+ * The receipt already carries identity — contract, implementation, extension version,
5
+ * content digest, activation generation, caller scope. OBS-01 asks for four things it did
6
+ * not have:
7
+ *
8
+ * - **queue / load / inference / total time**, separated, because a slow call has three
9
+ * very different causes and a single duration cannot tell them apart;
10
+ * - **a cancellation/failure CLASS**, so an operations reader can group failures rather
11
+ * than reading prose;
12
+ * - **sizes**, measured rather than estimated;
13
+ * - and all of it **without credentials or bodies**, which is why the sizes are NUMBERS
14
+ * and there is deliberately nowhere to put a payload.
15
+ *
16
+ * The last point is the design constraint rather than a disclaimer: this module has no
17
+ * field that can hold request or response content, so a future change cannot start logging
18
+ * bodies by accident. A `Record<string, unknown>` "details" bag would have undone that in
19
+ * one commit.
20
+ *
21
+ * OBS-05 is the other half: what is recorded is MEASURED, with the runtime that measured
22
+ * it, so a vendor's published figure can never be mistaken for this machine's.
23
+ *
24
+ * @module @try-works/dsh-model-as-tool/invocation-accounting
25
+ */
26
+ /**
27
+ * Why an invocation ended.
28
+ *
29
+ * Deliberately coarse and closed: a reader groups by these, and an open string would make
30
+ * every dashboard a list of one-off messages.
31
+ */
32
+ export type FailureClass =
33
+ /** The call completed. */
34
+ 'none'
35
+ /** The caller cancelled, or an imported signal aborted. */
36
+ | 'cancelled'
37
+ /** Policy or the contract refused before work began. */
38
+ | 'refused'
39
+ /** A deadline expired. */
40
+ | 'timeout'
41
+ /** An extension or provider failed. */
42
+ | 'failed'
43
+ /** Authorization denied. */
44
+ | 'policy-denied';
45
+ /** Where the time went, in milliseconds. */
46
+ export interface InvocationTimings {
47
+ /**
48
+ * Time waiting for admission — a queue, a pool, or a load already in flight.
49
+ *
50
+ * Separated from load time because "the model is already loading for someone else" and
51
+ * "the model is slow to load" are different problems with different fixes.
52
+ */
53
+ readonly queuedMs: number;
54
+ /** Time spent preparing or loading, when the invocation had to. */
55
+ readonly loadMs: number;
56
+ /** Time the implementation spent on the work itself. */
57
+ readonly inferenceMs: number;
58
+ /**
59
+ * Wall time from admission attempt to result.
60
+ *
61
+ * NOT asserted equal to the sum: phases can overlap, and forcing equality would make the
62
+ * record wrong whenever they do.
63
+ */
64
+ readonly totalMs: number;
65
+ }
66
+ /** Byte sizes, measured rather than estimated. */
67
+ export interface InvocationSizes {
68
+ /** Serialized request size in bytes. */
69
+ readonly inputBytes: number;
70
+ /** Serialized result size in bytes. */
71
+ readonly outputBytes: number;
72
+ /** Bytes read from assets during this invocation, when any were. */
73
+ readonly assetBytes: number;
74
+ }
75
+ /** The runtime that produced the measurements (OBS-05). */
76
+ export interface MeasurementContext {
77
+ /** Platform, e.g. `win32`. */
78
+ readonly platform: string;
79
+ /** Architecture, e.g. `x64`. */
80
+ readonly architecture: string;
81
+ /** Node version. */
82
+ readonly nodeVersion: string;
83
+ /** The engine or runtime version actually used. */
84
+ readonly engineVersion: string;
85
+ }
86
+ /** One invocation's accounting record. */
87
+ export interface InvocationAccounting {
88
+ /** Correlation id, matching the receipt. */
89
+ readonly receiptId: string;
90
+ readonly timings: InvocationTimings;
91
+ readonly sizes: InvocationSizes;
92
+ readonly failureClass: FailureClass;
93
+ /** A short class-level reason, never a payload. */
94
+ readonly reason: string | null;
95
+ /**
96
+ * How the timings were obtained.
97
+ *
98
+ * `measured` for this process's own clock; the alternative exists so an imported figure
99
+ * can never be presented as one taken here.
100
+ */
101
+ readonly timingSource: 'measured' | 'reported-by-implementation';
102
+ /** The runtime the measurement belongs to. */
103
+ readonly measuredOn: MeasurementContext;
104
+ /**
105
+ * The CALLER'S grant identity, present only for external MCP calls (SEC-04).
106
+ *
107
+ * Identity, never payload: the operator can tell WHICH client called, while the
108
+ * record still has no field that can hold request or response content.
109
+ */
110
+ readonly grantId?: string;
111
+ /** The authenticated client identity, present with {@link grantId}. */
112
+ readonly clientId?: string;
113
+ }
114
+ /**
115
+ * A phase timer.
116
+ *
117
+ * Records the phases as they HAPPEN rather than inferring them afterwards, because a
118
+ * duration measured by subtraction cannot distinguish a slow load from a slow queue.
119
+ */
120
+ export declare class PhaseTimer {
121
+ #private;
122
+ constructor(now?: () => number);
123
+ /** Begin a phase, closing any phase already open. */
124
+ begin(name: 'queued' | 'load' | 'inference'): void;
125
+ /** Close the open phase, if any. Idempotent. */
126
+ end(): void;
127
+ /** The timings recorded so far. */
128
+ finish(): InvocationTimings;
129
+ }
130
+ /** Classify an outcome from what was observed (OBS-01). */
131
+ export declare function classifyOutcome(input: {
132
+ readonly ok: boolean;
133
+ readonly aborted?: boolean;
134
+ readonly timedOut?: boolean;
135
+ readonly denied?: boolean;
136
+ readonly refused?: boolean;
137
+ }): FailureClass;
138
+ /**
139
+ * The runtime this process is measuring on (OBS-05).
140
+ *
141
+ * Read from the process rather than configured, so a record cannot claim a platform it was
142
+ * not produced on. That is the specific defect OBS-05 names: Apple Neural Engine figures
143
+ * presented as Windows performance.
144
+ * @param engineVersion - the engine actually used for this invocation.
145
+ * @returns the measurement context.
146
+ */
147
+ export declare function measurementContext(engineVersion: string): MeasurementContext;
148
+ /**
149
+ * Build an accounting record (OBS-01).
150
+ *
151
+ * Sizes are computed from the SERIALIZED forms because that is what crossed the boundary;
152
+ * an object's in-memory size is not what a caller paid for.
153
+ * @param request - what to record.
154
+ * @returns the accounting record.
155
+ */
156
+ export declare function accountInvocation(request: {
157
+ readonly receiptId: string;
158
+ readonly timings: InvocationTimings;
159
+ readonly failureClass: FailureClass;
160
+ readonly reason?: string;
161
+ readonly input: unknown;
162
+ readonly output?: unknown;
163
+ readonly assetBytes?: number;
164
+ readonly engineVersion: string;
165
+ /** The external caller's grant identity, when the call was external (SEC-04). */
166
+ readonly grantId?: string;
167
+ readonly clientId?: string;
168
+ }): InvocationAccounting;
169
+ //# sourceMappingURL=invocation-accounting.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invocation-accounting.d.ts","sourceRoot":"","sources":["../src/invocation-accounting.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Invocation accounting: timings, outcome class and sizes (OBS-01, OBS-05).
3
+ *
4
+ * The receipt already carries identity — contract, implementation, extension version,
5
+ * content digest, activation generation, caller scope. OBS-01 asks for four things it did
6
+ * not have:
7
+ *
8
+ * - **queue / load / inference / total time**, separated, because a slow call has three
9
+ * very different causes and a single duration cannot tell them apart;
10
+ * - **a cancellation/failure CLASS**, so an operations reader can group failures rather
11
+ * than reading prose;
12
+ * - **sizes**, measured rather than estimated;
13
+ * - and all of it **without credentials or bodies**, which is why the sizes are NUMBERS
14
+ * and there is deliberately nowhere to put a payload.
15
+ *
16
+ * The last point is the design constraint rather than a disclaimer: this module has no
17
+ * field that can hold request or response content, so a future change cannot start logging
18
+ * bodies by accident. A `Record<string, unknown>` "details" bag would have undone that in
19
+ * one commit.
20
+ *
21
+ * OBS-05 is the other half: what is recorded is MEASURED, with the runtime that measured
22
+ * it, so a vendor's published figure can never be mistaken for this machine's.
23
+ *
24
+ * @module @try-works/dsh-model-as-tool/invocation-accounting
25
+ */
26
+ /**
27
+ * A phase timer.
28
+ *
29
+ * Records the phases as they HAPPEN rather than inferring them afterwards, because a
30
+ * duration measured by subtraction cannot distinguish a slow load from a slow queue.
31
+ */
32
+ export class PhaseTimer {
33
+ #start;
34
+ #phases = new Map();
35
+ #current = null;
36
+ constructor(now = Date.now) {
37
+ this.#now = now;
38
+ this.#start = now();
39
+ }
40
+ #now;
41
+ /** Begin a phase, closing any phase already open. */
42
+ begin(name) {
43
+ this.end();
44
+ this.#current = { name, startedAt: this.#now() };
45
+ }
46
+ /** Close the open phase, if any. Idempotent. */
47
+ end() {
48
+ if (this.#current === null)
49
+ return;
50
+ const elapsed = this.#now() - this.#current.startedAt;
51
+ // Phases ACCUMULATE: a call may load, infer, and resume the same phase after a retry.
52
+ this.#phases.set(this.#current.name, (this.#phases.get(this.#current.name) ?? 0) + elapsed);
53
+ this.#current = null;
54
+ }
55
+ /** The timings recorded so far. */
56
+ finish() {
57
+ this.end();
58
+ return {
59
+ queuedMs: this.#phases.get('queued') ?? 0,
60
+ loadMs: this.#phases.get('load') ?? 0,
61
+ inferenceMs: this.#phases.get('inference') ?? 0,
62
+ totalMs: this.#now() - this.#start,
63
+ };
64
+ }
65
+ }
66
+ /** Classify an outcome from what was observed (OBS-01). */
67
+ export function classifyOutcome(input) {
68
+ /**
69
+ * ORDER MATTERS, and it is the caller's intent that wins.
70
+ *
71
+ * A deadline that fires will usually also surface as an abort, so checking `aborted`
72
+ * first would report every timeout as a cancellation and hide the deadline. Likewise a
73
+ * denial is a policy decision rather than a failure of the work.
74
+ */
75
+ if (input.ok)
76
+ return 'none';
77
+ if (input.denied === true)
78
+ return 'policy-denied';
79
+ if (input.refused === true)
80
+ return 'refused';
81
+ if (input.timedOut === true)
82
+ return 'timeout';
83
+ if (input.aborted === true)
84
+ return 'cancelled';
85
+ return 'failed';
86
+ }
87
+ /**
88
+ * The runtime this process is measuring on (OBS-05).
89
+ *
90
+ * Read from the process rather than configured, so a record cannot claim a platform it was
91
+ * not produced on. That is the specific defect OBS-05 names: Apple Neural Engine figures
92
+ * presented as Windows performance.
93
+ * @param engineVersion - the engine actually used for this invocation.
94
+ * @returns the measurement context.
95
+ */
96
+ export function measurementContext(engineVersion) {
97
+ return {
98
+ platform: process.platform,
99
+ architecture: process.arch,
100
+ nodeVersion: process.version,
101
+ engineVersion,
102
+ };
103
+ }
104
+ /**
105
+ * Build an accounting record (OBS-01).
106
+ *
107
+ * Sizes are computed from the SERIALIZED forms because that is what crossed the boundary;
108
+ * an object's in-memory size is not what a caller paid for.
109
+ * @param request - what to record.
110
+ * @returns the accounting record.
111
+ */
112
+ export function accountInvocation(request) {
113
+ return {
114
+ receiptId: request.receiptId,
115
+ timings: request.timings,
116
+ sizes: {
117
+ inputBytes: byteLengthOf(request.input),
118
+ // An absent output is ZERO bytes rather than unknown: nothing crossed the boundary,
119
+ // and reporting `null` would invite a reader to treat it as unmeasured.
120
+ outputBytes: request.output === undefined ? 0 : byteLengthOf(request.output),
121
+ assetBytes: request.assetBytes ?? 0,
122
+ },
123
+ failureClass: request.failureClass,
124
+ reason: request.reason ?? null,
125
+ timingSource: 'measured',
126
+ measuredOn: measurementContext(request.engineVersion),
127
+ ...request.grantId === undefined
128
+ ? {}
129
+ : { grantId: request.grantId, ...request.clientId === undefined ? {} : { clientId: request.clientId } },
130
+ };
131
+ }
132
+ /** Serialized byte length, with a defined answer for values that cannot serialize. */
133
+ function byteLengthOf(value) {
134
+ try {
135
+ const serialized = JSON.stringify(value);
136
+ // `undefined` and functions serialize to `undefined`, which is zero bytes on the wire.
137
+ return serialized === undefined ? 0 : Buffer.byteLength(serialized, 'utf8');
138
+ }
139
+ catch {
140
+ /**
141
+ * A cyclic or otherwise unserializable value did cross the boundary, but its size is
142
+ * unknown — and reporting `0` would understate it. Recorded as `-1`, which no real
143
+ * payload can produce, so a reader sees "unmeasured" rather than "empty".
144
+ */
145
+ return -1;
146
+ }
147
+ }
148
+ //# sourceMappingURL=invocation-accounting.js.map
@@ -0,0 +1,95 @@
1
+ /**
2
+ * The startup hook that migrates a legacy model-id era `state.json` into the
3
+ * versioned world (BASE-09, BASE-10), ONCE per profile — as a REAL
4
+ * transaction with crash recovery, not a read-then-overwrite.
5
+ *
6
+ * Before this module the migration table existed only as an SDK library with
7
+ * tests: nothing in the host's production startup ever ran it, so a real
8
+ * upgrade kept reading the old-world document forever. This module is the
9
+ * production caller. Its guarantees:
10
+ *
11
+ * - ONCE-ANCHOR + COMMIT: a non-secret sidecar marker
12
+ * (`<stateFile>.migrated.json`) is the commit record, written ATOMICALLY
13
+ * (temp + fsync + rename) as the LAST step of the transaction. The host's
14
+ * own state document keeps its exact shape — the store's writes are
15
+ * untouched and no parallel format is written. A marker is VALIDATED on
16
+ * every read (parse + exact version + list shape): a corrupt or
17
+ * foreign-version marker FAILS CLOSED instead of silently counting the
18
+ * profile as migrated;
19
+ * - IMMUTABLE JOURNAL: before ANY mutation, the original legacy document is
20
+ * journaled to `<stateFile>.legacy-backup.json` with EXCLUSIVE creation
21
+ * (`wx`). The journal is the legacy INPUT for every recovery. Its
22
+ * first-write-wins behavior is guaranteed BY THE TRANSACTION LOCK (the
23
+ * exists-check before the rename is advisory, not a lock);
24
+ * - RECOVERY: a crash between the host write and the marker leaves a journal
25
+ * WITHOUT a committed marker. The next boot detects that state and re-runs
26
+ * the transaction FROM THE VALIDATED JOURNAL — never from the already-
27
+ * rewritten state file, which has lost the staged enables, provider picks
28
+ * and prepared-asset facts. The host write MERGES with the current
29
+ * document (current enables are operator-era facts and are preserved;
30
+ * legacy disables are added), so an operator change after the crash is
31
+ * never discarded. A corrupt journal with no marker FAILS CLOSED;
32
+ * - TRANSACTION LOCK: the whole transaction runs under an exclusive lock
33
+ * file with an ownership token and pid. A stale lock is NEVER taken over
34
+ * automatically — the read-then-remove sequence is not atomic and two
35
+ * concurrent reapers could delete a successor's fresh lock — so a held lock
36
+ * FAILS CLOSED at the deadline and the operator removes it deliberately;
37
+ * release removes only a token-owned lock (the same discipline as the
38
+ * credential store);
39
+ * - the SDK profile half runs THROUGH the SDK's own
40
+ * `migrateLegacyProfileState` (its lock, idempotence, version gate) BEFORE
41
+ * the host document is written;
42
+ * - DISABLED legacy choices are preserved — ALL of them, mapped or not: an
43
+ * unmapped disabled id that vanished from the host state would let a later
44
+ * package restore silently enable what the operator turned off. Unresolved
45
+ * ids are REPORTED separately, never enabled;
46
+ * - legacy ENABLES are STAGED, never granted (BASE-10: a legacy enable is
47
+ * not consent to install, activate or prepare third-party code);
48
+ * - every persisted artifact (marker, journal, lock) is NON-SECRET by
49
+ * construction: model ids, provider identifiers and counts, never a secret.
50
+ *
51
+ * @module @try-works/dsh-model-as-tool/legacy-migration
52
+ */
53
+ import { type PersistedState, type StateStore } from './state.ts';
54
+ /** The marker version this host writes; equality, never a lower bound. */
55
+ export declare const MIGRATION_MARKER_VERSION: 1;
56
+ /** What the startup hook did. */
57
+ export interface LegacyStartupOutcome {
58
+ /** False when there was nothing to migrate (marker present, or fresh profile). */
59
+ readonly ran: boolean;
60
+ /** The host choices to adopt after the run (the caller replaces its persisted copy). */
61
+ readonly hostState: PersistedState;
62
+ /** Legacy model ids that were ENABLED and are therefore STAGED, never granted. */
63
+ readonly staged: readonly string[];
64
+ /** Legacy ids the table could not map; reported, never enabled. */
65
+ readonly unresolved: readonly string[];
66
+ /** A non-secret one-line summary for the startup log, when anything happened. */
67
+ readonly logLine: string | undefined;
68
+ /** True when this run RECOVERED an interrupted transaction from the journal. */
69
+ readonly recovered: boolean;
70
+ }
71
+ /** The marker path for one state file. */
72
+ export declare function migrationMarkerPath(stateFile: string): string;
73
+ /** The backup path for one state file. */
74
+ export declare function legacyBackupPath(stateFile: string): string;
75
+ /** The transaction lock path for one state file. */
76
+ export declare function migrationLockPath(stateFile: string): string;
77
+ /**
78
+ * Run the one-time legacy startup migration (with crash recovery).
79
+ *
80
+ * @param options.stateFile - the host's configured isolated state path.
81
+ * @param options.store - the host's state store over that path.
82
+ * @param options.extensionStoreDir - when the deployment mounts an extension
83
+ * store, the SDK profile migration runs there too.
84
+ * @param options.log - a non-secret log sink (the host's logger).
85
+ * @returns the outcome; the caller ALWAYS adopts `hostState` (the hook returns
86
+ * a fresh post-lock read on every path, so adopting it never re-applies a
87
+ * pre-hook snapshot).
88
+ */
89
+ export declare function runLegacyStartupMigration(options: {
90
+ readonly stateFile: string;
91
+ readonly store: StateStore;
92
+ readonly extensionStoreDir?: string;
93
+ readonly log?: (line: string) => void;
94
+ }): Promise<LegacyStartupOutcome>;
95
+ //# sourceMappingURL=legacy-migration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legacy-migration.d.ts","sourceRoot":"","sources":["../src/legacy-migration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAqBH,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAA;AAGjE,0EAA0E;AAC1E,eAAO,MAAM,wBAAwB,EAAG,CAAU,CAAA;AAElD,iCAAiC;AACjC,MAAM,WAAW,oBAAoB;IACnC,kFAAkF;IAClF,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAA;IACrB,wFAAwF;IACxF,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAA;IAClC,kFAAkF;IAClF,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;IAClC,mEAAmE;IACnE,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAA;IACtC,iFAAiF;IACjF,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC,gFAAgF;IAChF,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;CAC5B;AA2BD,0CAA0C;AAC1C,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,0CAA0C;AAC1C,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,oDAAoD;AACpD,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE3D;AA+ND;;;;;;;;;;;GAWG;AACH,wBAAsB,yBAAyB,CAAC,OAAO,EAAE;IACvD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;IAC1B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;IACnC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CACtC,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAWhC"}