@try-works/dsh-model-as-tool 0.1.3 → 0.4.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 (260) 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 +614 -0
  5. package/client/index.js +1717 -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 +325 -0
  19. package/lib/extension-dependencies.d.ts.map +1 -0
  20. package/lib/extension-dependencies.js +858 -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 +221 -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 +367 -0
  34. package/lib/extensions-service.d.ts.map +1 -0
  35. package/lib/extensions-service.js +1527 -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 +271 -7
  49. package/lib/index.d.ts.map +1 -1
  50. package/lib/index.js +2644 -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/standard.d.ts +38 -0
  130. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/standard.d.ts.map +1 -0
  131. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/standard.js +445 -0
  132. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-embed.d.ts +14 -0
  133. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-embed.d.ts.map +1 -0
  134. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-embed.js +63 -0
  135. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-rerank.d.ts +14 -0
  136. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-rerank.d.ts.map +1 -0
  137. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-rerank.js +76 -0
  138. package/node_modules/@try-works/tool-mode-contracts/lib/dsh.d.ts.map +1 -1
  139. package/node_modules/@try-works/tool-mode-contracts/lib/dsh.js +69 -55
  140. package/node_modules/@try-works/tool-mode-contracts/lib/index.d.ts +4 -1
  141. package/node_modules/@try-works/tool-mode-contracts/lib/index.d.ts.map +1 -1
  142. package/node_modules/@try-works/tool-mode-contracts/lib/index.js +26 -2
  143. package/node_modules/@try-works/tool-mode-contracts/lib/registry.d.ts +28 -2
  144. package/node_modules/@try-works/tool-mode-contracts/lib/registry.d.ts.map +1 -1
  145. package/node_modules/@try-works/tool-mode-contracts/lib/registry.js +93 -10
  146. package/node_modules/@try-works/tool-mode-contracts/package.json +0 -1
  147. package/node_modules/@try-works/tool-mode-extension-sdk/bin/dsh-tool-mode.mjs +20 -0
  148. package/node_modules/@try-works/tool-mode-extension-sdk/lib/cli.d.ts +80 -0
  149. package/node_modules/@try-works/tool-mode-extension-sdk/lib/cli.d.ts.map +1 -0
  150. package/node_modules/@try-works/tool-mode-extension-sdk/lib/cli.js +533 -0
  151. package/node_modules/@try-works/tool-mode-extension-sdk/lib/declarative-recipes.d.ts +83 -0
  152. package/node_modules/@try-works/tool-mode-extension-sdk/lib/declarative-recipes.d.ts.map +1 -0
  153. package/node_modules/@try-works/tool-mode-extension-sdk/lib/declarative-recipes.js +125 -0
  154. package/node_modules/@try-works/tool-mode-extension-sdk/lib/discovery.d.ts +70 -0
  155. package/node_modules/@try-works/tool-mode-extension-sdk/lib/discovery.d.ts.map +1 -0
  156. package/node_modules/@try-works/tool-mode-extension-sdk/lib/discovery.js +201 -0
  157. package/node_modules/@try-works/tool-mode-extension-sdk/lib/errors.d.ts +57 -0
  158. package/node_modules/@try-works/tool-mode-extension-sdk/lib/errors.d.ts.map +1 -0
  159. package/node_modules/@try-works/tool-mode-extension-sdk/lib/errors.js +83 -0
  160. package/node_modules/@try-works/tool-mode-extension-sdk/lib/index.d.ts +32 -0
  161. package/node_modules/@try-works/tool-mode-extension-sdk/lib/index.d.ts.map +1 -0
  162. package/node_modules/@try-works/tool-mode-extension-sdk/lib/index.js +32 -0
  163. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/archive.d.ts +86 -0
  164. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/archive.d.ts.map +1 -0
  165. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/archive.js +191 -0
  166. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/dependencies.d.ts +126 -0
  167. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/dependencies.d.ts.map +1 -0
  168. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/dependencies.js +297 -0
  169. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/lifecycle.d.ts +216 -0
  170. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/lifecycle.d.ts.map +1 -0
  171. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/lifecycle.js +800 -0
  172. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/migration.d.ts +210 -0
  173. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/migration.d.ts.map +1 -0
  174. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/migration.js +368 -0
  175. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/runtime-link.d.ts +63 -0
  176. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/runtime-link.d.ts.map +1 -0
  177. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/runtime-link.js +149 -0
  178. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/source-directory.d.ts +35 -0
  179. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/source-directory.d.ts.map +1 -0
  180. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/source-directory.js +179 -0
  181. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/staged.d.ts +179 -0
  182. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/staged.d.ts.map +1 -0
  183. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/staged.js +235 -0
  184. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/store.d.ts +367 -0
  185. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/store.d.ts.map +1 -0
  186. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/store.js +807 -0
  187. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/tar-gzip-source.d.ts +44 -0
  188. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/tar-gzip-source.d.ts.map +1 -0
  189. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/tar-gzip-source.js +243 -0
  190. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/update-flow.d.ts +185 -0
  191. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/update-flow.d.ts.map +1 -0
  192. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/update-flow.js +504 -0
  193. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/zip-source.d.ts +17 -0
  194. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/zip-source.d.ts.map +1 -0
  195. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/zip-source.js +80 -0
  196. package/node_modules/@try-works/tool-mode-extension-sdk/lib/load.d.ts +52 -0
  197. package/node_modules/@try-works/tool-mode-extension-sdk/lib/load.d.ts.map +1 -0
  198. package/node_modules/@try-works/tool-mode-extension-sdk/lib/load.js +102 -0
  199. package/node_modules/@try-works/tool-mode-extension-sdk/lib/manifest.d.ts +171 -0
  200. package/node_modules/@try-works/tool-mode-extension-sdk/lib/manifest.d.ts.map +1 -0
  201. package/node_modules/@try-works/tool-mode-extension-sdk/lib/manifest.js +271 -0
  202. package/node_modules/@try-works/tool-mode-extension-sdk/lib/runtime.d.ts +242 -0
  203. package/node_modules/@try-works/tool-mode-extension-sdk/lib/runtime.d.ts.map +1 -0
  204. package/node_modules/@try-works/tool-mode-extension-sdk/lib/runtime.js +58 -0
  205. package/node_modules/@try-works/tool-mode-extension-sdk/lib/state.d.ts +118 -0
  206. package/node_modules/@try-works/tool-mode-extension-sdk/lib/state.d.ts.map +1 -0
  207. package/node_modules/@try-works/tool-mode-extension-sdk/lib/state.js +113 -0
  208. package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker/worker-child.d.ts +2 -0
  209. package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker/worker-child.d.ts.map +1 -0
  210. package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker/worker-child.js +351 -0
  211. package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker.d.ts +150 -0
  212. package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker.d.ts.map +1 -0
  213. package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker.js +670 -0
  214. package/node_modules/@try-works/tool-mode-extension-sdk/package.json +53 -0
  215. package/node_modules/@try-works/tool-mode-extension-sdk/schema/extension-manifest-1.1.0.schema.json +253 -0
  216. package/node_modules/@try-works/tool-mode-recipes/bin/tool-mode-recipe.mjs +15 -0
  217. package/node_modules/@try-works/tool-mode-recipes/lib/broker.d.ts +427 -0
  218. package/node_modules/@try-works/tool-mode-recipes/lib/broker.d.ts.map +1 -0
  219. package/node_modules/@try-works/tool-mode-recipes/lib/broker.js +592 -0
  220. package/node_modules/@try-works/tool-mode-recipes/lib/cli.d.ts +60 -0
  221. package/node_modules/@try-works/tool-mode-recipes/lib/cli.d.ts.map +1 -0
  222. package/node_modules/@try-works/tool-mode-recipes/lib/cli.js +936 -0
  223. package/node_modules/@try-works/tool-mode-recipes/lib/dsh-adapter.d.ts +237 -0
  224. package/node_modules/@try-works/tool-mode-recipes/lib/dsh-adapter.d.ts.map +1 -0
  225. package/node_modules/@try-works/tool-mode-recipes/lib/dsh-adapter.js +200 -0
  226. package/node_modules/@try-works/tool-mode-recipes/lib/fixture-provider.d.ts +85 -0
  227. package/node_modules/@try-works/tool-mode-recipes/lib/fixture-provider.d.ts.map +1 -0
  228. package/node_modules/@try-works/tool-mode-recipes/lib/fixture-provider.js +176 -0
  229. package/node_modules/@try-works/tool-mode-recipes/lib/images.d.ts +105 -0
  230. package/node_modules/@try-works/tool-mode-recipes/lib/images.d.ts.map +1 -0
  231. package/node_modules/@try-works/tool-mode-recipes/lib/images.js +129 -0
  232. package/node_modules/@try-works/tool-mode-recipes/lib/index.d.ts +25 -0
  233. package/node_modules/@try-works/tool-mode-recipes/lib/index.d.ts.map +1 -0
  234. package/node_modules/@try-works/tool-mode-recipes/lib/index.js +25 -0
  235. package/node_modules/@try-works/tool-mode-recipes/lib/recipe-format.d.ts +325 -0
  236. package/node_modules/@try-works/tool-mode-recipes/lib/recipe-format.d.ts.map +1 -0
  237. package/node_modules/@try-works/tool-mode-recipes/lib/recipe-format.js +1310 -0
  238. package/node_modules/@try-works/tool-mode-recipes/lib/templates.d.ts +51 -0
  239. package/node_modules/@try-works/tool-mode-recipes/lib/templates.d.ts.map +1 -0
  240. package/node_modules/@try-works/tool-mode-recipes/lib/templates.js +310 -0
  241. package/node_modules/@try-works/tool-mode-recipes/lib/titles.d.ts +227 -0
  242. package/node_modules/@try-works/tool-mode-recipes/lib/titles.d.ts.map +1 -0
  243. package/node_modules/@try-works/tool-mode-recipes/lib/titles.js +407 -0
  244. package/node_modules/@try-works/tool-mode-recipes/package.json +56 -0
  245. package/node_modules/@try-works/tool-mode-recipes/recipes/describe-image.json +38 -0
  246. package/node_modules/@try-works/tool-mode-recipes/recipes/text-title.json +45 -0
  247. package/node_modules/@try-works/tool-mode-recipes/schema/harness-model-recipe.schema.json +273 -0
  248. package/package.json +43 -15
  249. package/remote/spec.mjs +462 -0
  250. package/remote/typert.host.mjs +14 -0
  251. package/remote/typert.remote-client.mjs +16 -0
  252. package/lib/adapters/tongue.d.ts +0 -31
  253. package/lib/adapters/tongue.d.ts.map +0 -1
  254. package/lib/adapters/tongue.js +0 -93
  255. package/lib/adapters/voz.d.ts +0 -28
  256. package/lib/adapters/voz.d.ts.map +0 -1
  257. package/lib/adapters/voz.js +0 -102
  258. /package/{lib → node_modules/@try-works/tool-mode-extension-sdk/lib}/licensing.d.ts +0 -0
  259. /package/{lib → node_modules/@try-works/tool-mode-extension-sdk/lib}/licensing.d.ts.map +0 -0
  260. /package/{lib → node_modules/@try-works/tool-mode-extension-sdk/lib}/licensing.js +0 -0
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Provider-backed dispatch for extension-declared tools (EXT-19, EXT-21, EXT-22, ARCH-05).
3
+ *
4
+ * The TMX runtime API has **no tool-invocation surface**. `ExtensionInstanceV1` exposes
5
+ * exactly `createProvider` and `dispose` — nothing else. So an extension's tool is not
6
+ * something the host calls directly; the tool is a caller-facing NAME whose contract is
7
+ * bound to an IMPLEMENTATION, and the implementation is a model PROVIDER.
8
+ *
9
+ * manifest.tools[] -> the caller-facing name and its contract
10
+ * manifest.implementations[] -> which contract, served by which model
11
+ * instance.createProvider() -> the thing that actually runs
12
+ *
13
+ * That chain is what this module walks. An earlier version of the host registrar
14
+ * registered a tool whose `execute` simply REFUSED, which was honest about there being no
15
+ * implementation bound but left the bridge functionally incomplete: the name appeared in
16
+ * the registry and could never be called.
17
+ *
18
+ * The context is INJECTED so the chain is testable without a real extension on disk.
19
+ *
20
+ * @module @try-works/dsh-model-as-tool/extension-dispatch
21
+ */
22
+ import type { PreparedAssetMap } from './prepared-assets.ts';
23
+ /** What a manifest declares about one tool. */
24
+ export interface DeclaredTool {
25
+ readonly name: string;
26
+ readonly contractId: string;
27
+ readonly contractVersion: string;
28
+ }
29
+ /** What a manifest declares about one implementation. */
30
+ export interface DeclaredImplementation {
31
+ readonly id: string;
32
+ readonly contractId: string;
33
+ readonly contractVersion: string;
34
+ /** The model that serves the contract. */
35
+ readonly modelId: string;
36
+ }
37
+ /** The parts of a manifest this module needs. */
38
+ export interface DispatchManifest {
39
+ readonly tools: readonly DeclaredTool[];
40
+ readonly implementations: readonly DeclaredImplementation[];
41
+ }
42
+ /** A provider, narrowed to what dispatch needs. */
43
+ export interface DispatchProvider {
44
+ load(request: {
45
+ readonly assets: unknown;
46
+ readonly signal: AbortSignal;
47
+ /** The manifest model id; the managed worker's load keys by it. */
48
+ readonly modelId?: string;
49
+ }): Promise<void>;
50
+ invoke(request: {
51
+ readonly implementationId: string;
52
+ readonly input: Readonly<Record<string, unknown>>;
53
+ readonly context: unknown;
54
+ }): Promise<Record<string, unknown>>;
55
+ }
56
+ /** What dispatch needs from the host to reach an extension. */
57
+ export interface DispatchEnvironment {
58
+ /** The manifest of the activated extension that declared the tool. */
59
+ getManifest(): DispatchManifest;
60
+ /** Create (or return a cached) provider for a model deployment. */
61
+ providerFor(modelId: string): Promise<DispatchProvider>;
62
+ /** Build the invocation context, which carries host-issued identity. */
63
+ contextFor(implementationId: string, signal: AbortSignal): unknown;
64
+ /**
65
+ * The host's verified prepared-asset map for THIS extension, or undefined
66
+ * when nothing was prepared (the load then receives the EMPTY map — an
67
+ * extension needing assets refuses by name inside its own load, which is the
68
+ * honest MOD-02 behavior rather than an invented verification). Closes over
69
+ * the extension the environment was built for.
70
+ */
71
+ assetsFor?(): PreparedAssetMap | undefined;
72
+ }
73
+ /** Why a tool could not be dispatched. */
74
+ export interface DispatchFailure {
75
+ readonly code: 'not-declared' | 'no-implementation' | 'unsupported';
76
+ readonly message: string;
77
+ readonly remedy: string;
78
+ }
79
+ /**
80
+ * Resolve the implementation chain for a declared tool.
81
+ *
82
+ * @param manifest - the activated extension's manifest.
83
+ * @param toolName - the caller-facing name.
84
+ * @returns the tool, its implementation, or why the chain is incomplete.
85
+ */
86
+ export declare function resolveImplementation(manifest: DispatchManifest, toolName: string): {
87
+ readonly ok: true;
88
+ readonly tool: DeclaredTool;
89
+ readonly implementation: DeclaredImplementation;
90
+ } | {
91
+ readonly ok: false;
92
+ readonly failure: DispatchFailure;
93
+ };
94
+ /**
95
+ * Build an `execute` for one declared tool.
96
+ *
97
+ * The provider is created lazily on first call, so ACTIVATION stays lightweight as EXT-19
98
+ * requires: nothing is loaded until a caller actually invokes the tool.
99
+ *
100
+ * @param environment - how to reach the extension.
101
+ * @param toolName - the caller-facing name.
102
+ * @returns the execute function, or the failure that prevents one.
103
+ */
104
+ export declare function createDispatch(environment: DispatchEnvironment, toolName: string): Promise<{
105
+ readonly ok: true;
106
+ readonly execute: (args: Record<string, unknown>, signal: AbortSignal) => Promise<Record<string, unknown>>;
107
+ } | {
108
+ readonly ok: false;
109
+ readonly failure: DispatchFailure;
110
+ }>;
111
+ /**
112
+ * Describe a dispatch failure for a caller (EXT-30).
113
+ * @param failure - the failure.
114
+ * @returns a readable message naming what to do.
115
+ */
116
+ export declare function describeDispatchFailure(failure: DispatchFailure): string;
117
+ //# sourceMappingURL=extension-dispatch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-dispatch.d.ts","sourceRoot":"","sources":["../src/extension-dispatch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Provider-backed dispatch for extension-declared tools (EXT-19, EXT-21, EXT-22, ARCH-05).
3
+ *
4
+ * The TMX runtime API has **no tool-invocation surface**. `ExtensionInstanceV1` exposes
5
+ * exactly `createProvider` and `dispose` — nothing else. So an extension's tool is not
6
+ * something the host calls directly; the tool is a caller-facing NAME whose contract is
7
+ * bound to an IMPLEMENTATION, and the implementation is a model PROVIDER.
8
+ *
9
+ * manifest.tools[] -> the caller-facing name and its contract
10
+ * manifest.implementations[] -> which contract, served by which model
11
+ * instance.createProvider() -> the thing that actually runs
12
+ *
13
+ * That chain is what this module walks. An earlier version of the host registrar
14
+ * registered a tool whose `execute` simply REFUSED, which was honest about there being no
15
+ * implementation bound but left the bridge functionally incomplete: the name appeared in
16
+ * the registry and could never be called.
17
+ *
18
+ * The context is INJECTED so the chain is testable without a real extension on disk.
19
+ *
20
+ * @module @try-works/dsh-model-as-tool/extension-dispatch
21
+ */
22
+ import { assertNoReservedMeta } from '@try-works/tool-mode-extension-sdk';
23
+ /**
24
+ * Resolve the implementation chain for a declared tool.
25
+ *
26
+ * @param manifest - the activated extension's manifest.
27
+ * @param toolName - the caller-facing name.
28
+ * @returns the tool, its implementation, or why the chain is incomplete.
29
+ */
30
+ export function resolveImplementation(manifest, toolName) {
31
+ const tool = manifest.tools.find(candidate => candidate.name === toolName);
32
+ if (tool === undefined) {
33
+ return {
34
+ ok: false,
35
+ failure: {
36
+ code: 'not-declared',
37
+ message: `${toolName} is not declared by this extension's manifest`,
38
+ remedy: 'A registered tool must be declared in the manifest it was published from.',
39
+ },
40
+ };
41
+ }
42
+ const implementation = manifest.implementations.find(candidate => candidate.contractId === tool.contractId && candidate.contractVersion === tool.contractVersion);
43
+ if (implementation === undefined) {
44
+ /**
45
+ * THE HONEST REFUSAL, and the case the earlier stub conflated with every other.
46
+ *
47
+ * An extension may DECLARE a tool it does not yet serve — EmbeddingGemma does exactly
48
+ * this, listing contracts whose ONNX path is not wired. The name is legitimately
49
+ * registered and legitimately uncallable, and the caller must be told WHICH of those
50
+ * two situations they are in.
51
+ */
52
+ return {
53
+ ok: false,
54
+ failure: {
55
+ code: 'no-implementation',
56
+ message: `${toolName} declares contract ${tool.contractId}, which no implementation serves`,
57
+ remedy: 'The extension declares this tool but binds no model to it yet; it is not callable in this build.',
58
+ },
59
+ };
60
+ }
61
+ return { ok: true, tool, implementation };
62
+ }
63
+ /**
64
+ * Build an `execute` for one declared tool.
65
+ *
66
+ * The provider is created lazily on first call, so ACTIVATION stays lightweight as EXT-19
67
+ * requires: nothing is loaded until a caller actually invokes the tool.
68
+ *
69
+ * @param environment - how to reach the extension.
70
+ * @param toolName - the caller-facing name.
71
+ * @returns the execute function, or the failure that prevents one.
72
+ */
73
+ export async function createDispatch(environment, toolName) {
74
+ const resolved = resolveImplementation(environment.getManifest(), toolName);
75
+ if (!resolved.ok)
76
+ return resolved;
77
+ const { implementation } = resolved;
78
+ return {
79
+ ok: true,
80
+ async execute(args, signal) {
81
+ // Resolved per call rather than captured, so a provider that was unloaded — or an
82
+ // extension that was deactivated and reactivated — is not served from a stale handle.
83
+ const provider = await environment.providerFor(implementation.modelId);
84
+ /**
85
+ * The HOST-VERIFIED prepared-asset map, when a preparation completed.
86
+ * An absent map means the empty map — the extension's own load refuses a
87
+ * missing group by name (MOD-02), which is the honest outcome rather than
88
+ * a host that invents a verification that never happened. The same map
89
+ * reaches BOTH provider routes here: the in-process module provider and
90
+ * the managed worker (its load forwards the assets to the child).
91
+ */
92
+ const prepared = environment.assetsFor?.();
93
+ await provider.load({ assets: prepared ?? { get: () => undefined, assetIds: [] }, signal, modelId: implementation.modelId });
94
+ const value = await provider.invoke({
95
+ implementationId: implementation.id,
96
+ input: args,
97
+ context: environment.contextFor(implementation.id, signal),
98
+ });
99
+ /**
100
+ * THE EXT-17 META RESERVATION IS ENFORCED HERE, AT THE DISPATCH BOUNDARY.
101
+ *
102
+ * The reserved root `meta` is HOST-authored provenance; an extension supplying one
103
+ * is asserting who ran it and under what receipt, which it does not get to do. The
104
+ * ProviderBridge asserts this on the CATALOG path, but the contribution path
105
+ * (module and declarative providers alike) went unasserted — so a provider that
106
+ * smuggled a `meta` key reached callers whenever its declared output schema did not
107
+ * require the envelope. Asserting at the boundary the two provider routes share
108
+ * closes the gap for both, and it runs BEFORE any host stamping, so a forged
109
+ * envelope is refused rather than overwritten.
110
+ */
111
+ assertNoReservedMeta(value, implementation.id);
112
+ return value;
113
+ },
114
+ };
115
+ }
116
+ /**
117
+ * Describe a dispatch failure for a caller (EXT-30).
118
+ * @param failure - the failure.
119
+ * @returns a readable message naming what to do.
120
+ */
121
+ export function describeDispatchFailure(failure) {
122
+ return `${failure.message}. ${failure.remedy}`;
123
+ }
124
+ //# sourceMappingURL=extension-dispatch.js.map
@@ -0,0 +1,100 @@
1
+ /**
2
+ * The host-side contribution registrar (EXT-21..EXT-30, ARCH-06).
3
+ *
4
+ * This is the bridge that was MISSING: `ExtensionLifecycle` could install, activate and
5
+ * publish contributions, and the SDK was fully tested doing so — but the HOST never
6
+ * mounted the lifecycle, so **no extension's tools ever reached the DSH registry**. An
7
+ * extension could be installed, activated and reported `observedActivation: 'active'` with
8
+ * its tool listed, and a caller still could not invoke it.
9
+ *
10
+ * The registrar is the other half: it turns a published contribution into a real registry
11
+ * entry, and withdraws it again on deactivation.
12
+ *
13
+ * Four rules, each of which has been a real defect somewhere:
14
+ *
15
+ * - **Handles are opaque and unguessable.** An extension must not be able to construct a
16
+ * handle and withdraw a contribution it does not own. A sequence number is guessable;
17
+ * the handle is a branded object the caller never sees the inside of.
18
+ * - **Withdrawing is idempotent.** A deactivation that runs twice must not throw the
19
+ * second time, and must not withdraw a DIFFERENT contribution that reused the handle.
20
+ * - **A name collision is refused, not silently overwritten.** Two extensions contributing
21
+ * `transcribe` is a configuration error; letting the second win would silently change
22
+ * what an existing caller reaches.
23
+ * - **The host stamps identity.** The contribution carries an extension id, but the HOST
24
+ * decides what that means; a package claiming another's id is refused rather than
25
+ * trusted.
26
+ *
27
+ * @module @try-works/dsh-model-as-tool/extension-registrar
28
+ */
29
+ import type { Contribution, ContributionRegistrar } from '@try-works/tool-mode-extension-sdk';
30
+ /** One thing the registrar can put into the DSH registry. */
31
+ export interface RegistrableTool {
32
+ /** The caller-facing tool name. */
33
+ readonly name: string;
34
+ /** The extension that owns it, as the HOST resolved it. */
35
+ readonly ownerExtension: string;
36
+ /** The contract it implements, when it declares one. */
37
+ readonly contractId?: string;
38
+ }
39
+ /** What the registrar needs from the host registry. */
40
+ export interface HostRegistrySurface {
41
+ /**
42
+ * Register one tool.
43
+ * @param tool - the tool, with identity already stamped by the host.
44
+ * @returns a disposer that removes it.
45
+ */
46
+ registerTool(tool: RegistrableTool): () => void;
47
+ /** Register one skill, returning a disposer. */
48
+ registerSkill?(skill: {
49
+ readonly name: string;
50
+ readonly ownerExtension: string;
51
+ }): () => void;
52
+ /**
53
+ * Register the CALLER-FACING tools of one declarative implementation (RCP-01).
54
+ *
55
+ * A declarative package declares implementations only — its manifest has no
56
+ * `tools` array — so the tool names and schemas come from the RESOLVED RECIPES,
57
+ * which only the host can turn into registry entries (the recipes need the
58
+ * deployment's harness provider to be served at all). The contribution arrives
59
+ * per implementation; the host resolves the package's recipes and registers the
60
+ * matching tool, returning its disposer. Absent (or a non-declarative package)
61
+ * keeps the earlier behavior: implementations publish nothing.
62
+ */
63
+ registerDeclarative?(contribution: {
64
+ readonly extensionId: string;
65
+ readonly name: string;
66
+ readonly contractId?: string;
67
+ }): () => void;
68
+ }
69
+ /** Raised when a contribution cannot be published. */
70
+ export declare class ContributionError extends Error {
71
+ readonly name = "ContributionError";
72
+ readonly code: 'name-collision' | 'unsupported-kind' | 'unknown-extension';
73
+ constructor(code: ContributionError['code'], message: string);
74
+ }
75
+ /**
76
+ * The published contributions, keyed by handle id.
77
+ *
78
+ * A Map rather than a field on the handle, so an extension that receives a handle cannot
79
+ * reach the disposer or another extension's entry through it.
80
+ */
81
+ export interface RegistrarOptions {
82
+ readonly registry: HostRegistrySurface;
83
+ /**
84
+ * The extensions the host has ACTIVATED.
85
+ *
86
+ * A contribution from an extension not in this set is refused: publishing is a privilege
87
+ * of activation, and without this check any code holding the registrar could register a
88
+ * tool under an extension that was never installed.
89
+ */
90
+ readonly activated: ReadonlySet<string>;
91
+ /** Called when a contribution is refused, so the reason is recorded rather than lost. */
92
+ readonly onRefused?: (contribution: Contribution, error: ContributionError) => void;
93
+ }
94
+ /**
95
+ * Create the registrar the lifecycle publishes through.
96
+ * @param options - the registry surface and the activated set.
97
+ * @returns the registrar.
98
+ */
99
+ export declare function createContributionRegistrar(options: RegistrarOptions): ContributionRegistrar;
100
+ //# sourceMappingURL=extension-registrar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-registrar.d.ts","sourceRoot":"","sources":["../src/extension-registrar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAA;AAE7F,6DAA6D;AAC7D,MAAM,WAAW,eAAe;IAC9B,mCAAmC;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,2DAA2D;IAC3D,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,wDAAwD;IACxD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAC7B;AAED,uDAAuD;AACvD,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,YAAY,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,IAAI,CAAA;IAC/C,gDAAgD;IAChD,aAAa,CAAC,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,IAAI,CAAA;IAC7F;;;;;;;;;;OAUG;IACH,mBAAmB,CAAC,CAAC,YAAY,EAAE;QACjC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;QAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;QACrB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAC7B,GAAG,MAAM,IAAI,CAAA;CACf;AAED,sDAAsD;AACtD,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,SAAkB,IAAI,uBAAsB;IAC5C,QAAQ,CAAC,IAAI,EAAE,gBAAgB,GAAG,kBAAkB,GAAG,mBAAmB,CAAA;gBAC9D,IAAI,EAAE,iBAAiB,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM;CAI7D;AAUD;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAA;IACtC;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACvC,yFAAyF;IACzF,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAA;CACpF;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,gBAAgB,GAAG,qBAAqB,CAkG5F"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * The host-side contribution registrar (EXT-21..EXT-30, ARCH-06).
3
+ *
4
+ * This is the bridge that was MISSING: `ExtensionLifecycle` could install, activate and
5
+ * publish contributions, and the SDK was fully tested doing so — but the HOST never
6
+ * mounted the lifecycle, so **no extension's tools ever reached the DSH registry**. An
7
+ * extension could be installed, activated and reported `observedActivation: 'active'` with
8
+ * its tool listed, and a caller still could not invoke it.
9
+ *
10
+ * The registrar is the other half: it turns a published contribution into a real registry
11
+ * entry, and withdraws it again on deactivation.
12
+ *
13
+ * Four rules, each of which has been a real defect somewhere:
14
+ *
15
+ * - **Handles are opaque and unguessable.** An extension must not be able to construct a
16
+ * handle and withdraw a contribution it does not own. A sequence number is guessable;
17
+ * the handle is a branded object the caller never sees the inside of.
18
+ * - **Withdrawing is idempotent.** A deactivation that runs twice must not throw the
19
+ * second time, and must not withdraw a DIFFERENT contribution that reused the handle.
20
+ * - **A name collision is refused, not silently overwritten.** Two extensions contributing
21
+ * `transcribe` is a configuration error; letting the second win would silently change
22
+ * what an existing caller reaches.
23
+ * - **The host stamps identity.** The contribution carries an extension id, but the HOST
24
+ * decides what that means; a package claiming another's id is refused rather than
25
+ * trusted.
26
+ *
27
+ * @module @try-works/dsh-model-as-tool/extension-registrar
28
+ */
29
+ /** Raised when a contribution cannot be published. */
30
+ export class ContributionError extends Error {
31
+ name = 'ContributionError';
32
+ code;
33
+ constructor(code, message) {
34
+ super(message);
35
+ this.code = code;
36
+ }
37
+ }
38
+ /**
39
+ * Create the registrar the lifecycle publishes through.
40
+ * @param options - the registry surface and the activated set.
41
+ * @returns the registrar.
42
+ */
43
+ export function createContributionRegistrar(options) {
44
+ const published = new Map();
45
+ /** Names currently taken, so a collision is detected rather than overwritten. */
46
+ const takenNames = new Map();
47
+ let nextId = 1;
48
+ const refuse = (contribution, error) => {
49
+ options.onRefused?.(contribution, error);
50
+ throw error;
51
+ };
52
+ return {
53
+ publish(contribution) {
54
+ // ACTIVATION IS A PRECONDITION. A contribution from a package that was never
55
+ // activated is refused rather than registered.
56
+ if (!options.activated.has(contribution.extensionId)) {
57
+ return refuse(contribution, new ContributionError('unknown-extension', `${contribution.extensionId} is not activated, so it cannot publish ${contribution.name}`));
58
+ }
59
+ /**
60
+ * A COLLISION IS REFUSED. Letting the second registration win would silently change
61
+ * what an existing caller reaches — the same name would resolve to a different tool
62
+ * with no signal.
63
+ */
64
+ const existing = takenNames.get(contribution.name);
65
+ if (existing !== undefined) {
66
+ return refuse(contribution, new ContributionError('name-collision', `${contribution.name} is already published by ${existing}; `
67
+ + `${contribution.extensionId} cannot take the name over`));
68
+ }
69
+ const handle = {
70
+ __contributionHandle: true,
71
+ id: nextId++,
72
+ extensionId: contribution.extensionId,
73
+ name: contribution.name,
74
+ };
75
+ let dispose;
76
+ if (contribution.kind === 'tool') {
77
+ dispose = options.registry.registerTool({
78
+ name: contribution.name,
79
+ // The HOST stamps the owner from the contribution it validated, so a package
80
+ // cannot claim another's provenance.
81
+ ownerExtension: contribution.extensionId,
82
+ ...contribution.contractId === undefined ? {} : { contractId: contribution.contractId },
83
+ });
84
+ }
85
+ else if (contribution.kind === 'skill' && options.registry.registerSkill !== undefined) {
86
+ dispose = options.registry.registerSkill({
87
+ name: contribution.name,
88
+ ownerExtension: contribution.extensionId,
89
+ });
90
+ }
91
+ else if (contribution.kind === 'implementation' && options.registry.registerDeclarative !== undefined) {
92
+ // An `implementation` of a MODULE package is not a caller-facing tool: the model
93
+ // catalogue binds it. An implementation of a DECLARATIVE package, however, IS the
94
+ // whole package: the host turns its resolved recipe into the caller-facing tool
95
+ // here (RCP-01), and the returned disposer is tracked like any other handle.
96
+ dispose = options.registry.registerDeclarative({
97
+ extensionId: contribution.extensionId,
98
+ name: contribution.name,
99
+ ...contribution.contractId === undefined ? {} : { contractId: contribution.contractId },
100
+ });
101
+ }
102
+ else {
103
+ dispose = () => { };
104
+ }
105
+ takenNames.set(contribution.name, contribution.extensionId);
106
+ published.set(handle.id, { handle, dispose });
107
+ // The SDK types the handle as a string; the runtime value is a branded object, which
108
+ // is what makes it unforgeable. The cast is the boundary between the two.
109
+ return handle;
110
+ },
111
+ withdraw(rawHandle) {
112
+ const handle = rawHandle;
113
+ // A handle that is not ours — a string, a number, a forged object — is ignored
114
+ // rather than treated as a lookup that might match something.
115
+ if (handle === null || typeof handle !== 'object' || handle.__contributionHandle !== true)
116
+ return;
117
+ const entry = published.get(handle.id);
118
+ if (entry === undefined) {
119
+ // IDEMPOTENT: withdrawing twice is not an error, and must not withdraw whatever
120
+ // might have reused the id.
121
+ return;
122
+ }
123
+ // The handle must be the SAME one that was issued, not merely an object with the
124
+ // right id, so a reconstructed handle cannot withdraw someone else's tool.
125
+ if (entry.handle !== handle)
126
+ return;
127
+ // Failed cleanup retains ownership and the handle for an explicit retry.
128
+ entry.dispose();
129
+ published.delete(handle.id);
130
+ takenNames.delete(handle.name);
131
+ },
132
+ };
133
+ }
134
+ //# sourceMappingURL=extension-registrar.js.map