@contractspec/lib.ai-agent 1.57.0 → 1.59.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 (232) hide show
  1. package/dist/agent/agent-factory.d.ts +67 -71
  2. package/dist/agent/agent-factory.d.ts.map +1 -1
  3. package/dist/agent/agent-factory.js +658 -100
  4. package/dist/agent/agent.test.d.ts +2 -0
  5. package/dist/agent/agent.test.d.ts.map +1 -0
  6. package/dist/agent/contract-spec-agent.d.ts +48 -52
  7. package/dist/agent/contract-spec-agent.d.ts.map +1 -1
  8. package/dist/agent/contract-spec-agent.js +605 -146
  9. package/dist/agent/index.d.ts +4 -4
  10. package/dist/agent/index.d.ts.map +1 -0
  11. package/dist/agent/index.js +2102 -4
  12. package/dist/agent/json-runner.d.ts +15 -19
  13. package/dist/agent/json-runner.d.ts.map +1 -1
  14. package/dist/agent/json-runner.js +672 -57
  15. package/dist/agent/json-runner.test.d.ts +2 -0
  16. package/dist/agent/json-runner.test.d.ts.map +1 -0
  17. package/dist/agent/unified-agent.d.ts +132 -109
  18. package/dist/agent/unified-agent.d.ts.map +1 -1
  19. package/dist/agent/unified-agent.js +2011 -293
  20. package/dist/approval/index.d.ts +3 -2
  21. package/dist/approval/index.d.ts.map +1 -0
  22. package/dist/approval/index.js +128 -2
  23. package/dist/approval/workflow.d.ts +106 -110
  24. package/dist/approval/workflow.d.ts.map +1 -1
  25. package/dist/approval/workflow.js +126 -157
  26. package/dist/exporters/claude-agent-exporter.d.ts +50 -48
  27. package/dist/exporters/claude-agent-exporter.d.ts.map +1 -1
  28. package/dist/exporters/claude-agent-exporter.js +258 -203
  29. package/dist/exporters/index.d.ts +28 -4
  30. package/dist/exporters/index.d.ts.map +1 -0
  31. package/dist/exporters/index.js +737 -3
  32. package/dist/exporters/opencode-exporter.d.ts +47 -45
  33. package/dist/exporters/opencode-exporter.d.ts.map +1 -1
  34. package/dist/exporters/opencode-exporter.js +507 -191
  35. package/dist/exporters/types.d.ts +171 -169
  36. package/dist/exporters/types.d.ts.map +1 -1
  37. package/dist/exporters/types.js +1 -0
  38. package/dist/index.d.ts +15 -39
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +3337 -32
  41. package/dist/interop/index.d.ts +48 -4
  42. package/dist/interop/index.d.ts.map +1 -0
  43. package/dist/interop/index.js +709 -3
  44. package/dist/interop/spec-consumer.d.ts +57 -53
  45. package/dist/interop/spec-consumer.d.ts.map +1 -1
  46. package/dist/interop/spec-consumer.js +302 -282
  47. package/dist/interop/tool-consumer.d.ts +57 -53
  48. package/dist/interop/tool-consumer.d.ts.map +1 -1
  49. package/dist/interop/tool-consumer.js +412 -213
  50. package/dist/interop/types.d.ts +173 -171
  51. package/dist/interop/types.d.ts.map +1 -1
  52. package/dist/interop/types.js +1 -0
  53. package/dist/knowledge/index.d.ts +2 -2
  54. package/dist/knowledge/index.d.ts.map +1 -0
  55. package/dist/knowledge/index.js +66 -2
  56. package/dist/knowledge/injector.d.ts +16 -20
  57. package/dist/knowledge/injector.d.ts.map +1 -1
  58. package/dist/knowledge/injector.js +56 -47
  59. package/dist/memory/in-memory.d.ts +15 -19
  60. package/dist/memory/in-memory.d.ts.map +1 -1
  61. package/dist/memory/in-memory.js +152 -46
  62. package/dist/memory/index.d.ts +3 -3
  63. package/dist/memory/index.d.ts.map +1 -0
  64. package/dist/memory/index.js +155 -3
  65. package/dist/memory/manager.d.ts +32 -36
  66. package/dist/memory/manager.d.ts.map +1 -1
  67. package/dist/memory/manager.js +96 -70
  68. package/dist/memory/memory.test.d.ts +2 -0
  69. package/dist/memory/memory.test.d.ts.map +1 -0
  70. package/dist/node/agent/agent-factory.js +661 -0
  71. package/dist/node/agent/contract-spec-agent.js +607 -0
  72. package/dist/node/agent/index.js +2103 -0
  73. package/dist/node/agent/json-runner.js +684 -0
  74. package/dist/node/agent/unified-agent.js +2019 -0
  75. package/dist/node/approval/index.js +129 -0
  76. package/dist/node/approval/workflow.js +129 -0
  77. package/dist/node/exporters/claude-agent-exporter.js +265 -0
  78. package/dist/node/exporters/index.js +738 -0
  79. package/dist/node/exporters/opencode-exporter.js +516 -0
  80. package/dist/node/exporters/types.js +0 -0
  81. package/dist/node/index.js +3337 -0
  82. package/dist/node/interop/index.js +710 -0
  83. package/dist/node/interop/spec-consumer.js +307 -0
  84. package/dist/node/interop/tool-consumer.js +419 -0
  85. package/dist/node/interop/types.js +0 -0
  86. package/dist/node/knowledge/index.js +67 -0
  87. package/dist/node/knowledge/injector.js +67 -0
  88. package/dist/node/memory/in-memory.js +154 -0
  89. package/dist/node/memory/index.js +156 -0
  90. package/dist/node/memory/manager.js +105 -0
  91. package/dist/node/providers/claude-agent-sdk/adapter.js +624 -0
  92. package/dist/node/providers/claude-agent-sdk/index.js +673 -0
  93. package/dist/node/providers/claude-agent-sdk/session-bridge.js +149 -0
  94. package/dist/node/providers/claude-agent-sdk/tool-bridge.js +118 -0
  95. package/dist/node/providers/index.js +1261 -0
  96. package/dist/node/providers/opencode-sdk/adapter.js +669 -0
  97. package/dist/node/providers/opencode-sdk/agent-bridge.js +299 -0
  98. package/dist/node/providers/opencode-sdk/index.js +703 -0
  99. package/dist/node/providers/opencode-sdk/tool-bridge.js +141 -0
  100. package/dist/node/providers/registry.js +89 -0
  101. package/dist/node/providers/types.js +56 -0
  102. package/dist/node/schema/index.js +195 -0
  103. package/dist/node/schema/json-schema-to-zod.js +152 -0
  104. package/dist/node/schema/schema-output.js +190 -0
  105. package/dist/node/session/index.js +90 -0
  106. package/dist/node/session/store.js +90 -0
  107. package/dist/node/spec/index.js +85 -0
  108. package/dist/node/spec/registry.js +56 -0
  109. package/dist/node/spec/spec.js +44 -0
  110. package/dist/node/telemetry/adapter.js +85 -0
  111. package/dist/node/telemetry/index.js +86 -0
  112. package/dist/node/tools/index.js +345 -0
  113. package/dist/node/tools/knowledge-tool.js +74 -0
  114. package/dist/node/tools/mcp-client.js +47 -0
  115. package/dist/node/tools/mcp-server.js +205 -0
  116. package/dist/node/tools/tool-adapter.js +197 -0
  117. package/dist/node/types.js +0 -0
  118. package/dist/providers/claude-agent-sdk/adapter.d.ts +60 -52
  119. package/dist/providers/claude-agent-sdk/adapter.d.ts.map +1 -1
  120. package/dist/providers/claude-agent-sdk/adapter.js +622 -304
  121. package/dist/providers/claude-agent-sdk/index.d.ts +22 -4
  122. package/dist/providers/claude-agent-sdk/index.d.ts.map +1 -0
  123. package/dist/providers/claude-agent-sdk/index.js +672 -4
  124. package/dist/providers/claude-agent-sdk/session-bridge.d.ts +43 -40
  125. package/dist/providers/claude-agent-sdk/session-bridge.d.ts.map +1 -1
  126. package/dist/providers/claude-agent-sdk/session-bridge.js +121 -130
  127. package/dist/providers/claude-agent-sdk/tool-bridge.d.ts +63 -60
  128. package/dist/providers/claude-agent-sdk/tool-bridge.d.ts.map +1 -1
  129. package/dist/providers/claude-agent-sdk/tool-bridge.js +104 -108
  130. package/dist/providers/index.d.ts +28 -7
  131. package/dist/providers/index.d.ts.map +1 -0
  132. package/dist/providers/index.js +1261 -8
  133. package/dist/providers/opencode-sdk/adapter.d.ts +56 -48
  134. package/dist/providers/opencode-sdk/adapter.d.ts.map +1 -1
  135. package/dist/providers/opencode-sdk/adapter.js +667 -274
  136. package/dist/providers/opencode-sdk/agent-bridge.d.ts +62 -57
  137. package/dist/providers/opencode-sdk/agent-bridge.d.ts.map +1 -1
  138. package/dist/providers/opencode-sdk/agent-bridge.js +289 -155
  139. package/dist/providers/opencode-sdk/index.d.ts +22 -4
  140. package/dist/providers/opencode-sdk/index.d.ts.map +1 -0
  141. package/dist/providers/opencode-sdk/index.js +702 -4
  142. package/dist/providers/opencode-sdk/tool-bridge.d.ts +41 -42
  143. package/dist/providers/opencode-sdk/tool-bridge.d.ts.map +1 -1
  144. package/dist/providers/opencode-sdk/tool-bridge.js +121 -107
  145. package/dist/providers/registry.d.ts +10 -11
  146. package/dist/providers/registry.d.ts.map +1 -1
  147. package/dist/providers/registry.js +86 -49
  148. package/dist/providers/types.d.ts +169 -166
  149. package/dist/providers/types.d.ts.map +1 -1
  150. package/dist/providers/types.js +54 -42
  151. package/dist/schema/index.d.ts +3 -3
  152. package/dist/schema/index.d.ts.map +1 -0
  153. package/dist/schema/index.js +194 -3
  154. package/dist/schema/json-schema-to-zod.d.ts +23 -26
  155. package/dist/schema/json-schema-to-zod.d.ts.map +1 -1
  156. package/dist/schema/json-schema-to-zod.js +138 -110
  157. package/dist/schema/schema-output.d.ts +29 -32
  158. package/dist/schema/schema-output.d.ts.map +1 -1
  159. package/dist/schema/schema-output.js +178 -53
  160. package/dist/session/index.d.ts +2 -2
  161. package/dist/session/index.d.ts.map +1 -0
  162. package/dist/session/index.js +89 -2
  163. package/dist/session/store.d.ts +51 -55
  164. package/dist/session/store.d.ts.map +1 -1
  165. package/dist/session/store.js +85 -74
  166. package/dist/spec/index.d.ts +3 -3
  167. package/dist/spec/index.d.ts.map +1 -0
  168. package/dist/spec/index.js +84 -3
  169. package/dist/spec/registry.d.ts +32 -36
  170. package/dist/spec/registry.d.ts.map +1 -1
  171. package/dist/spec/registry.js +51 -60
  172. package/dist/spec/spec.d.ts +80 -84
  173. package/dist/spec/spec.d.ts.map +1 -1
  174. package/dist/spec/spec.js +40 -26
  175. package/dist/telemetry/adapter.d.ts +33 -37
  176. package/dist/telemetry/adapter.d.ts.map +1 -1
  177. package/dist/telemetry/adapter.js +78 -96
  178. package/dist/telemetry/index.d.ts +2 -2
  179. package/dist/telemetry/index.d.ts.map +1 -0
  180. package/dist/telemetry/index.js +85 -2
  181. package/dist/tools/index.d.ts +5 -5
  182. package/dist/tools/index.d.ts.map +1 -0
  183. package/dist/tools/index.js +344 -5
  184. package/dist/tools/knowledge-tool.d.ts +4 -8
  185. package/dist/tools/knowledge-tool.d.ts.map +1 -1
  186. package/dist/tools/knowledge-tool.js +68 -48
  187. package/dist/tools/mcp-client.d.ts +17 -21
  188. package/dist/tools/mcp-client.d.ts.map +1 -1
  189. package/dist/tools/mcp-client.js +42 -53
  190. package/dist/tools/mcp-server.d.ts +14 -18
  191. package/dist/tools/mcp-server.d.ts.map +1 -1
  192. package/dist/tools/mcp-server.js +200 -64
  193. package/dist/tools/tool-adapter.d.ts +7 -11
  194. package/dist/tools/tool-adapter.d.ts.map +1 -1
  195. package/dist/tools/tool-adapter.js +187 -70
  196. package/dist/tools/tools.test.d.ts +2 -0
  197. package/dist/tools/tools.test.d.ts.map +1 -0
  198. package/dist/types.d.ts +108 -111
  199. package/dist/types.d.ts.map +1 -1
  200. package/dist/types.js +1 -0
  201. package/package.json +448 -90
  202. package/dist/_virtual/_rolldown/runtime.js +0 -8
  203. package/dist/agent/agent-factory.js.map +0 -1
  204. package/dist/agent/contract-spec-agent.js.map +0 -1
  205. package/dist/agent/json-runner.js.map +0 -1
  206. package/dist/agent/unified-agent.js.map +0 -1
  207. package/dist/approval/workflow.js.map +0 -1
  208. package/dist/exporters/claude-agent-exporter.js.map +0 -1
  209. package/dist/exporters/opencode-exporter.js.map +0 -1
  210. package/dist/interop/spec-consumer.js.map +0 -1
  211. package/dist/interop/tool-consumer.js.map +0 -1
  212. package/dist/knowledge/injector.js.map +0 -1
  213. package/dist/memory/in-memory.js.map +0 -1
  214. package/dist/memory/manager.js.map +0 -1
  215. package/dist/providers/claude-agent-sdk/adapter.js.map +0 -1
  216. package/dist/providers/claude-agent-sdk/session-bridge.js.map +0 -1
  217. package/dist/providers/claude-agent-sdk/tool-bridge.js.map +0 -1
  218. package/dist/providers/opencode-sdk/adapter.js.map +0 -1
  219. package/dist/providers/opencode-sdk/agent-bridge.js.map +0 -1
  220. package/dist/providers/opencode-sdk/tool-bridge.js.map +0 -1
  221. package/dist/providers/registry.js.map +0 -1
  222. package/dist/providers/types.js.map +0 -1
  223. package/dist/schema/json-schema-to-zod.js.map +0 -1
  224. package/dist/schema/schema-output.js.map +0 -1
  225. package/dist/session/store.js.map +0 -1
  226. package/dist/spec/registry.js.map +0 -1
  227. package/dist/spec/spec.js.map +0 -1
  228. package/dist/telemetry/adapter.js.map +0 -1
  229. package/dist/tools/knowledge-tool.js.map +0 -1
  230. package/dist/tools/mcp-client.js.map +0 -1
  231. package/dist/tools/mcp-server.js.map +0 -1
  232. package/dist/tools/tool-adapter.js.map +0 -1
@@ -0,0 +1,710 @@
1
+ import { createRequire } from "node:module";
2
+ var __defProp = Object.defineProperty;
3
+ var __export = (target, all) => {
4
+ for (var name in all)
5
+ __defProp(target, name, {
6
+ get: all[name],
7
+ enumerable: true,
8
+ configurable: true,
9
+ set: (newValue) => all[name] = () => newValue
10
+ });
11
+ };
12
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
13
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
14
+
15
+ // src/spec/spec.ts
16
+ function defineAgent(spec) {
17
+ if (!spec.meta?.key) {
18
+ throw new Error("Agent key is required");
19
+ }
20
+ if (typeof spec.meta.version !== "string") {
21
+ throw new Error(`Agent ${spec.meta.key} is missing a string version`);
22
+ }
23
+ if (!spec.instructions?.trim()) {
24
+ throw new Error(`Agent ${spec.meta.key} requires instructions`);
25
+ }
26
+ if (!spec.tools?.length) {
27
+ throw new Error(`Agent ${spec.meta.key} must expose at least one tool`);
28
+ }
29
+ const toolNames = new Set;
30
+ for (const tool of spec.tools) {
31
+ if (toolNames.has(tool.name)) {
32
+ throw new Error(`Agent ${spec.meta.key} has duplicate tool name: ${tool.name}`);
33
+ }
34
+ toolNames.add(tool.name);
35
+ }
36
+ return Object.freeze(spec);
37
+ }
38
+ function agentKey(meta) {
39
+ return `${meta.key}.v${meta.version}`;
40
+ }
41
+
42
+ // src/providers/claude-agent-sdk/tool-bridge.ts
43
+ function specToolToClaudeAgentTool(tool, handler, context) {
44
+ return {
45
+ name: tool.name,
46
+ description: tool.description ?? `Execute ${tool.name}`,
47
+ input_schema: normalizeSchema(tool.schema),
48
+ requires_confirmation: tool.requiresApproval ?? !tool.automationSafe,
49
+ execute: async (input) => {
50
+ const fullContext = {
51
+ agentId: context.agentId ?? "unknown",
52
+ sessionId: context.sessionId ?? "unknown",
53
+ tenantId: context.tenantId,
54
+ actorId: context.actorId,
55
+ metadata: context.metadata,
56
+ signal: context.signal
57
+ };
58
+ return handler(input, fullContext);
59
+ }
60
+ };
61
+ }
62
+ function specToolsToClaudeAgentTools(tools, handlers, context) {
63
+ return tools.filter((tool) => handlers.has(tool.name)).map((tool) => {
64
+ const handler = handlers.get(tool.name);
65
+ if (!handler) {
66
+ throw new Error(`Handler not found for tool ${tool.name}`);
67
+ }
68
+ return specToolToClaudeAgentTool(tool, handler, context);
69
+ });
70
+ }
71
+ function claudeAgentToolToSpecTool(claudeTool, execute) {
72
+ const config = {
73
+ name: claudeTool.name,
74
+ description: claudeTool.description,
75
+ schema: claudeTool.input_schema,
76
+ requiresApproval: claudeTool.requires_confirmation,
77
+ automationSafe: !claudeTool.requires_confirmation
78
+ };
79
+ const handler = execute ? async (input, _ctx) => String(await execute(input)) : undefined;
80
+ return { config, handler };
81
+ }
82
+ function claudeAgentToolsToSpecTools(claudeTools) {
83
+ const configs = [];
84
+ const handlers = new Map;
85
+ for (const claudeTool of claudeTools) {
86
+ const { config, handler } = claudeAgentToolToSpecTool(claudeTool, claudeTool.execute);
87
+ configs.push(config);
88
+ if (handler) {
89
+ handlers.set(config.name, handler);
90
+ }
91
+ }
92
+ return { configs, handlers };
93
+ }
94
+ function specToolToExternalTool(tool, handler, context) {
95
+ return {
96
+ name: tool.name,
97
+ description: tool.description ?? `Execute ${tool.name}`,
98
+ inputSchema: tool.schema ?? { type: "object" },
99
+ requiresApproval: tool.requiresApproval ?? !tool.automationSafe,
100
+ execute: handler ? async (input) => {
101
+ const fullContext = {
102
+ agentId: context?.agentId ?? "unknown",
103
+ sessionId: context?.sessionId ?? "unknown",
104
+ tenantId: context?.tenantId,
105
+ actorId: context?.actorId,
106
+ metadata: context?.metadata,
107
+ signal: context?.signal
108
+ };
109
+ return handler(input, fullContext);
110
+ } : undefined
111
+ };
112
+ }
113
+ function normalizeSchema(schema) {
114
+ if (!schema) {
115
+ return { type: "object" };
116
+ }
117
+ if (schema.type === "object") {
118
+ return schema;
119
+ }
120
+ return {
121
+ type: "object",
122
+ properties: {
123
+ value: schema
124
+ },
125
+ required: ["value"]
126
+ };
127
+ }
128
+ function extractToolCalls(response) {
129
+ if (!response.content) {
130
+ return [];
131
+ }
132
+ return response.content.filter((block) => block.type === "tool_use").map((block) => ({
133
+ toolCallId: block.id ?? "",
134
+ toolName: block.name ?? "",
135
+ args: block.input
136
+ }));
137
+ }
138
+
139
+ // src/providers/opencode-sdk/tool-bridge.ts
140
+ function specToolToOpenCodeTool(tool) {
141
+ return {
142
+ name: tool.name,
143
+ description: tool.description ?? `Execute ${tool.name}`,
144
+ parameters: normalizeToOpenCodeParameters(tool.schema),
145
+ permission: getPermissionLevel(tool)
146
+ };
147
+ }
148
+ function specToolsToOpenCodeTools(tools) {
149
+ return tools.map(specToolToOpenCodeTool);
150
+ }
151
+ function getPermissionLevel(tool) {
152
+ if (tool.requiresApproval) {
153
+ return "ask";
154
+ }
155
+ if (tool.automationSafe === false) {
156
+ return "ask";
157
+ }
158
+ return "allow";
159
+ }
160
+ function openCodeToolToSpecTool(openCodeTool) {
161
+ return {
162
+ name: openCodeTool.name,
163
+ description: openCodeTool.description,
164
+ schema: openCodeTool.parameters,
165
+ requiresApproval: openCodeTool.permission === "ask",
166
+ automationSafe: openCodeTool.permission === "allow"
167
+ };
168
+ }
169
+ function openCodeToolsToSpecTools(openCodeTools) {
170
+ return openCodeTools.map(openCodeToolToSpecTool);
171
+ }
172
+ function specToolToExternalToolForOpenCode(tool, handler, context) {
173
+ return {
174
+ name: tool.name,
175
+ description: tool.description ?? `Execute ${tool.name}`,
176
+ inputSchema: tool.schema ?? { type: "object" },
177
+ requiresApproval: tool.requiresApproval ?? !tool.automationSafe,
178
+ execute: handler ? async (input) => {
179
+ const fullContext = {
180
+ agentId: context?.agentId ?? "unknown",
181
+ sessionId: context?.sessionId ?? "unknown",
182
+ tenantId: context?.tenantId,
183
+ actorId: context?.actorId,
184
+ metadata: context?.metadata,
185
+ signal: context?.signal
186
+ };
187
+ return handler(input, fullContext);
188
+ } : undefined
189
+ };
190
+ }
191
+ function normalizeToOpenCodeParameters(schema) {
192
+ if (!schema) {
193
+ return { type: "object" };
194
+ }
195
+ if (schema.type === "object") {
196
+ return {
197
+ type: "object",
198
+ properties: schema.properties,
199
+ required: schema.required
200
+ };
201
+ }
202
+ return {
203
+ type: "object",
204
+ properties: {
205
+ value: convertToOpenCodeParameter(schema)
206
+ },
207
+ required: ["value"]
208
+ };
209
+ }
210
+ function convertToOpenCodeParameter(schema) {
211
+ const param = {
212
+ type: schema.type ?? "string"
213
+ };
214
+ if (schema.description) {
215
+ param.description = schema.description;
216
+ }
217
+ if (schema.enum) {
218
+ param.enum = schema.enum;
219
+ }
220
+ if (schema.default !== undefined) {
221
+ param.default = schema.default;
222
+ }
223
+ return param;
224
+ }
225
+ function createToolHandlerMap(tools) {
226
+ const handlers = new Map;
227
+ for (const [name, tool] of Object.entries(tools)) {
228
+ if (tool.execute) {
229
+ handlers.set(name, tool.execute);
230
+ }
231
+ }
232
+ return handlers;
233
+ }
234
+ async function executeToolCall(toolCall, handlers) {
235
+ const handler = handlers.get(toolCall.name);
236
+ if (!handler) {
237
+ return {
238
+ tool_call_id: toolCall.id,
239
+ output: `Error: Tool '${toolCall.name}' not found`,
240
+ is_error: true
241
+ };
242
+ }
243
+ try {
244
+ const result = await handler(toolCall.arguments);
245
+ return {
246
+ tool_call_id: toolCall.id,
247
+ output: typeof result === "string" ? result : JSON.stringify(result)
248
+ };
249
+ } catch (error) {
250
+ return {
251
+ tool_call_id: toolCall.id,
252
+ output: `Error: ${error instanceof Error ? error.message : String(error)}`,
253
+ is_error: true
254
+ };
255
+ }
256
+ }
257
+ // src/interop/spec-consumer.ts
258
+ class ContractSpecConsumer {
259
+ specs;
260
+ includeMetadata;
261
+ baseUrl;
262
+ constructor(config) {
263
+ this.specs = new Map;
264
+ this.includeMetadata = config.includeMetadata ?? true;
265
+ this.baseUrl = config.baseUrl;
266
+ for (const spec of config.specs) {
267
+ const key = agentKey(spec.meta);
268
+ this.specs.set(key, spec);
269
+ }
270
+ }
271
+ getSpecMarkdown(specKey, options) {
272
+ const spec = this.specs.get(specKey);
273
+ if (!spec) {
274
+ throw new Error(`Spec not found: ${specKey}`);
275
+ }
276
+ const sections = [];
277
+ const opts = {
278
+ includeToc: options?.includeToc ?? true,
279
+ includeTools: options?.includeTools ?? true,
280
+ ...options
281
+ };
282
+ if (opts.customHeader) {
283
+ sections.push(opts.customHeader);
284
+ sections.push("");
285
+ }
286
+ const specName = spec.meta.key;
287
+ sections.push(`# ${specName}`);
288
+ sections.push("");
289
+ if (spec.description) {
290
+ sections.push(spec.description);
291
+ sections.push("");
292
+ }
293
+ if (opts.includeToc) {
294
+ sections.push("## Table of Contents");
295
+ sections.push("");
296
+ sections.push("- [Overview](#overview)");
297
+ sections.push("- [Instructions](#instructions)");
298
+ if (opts.includeTools && spec.tools && spec.tools.length > 0) {
299
+ sections.push("- [Tools](#tools)");
300
+ }
301
+ if (spec.knowledge && spec.knowledge.length > 0) {
302
+ sections.push("- [Knowledge](#knowledge)");
303
+ }
304
+ sections.push("");
305
+ }
306
+ sections.push("## Overview");
307
+ sections.push("");
308
+ if (this.includeMetadata) {
309
+ sections.push(`- **Key**: \`${spec.meta.key}\``);
310
+ sections.push(`- **Version**: ${spec.meta.version}`);
311
+ if (spec.meta.stability) {
312
+ sections.push(`- **Stability**: ${spec.meta.stability}`);
313
+ }
314
+ if (spec.meta.owners && spec.meta.owners.length > 0) {
315
+ sections.push(`- **Owners**: ${spec.meta.owners.join(", ")}`);
316
+ }
317
+ if (spec.tags && spec.tags.length > 0) {
318
+ sections.push(`- **Tags**: ${spec.tags.join(", ")}`);
319
+ }
320
+ }
321
+ sections.push("");
322
+ sections.push("## Instructions");
323
+ sections.push("");
324
+ sections.push(spec.instructions);
325
+ sections.push("");
326
+ if (opts.includeTools && spec.tools && spec.tools.length > 0) {
327
+ sections.push("## Tools");
328
+ sections.push("");
329
+ for (const tool of spec.tools) {
330
+ sections.push(`### ${tool.name}`);
331
+ sections.push("");
332
+ if (tool.description) {
333
+ sections.push(tool.description);
334
+ sections.push("");
335
+ }
336
+ if (tool.schema) {
337
+ sections.push("**Schema:**");
338
+ sections.push("");
339
+ sections.push("```json");
340
+ sections.push(JSON.stringify(tool.schema, null, 2));
341
+ sections.push("```");
342
+ sections.push("");
343
+ }
344
+ if (tool.automationSafe !== undefined) {
345
+ sections.push(`**Automation Safe**: ${tool.automationSafe ? "Yes" : "No"}`);
346
+ sections.push("");
347
+ }
348
+ }
349
+ }
350
+ if (spec.knowledge && spec.knowledge.length > 0) {
351
+ sections.push("## Knowledge");
352
+ sections.push("");
353
+ for (const k of spec.knowledge) {
354
+ sections.push(`- **${k.key}**${k.required ? " (required)" : ""}`);
355
+ if (k.instructions) {
356
+ sections.push(` - ${k.instructions}`);
357
+ }
358
+ }
359
+ sections.push("");
360
+ }
361
+ if (spec.policy) {
362
+ sections.push("## Policy");
363
+ sections.push("");
364
+ if (spec.policy.confidence) {
365
+ sections.push(`- **Minimum Confidence**: ${spec.policy.confidence.min ?? 0.7}`);
366
+ }
367
+ if (spec.policy.escalation) {
368
+ const esc = spec.policy.escalation;
369
+ if (esc.confidenceThreshold) {
370
+ sections.push(`- **Escalation Threshold**: ${esc.confidenceThreshold}`);
371
+ }
372
+ if (esc.onToolFailure) {
373
+ sections.push("- **Escalate on Tool Failure**: Yes");
374
+ }
375
+ if (esc.onTimeout) {
376
+ sections.push("- **Escalate on Timeout**: Yes");
377
+ }
378
+ }
379
+ sections.push("");
380
+ }
381
+ return sections.join(`
382
+ `);
383
+ }
384
+ getSpecPrompt(specKey, options) {
385
+ const spec = this.specs.get(specKey);
386
+ if (!spec) {
387
+ throw new Error(`Spec not found: ${specKey}`);
388
+ }
389
+ const sections = [];
390
+ const opts = {
391
+ includeTools: options?.includeTools ?? true,
392
+ format: options?.format ?? "structured",
393
+ ...options
394
+ };
395
+ sections.push("# Agent Identity");
396
+ sections.push("");
397
+ sections.push(`You are ${spec.meta.key} (v${spec.meta.version}).`);
398
+ sections.push("");
399
+ if (spec.description) {
400
+ sections.push("## Description");
401
+ sections.push("");
402
+ sections.push(spec.description);
403
+ sections.push("");
404
+ }
405
+ sections.push("## Instructions");
406
+ sections.push("");
407
+ sections.push(spec.instructions);
408
+ sections.push("");
409
+ if (opts.includeTools && spec.tools && spec.tools.length > 0) {
410
+ sections.push("## Available Tools");
411
+ sections.push("");
412
+ sections.push("You have access to the following tools:");
413
+ sections.push("");
414
+ for (const tool of spec.tools) {
415
+ sections.push(`### ${tool.name}`);
416
+ sections.push("");
417
+ if (tool.description) {
418
+ sections.push(tool.description);
419
+ sections.push("");
420
+ }
421
+ if (tool.schema && opts.format === "structured") {
422
+ sections.push("Parameters:");
423
+ sections.push("```json");
424
+ sections.push(JSON.stringify(tool.schema, null, 2));
425
+ sections.push("```");
426
+ sections.push("");
427
+ }
428
+ }
429
+ }
430
+ if (spec.knowledge && spec.knowledge.length > 0) {
431
+ const requiredKnowledge = spec.knowledge.filter((k) => k.required);
432
+ if (requiredKnowledge.length > 0) {
433
+ sections.push("## Knowledge Context");
434
+ sections.push("");
435
+ for (const k of requiredKnowledge) {
436
+ if (k.instructions) {
437
+ sections.push(k.instructions);
438
+ sections.push("");
439
+ }
440
+ }
441
+ }
442
+ }
443
+ if (options?.customContext) {
444
+ sections.push("## Additional Context");
445
+ sections.push("");
446
+ sections.push(options.customContext);
447
+ sections.push("");
448
+ }
449
+ return sections.join(`
450
+ `);
451
+ }
452
+ listSpecs(options) {
453
+ const results = [];
454
+ for (const [key, spec] of this.specs) {
455
+ if (options?.stability && spec.meta.stability !== options.stability) {
456
+ continue;
457
+ }
458
+ if (options?.tags && options.tags.length > 0) {
459
+ const specTags = spec.tags ?? [];
460
+ const hasMatchingTag = options.tags.some((tag) => specTags.includes(tag));
461
+ if (!hasMatchingTag) {
462
+ continue;
463
+ }
464
+ }
465
+ results.push({
466
+ key,
467
+ name: spec.meta.key,
468
+ version: spec.meta.version,
469
+ description: spec.description,
470
+ stability: spec.meta.stability,
471
+ tags: spec.tags,
472
+ toolCount: spec.tools?.length ?? 0
473
+ });
474
+ }
475
+ return results;
476
+ }
477
+ querySpec(specKey) {
478
+ const spec = this.specs.get(specKey);
479
+ if (!spec) {
480
+ return;
481
+ }
482
+ return {
483
+ key: specKey,
484
+ spec,
485
+ markdown: this.getSpecMarkdown(specKey),
486
+ prompt: this.getSpecPrompt(specKey)
487
+ };
488
+ }
489
+ hasSpec(specKey) {
490
+ return this.specs.has(specKey);
491
+ }
492
+ getSpec(specKey) {
493
+ return this.specs.get(specKey);
494
+ }
495
+ getAllSpecs() {
496
+ return Array.from(this.specs.values());
497
+ }
498
+ getSpecCount() {
499
+ return this.specs.size;
500
+ }
501
+ addSpec(spec) {
502
+ const key = agentKey(spec.meta);
503
+ this.specs.set(key, spec);
504
+ }
505
+ removeSpec(specKey) {
506
+ return this.specs.delete(specKey);
507
+ }
508
+ }
509
+ function createSpecConsumer(config) {
510
+ return new ContractSpecConsumer(config);
511
+ }
512
+ function createSingleSpecConsumer(spec, options) {
513
+ return new ContractSpecConsumer({
514
+ specs: [spec],
515
+ ...options
516
+ });
517
+ }
518
+
519
+ // src/interop/tool-consumer.ts
520
+ class MCPToolServer {
521
+ tools;
522
+ name;
523
+ version;
524
+ running = false;
525
+ constructor(config) {
526
+ this.tools = new Map;
527
+ this.name = config.name ?? "contractspec-tools";
528
+ this.version = config.version ?? "1.0.0";
529
+ for (const tool of config.tools) {
530
+ this.tools.set(tool.config.name, tool);
531
+ }
532
+ }
533
+ async start() {
534
+ if (this.running) {
535
+ return;
536
+ }
537
+ this.running = true;
538
+ console.log(`[MCPToolServer] Started ${this.name}@${this.version} with ${this.tools.size} tools`);
539
+ }
540
+ async stop() {
541
+ if (!this.running) {
542
+ return;
543
+ }
544
+ this.running = false;
545
+ console.log(`[MCPToolServer] Stopped ${this.name}`);
546
+ }
547
+ isRunning() {
548
+ return this.running;
549
+ }
550
+ getTools() {
551
+ return Array.from(this.tools.values()).map((t) => t.config);
552
+ }
553
+ async executeTool(toolName, args, context) {
554
+ const tool = this.tools.get(toolName);
555
+ if (!tool) {
556
+ throw new Error(`Tool not found: ${toolName}`);
557
+ }
558
+ if (!tool.handler) {
559
+ throw new Error(`No handler registered for tool: ${toolName}`);
560
+ }
561
+ const fullContext = {
562
+ agentId: context?.agentId ?? "mcp-server",
563
+ sessionId: context?.sessionId ?? "mcp-session",
564
+ tenantId: context?.tenantId,
565
+ actorId: context?.actorId,
566
+ metadata: context?.metadata,
567
+ signal: context?.signal
568
+ };
569
+ return await tool.handler(args, fullContext);
570
+ }
571
+ getMCPToolDefinitions() {
572
+ const definitions = [];
573
+ for (const [name, tool] of this.tools) {
574
+ definitions.push({
575
+ name,
576
+ description: tool.config.description ?? "",
577
+ inputSchema: tool.config.schema ?? { type: "object", properties: {} }
578
+ });
579
+ }
580
+ return definitions;
581
+ }
582
+ getServerInfo() {
583
+ return {
584
+ name: this.name,
585
+ version: this.version,
586
+ tools: this.tools.size,
587
+ running: this.running
588
+ };
589
+ }
590
+ }
591
+
592
+ class ContractSpecToolConsumer {
593
+ tools;
594
+ constructor(config) {
595
+ this.tools = new Map;
596
+ for (const tool of config.tools) {
597
+ this.tools.set(tool.config.name, tool);
598
+ }
599
+ }
600
+ createToolServer(config) {
601
+ return new MCPToolServer({
602
+ tools: Array.from(this.tools.values()),
603
+ ...config
604
+ });
605
+ }
606
+ exportToolsForSDK(format) {
607
+ const tools = Array.from(this.tools.values());
608
+ const defaultContext = {
609
+ agentId: "export",
610
+ sessionId: "export"
611
+ };
612
+ switch (format) {
613
+ case "claude-agent":
614
+ return tools.filter((tool) => !!tool.handler).map((tool) => specToolToClaudeAgentTool(tool.config, tool.handler, defaultContext));
615
+ case "opencode":
616
+ return tools.map((tool) => specToolToOpenCodeTool(tool.config));
617
+ case "mcp":
618
+ return tools.map((tool) => ({
619
+ name: tool.config.name,
620
+ description: tool.config.description ?? "",
621
+ inputSchema: tool.config.schema ?? { type: "object", properties: {} }
622
+ }));
623
+ case "openai":
624
+ return tools.map((tool) => ({
625
+ type: "function",
626
+ function: {
627
+ name: tool.config.name,
628
+ description: tool.config.description ?? "",
629
+ parameters: tool.config.schema ?? {
630
+ type: "object",
631
+ properties: {}
632
+ }
633
+ }
634
+ }));
635
+ default:
636
+ throw new Error(`Unknown export format: ${format}`);
637
+ }
638
+ }
639
+ createBridgedHandler(toolName, _format) {
640
+ const tool = this.tools.get(toolName);
641
+ if (!tool || !tool.handler) {
642
+ return;
643
+ }
644
+ const handler = tool.handler;
645
+ return async (args) => {
646
+ const context = {
647
+ agentId: "bridge",
648
+ sessionId: "bridge"
649
+ };
650
+ return handler(args, context);
651
+ };
652
+ }
653
+ getTools() {
654
+ return Array.from(this.tools.values()).map((t) => t.config);
655
+ }
656
+ getTool(name) {
657
+ return this.tools.get(name)?.config;
658
+ }
659
+ hasTool(name) {
660
+ return this.tools.has(name);
661
+ }
662
+ async executeTool(name, args, context) {
663
+ const tool = this.tools.get(name);
664
+ if (!tool) {
665
+ throw new Error(`Tool not found: ${name}`);
666
+ }
667
+ if (!tool.handler) {
668
+ throw new Error(`No handler for tool: ${name}`);
669
+ }
670
+ const fullContext = {
671
+ agentId: context?.agentId ?? "consumer",
672
+ sessionId: context?.sessionId ?? "consumer-session",
673
+ tenantId: context?.tenantId,
674
+ actorId: context?.actorId,
675
+ metadata: context?.metadata,
676
+ signal: context?.signal
677
+ };
678
+ return await tool.handler(args, fullContext);
679
+ }
680
+ addTool(config, handler) {
681
+ this.tools.set(config.name, { config, handler });
682
+ }
683
+ removeTool(name) {
684
+ return this.tools.delete(name);
685
+ }
686
+ getToolCount() {
687
+ return this.tools.size;
688
+ }
689
+ }
690
+ function createToolConsumer(config) {
691
+ return new ContractSpecToolConsumer(config);
692
+ }
693
+ function createToolServer(config) {
694
+ return new MCPToolServer(config);
695
+ }
696
+ function exportToolsForExternalSDK(tools, format) {
697
+ const consumer = new ContractSpecToolConsumer({
698
+ tools: tools.map((config) => ({ config }))
699
+ });
700
+ return consumer.exportToolsForSDK(format);
701
+ }
702
+ export {
703
+ exportToolsForExternalSDK,
704
+ createToolServer,
705
+ createToolConsumer,
706
+ createSpecConsumer,
707
+ createSingleSpecConsumer,
708
+ ContractSpecToolConsumer,
709
+ ContractSpecConsumer
710
+ };