@agentproto/tool 0.1.1 → 0.2.1

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.
package/LICENSE CHANGED
@@ -1,21 +1,202 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Jeremy (agentik.net)
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+
2
+ Apache License
3
+ Version 2.0, January 2004
4
+ http://www.apache.org/licenses/
5
+
6
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
+
8
+ 1. Definitions.
9
+
10
+ "License" shall mean the terms and conditions for use, reproduction,
11
+ and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean the copyright owner or entity authorized by
14
+ the copyright owner that is granting the License.
15
+
16
+ "Legal Entity" shall mean the union of the acting entity and all
17
+ other entities that control, are controlled by, or are under common
18
+ control with that entity. For the purposes of this definition,
19
+ "control" means (i) the power, direct or indirect, to cause the
20
+ direction or management of such entity, whether by contract or
21
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
22
+ outstanding shares, or (iii) beneficial ownership of such entity.
23
+
24
+ "You" (or "Your") shall mean an individual or Legal Entity
25
+ exercising permissions granted by this License.
26
+
27
+ "Source" form shall mean the preferred form for making modifications,
28
+ including but not limited to software source code, documentation
29
+ source, and configuration files.
30
+
31
+ "Object" form shall mean any form resulting from mechanical
32
+ transformation or translation of a Source form, including but
33
+ not limited to compiled object code, generated documentation,
34
+ and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or
37
+ Object form, made available under the License, as indicated by a
38
+ copyright notice that is included in or attached to the work
39
+ (an example is provided in the Appendix below).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based on (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and Derivative Works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control systems,
58
+ and issue tracking systems that are managed by, or on behalf of, the
59
+ Licensor for the purpose of discussing and improving the Work, but
60
+ excluding communication that is conspicuously marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to reproduce, prepare Derivative Works of,
71
+ publicly display, publicly perform, sublicense, and distribute the
72
+ Work and such Derivative Works in Source or Object form.
73
+
74
+ 3. Grant of Patent License. Subject to the terms and conditions of
75
+ this License, each Contributor hereby grants to You a perpetual,
76
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+ (except as stated in this section) patent license to make, have made,
78
+ use, offer to sell, sell, import, and otherwise transfer the Work,
79
+ where such license applies only to those patent claims licensable
80
+ by such Contributor that are necessarily infringed by their
81
+ Contribution(s) alone or by combination of their Contribution(s)
82
+ with the Work to which such Contribution(s) was submitted. If You
83
+ institute patent litigation against any entity (including a
84
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
85
+ or a Contribution incorporated within the Work constitutes direct
86
+ or contributory patent infringement, then any patent licenses
87
+ granted to You under this License for that Work shall terminate
88
+ as of the date such litigation is filed.
89
+
90
+ 4. Redistribution. You may reproduce and distribute copies of the
91
+ Work or Derivative Works thereof in any medium, with or without
92
+ modifications, and in Source or Object form, provided that You
93
+ meet the following conditions:
94
+
95
+ (a) You must give any other recipients of the Work or
96
+ Derivative Works a copy of this License; and
97
+
98
+ (b) You must cause any modified files to carry prominent notices
99
+ stating that You changed the files; and
100
+
101
+ (c) You must retain, in the Source form of any Derivative Works
102
+ that You distribute, all copyright, patent, trademark, and
103
+ attribution notices from the Source form of the Work,
104
+ excluding those notices that do not pertain to any part of
105
+ the Derivative Works; and
106
+
107
+ (d) If the Work includes a "NOTICE" text file as part of its
108
+ distribution, then any Derivative Works that You distribute must
109
+ include a readable copy of the attribution notices contained
110
+ within such NOTICE file, excluding those notices that do not
111
+ pertain to any part of the Derivative Works, in at least one
112
+ of the following places: within a NOTICE text file distributed
113
+ as part of the Derivative Works; within the Source form or
114
+ documentation, if provided along with the Derivative Works; or,
115
+ within a display generated by the Derivative Works, if and
116
+ wherever such third-party notices normally appear. The contents
117
+ of the NOTICE file are for informational purposes only and
118
+ do not modify the License. You may add Your own attribution
119
+ notices within Derivative Works that You distribute, alongside
120
+ or as an addendum to the NOTICE text from the Work, provided
121
+ that such additional attribution notices cannot be construed
122
+ as modifying the License.
123
+
124
+ You may add Your own copyright statement to Your modifications and
125
+ may provide additional or different license terms and conditions
126
+ for use, reproduction, or distribution of Your modifications, or
127
+ for any such Derivative Works as a whole, provided Your use,
128
+ reproduction, and distribution of the Work otherwise complies with
129
+ the conditions stated in this License.
130
+
131
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
132
+ any Contribution intentionally submitted for inclusion in the Work
133
+ by You to the Licensor shall be under the terms and conditions of
134
+ this License, without any additional terms or conditions.
135
+ Notwithstanding the above, nothing herein shall supersede or modify
136
+ the terms of any separate license agreement you may have executed
137
+ with Licensor regarding such Contributions.
138
+
139
+ 6. Trademarks. This License does not grant permission to use the trade
140
+ names, trademarks, service marks, or product names of the Licensor,
141
+ except as required for reasonable and customary use in describing the
142
+ origin of the Work and reproducing the content of the NOTICE file.
143
+
144
+ 7. Disclaimer of Warranty. Unless required by applicable law or
145
+ agreed to in writing, Licensor provides the Work (and each
146
+ Contributor provides its Contributions) on an "AS IS" BASIS,
147
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148
+ implied, including, without limitation, any warranties or conditions
149
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150
+ PARTICULAR PURPOSE. You are solely responsible for determining the
151
+ appropriateness of using or redistributing the Work and assume any
152
+ risks associated with Your exercise of permissions under this License.
153
+
154
+ 8. Limitation of Liability. In no event and under no legal theory,
155
+ whether in tort (including negligence), contract, or otherwise,
156
+ unless required by applicable law (such as deliberate and grossly
157
+ negligent acts) or agreed to in writing, shall any Contributor be
158
+ liable to You for damages, including any direct, indirect, special,
159
+ incidental, or consequential damages of any character arising as a
160
+ result of this License or out of the use or inability to use the
161
+ Work (including but not limited to damages for loss of goodwill,
162
+ work stoppage, computer failure or malfunction, or any and all
163
+ other commercial damages or losses), even if such Contributor
164
+ has been advised of the possibility of such damages.
165
+
166
+ 9. Accepting Warranty or Additional Liability. While redistributing
167
+ the Work or Derivative Works thereof, You may choose to offer,
168
+ and charge a fee for, acceptance of support, warranty, indemnity,
169
+ or other liability obligations and/or rights consistent with this
170
+ License. However, in accepting such obligations, You may act only
171
+ on Your own behalf and on Your sole responsibility, not on behalf
172
+ of any other Contributor, and only if You agree to indemnify,
173
+ defend, and hold each Contributor harmless for any liability
174
+ incurred by, or claims asserted against, such Contributor by reason
175
+ of your accepting any such warranty or additional liability.
176
+
177
+ END OF TERMS AND CONDITIONS
178
+
179
+ APPENDIX: How to apply the Apache License to your work.
180
+
181
+ To apply the Apache License to your work, attach the following
182
+ boilerplate notice, with the fields enclosed by brackets "[]"
183
+ replaced with your own identifying information. (Don't include
184
+ the brackets!) The text should be enclosed in the appropriate
185
+ comment syntax for the file format. We also recommend that a
186
+ file or class name and description of purpose be included on the
187
+ same "printed page" as the copyright notice for easier
188
+ identification within third-party archives.
189
+
190
+ Copyright [yyyy] [name of copyright owner]
191
+
192
+ Licensed under the Apache License, Version 2.0 (the "License");
193
+ you may not use this file except in compliance with the License.
194
+ You may obtain a copy of the License at
195
+
196
+ http://www.apache.org/licenses/LICENSE-2.0
197
+
198
+ Unless required by applicable law or agreed to in writing, software
199
+ distributed under the License is distributed on an "AS IS" BASIS,
200
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201
+ See the License for the specific language governing permissions and
202
+ limitations under the License.
@@ -1,6 +1,7 @@
1
1
  import matter from 'gray-matter';
2
2
  import { z } from 'zod';
3
3
  import { createDoctype } from '@agentproto/define-doctype';
4
+ import Ajv from 'ajv';
4
5
 
5
6
  /**
6
7
  * @agentproto/tool v0.1.0-alpha
@@ -78,6 +79,8 @@ var constructTool = createDoctype({
78
79
  version: def.version,
79
80
  inputSchema: def.inputSchema,
80
81
  outputSchema: def.outputSchema,
82
+ inputs: def.inputs ? Object.freeze({ ...def.inputs }) : void 0,
83
+ outputs: def.outputs ? Object.freeze({ ...def.outputs }) : void 0,
81
84
  contextSchema: def.contextSchema,
82
85
  mutates: Object.freeze([...def.mutates ?? []]),
83
86
  requires: freezeCapabilities(def.requires),
@@ -100,18 +103,24 @@ function defineTool(definition) {
100
103
  );
101
104
  }
102
105
  function validateInput(handle, input) {
103
- const result = handle.inputSchema.safeParse(input);
104
- if (!result.success) {
105
- return {
106
- ok: false,
107
- error: {
108
- code: "input_invalid",
109
- message: `id='${handle.id}': ${formatZodIssues(result.error.issues)}`,
110
- cause: result.error.issues
111
- }
112
- };
106
+ if (handle.inputSchema) {
107
+ const result = handle.inputSchema.safeParse(input);
108
+ if (!result.success) {
109
+ return {
110
+ ok: false,
111
+ error: {
112
+ code: "input_invalid",
113
+ message: `id='${handle.id}': ${formatZodIssues(result.error.issues)}`,
114
+ cause: result.error.issues
115
+ }
116
+ };
117
+ }
118
+ return { ok: true, value: result.data };
113
119
  }
114
- return { ok: true, value: result.data };
120
+ if (handle.inputs) {
121
+ return validateJsonSchema(handle.id, handle.inputs, input);
122
+ }
123
+ return { ok: true, value: input };
115
124
  }
116
125
  function validateContext(handle, context) {
117
126
  if (!handle.contextSchema) {
@@ -132,15 +141,29 @@ function validateContext(handle, context) {
132
141
  return { ok: true, value: result.data };
133
142
  }
134
143
  function validateOutput(handle, output) {
135
- const result = handle.outputSchema.safeParse(output);
136
- if (!result.success) {
137
- throw new ToolError({
138
- code: "output_invalid",
139
- message: `id='${handle.id}': provider produced output that does not match outputSchema \u2014 ${formatZodIssues(result.error.issues)}`,
140
- cause: result.error.issues
141
- });
144
+ if (handle.outputSchema) {
145
+ const result = handle.outputSchema.safeParse(output);
146
+ if (!result.success) {
147
+ throw new ToolError({
148
+ code: "output_invalid",
149
+ message: `id='${handle.id}': provider produced output that does not match outputSchema \u2014 ${formatZodIssues(result.error.issues)}`,
150
+ cause: result.error.issues
151
+ });
152
+ }
153
+ return result.data;
154
+ }
155
+ if (handle.outputs) {
156
+ const result = validateJsonSchema(handle.id, handle.outputs, output);
157
+ if (!result.ok) {
158
+ throw new ToolError({
159
+ code: "output_invalid",
160
+ message: result.error.message,
161
+ cause: result.error.cause
162
+ });
163
+ }
164
+ return result.value;
142
165
  }
143
- return result.data;
166
+ return output;
144
167
  }
145
168
  function defaultApproval(declared, mutates) {
146
169
  if (declared) return declared;
@@ -168,6 +191,29 @@ function freezeProviderConstraints(c) {
168
191
  function formatZodIssues(issues) {
169
192
  return issues.map((i) => `${i.path.length > 0 ? i.path.join(".") + ": " : ""}${i.message}`).join("; ");
170
193
  }
194
+ var _ajv = new Ajv({ allErrors: true });
195
+ var _validatorCache = /* @__PURE__ */ new WeakMap();
196
+ function validateJsonSchema(toolId, schema, value) {
197
+ let validate = _validatorCache.get(schema);
198
+ if (!validate) {
199
+ validate = _ajv.compile(schema);
200
+ _validatorCache.set(schema, validate);
201
+ }
202
+ const valid = validate(value);
203
+ if (!valid) {
204
+ const errors = validate.errors ?? [];
205
+ const message = errors.map((e) => `${e.instancePath || "/"} ${e.message}`).join("; ");
206
+ return {
207
+ ok: false,
208
+ error: {
209
+ code: "input_invalid",
210
+ message: `id='${toolId}': ${message}`,
211
+ cause: errors
212
+ }
213
+ };
214
+ }
215
+ return { ok: true, value };
216
+ }
171
217
 
172
218
  // src/manifest/index.ts
173
219
  var toolManifestFrontmatterSchema = z.object({
@@ -197,6 +243,12 @@ var toolManifestFrontmatterSchema = z.object({
197
243
  idempotent: z.boolean().optional(),
198
244
  tags: z.array(z.string()).optional(),
199
245
  metadata: z.record(z.string(), z.unknown()).optional(),
246
+ // AIP-16 IO blocks — `inputs`/`outputs` as JSON Schema objects. Kept
247
+ // structurally loose here (validated as objects, not deep-checked against
248
+ // the AIP-16 meta-schema); preserved so a manifest's declared IO contract
249
+ // survives the parse → handle round-trip instead of being silently dropped.
250
+ inputs: z.record(z.string(), z.unknown()).optional(),
251
+ outputs: z.record(z.string(), z.unknown()).optional(),
200
252
  // AIP-26 / AIP-17 / AIP-19 references — kept loose; validated by their
201
253
  // respective AIPs' adapters when consumed.
202
254
  code: z.unknown().optional(),
@@ -218,6 +270,26 @@ function parseToolManifest(source) {
218
270
  }
219
271
  return { frontmatter: result.data, body: parsed.content };
220
272
  }
273
+ function toolFromManifestOnly(manifest) {
274
+ const fm = manifest.frontmatter;
275
+ return defineTool({
276
+ id: fm.id,
277
+ name: fm.name,
278
+ description: fm.description,
279
+ version: fm.version,
280
+ inputs: fm.inputs,
281
+ outputs: fm.outputs,
282
+ mutates: fm.mutates,
283
+ requires: fm.requires,
284
+ approval: fm.approval,
285
+ riskLevel: fm.risk_level,
286
+ costClass: fm.cost_class,
287
+ timeoutMs: fm.timeout_ms,
288
+ idempotent: fm.idempotent,
289
+ tags: fm.tags,
290
+ metadata: fm.metadata
291
+ });
292
+ }
221
293
  function toolFromManifest(args) {
222
294
  const fm = args.manifest.frontmatter;
223
295
  return defineTool({
@@ -227,6 +299,8 @@ function toolFromManifest(args) {
227
299
  version: fm.version,
228
300
  inputSchema: args.inputSchema,
229
301
  outputSchema: args.outputSchema,
302
+ inputs: fm.inputs,
303
+ outputs: fm.outputs,
230
304
  contextSchema: args.contextSchema,
231
305
  mutates: fm.mutates,
232
306
  requires: fm.requires,
@@ -240,6 +314,6 @@ function toolFromManifest(args) {
240
314
  });
241
315
  }
242
316
 
243
- export { ToolError, defineTool, parseToolManifest, toToolError, toToolResult, toolFromManifest, toolManifestFrontmatterSchema, validateContext, validateInput, validateOutput };
244
- //# sourceMappingURL=chunk-ZFIMSZXN.mjs.map
245
- //# sourceMappingURL=chunk-ZFIMSZXN.mjs.map
317
+ export { ToolError, defineTool, parseToolManifest, toToolError, toToolResult, toolFromManifest, toolFromManifestOnly, toolManifestFrontmatterSchema, validateContext, validateInput, validateOutput };
318
+ //# sourceMappingURL=chunk-VCLSUUB5.mjs.map
319
+ //# sourceMappingURL=chunk-VCLSUUB5.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts","../src/define-tool.ts","../src/manifest/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AA6BO,IAAM,SAAA,GAAN,cAAwB,KAAA,CAAM;AAAA,EAC1B,IAAA;AAAA,EACA,SAAA;AAAA,EACA,KAAA;AAAA,EAET,YAAY,OAAA,EAA2B;AACrC,IAAA,KAAA,CAAM,QAAQ,OAAO,CAAA;AACrB,IAAA,IAAA,CAAK,IAAA,GAAO,WAAA;AACZ,IAAA,IAAA,CAAK,OAAO,OAAA,CAAQ,IAAA;AACpB,IAAA,IAAA,CAAK,SAAA,GAAY,QAAQ,SAAA,IAAa,KAAA;AACtC,IAAA,IAAA,CAAK,QAAQ,OAAA,CAAQ,KAAA;AAAA,EACvB;AAAA,EAEA,MAAA,GAA2B;AACzB,IAAA,OAAO;AAAA,MACL,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,WAAW,IAAA,CAAK,SAAA;AAAA,MAChB,GAAI,KAAK,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,EAAO,IAAA,CAAK,KAAA,EAAM,GAAI;AAAC,KAC1D;AAAA,EACF;AACF;AAMO,SAAS,YAAY,MAAA,EAA4B;AACtD,EAAA,IAAI,MAAA,YAAkB,WAAW,OAAO,MAAA;AACxC,EAAA,IAAI,kBAAkB,KAAA,EAAO;AAC3B,IAAA,OAAO,IAAI,SAAA,CAAU;AAAA,MACnB,IAAA,EAAM,UAAA;AAAA,MACN,SAAS,MAAA,CAAO,OAAA;AAAA,MAChB,KAAA,EAAO;AAAA,KACR,CAAA;AAAA,EACH;AACA,EAAA,OAAO,IAAI,SAAA,CAAU;AAAA,IACnB,IAAA,EAAM,UAAA;AAAA,IACN,OAAA,EAAS,OAAO,MAAM,CAAA;AAAA,IACtB,KAAA,EAAO;AAAA,GACR,CAAA;AACH;AAMO,SAAS,YAAA,CACd,OACA,MAAA,EACe;AACf,EAAA,IAAI,WAAW,MAAA,EAAW;AACxB,IAAA,MAAM,GAAA,GAAM,YAAY,MAAM,CAAA;AAC9B,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,KAAA,EAAO,GAAA,CAAI,QAAO,EAAE;AAAA,EAC1C;AACA,EAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,KAAA,EAAkB;AACvC;;;ACtEA,IAAM,cAAA,GAAwC;AAAA,EAC5C,KAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA;AACF,CAAA;AAsBA,IAAM,gBAAgB,aAAA,CAGpB;AAAA,EACA,GAAA,EAAK,EAAA;AAAA,EACL,IAAA,EAAM,MAAA;AAAA,EACN,SAAS,GAAA,EAAK;AAGZ,IAAA,IAAI,aAAc,GAAA,EAA4C;AAC5D,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,gBAAA,EAAmB,IAAI,EAAE,CAAA,yJAAA;AAAA,OAG3B;AAAA,IACF;AAAA,EACF,CAAA;AAAA,EACA,MAAM,GAAA,EAAK;AACT,IAAA,OAAO;AAAA,MACL,IAAI,GAAA,CAAI,EAAA;AAAA,MACR,IAAA,EAAM,GAAA,CAAI,IAAA,IAAQ,GAAA,CAAI,EAAA;AAAA,MACtB,aAAa,GAAA,CAAI,WAAA;AAAA,MACjB,SAAS,GAAA,CAAI,OAAA;AAAA,MACb,aAAa,GAAA,CAAI,WAAA;AAAA,MACjB,cAAc,GAAA,CAAI,YAAA;AAAA,MAClB,MAAA,EAAQ,GAAA,CAAI,MAAA,GAAS,MAAA,CAAO,MAAA,CAAO,EAAE,GAAG,GAAA,CAAI,MAAA,EAAQ,CAAA,GAAI,MAAA;AAAA,MACxD,OAAA,EAAS,GAAA,CAAI,OAAA,GAAU,MAAA,CAAO,MAAA,CAAO,EAAE,GAAG,GAAA,CAAI,OAAA,EAAS,CAAA,GAAI,MAAA;AAAA,MAC3D,eAAe,GAAA,CAAI,aAAA;AAAA,MACnB,OAAA,EAAS,OAAO,MAAA,CAAO,CAAC,GAAI,GAAA,CAAI,OAAA,IAAW,EAAG,CAAC,CAAA;AAAA,MAC/C,QAAA,EAAU,kBAAA,CAAmB,GAAA,CAAI,QAAQ,CAAA;AAAA,MACzC,QAAA,EAAU,eAAA,CAAgB,GAAA,CAAI,QAAA,EAAU,IAAI,OAAO,CAAA;AAAA,MACnD,SAAA,EAAW,IAAI,SAAA,IAAa,CAAA;AAAA,MAC5B,SAAA,EAAW,IAAI,SAAA,IAAa,SAAA;AAAA,MAC5B,SAAA,EAAW,IAAI,SAAA,IAAa,GAAA;AAAA,MAC5B,OAAO,GAAA,CAAI,KAAA;AAAA,MACX,IAAA,EAAM,OAAO,MAAA,CAAO,CAAC,GAAI,GAAA,CAAI,IAAA,IAAQ,EAAG,CAAC,CAAA;AAAA,MACzC,QAAA,EAAU,OAAO,MAAA,CAAO,EAAE,GAAI,GAAA,CAAI,QAAA,IAAY,EAAC,EAAI,CAAA;AAAA,MACnD,UAAA,EAAY,IAAI,UAAA,IAAc,KAAA;AAAA,MAC9B,uBAAuB,GAAA,CAAI,qBAAA;AAAA,MAC3B,iBAAA,EAAmB,yBAAA,CAA0B,GAAA,CAAI,iBAAiB;AAAA,KACpE;AAAA,EACF;AACF,CAAC,CAAA;AAQM,SAAS,WAKd,UAAA,EACuC;AACvC,EAAA,OAAO,aAAA;AAAA,IACL;AAAA,GACF;AACF;AAYO,SAAS,aAAA,CACd,QACA,KAAA,EAC0B;AAC1B,EAAA,IAAI,OAAO,WAAA,EAAa;AACtB,IAAA,MAAM,MAAA,GAAS,MAAA,CAAO,WAAA,CAAY,SAAA,CAAU,KAAK,CAAA;AACjD,IAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,MAAA,OAAO;AAAA,QACL,EAAA,EAAI,KAAA;AAAA,QACJ,KAAA,EAAO;AAAA,UACL,IAAA,EAAM,eAAA;AAAA,UACN,OAAA,EAAS,OAAO,MAAA,CAAO,EAAE,MAAM,eAAA,CAAgB,MAAA,CAAO,KAAA,CAAM,MAAM,CAAC,CAAA,CAAA;AAAA,UACnE,KAAA,EAAO,OAAO,KAAA,CAAM;AAAA;AACtB,OACF;AAAA,IACF;AACA,IAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,KAAA,EAAO,OAAO,IAAA,EAAe;AAAA,EAClD;AACA,EAAA,IAAI,OAAO,MAAA,EAAQ;AACjB,IAAA,OAAO,kBAAA,CAA2B,MAAA,CAAO,EAAA,EAAI,MAAA,CAAO,QAAQ,KAAK,CAAA;AAAA,EACnE;AACA,EAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,KAAA,EAAO,KAAA,EAAgB;AAC5C;AAaO,SAAS,eAAA,CACd,QACA,OAAA,EAC4B;AAC5B,EAAA,IAAI,CAAC,OAAO,aAAA,EAAe;AACzB,IAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,KAAA,EAAO,OAAA,EAAoB;AAAA,EAChD;AACA,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,aAAA,CAAc,SAAA,CAAU,OAAO,CAAA;AACrD,EAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,IAAA,OAAO;AAAA,MACL,EAAA,EAAI,KAAA;AAAA,MACJ,KAAA,EAAO;AAAA,QACL,IAAA,EAAM,eAAA;AAAA,QACN,OAAA,EAAS,OAAO,MAAA,CAAO,EAAE,kDAA6C,eAAA,CAAgB,MAAA,CAAO,KAAA,CAAM,MAAM,CAAC,CAAA,CAAA;AAAA,QAC1G,KAAA,EAAO,SAAA;AAAA,QACP,KAAA,EAAO,OAAO,KAAA,CAAM;AAAA;AACtB,KACF;AAAA,EACF;AACA,EAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,KAAA,EAAO,OAAO,IAAA,EAAiB;AACpD;AAYO,SAAS,cAAA,CACd,QACA,MAAA,EACS;AACT,EAAA,IAAI,OAAO,YAAA,EAAc;AACvB,IAAA,MAAM,MAAA,GAAS,MAAA,CAAO,YAAA,CAAa,SAAA,CAAU,MAAM,CAAA;AACnD,IAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,MAAA,MAAM,IAAI,SAAA,CAAU;AAAA,QAClB,IAAA,EAAM,gBAAA;AAAA,QACN,OAAA,EAAS,OAAO,MAAA,CAAO,EAAE,uEAAkE,eAAA,CAAgB,MAAA,CAAO,KAAA,CAAM,MAAM,CAAC,CAAA,CAAA;AAAA,QAC/H,KAAA,EAAO,OAAO,KAAA,CAAM;AAAA,OACrB,CAAA;AAAA,IACH;AACA,IAAA,OAAO,MAAA,CAAO,IAAA;AAAA,EAChB;AACA,EAAA,IAAI,OAAO,OAAA,EAAS;AAClB,IAAA,MAAM,SAAS,kBAAA,CAA4B,MAAA,CAAO,EAAA,EAAI,MAAA,CAAO,SAAS,MAAM,CAAA;AAC5E,IAAA,IAAI,CAAC,OAAO,EAAA,EAAI;AACd,MAAA,MAAM,IAAI,SAAA,CAAU;AAAA,QAClB,IAAA,EAAM,gBAAA;AAAA,QACN,OAAA,EAAS,OAAO,KAAA,CAAM,OAAA;AAAA,QACtB,KAAA,EAAO,OAAO,KAAA,CAAM;AAAA,OACrB,CAAA;AAAA,IACH;AACA,IAAA,OAAO,MAAA,CAAO,KAAA;AAAA,EAChB;AACA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,eAAA,CACP,UACA,OAAA,EACe;AACf,EAAA,IAAI,UAAU,OAAO,QAAA;AACrB,EAAA,OAAO,OAAA,IAAW,OAAA,CAAQ,MAAA,GAAS,CAAA,GAAI,WAAA,GAAc,MAAA;AACvD;AAEA,SAAS,mBACP,IAAA,EAC4B;AAC5B,EAAA,OAAO,OAAO,MAAA,CAAO;AAAA,IACnB,OAAA,EAAS,OAAO,MAAA,CAAO,CAAC,GAAI,IAAA,EAAM,OAAA,IAAW,EAAG,CAAC,CAAA;AAAA,IACjD,OAAA,EAAS,OAAO,MAAA,CAAO,CAAC,GAAI,IAAA,EAAM,OAAA,IAAW,EAAG,CAAC,CAAA;AAAA,IACjD,KAAA,EAAO,OAAO,MAAA,CAAO,CAAC,GAAI,IAAA,EAAM,KAAA,IAAS,EAAG,CAAC;AAAA,GAC9C,CAAA;AACH;AAEA,SAAS,0BACP,CAAA,EAC6B;AAC7B,EAAA,MAAM,MAAA,GAAA,CAAU,CAAA,EAAG,MAAA,IAAU,EAAC,EAAG,MAAA;AAAA,IAAO,CAAC,CAAA,KACvC,cAAA,CAAe,QAAA,CAAS,CAAe;AAAA,GACzC;AACA,EAAA,MAAM,WAAA,GAAA,CAAe,CAAA,EAAG,WAAA,IAAe,EAAC,EAAG,MAAA;AAAA,IAAO,CAAC,CAAA,KACjD,cAAA,CAAe,QAAA,CAAS,CAAe;AAAA,GACzC;AACA,EAAA,OAAO,OAAO,MAAA,CAAO;AAAA,IACnB,MAAA,EAAQ,MAAA,CAAO,MAAA,CAAO,MAAM,CAAA;AAAA,IAC5B,WAAA,EAAa,MAAA,CAAO,MAAA,CAAO,WAAW;AAAA,GACvC,CAAA;AACH;AAEA,SAAS,gBACP,MAAA,EACQ;AACR,EAAA,OAAO,MAAA,CACJ,IAAI,CAAC,CAAA,KAAM,GAAG,CAAA,CAAE,IAAA,CAAK,MAAA,GAAS,CAAA,GAAI,CAAA,CAAE,IAAA,CAAK,KAAK,GAAG,CAAA,GAAI,OAAO,EAAE,CAAA,EAAG,EAAE,OAAO,CAAA,CAAE,CAAA,CAC5E,IAAA,CAAK,IAAI,CAAA;AACd;AAIA,IAAM,OAAO,IAAI,GAAA,CAAI,EAAE,SAAA,EAAW,MAAM,CAAA;AAKxC,IAAM,eAAA,uBAAsB,OAAA,EAG1B;AAEF,SAAS,kBAAA,CACP,MAAA,EACA,MAAA,EACA,KAAA,EACqB;AACrB,EAAA,IAAI,QAAA,GAAW,eAAA,CAAgB,GAAA,CAAI,MAAM,CAAA;AACzC,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,QAAA,GAAW,IAAA,CAAK,QAAQ,MAA4C,CAAA;AACpE,IAAA,eAAA,CAAgB,GAAA,CAAI,QAAQ,QAAQ,CAAA;AAAA,EACtC;AACA,EAAA,MAAM,KAAA,GAAQ,SAAS,KAAK,CAAA;AAC5B,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,MAAA,IAAU,EAAC;AACnC,IAAA,MAAM,OAAA,GAAU,MAAA,CACb,GAAA,CAAI,CAAC,MAAM,CAAA,EAAG,CAAA,CAAE,YAAA,IAAgB,GAAG,IAAI,CAAA,CAAE,OAAO,CAAA,CAAE,CAAA,CAClD,KAAK,IAAI,CAAA;AACZ,IAAA,OAAO;AAAA,MACL,EAAA,EAAI,KAAA;AAAA,MACJ,KAAA,EAAO;AAAA,QACL,IAAA,EAAM,eAAA;AAAA,QACN,OAAA,EAAS,CAAA,IAAA,EAAO,MAAM,CAAA,GAAA,EAAM,OAAO,CAAA,CAAA;AAAA,QACnC,KAAA,EAAO;AAAA;AACT,KACF;AAAA,EACF;AACA,EAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,KAAA,EAAkB;AACvC;;;ACjRO,IAAM,6BAAA,GAAgC,EAAE,MAAA,CAAO;AAAA,EACpD,MAAA,EAAQ,CAAA,CAAE,OAAA,CAAQ,oBAAoB,EAAE,QAAA,EAAS;AAAA,EACjD,IAAA,EAAM,EAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA,CAAE,IAAI,EAAE,CAAA;AAAA,EAC9B,EAAA,EAAI,CAAA,CAAE,MAAA,EAAO,CAAE,MAAM,0BAA0B,CAAA;AAAA,EAC/C,WAAA,EAAa,EAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA,CAAE,IAAI,GAAI,CAAA;AAAA,EACvC,OAAA,EAAS,CAAA,CAAE,MAAA,EAAO,CAAE,MAAM,gBAAgB,CAAA;AAAA;AAAA,EAG1C,SAAS,CAAA,CAAE,KAAA,CAAM,EAAE,MAAA,EAAQ,EAAE,QAAA,EAAS;AAAA,EACtC,QAAA,EAAU,EACP,MAAA,CAAO;AAAA,IACN,SAAS,CAAA,CAAE,KAAA,CAAM,EAAE,MAAA,EAAQ,EAAE,QAAA,EAAS;AAAA,IACtC,SAAS,CAAA,CAAE,KAAA,CAAM,EAAE,MAAA,EAAQ,EAAE,QAAA,EAAS;AAAA,IACtC,OAAO,CAAA,CAAE,KAAA,CAAM,EAAE,MAAA,EAAQ,EAAE,QAAA;AAAS,GACrC,EACA,QAAA,EAAS;AAAA;AAAA;AAAA;AAAA;AAAA,EAKZ,UAAU,CAAA,CACP,MAAA;AAAA,IACC,CAAC,CAAA,KACC,OAAO,CAAA,KAAM,QAAA,KACZ,CAAA,KAAM,MAAA,IACL,CAAA,KAAM,QAAA,IACN,CAAA,KAAM,WAAA,IACN,UAAA,CAAW,KAAK,CAAC,CAAA,CAAA;AAAA,IACrB,EAAE,SAAS,4DAAA;AAA6D,IAEzE,QAAA,EAAS;AAAA,EACZ,UAAA,EAAY,EACT,KAAA,CAAM,CAAC,EAAE,OAAA,CAAQ,CAAC,CAAA,EAAG,CAAA,CAAE,OAAA,CAAQ,CAAC,GAAG,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA,EAAG,CAAA,CAAE,QAAQ,CAAC,CAAC,CAAC,CAAA,CAC9D,QAAA,EAAS;AAAA,EACZ,UAAA,EAAY,EAAE,IAAA,CAAK,CAAC,WAAW,SAAA,EAAW,WAAW,CAAC,CAAA,CAAE,QAAA,EAAS;AAAA,EACjE,UAAA,EAAY,EAAE,MAAA,EAAO,CAAE,KAAI,CAAE,QAAA,GAAW,QAAA,EAAS;AAAA,EACjD,UAAA,EAAY,CAAA,CAAE,OAAA,EAAQ,CAAE,QAAA,EAAS;AAAA,EACjC,MAAM,CAAA,CAAE,KAAA,CAAM,EAAE,MAAA,EAAQ,EAAE,QAAA,EAAS;AAAA,EACnC,QAAA,EAAU,CAAA,CAAE,MAAA,CAAO,CAAA,CAAE,MAAA,IAAU,CAAA,CAAE,OAAA,EAAS,CAAA,CAAE,QAAA,EAAS;AAAA;AAAA;AAAA;AAAA;AAAA,EAMrD,MAAA,EAAQ,CAAA,CAAE,MAAA,CAAO,CAAA,CAAE,MAAA,IAAU,CAAA,CAAE,OAAA,EAAS,CAAA,CAAE,QAAA,EAAS;AAAA,EACnD,OAAA,EAAS,CAAA,CAAE,MAAA,CAAO,CAAA,CAAE,MAAA,IAAU,CAAA,CAAE,OAAA,EAAS,CAAA,CAAE,QAAA,EAAS;AAAA;AAAA;AAAA,EAIpD,IAAA,EAAM,CAAA,CAAE,OAAA,EAAQ,CAAE,QAAA,EAAS;AAAA,EAC3B,GAAA,EAAK,CAAA,CAAE,OAAA,EAAQ,CAAE,QAAA,EAAS;AAAA,EAC1B,MAAA,EAAQ,CAAA,CAAE,OAAA,EAAQ,CAAE,QAAA,EAAS;AAAA,EAC7B,OAAA,EAAS,CAAA,CAAE,OAAA,EAAQ,CAAE,QAAA,EAAS;AAAA,EAC9B,OAAA,EAAS,CAAA,CAAE,OAAA,EAAQ,CAAE,QAAA;AACvB,CAAC;AAeM,SAAS,kBAAkB,MAAA,EAA8B;AAC9D,EAAA,MAAM,MAAA,GAAS,OAAO,MAAM,CAAA;AAC5B,EAAA,IAAI,OAAO,IAAA,CAAK,MAAA,CAAO,IAAI,CAAA,CAAE,WAAW,CAAA,EAAG;AACzC,IAAA,MAAM,IAAI,MAAM,iDAAiD,CAAA;AAAA,EACnE;AACA,EAAA,MAAM,MAAA,GAAS,6BAAA,CAA8B,SAAA,CAAU,MAAA,CAAO,IAAI,CAAA;AAClE,EAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,iDAA4C,MAAA,CAAO,KAAA,CAAM,OACtD,GAAA,CAAI,CAAA,CAAA,KAAK,GAAG,CAAA,CAAE,IAAA,CAAK,KAAK,GAAG,CAAC,KAAK,CAAA,CAAE,OAAO,EAAE,CAAA,CAC5C,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,KACf;AAAA,EACF;AACA,EAAA,OAAO,EAAE,WAAA,EAAa,MAAA,CAAO,IAAA,EAAM,IAAA,EAAM,OAAO,OAAA,EAAQ;AAC1D;AAcO,SAAS,qBACd,QAAA,EAC8B;AAC9B,EAAA,MAAM,KAAK,QAAA,CAAS,WAAA;AACpB,EAAA,OAAO,UAAA,CAAW;AAAA,IAChB,IAAI,EAAA,CAAG,EAAA;AAAA,IACP,MAAM,EAAA,CAAG,IAAA;AAAA,IACT,aAAa,EAAA,CAAG,WAAA;AAAA,IAChB,SAAS,EAAA,CAAG,OAAA;AAAA,IACZ,QAAQ,EAAA,CAAG,MAAA;AAAA,IACX,SAAS,EAAA,CAAG,OAAA;AAAA,IACZ,SAAS,EAAA,CAAG,OAAA;AAAA,IACZ,UAAU,EAAA,CAAG,QAAA;AAAA,IACb,UAAU,EAAA,CAAG,QAAA;AAAA,IACb,WAAW,EAAA,CAAG,UAAA;AAAA,IACd,WAAW,EAAA,CAAG,UAAA;AAAA,IACd,WAAW,EAAA,CAAG,UAAA;AAAA,IACd,YAAY,EAAA,CAAG,UAAA;AAAA,IACf,MAAM,EAAA,CAAG,IAAA;AAAA,IACT,UAAU,EAAA,CAAG;AAAA,GACd,CAAA;AACH;AAuBO,SAAS,iBAId,IAAA,EAKwC;AACxC,EAAA,MAAM,EAAA,GAAK,KAAK,QAAA,CAAS,WAAA;AACzB,EAAA,OAAO,UAAA,CAAsC;AAAA,IAC3C,IAAI,EAAA,CAAG,EAAA;AAAA,IACP,MAAM,EAAA,CAAG,IAAA;AAAA,IACT,aAAa,EAAA,CAAG,WAAA;AAAA,IAChB,SAAS,EAAA,CAAG,OAAA;AAAA,IACZ,aAAa,IAAA,CAAK,WAAA;AAAA,IAClB,cAAc,IAAA,CAAK,YAAA;AAAA,IACnB,QAAQ,EAAA,CAAG,MAAA;AAAA,IACX,SAAS,EAAA,CAAG,OAAA;AAAA,IACZ,eAAe,IAAA,CAAK,aAAA;AAAA,IACpB,SAAS,EAAA,CAAG,OAAA;AAAA,IACZ,UAAU,EAAA,CAAG,QAAA;AAAA,IACb,UAAU,EAAA,CAAG,QAAA;AAAA,IACb,WAAW,EAAA,CAAG,UAAA;AAAA,IACd,WAAW,EAAA,CAAG,UAAA;AAAA,IACd,WAAW,EAAA,CAAG,UAAA;AAAA,IACd,YAAY,EAAA,CAAG,UAAA;AAAA,IACf,MAAM,EAAA,CAAG,IAAA;AAAA,IACT,UAAU,EAAA,CAAG;AAAA,GACd,CAAA;AACH","file":"chunk-VCLSUUB5.mjs","sourcesContent":["import type { ToolResult } from \"./types.js\"\n\n/**\n * AIP-14 conventional error codes. Tool-specific codes MAY use a domain\n * prefix (`\"stripe:card_declined\"`).\n */\nexport type ToolErrorCode =\n | \"input_invalid\"\n | \"output_invalid\"\n | \"unauthorised\"\n | \"not_found\"\n | \"rate_limited\"\n | \"timeout\"\n | \"upstream_error\"\n | \"internal\"\n | (string & {})\n\nexport interface ToolErrorPayload {\n code: ToolErrorCode\n message: string\n retryable?: boolean\n cause?: unknown\n}\n\n/**\n * Structured error thrown by tool bodies. Adapters wrap this into the\n * standard {@link ToolResult} envelope; bodies MUST throw it (never\n * return error objects).\n */\nexport class ToolError extends Error {\n readonly code: ToolErrorCode\n readonly retryable: boolean\n readonly cause: unknown\n\n constructor(payload: ToolErrorPayload) {\n super(payload.message)\n this.name = \"ToolError\"\n this.code = payload.code\n this.retryable = payload.retryable ?? false\n this.cause = payload.cause\n }\n\n toJSON(): ToolErrorPayload {\n return {\n code: this.code,\n message: this.message,\n retryable: this.retryable,\n ...(this.cause !== undefined ? { cause: this.cause } : {}),\n }\n }\n}\n\n/**\n * Wrap an unknown thrown value into a {@link ToolError}. Used by adapters\n * to normalise non-ToolError throws into the standard envelope.\n */\nexport function toToolError(thrown: unknown): ToolError {\n if (thrown instanceof ToolError) return thrown\n if (thrown instanceof Error) {\n return new ToolError({\n code: \"internal\",\n message: thrown.message,\n cause: thrown,\n })\n }\n return new ToolError({\n code: \"internal\",\n message: String(thrown),\n cause: thrown,\n })\n}\n\n/**\n * Adapter helper: project a thrown ToolError (or any throw) into the\n * standard {@link ToolResult} envelope. Adapters MUST do this; bodies MUST NOT.\n */\nexport function toToolResult<T>(\n value: T | undefined,\n thrown: unknown\n): ToolResult<T> {\n if (thrown !== undefined) {\n const err = toToolError(thrown)\n return { ok: false, error: err.toJSON() }\n }\n return { ok: true, value: value as T }\n}\n","import { createDoctype } from \"@agentproto/define-doctype\"\nimport Ajv from \"ajv\"\nimport type { ZodType } from \"zod\"\nimport { ToolError } from \"./errors.js\"\nimport type {\n ApprovalClass,\n DriverConstraints,\n DriverKind,\n ToolCapabilities,\n ToolContext,\n ToolDefinition,\n ToolHandle,\n ValidationResult,\n} from \"./types.js\"\n\nconst PROVIDER_KINDS: readonly DriverKind[] = [\n \"cli\",\n \"http\",\n \"mcp\",\n \"sdk\",\n \"builtin\",\n]\n\n/**\n * AIP-14 reference implementation of `defineTool`.\n *\n * Returns a {@link ToolHandle} with defaults applied. The handle is a\n * pure contract — schemas, governance metadata, provider routing\n * hints. Bodies live on AIP-30 PROVIDER manifests; invocation goes\n * through provider-runtime's resolver.\n *\n * Built on `createDoctype` from `@agentproto/define-doctype`: the\n * id-pattern + description-length validation and the top-level\n * `Object.freeze` are shared with every other AIP defineX. The\n * spec-14-specific parts (migration guard for `execute`, defaulting\n * `approval` from `mutates`, freezing nested arrays/objects) live in\n * `validate` and `build` below.\n *\n * Conformance highlights ([§ Conformance rules](https://agentproto.sh/docs/aip-14)):\n * - No `execute` field on the contract — bodies are providers' job.\n * - `defineTool` MUST refuse a definition carrying `execute` (migration error).\n * - No I/O at module load — `defineTool(...)` is pure construction.\n */\nconst constructTool = createDoctype<\n ToolDefinition<unknown, unknown, ToolContext>,\n ToolHandle<unknown, unknown, ToolContext>\n>({\n aip: 14,\n name: \"tool\",\n validate(def) {\n // Migration guard: catch authors trying to ship a body on the contract.\n // The body lives on a PROVIDER (per AIP-30); reject at construction.\n if (\"execute\" in (def as unknown as Record<string, unknown>)) {\n throw new Error(\n `defineTool: id='${def.id}' carries an 'execute' property. ` +\n `Bodies live on AIP-30 PROVIDER manifests, not on the TOOL contract. ` +\n `See https://agentproto.sh/docs/aip-30 for migration.`,\n )\n }\n },\n build(def) {\n return {\n id: def.id,\n name: def.name ?? def.id,\n description: def.description,\n version: def.version,\n inputSchema: def.inputSchema,\n outputSchema: def.outputSchema,\n inputs: def.inputs ? Object.freeze({ ...def.inputs }) : undefined,\n outputs: def.outputs ? Object.freeze({ ...def.outputs }) : undefined,\n contextSchema: def.contextSchema,\n mutates: Object.freeze([...(def.mutates ?? [])]),\n requires: freezeCapabilities(def.requires),\n approval: defaultApproval(def.approval, def.mutates),\n riskLevel: def.riskLevel ?? 0,\n costClass: def.costClass ?? \"trivial\",\n timeoutMs: def.timeoutMs ?? 30_000,\n retry: def.retry,\n tags: Object.freeze([...(def.tags ?? [])]),\n metadata: Object.freeze({ ...(def.metadata ?? {}) }),\n idempotent: def.idempotent ?? false,\n defaultImplementation: def.defaultImplementation,\n driverConstraints: freezeProviderConstraints(def.driverConstraints),\n }\n },\n})\n\n/**\n * Public-facing `defineTool` — typed wrapper around `constructTool`\n * that preserves the per-call `<TInput, TOutput, TContext>` inference\n * so callers don't write any generics. The wrapper exists purely for\n * generic propagation; the runtime body is the meta-factory above.\n */\nexport function defineTool<\n TInput,\n TOutput,\n TContext extends ToolContext = ToolContext,\n>(\n definition: ToolDefinition<TInput, TOutput, TContext>,\n): ToolHandle<TInput, TOutput, TContext> {\n return constructTool(\n definition as ToolDefinition<unknown, unknown, ToolContext>,\n ) as unknown as ToolHandle<TInput, TOutput, TContext>\n}\n\n/**\n * Validate input against a tool's `inputSchema`. Returns a typed\n * {@link ValidationResult}; provider runtimes MUST call this BEFORE\n * dispatching to the provider's body.\n *\n * Priority:\n * 1. zod `inputSchema` (v0.1) — used when present.\n * 2. JSON Schema `inputs` (v0.2) — fallback for manifest-only tools.\n * 3. No schema — passthrough (returns `ok: true`).\n */\nexport function validateInput<TInput>(\n handle: Pick<ToolHandle<TInput>, \"id\" | \"inputSchema\" | \"inputs\">,\n input: unknown,\n): ValidationResult<TInput> {\n if (handle.inputSchema) {\n const result = handle.inputSchema.safeParse(input)\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"input_invalid\",\n message: `id='${handle.id}': ${formatZodIssues(result.error.issues)}`,\n cause: result.error.issues,\n },\n }\n }\n return { ok: true, value: result.data as TInput }\n }\n if (handle.inputs) {\n return validateJsonSchema<TInput>(handle.id, handle.inputs, input)\n }\n return { ok: true, value: input as TInput }\n}\n\n/**\n * Validate context against a tool's `contextSchema` (when declared).\n * Returns a typed {@link ValidationResult}; provider runtimes MUST\n * call this BEFORE dispatching when the contract has a contextSchema.\n *\n * Tools without a contextSchema accept any context shape; this helper\n * returns the input verbatim in that case.\n *\n * Context validation uses only zod (no JSON Schema fallback) — context\n * schemas are always authored in TS, never in manifests.\n */\nexport function validateContext<TContext extends ToolContext = ToolContext>(\n handle: Pick<ToolHandle<unknown, unknown, TContext>, \"id\" | \"contextSchema\">,\n context: unknown,\n): ValidationResult<TContext> {\n if (!handle.contextSchema) {\n return { ok: true, value: context as TContext }\n }\n const result = handle.contextSchema.safeParse(context)\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"input_invalid\",\n message: `id='${handle.id}': context does not match contextSchema — ${formatZodIssues(result.error.issues)}`,\n field: \"context\",\n cause: result.error.issues,\n },\n }\n }\n return { ok: true, value: result.data as TContext }\n}\n\n/**\n * Validate output against a tool's `outputSchema`. Returns the typed\n * value on success; throws {@link ToolError} with code `\"output_invalid\"`\n * on contract violation.\n *\n * Priority:\n * 1. zod `outputSchema` (v0.1) — used when present.\n * 2. JSON Schema `outputs` (v0.2) — fallback for manifest-only tools.\n * 3. No schema — passthrough (returns the value as-is).\n */\nexport function validateOutput<TOutput>(\n handle: Pick<ToolHandle<unknown, TOutput>, \"id\" | \"outputSchema\" | \"outputs\">,\n output: unknown,\n): TOutput {\n if (handle.outputSchema) {\n const result = handle.outputSchema.safeParse(output)\n if (!result.success) {\n throw new ToolError({\n code: \"output_invalid\",\n message: `id='${handle.id}': provider produced output that does not match outputSchema — ${formatZodIssues(result.error.issues)}`,\n cause: result.error.issues,\n })\n }\n return result.data as TOutput\n }\n if (handle.outputs) {\n const result = validateJsonSchema<TOutput>(handle.id, handle.outputs, output)\n if (!result.ok) {\n throw new ToolError({\n code: \"output_invalid\",\n message: result.error.message,\n cause: result.error.cause,\n })\n }\n return result.value\n }\n return output as TOutput\n}\n\nfunction defaultApproval(\n declared: ApprovalClass | undefined,\n mutates: readonly string[] | undefined,\n): ApprovalClass {\n if (declared) return declared\n return mutates && mutates.length > 0 ? \"on-mutate\" : \"auto\"\n}\n\nfunction freezeCapabilities(\n caps: ToolCapabilities | undefined,\n): Readonly<ToolCapabilities> {\n return Object.freeze({\n network: Object.freeze([...(caps?.network ?? [])]),\n secrets: Object.freeze([...(caps?.secrets ?? [])]),\n tools: Object.freeze([...(caps?.tools ?? [])]),\n })\n}\n\nfunction freezeProviderConstraints(\n c: DriverConstraints | undefined,\n): Required<DriverConstraints> {\n const forbid = (c?.forbid ?? []).filter((k): k is DriverKind =>\n PROVIDER_KINDS.includes(k as DriverKind),\n )\n const requireKind = (c?.requireKind ?? []).filter((k): k is DriverKind =>\n PROVIDER_KINDS.includes(k as DriverKind),\n )\n return Object.freeze({\n forbid: Object.freeze(forbid) as readonly DriverKind[],\n requireKind: Object.freeze(requireKind) as readonly DriverKind[],\n })\n}\n\nfunction formatZodIssues(\n issues: ReadonlyArray<{ path: ReadonlyArray<PropertyKey>; message: string }>,\n): string {\n return issues\n .map((i) => `${i.path.length > 0 ? i.path.join(\".\") + \": \" : \"\"}${i.message}`)\n .join(\"; \")\n}\n\n// Shared Ajv instance — created once at module load.\n// allErrors: true so we surface all violations, not just the first.\nconst _ajv = new Ajv({ allErrors: true })\n\n// Validator cache keyed by schema object identity. Avoids repeated _ajv.compile()\n// calls (which go through Ajv's internal registry) and lets GC collect validators\n// when a tool handle is no longer referenced.\nconst _validatorCache = new WeakMap<\n object,\n ReturnType<typeof _ajv.compile>\n>()\n\nfunction validateJsonSchema<T>(\n toolId: string,\n schema: Record<string, unknown>,\n value: unknown,\n): ValidationResult<T> {\n let validate = _validatorCache.get(schema)\n if (!validate) {\n validate = _ajv.compile(schema as Parameters<typeof _ajv.compile>[0])\n _validatorCache.set(schema, validate)\n }\n const valid = validate(value)\n if (!valid) {\n const errors = validate.errors ?? []\n const message = errors\n .map((e) => `${e.instancePath || \"/\"} ${e.message}`)\n .join(\"; \")\n return {\n ok: false,\n error: {\n code: \"input_invalid\",\n message: `id='${toolId}': ${message}`,\n cause: errors,\n },\n }\n }\n return { ok: true, value: value as T }\n}\n\nexport type { ZodType }\n","import matter from \"gray-matter\"\nimport { z, type ZodType } from \"zod\"\nimport { defineTool } from \"../define-tool.js\"\nimport type { ApprovalClass, ToolContext, ToolHandle } from \"../types.js\"\n\n/**\n * AIP-14 TOOL.md sidecar parser.\n *\n * Reads frontmatter (host-relevant metadata) + body (long-form\n * description / examples / errors). The TS module's `defineTool(...)`\n * supplies the schemas and execute body; this manifest supplies the\n * runtime metadata that overrides or augments the in-code defaults.\n *\n * Field set covers AIP-14 §\"Frontmatter\" — required and optional fields\n * normalised to snake_case → camelCase.\n */\n\nexport const toolManifestFrontmatterSchema = z.object({\n schema: z.literal(\"agentproto/tool/v1\").optional(),\n name: z.string().min(1).max(80),\n id: z.string().regex(/^[a-z][a-z0-9._-]{1,63}$/),\n description: z.string().min(1).max(2000),\n version: z.string().regex(/^\\d+\\.\\d+\\.\\d+/),\n\n // Optional metadata\n mutates: z.array(z.string()).optional(),\n requires: z\n .object({\n network: z.array(z.string()).optional(),\n secrets: z.array(z.string()).optional(),\n tools: z.array(z.string()).optional(),\n })\n .optional(),\n // `ApprovalClass` is `\"auto\" | \"always\" | \"on-mutate\" | \\`policy:${string}\\``.\n // z.union widens the regex branch to plain `string` (zod can't express\n // template literal types), so we use `z.custom` to keep the inferred\n // type exact — matters because `defineTool` accepts `ApprovalClass`.\n approval: z\n .custom<ApprovalClass>(\n (v): v is ApprovalClass =>\n typeof v === \"string\" &&\n (v === \"auto\" ||\n v === \"always\" ||\n v === \"on-mutate\" ||\n /^policy:/.test(v)),\n { message: \"expected 'auto' | 'always' | 'on-mutate' | 'policy:<name>'\" },\n )\n .optional(),\n risk_level: z\n .union([z.literal(0), z.literal(1), z.literal(2), z.literal(3)])\n .optional(),\n cost_class: z.enum([\"trivial\", \"metered\", \"expensive\"]).optional(),\n timeout_ms: z.number().int().positive().optional(),\n idempotent: z.boolean().optional(),\n tags: z.array(z.string()).optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n\n // AIP-16 IO blocks — `inputs`/`outputs` as JSON Schema objects. Kept\n // structurally loose here (validated as objects, not deep-checked against\n // the AIP-16 meta-schema); preserved so a manifest's declared IO contract\n // survives the parse → handle round-trip instead of being silently dropped.\n inputs: z.record(z.string(), z.unknown()).optional(),\n outputs: z.record(z.string(), z.unknown()).optional(),\n\n // AIP-26 / AIP-17 / AIP-19 references — kept loose; validated by their\n // respective AIPs' adapters when consumed.\n code: z.unknown().optional(),\n run: z.unknown().optional(),\n runner: z.unknown().optional(),\n secrets: z.unknown().optional(),\n network: z.unknown().optional(),\n})\n\nexport type ToolManifestFrontmatter = z.infer<\n typeof toolManifestFrontmatterSchema\n>\n\nexport interface ToolManifest {\n frontmatter: ToolManifestFrontmatter\n body: string\n}\n\n/**\n * Parse a TOOL.md source string into structured frontmatter + body.\n * Throws on missing frontmatter or schema-invalid frontmatter.\n */\nexport function parseToolManifest(source: string): ToolManifest {\n const parsed = matter(source)\n if (Object.keys(parsed.data).length === 0) {\n throw new Error(\"parseToolManifest: missing or empty frontmatter\")\n }\n const result = toolManifestFrontmatterSchema.safeParse(parsed.data)\n if (!result.success) {\n throw new Error(\n `parseToolManifest: invalid frontmatter — ${result.error.issues\n .map(i => `${i.path.join(\".\")}: ${i.message}`)\n .join(\"; \")}`\n )\n }\n return { frontmatter: result.data, body: parsed.content }\n}\n\n/**\n * Build a {@link ToolHandle} from a manifest that has no companion TS module.\n *\n * `inputSchema`/`outputSchema` are omitted; IO validation falls back to the\n * AIP-16 `inputs`/`outputs` JSON Schema blocks declared in the frontmatter\n * (via `validateInput`/`validateOutput`). The returned handle is typed as\n * `ToolHandle<unknown, unknown>` since the generic shapes are not statically\n * known.\n *\n * Use this when loading an agent-generated TOOL.md whose IO contract is\n * expressed in YAML (`inputs:`/`outputs:`) rather than a compiled TS module.\n */\nexport function toolFromManifestOnly(\n manifest: ToolManifest,\n): ToolHandle<unknown, unknown> {\n const fm = manifest.frontmatter\n return defineTool({\n id: fm.id,\n name: fm.name,\n description: fm.description,\n version: fm.version,\n inputs: fm.inputs,\n outputs: fm.outputs,\n mutates: fm.mutates,\n requires: fm.requires,\n approval: fm.approval,\n riskLevel: fm.risk_level,\n costClass: fm.cost_class,\n timeoutMs: fm.timeout_ms,\n idempotent: fm.idempotent,\n tags: fm.tags,\n metadata: fm.metadata,\n })\n}\n\n/**\n * Build a fully-typed {@link ToolHandle} from a parsed `TOOL.md` manifest\n * + caller-supplied schemas. The .md is the single source of truth for\n * metadata (id, name, description, version, mutates, approval, …); the\n * schemas live in the TS module that ships alongside the .md.\n *\n * Both inputs are revalidated by `defineTool`'s shared invariants\n * (id pattern, description length, top-level freeze) — `parseToolManifest`\n * already enforces a stricter id pattern + version semver, so a\n * well-formed manifest passes through cleanly. Mismatches between the\n * manifest's id-shape and `defineTool`'s pattern surface a\n * descriptive error from the same validation pipeline as the TS path.\n *\n * @example\n * const manifest = parseToolManifest(readFileSync(\"./echo/TOOL.md\", \"utf8\"))\n * const echo = toolFromManifest({\n * manifest,\n * inputSchema: z.object({ msg: z.string() }),\n * outputSchema: z.object({ msg: z.string() }),\n * })\n */\nexport function toolFromManifest<\n TInput,\n TOutput,\n TContext extends ToolContext = ToolContext,\n>(args: {\n manifest: ToolManifest\n inputSchema: ZodType<TInput>\n outputSchema: ZodType<TOutput>\n contextSchema?: ZodType<TContext>\n}): ToolHandle<TInput, TOutput, TContext> {\n const fm = args.manifest.frontmatter\n return defineTool<TInput, TOutput, TContext>({\n id: fm.id,\n name: fm.name,\n description: fm.description,\n version: fm.version,\n inputSchema: args.inputSchema,\n outputSchema: args.outputSchema,\n inputs: fm.inputs,\n outputs: fm.outputs,\n contextSchema: args.contextSchema,\n mutates: fm.mutates,\n requires: fm.requires,\n approval: fm.approval,\n riskLevel: fm.risk_level,\n costClass: fm.cost_class,\n timeoutMs: fm.timeout_ms,\n idempotent: fm.idempotent,\n tags: fm.tags,\n metadata: fm.metadata,\n })\n}\n"]}
@@ -0,0 +1,274 @@
1
+ import { ZodType, z } from 'zod';
2
+
3
+ /**
4
+ * AIP-14 ToolDefinition — the abstract agent contract.
5
+ *
6
+ * Field set mirrors `TOOL.md` frontmatter so a manifest and a TS
7
+ * module are interchangeable inputs to the runtime. The contract
8
+ * carries identity, schemas, side-effect profile, approval class,
9
+ * and resource budget — but **not** the body. Bodies live on
10
+ * AIP-30 PROVIDER manifests + their `execute[<toolId>]` entries.
11
+ *
12
+ * Generic over context: tools that depend on host-injected state
13
+ * (database connections, governance config, …) declare a
14
+ * `contextSchema` — analogous to `inputSchema` but for the per-call
15
+ * context object — and the host validates context against it before
16
+ * dispatching to the resolved provider's body.
17
+ */
18
+ interface ToolDefinition<TInput = unknown, TOutput = unknown, TContext extends ToolContext = ToolContext> {
19
+ /** Machine identifier. Lowercase, digits, dashes, dots. 2–80 chars. */
20
+ id: string;
21
+ /** Human-readable display name. Optional; falls back to `id`. */
22
+ name?: string;
23
+ /** One-paragraph purpose, written for the LLM caller. */
24
+ description: string;
25
+ /** Spec version of THIS tool (semver). */
26
+ version?: string;
27
+ /**
28
+ * Input shape — zod schema (v0.1). Hosts validate args.input against it
29
+ * before dispatching to the resolved provider; bodies MUST NOT re-validate.
30
+ *
31
+ * Optional: manifest-only tools (loaded from a TOOL.md without a TS module)
32
+ * omit zod schemas and declare IO via AIP-16 `inputs`/`outputs` JSON Schema
33
+ * below instead. `validateInput`/`validateOutput` fall back to JSON Schema
34
+ * when these are absent.
35
+ */
36
+ inputSchema?: ZodType<TInput>;
37
+ outputSchema?: ZodType<TOutput>;
38
+ /**
39
+ * AIP-16 IO blocks — `inputs`/`outputs` as raw JSON Schema. This is the
40
+ * manifest-native shape: a TOOL.md authored in YAML (e.g. by an agent
41
+ * self-constructing a tool) declares its contract here, since it cannot
42
+ * ship a compiled zod module. Carried through load/create so a
43
+ * manifest-only tool still exposes a declared IO contract.
44
+ *
45
+ * Runtime validation from these JSON Schemas (compiling them to a
46
+ * validator) is the remaining v0.2 step; v0.1 validates via the zod
47
+ * `inputSchema`/`outputSchema` above when present.
48
+ */
49
+ inputs?: Record<string, unknown>;
50
+ outputs?: Record<string, unknown>;
51
+ /**
52
+ * Optional context schema. When provided, the host validates
53
+ * `args.context` against it before dispatching to the provider,
54
+ * rejecting with `input_invalid` (field=`context`) on mismatch.
55
+ * Providers receive the narrowed, typed context.
56
+ */
57
+ contextSchema?: ZodType<TContext>;
58
+ /** Resources the tool may modify. Format: `<class>:<scope>`. */
59
+ mutates?: readonly string[];
60
+ /** Capability requirements (governance/gating per AIP-7). */
61
+ requires?: ToolCapabilities;
62
+ approval?: ApprovalClass;
63
+ riskLevel?: 0 | 1 | 2 | 3;
64
+ costClass?: "trivial" | "metered" | "expensive";
65
+ /** Hard wall-clock contract ceiling. Providers MAY narrow; never widen. */
66
+ timeoutMs?: number;
67
+ retry?: RetryPolicy;
68
+ /** Free-form discovery tags. */
69
+ tags?: readonly string[];
70
+ /** Free-form metadata under namespaced keys (`mastra.…`, `langchain.…`). */
71
+ metadata?: Record<string, unknown>;
72
+ /** Whether retries are observably free of extra effect. Defaults to `false`. */
73
+ idempotent?: boolean;
74
+ /**
75
+ * Optional pin for the canonical provider. The AIP-30 resolver uses
76
+ * this in Phase 5 (cost ranking) when no other signal differentiates
77
+ * candidates. Null/undefined = pick by resolver policy.
78
+ */
79
+ defaultImplementation?: string;
80
+ /**
81
+ * Author-side allowlist/denylist on which provider kinds the contract
82
+ * permits. Use to express "this tool MUST NOT be served via untrusted
83
+ * HTTP" (`forbid: ["http"]`) for self-hosted-only contracts.
84
+ */
85
+ driverConstraints?: DriverConstraints;
86
+ }
87
+ type DriverKind = "cli" | "http" | "mcp" | "sdk" | "builtin";
88
+ interface DriverConstraints {
89
+ /** Provider kinds the contract refuses. */
90
+ forbid?: readonly DriverKind[];
91
+ /** Whitelist of allowed provider kinds. Empty/missing = all permitted. */
92
+ requireKind?: readonly DriverKind[];
93
+ }
94
+ type ToolContext = Record<string, unknown> & {
95
+ signal?: AbortSignal;
96
+ };
97
+ type ApprovalClass = "auto" | "always" | "on-mutate" | `policy:${string}`;
98
+ interface ToolCapabilities {
99
+ network?: readonly string[];
100
+ secrets?: readonly string[];
101
+ tools?: readonly string[];
102
+ }
103
+ interface RetryPolicy {
104
+ maxAttempts: number;
105
+ backoff: "fixed" | "exponential";
106
+ initialMs: number;
107
+ }
108
+ /**
109
+ * The host-registrable contract handle returned by `defineTool`.
110
+ *
111
+ * Adapters (`toMastraTool`, …) AND provider runtimes (`http-runtime`,
112
+ * `cli-runtime`, …) consume this shape. The handle does **not** carry
113
+ * an invoke method — invocation goes through provider-runtime, which
114
+ * resolves a provider per call and dispatches to its `execute[id]`.
115
+ */
116
+ interface ToolHandle<TInput = unknown, TOutput = unknown, TContext extends ToolContext = ToolContext> {
117
+ readonly id: string;
118
+ readonly name: string;
119
+ readonly description: string;
120
+ readonly version?: string;
121
+ /** Zod schema for input (v0.1). Absent on manifest-only tools — validate via `inputs` JSON Schema. */
122
+ readonly inputSchema?: ZodType<TInput>;
123
+ /** Zod schema for output (v0.1). Absent on manifest-only tools — validate via `outputs` JSON Schema. */
124
+ readonly outputSchema?: ZodType<TOutput>;
125
+ /** AIP-16 IO blocks (raw JSON Schema) as declared in the manifest. */
126
+ readonly inputs?: Record<string, unknown>;
127
+ readonly outputs?: Record<string, unknown>;
128
+ readonly contextSchema?: ZodType<TContext>;
129
+ readonly mutates: readonly string[];
130
+ readonly requires: ToolCapabilities;
131
+ readonly approval: ApprovalClass;
132
+ readonly riskLevel: 0 | 1 | 2 | 3;
133
+ readonly costClass: "trivial" | "metered" | "expensive";
134
+ readonly timeoutMs: number;
135
+ readonly retry?: RetryPolicy;
136
+ readonly tags: readonly string[];
137
+ readonly metadata: Record<string, unknown>;
138
+ readonly idempotent: boolean;
139
+ readonly defaultImplementation?: string;
140
+ readonly driverConstraints: Required<DriverConstraints>;
141
+ }
142
+ /**
143
+ * Standard out-of-band result envelope. Provider runtimes wrap thrown
144
+ * errors into this shape; consumers consume `ToolResult<T>` rather than
145
+ * `Promise<T>`.
146
+ */
147
+ type ToolResult<T> = {
148
+ ok: true;
149
+ value: T;
150
+ } | {
151
+ ok: false;
152
+ error: {
153
+ code: string;
154
+ message: string;
155
+ retryable?: boolean;
156
+ cause?: unknown;
157
+ };
158
+ };
159
+ /**
160
+ * Validation helpers exposed for provider-runtime to reuse the same
161
+ * input/output/context validation logic AIP-14 prescribes. Provider
162
+ * runtimes MUST validate args.input against `tool.inputSchema` and
163
+ * (when declared) args.context against `tool.contextSchema` BEFORE
164
+ * dispatching to a provider's body.
165
+ */
166
+ interface ValidationFailure {
167
+ ok: false;
168
+ error: {
169
+ code: "input_invalid";
170
+ message: string;
171
+ field?: string;
172
+ cause?: unknown;
173
+ };
174
+ }
175
+ interface ValidationSuccess<T> {
176
+ ok: true;
177
+ value: T;
178
+ }
179
+ type ValidationResult<T> = ValidationSuccess<T> | ValidationFailure;
180
+
181
+ /**
182
+ * AIP-14 TOOL.md sidecar parser.
183
+ *
184
+ * Reads frontmatter (host-relevant metadata) + body (long-form
185
+ * description / examples / errors). The TS module's `defineTool(...)`
186
+ * supplies the schemas and execute body; this manifest supplies the
187
+ * runtime metadata that overrides or augments the in-code defaults.
188
+ *
189
+ * Field set covers AIP-14 §"Frontmatter" — required and optional fields
190
+ * normalised to snake_case → camelCase.
191
+ */
192
+ declare const toolManifestFrontmatterSchema: z.ZodObject<{
193
+ schema: z.ZodOptional<z.ZodLiteral<"agentproto/tool/v1">>;
194
+ name: z.ZodString;
195
+ id: z.ZodString;
196
+ description: z.ZodString;
197
+ version: z.ZodString;
198
+ mutates: z.ZodOptional<z.ZodArray<z.ZodString>>;
199
+ requires: z.ZodOptional<z.ZodObject<{
200
+ network: z.ZodOptional<z.ZodArray<z.ZodString>>;
201
+ secrets: z.ZodOptional<z.ZodArray<z.ZodString>>;
202
+ tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
203
+ }, z.core.$strip>>;
204
+ approval: z.ZodOptional<z.ZodCustom<ApprovalClass, ApprovalClass>>;
205
+ risk_level: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>]>>;
206
+ cost_class: z.ZodOptional<z.ZodEnum<{
207
+ trivial: "trivial";
208
+ metered: "metered";
209
+ expensive: "expensive";
210
+ }>>;
211
+ timeout_ms: z.ZodOptional<z.ZodNumber>;
212
+ idempotent: z.ZodOptional<z.ZodBoolean>;
213
+ tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
214
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
215
+ inputs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
216
+ outputs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
217
+ code: z.ZodOptional<z.ZodUnknown>;
218
+ run: z.ZodOptional<z.ZodUnknown>;
219
+ runner: z.ZodOptional<z.ZodUnknown>;
220
+ secrets: z.ZodOptional<z.ZodUnknown>;
221
+ network: z.ZodOptional<z.ZodUnknown>;
222
+ }, z.core.$strip>;
223
+ type ToolManifestFrontmatter = z.infer<typeof toolManifestFrontmatterSchema>;
224
+ interface ToolManifest {
225
+ frontmatter: ToolManifestFrontmatter;
226
+ body: string;
227
+ }
228
+ /**
229
+ * Parse a TOOL.md source string into structured frontmatter + body.
230
+ * Throws on missing frontmatter or schema-invalid frontmatter.
231
+ */
232
+ declare function parseToolManifest(source: string): ToolManifest;
233
+ /**
234
+ * Build a {@link ToolHandle} from a manifest that has no companion TS module.
235
+ *
236
+ * `inputSchema`/`outputSchema` are omitted; IO validation falls back to the
237
+ * AIP-16 `inputs`/`outputs` JSON Schema blocks declared in the frontmatter
238
+ * (via `validateInput`/`validateOutput`). The returned handle is typed as
239
+ * `ToolHandle<unknown, unknown>` since the generic shapes are not statically
240
+ * known.
241
+ *
242
+ * Use this when loading an agent-generated TOOL.md whose IO contract is
243
+ * expressed in YAML (`inputs:`/`outputs:`) rather than a compiled TS module.
244
+ */
245
+ declare function toolFromManifestOnly(manifest: ToolManifest): ToolHandle<unknown, unknown>;
246
+ /**
247
+ * Build a fully-typed {@link ToolHandle} from a parsed `TOOL.md` manifest
248
+ * + caller-supplied schemas. The .md is the single source of truth for
249
+ * metadata (id, name, description, version, mutates, approval, …); the
250
+ * schemas live in the TS module that ships alongside the .md.
251
+ *
252
+ * Both inputs are revalidated by `defineTool`'s shared invariants
253
+ * (id pattern, description length, top-level freeze) — `parseToolManifest`
254
+ * already enforces a stricter id pattern + version semver, so a
255
+ * well-formed manifest passes through cleanly. Mismatches between the
256
+ * manifest's id-shape and `defineTool`'s pattern surface a
257
+ * descriptive error from the same validation pipeline as the TS path.
258
+ *
259
+ * @example
260
+ * const manifest = parseToolManifest(readFileSync("./echo/TOOL.md", "utf8"))
261
+ * const echo = toolFromManifest({
262
+ * manifest,
263
+ * inputSchema: z.object({ msg: z.string() }),
264
+ * outputSchema: z.object({ msg: z.string() }),
265
+ * })
266
+ */
267
+ declare function toolFromManifest<TInput, TOutput, TContext extends ToolContext = ToolContext>(args: {
268
+ manifest: ToolManifest;
269
+ inputSchema: ZodType<TInput>;
270
+ outputSchema: ZodType<TOutput>;
271
+ contextSchema?: ZodType<TContext>;
272
+ }): ToolHandle<TInput, TOutput, TContext>;
273
+
274
+ export { type ApprovalClass as A, type DriverConstraints as D, type RetryPolicy as R, type ToolContext as T, type ValidationResult as V, type ToolDefinition as a, type ToolHandle as b, type ToolResult as c, type DriverKind as d, type ToolCapabilities as e, type ToolManifest as f, type ToolManifestFrontmatter as g, type ValidationFailure as h, type ValidationSuccess as i, toolFromManifestOnly as j, toolManifestFrontmatterSchema as k, parseToolManifest as p, toolFromManifest as t };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { T as ToolContext, a as ToolDefinition, b as ToolHandle, V as ValidationResult, c as ToolResult } from './types-Ce8BEvMm.js';
2
- export { A as ApprovalClass, D as DriverConstraints, d as DriverKind, R as RetryPolicy, e as ToolCapabilities, f as ValidationFailure, g as ValidationSuccess } from './types-Ce8BEvMm.js';
1
+ import { T as ToolContext, a as ToolDefinition, b as ToolHandle, V as ValidationResult, c as ToolResult } from './index-63aR8ryG.js';
2
+ export { A as ApprovalClass, D as DriverConstraints, d as DriverKind, R as RetryPolicy, e as ToolCapabilities, f as ToolManifest, g as ToolManifestFrontmatter, h as ValidationFailure, i as ValidationSuccess, p as parseToolManifest, t as toolFromManifest, j as toolFromManifestOnly } from './index-63aR8ryG.js';
3
3
  import * as _agentproto_manifest from '@agentproto/manifest';
4
4
  import { DoctypeSpec } from '@agentproto/manifest';
5
5
  import 'zod';
@@ -15,8 +15,13 @@ declare function defineTool<TInput, TOutput, TContext extends ToolContext = Tool
15
15
  * Validate input against a tool's `inputSchema`. Returns a typed
16
16
  * {@link ValidationResult}; provider runtimes MUST call this BEFORE
17
17
  * dispatching to the provider's body.
18
+ *
19
+ * Priority:
20
+ * 1. zod `inputSchema` (v0.1) — used when present.
21
+ * 2. JSON Schema `inputs` (v0.2) — fallback for manifest-only tools.
22
+ * 3. No schema — passthrough (returns `ok: true`).
18
23
  */
19
- declare function validateInput<TInput>(handle: Pick<ToolHandle<TInput>, "id" | "inputSchema">, input: unknown): ValidationResult<TInput>;
24
+ declare function validateInput<TInput>(handle: Pick<ToolHandle<TInput>, "id" | "inputSchema" | "inputs">, input: unknown): ValidationResult<TInput>;
20
25
  /**
21
26
  * Validate context against a tool's `contextSchema` (when declared).
22
27
  * Returns a typed {@link ValidationResult}; provider runtimes MUST
@@ -24,17 +29,22 @@ declare function validateInput<TInput>(handle: Pick<ToolHandle<TInput>, "id" | "
24
29
  *
25
30
  * Tools without a contextSchema accept any context shape; this helper
26
31
  * returns the input verbatim in that case.
32
+ *
33
+ * Context validation uses only zod (no JSON Schema fallback) — context
34
+ * schemas are always authored in TS, never in manifests.
27
35
  */
28
36
  declare function validateContext<TContext extends ToolContext = ToolContext>(handle: Pick<ToolHandle<unknown, unknown, TContext>, "id" | "contextSchema">, context: unknown): ValidationResult<TContext>;
29
37
  /**
30
38
  * Validate output against a tool's `outputSchema`. Returns the typed
31
- * {@link ValidationResult}; provider runtimes MUST call this AFTER
32
- * the body returns and BEFORE handing the value to the caller.
39
+ * value on success; throws {@link ToolError} with code `"output_invalid"`
40
+ * on contract violation.
33
41
  *
34
- * On failure, hosts SHOULD throw {@link ToolError} with code
35
- * `"output_invalid"` — the tool produced a contract violation.
42
+ * Priority:
43
+ * 1. zod `outputSchema` (v0.1) used when present.
44
+ * 2. JSON Schema `outputs` (v0.2) — fallback for manifest-only tools.
45
+ * 3. No schema — passthrough (returns the value as-is).
36
46
  */
37
- declare function validateOutput<TOutput>(handle: Pick<ToolHandle<unknown, TOutput>, "id" | "outputSchema">, output: unknown): TOutput;
47
+ declare function validateOutput<TOutput>(handle: Pick<ToolHandle<unknown, TOutput>, "id" | "outputSchema" | "outputs">, output: unknown): TOutput;
38
48
 
39
49
  /**
40
50
  * `createTool(params, opts)` — write a TOOL.md to disk.
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { parseToolManifest, defineTool } from './chunk-ZFIMSZXN.mjs';
2
- export { ToolError, defineTool, toToolError, toToolResult, validateContext, validateInput, validateOutput } from './chunk-ZFIMSZXN.mjs';
1
+ import { parseToolManifest, defineTool } from './chunk-VCLSUUB5.mjs';
2
+ export { ToolError, defineTool, parseToolManifest, toToolError, toToolResult, toolFromManifest, toolFromManifestOnly, validateContext, validateInput, validateOutput } from './chunk-VCLSUUB5.mjs';
3
3
  import { filterSerializable } from '@agentproto/define-doctype';
4
4
  import matter from 'gray-matter';
5
5
  import { mkdir, writeFile } from 'fs/promises';
@@ -10,12 +10,17 @@ import { createVerbs } from '@agentproto/manifest';
10
10
  * @agentproto/tool v0.1.0-alpha
11
11
  * AIP-14 TOOL.md `defineTool` reference implementation.
12
12
  */
13
+ function toSnakeCaseKeys(obj) {
14
+ return Object.fromEntries(
15
+ Object.entries(obj).map(([k, v]) => [k.replace(/([A-Z])/g, "_$1").toLowerCase(), v])
16
+ );
17
+ }
13
18
  async function createTool(params, opts) {
14
19
  const handle = defineTool(params);
15
20
  const path = join(opts.dir, handle.id, "TOOL.md");
16
21
  const frontmatter = filterSerializable({
17
22
  schema: "agentproto/tool/v1",
18
- ...params
23
+ ...toSnakeCaseKeys(params)
19
24
  });
20
25
  const rendered = matter.stringify(
21
26
  opts.body ?? `# ${handle.name}
@@ -38,10 +43,26 @@ var toolSpec = {
38
43
  define: (params) => defineTool(params),
39
44
  parse: (source) => {
40
45
  const m = parseToolManifest(source);
41
- return {
42
- frontmatter: m.frontmatter,
43
- body: m.body
46
+ const fm = m.frontmatter;
47
+ const frontmatter = {
48
+ id: fm.id,
49
+ name: fm.name,
50
+ description: fm.description,
51
+ version: fm.version,
52
+ ...fm.mutates !== void 0 && { mutates: fm.mutates },
53
+ ...fm.requires !== void 0 && { requires: fm.requires },
54
+ ...fm.approval !== void 0 && { approval: fm.approval },
55
+ ...fm.risk_level !== void 0 && { riskLevel: fm.risk_level },
56
+ ...fm.cost_class !== void 0 && { costClass: fm.cost_class },
57
+ ...fm.timeout_ms !== void 0 && { timeoutMs: fm.timeout_ms },
58
+ ...fm.idempotent !== void 0 && { idempotent: fm.idempotent },
59
+ ...fm.tags !== void 0 && { tags: fm.tags },
60
+ ...fm.metadata !== void 0 && { metadata: fm.metadata },
61
+ // AIP-16 IO blocks pass through under the same keys.
62
+ ...fm.inputs !== void 0 && { inputs: fm.inputs },
63
+ ...fm.outputs !== void 0 && { outputs: fm.outputs }
44
64
  };
65
+ return { frontmatter, body: m.body };
45
66
  }
46
67
  };
47
68
  var toolVerbs = createVerbs(toolSpec);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/create-tool.ts","../src/spec.ts","../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAgDA,eAAsB,UAAA,CAKpB,QACA,IAAA,EACsD;AACtD,EAAA,MAAM,MAAA,GAAS,WAAsC,MAAM,CAAA;AAC3D,EAAA,MAAM,OAAO,IAAA,CAAK,IAAA,CAAK,GAAA,EAAK,MAAA,CAAO,IAAI,SAAS,CAAA;AAChD,EAAA,MAAM,cAAc,kBAAA,CAAmB;AAAA,IACrC,MAAA,EAAQ,oBAAA;AAAA,IACR,GAAG;AAAA,GACJ,CAAA;AACD,EAAA,MAAM,WAAW,MAAA,CAAO,SAAA;AAAA,IACtB,IAAA,CAAK,IAAA,IAAQ,CAAA,EAAA,EAAK,MAAA,CAAO,IAAI;;AAAA,EAAO,OAAO,WAAW;AAAA,CAAA;AAAA,IACtD;AAAA,GACF;AACA,EAAA,IAAI,CAAC,KAAK,MAAA,EAAQ;AAChB,IAAA,MAAM,MAAM,OAAA,CAAQ,IAAI,GAAG,EAAE,SAAA,EAAW,MAAM,CAAA;AAC9C,IAAA,MAAM,SAAA,CAAU,IAAA,EAAM,QAAA,EAAU,MAAM,CAAA;AAAA,EACxC;AACA,EAAA,OAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,QAAA,EAAS;AAClC;AC1DO,IAAM,QAAA,GAGT;AAAA,EACF,IAAA,EAAM,MAAA;AAAA,EACN,GAAA,EAAK,EAAA;AAAA,EACL,aAAA,EAAe,oBAAA;AAAA,EACf,MAAA,EAAQ,CAAC,CAAA,KAAM,CAAA,EAAG,EAAE,EAAE,CAAA,QAAA,CAAA;AAAA,EACtB,MAAA,EAAQ,CAAC,MAAA,KACP,UAAA,CAAW,MAAM,CAAA;AAAA,EACnB,KAAA,EAAO,CAAC,MAAA,KAAW;AACjB,IAAA,MAAM,CAAA,GAAI,kBAAkB,MAAM,CAAA;AAClC,IAAA,OAAO;AAAA,MACL,aAAa,CAAA,CAAE,WAAA;AAAA,MACf,MAAM,CAAA,CAAE;AAAA,KACV;AAAA,EACF;AACF;AAEO,IAAM,SAAA,GAAY,YAAY,QAAQ;;;ACpBtC,IAAM,SAAA,GAAY;AAClB,IAAM,YAAA,GAAe","file":"index.mjs","sourcesContent":["/**\n * `createTool(params, opts)` — write a TOOL.md to disk.\n *\n * Symmetric to `parseToolManifest` (.md → handle) and `defineTool`\n * (params → handle): this takes params, validates via defineTool\n * (single source of truth — same zod schema, same cross-AIP\n * invariants), then serialises the validated frontmatter to YAML\n * and writes it under `<dir>/<id>/TOOL.md`.\n *\n * The author's body markdown is preserved verbatim in `opts.body`.\n * Pass `dryRun: true` to get the rendered string without touching\n * disk — useful for tests, the MCP server's preview, and CI lints.\n *\n * Non-frontmatter values that can't appear in YAML (zod schemas,\n * function bodies) are filtered out by `filterSerializable` from\n * `@agentproto/define-doctype`; the resulting frontmatter matches\n * what `parseToolManifest` would consume on the way back in.\n */\n\nimport { filterSerializable } from \"@agentproto/define-doctype\"\nimport matter from \"gray-matter\"\nimport { mkdir, writeFile } from \"node:fs/promises\"\nimport { dirname, join } from \"node:path\"\nimport { defineTool } from \"./define-tool.js\"\nimport type { ToolContext, ToolDefinition, ToolHandle } from \"./types.js\"\n\nexport interface CreateToolOptions {\n /** Workspace-relative or absolute directory under which to write `<id>/TOOL.md`. */\n dir: string\n /** Body markdown after the frontmatter. Defaults to a one-line stub. */\n body?: string\n /** Render only — don't write. Returns the rendered string. */\n dryRun?: boolean\n}\n\nexport interface CreateToolResult<\n TInput,\n TOutput,\n TContext extends ToolContext,\n> {\n /** The path where the file was (or would be) written. */\n path: string\n /** The validated handle returned by defineTool. */\n handle: ToolHandle<TInput, TOutput, TContext>\n /** The full rendered file contents (frontmatter + body). */\n rendered: string\n}\n\nexport async function createTool<\n TInput,\n TOutput,\n TContext extends ToolContext = ToolContext,\n>(\n params: ToolDefinition<TInput, TOutput, TContext>,\n opts: CreateToolOptions,\n): Promise<CreateToolResult<TInput, TOutput, TContext>> {\n const handle = defineTool<TInput, TOutput, TContext>(params)\n const path = join(opts.dir, handle.id, \"TOOL.md\")\n const frontmatter = filterSerializable({\n schema: \"agentproto/tool/v1\",\n ...params,\n }) as Record<string, unknown>\n const rendered = matter.stringify(\n opts.body ?? `# ${handle.name}\\n\\n${handle.description}\\n`,\n frontmatter,\n )\n if (!opts.dryRun) {\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, rendered, \"utf8\")\n }\n return { path, handle, rendered }\n}\n","/**\n * AIP-14 doctype spec — fed to `@agentproto/manifest.createVerbs`\n * to derive create / load / list / update / resolve / delete in one\n * place. Keeping the spec separate from `define-tool.ts` lets the\n * manifest layer (and the future MCP server) iterate over a uniform\n * descriptor without each package re-implementing the wiring.\n */\n\nimport { createVerbs, type DoctypeSpec } from \"@agentproto/manifest\"\nimport { defineTool } from \"./define-tool.js\"\nimport { parseToolManifest } from \"./manifest/index.js\"\nimport type { ToolDefinition, ToolHandle } from \"./types.js\"\n\nexport const toolSpec: DoctypeSpec<\n ToolDefinition<unknown, unknown>,\n ToolHandle<unknown, unknown>\n> = {\n name: \"tool\",\n aip: 14,\n schemaLiteral: \"agentproto/tool/v1\",\n pathOf: (h) => `${h.id}/TOOL.md`,\n define: (params) =>\n defineTool(params) as ToolHandle<unknown, unknown>,\n parse: (source) => {\n const m = parseToolManifest(source)\n return {\n frontmatter: m.frontmatter as unknown as Record<string, unknown>,\n body: m.body,\n }\n },\n}\n\nexport const toolVerbs = createVerbs(toolSpec)\n","/**\n * @agentproto/tool — AIP-14 TOOL.md `defineTool` reference impl.\n *\n * Vendor-neutral tool **contract** registration: an author writes\n * `defineTool({...})` and the runtime returns a `ToolHandle` carrying\n * identity, schemas, side-effect profile, approval class, and\n * provider routing hints. Bodies live on AIP-30 PROVIDER manifests;\n * invocation goes through `@agentproto/driver`.\n *\n * Spec: https://agentproto.sh/docs/aip-14\n */\n\nexport const SPEC_NAME = \"agenttool/v1\" as const\nexport const SPEC_VERSION = \"1.0.0-alpha\" as const\n\nexport {\n defineTool,\n validateInput,\n validateContext,\n validateOutput,\n} from \"./define-tool.js\"\n// Standalone create-tool kept for back-compat; new code should import\n// the unified verb surface (`toolVerbs.create`, `.load`, `.list`,\n// `.update`, `.resolve`, `.delete`) from `./spec.js`.\nexport {\n createTool,\n type CreateToolOptions,\n type CreateToolResult,\n} from \"./create-tool.js\"\nexport { toolSpec, toolVerbs } from \"./spec.js\"\nexport {\n ToolError,\n toToolError,\n toToolResult,\n type ToolErrorCode,\n type ToolErrorPayload,\n} from \"./errors.js\"\nexport type {\n ToolDefinition,\n ToolHandle,\n ToolContext,\n ToolCapabilities,\n ApprovalClass,\n DriverConstraints,\n DriverKind,\n RetryPolicy,\n ToolResult,\n ValidationResult,\n ValidationFailure,\n ValidationSuccess,\n} from \"./types.js\"\n"]}
1
+ {"version":3,"sources":["../src/create-tool.ts","../src/spec.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * `createTool(params, opts)` — write a TOOL.md to disk.\n *\n * Symmetric to `parseToolManifest` (.md → handle) and `defineTool`\n * (params → handle): this takes params, validates via defineTool\n * (single source of truth — same zod schema, same cross-AIP\n * invariants), then serialises the validated frontmatter to YAML\n * and writes it under `<dir>/<id>/TOOL.md`.\n *\n * The author's body markdown is preserved verbatim in `opts.body`.\n * Pass `dryRun: true` to get the rendered string without touching\n * disk — useful for tests, the MCP server's preview, and CI lints.\n *\n * Non-frontmatter values that can't appear in YAML (zod schemas,\n * function bodies) are filtered out by `filterSerializable` from\n * `@agentproto/define-doctype`; the resulting frontmatter matches\n * what `parseToolManifest` would consume on the way back in.\n */\n\nimport { filterSerializable } from \"@agentproto/define-doctype\"\nimport matter from \"gray-matter\"\nimport { mkdir, writeFile } from \"node:fs/promises\"\nimport { dirname, join } from \"node:path\"\nimport { defineTool } from \"./define-tool.js\"\nimport type { ToolContext, ToolDefinition, ToolHandle } from \"./types.js\"\n\nfunction toSnakeCaseKeys(obj: Record<string, unknown>): Record<string, unknown> {\n return Object.fromEntries(\n Object.entries(obj).map(([k, v]) => [k.replace(/([A-Z])/g, \"_$1\").toLowerCase(), v]),\n )\n}\n\nexport interface CreateToolOptions {\n /** Workspace-relative or absolute directory under which to write `<id>/TOOL.md`. */\n dir: string\n /** Body markdown after the frontmatter. Defaults to a one-line stub. */\n body?: string\n /** Render only — don't write. Returns the rendered string. */\n dryRun?: boolean\n}\n\nexport interface CreateToolResult<\n TInput,\n TOutput,\n TContext extends ToolContext,\n> {\n /** The path where the file was (or would be) written. */\n path: string\n /** The validated handle returned by defineTool. */\n handle: ToolHandle<TInput, TOutput, TContext>\n /** The full rendered file contents (frontmatter + body). */\n rendered: string\n}\n\nexport async function createTool<\n TInput,\n TOutput,\n TContext extends ToolContext = ToolContext,\n>(\n params: ToolDefinition<TInput, TOutput, TContext>,\n opts: CreateToolOptions,\n): Promise<CreateToolResult<TInput, TOutput, TContext>> {\n const handle = defineTool<TInput, TOutput, TContext>(params)\n const path = join(opts.dir, handle.id, \"TOOL.md\")\n const frontmatter = filterSerializable({\n schema: \"agentproto/tool/v1\",\n ...toSnakeCaseKeys(params as unknown as Record<string, unknown>),\n }) as Record<string, unknown>\n const rendered = matter.stringify(\n opts.body ?? `# ${handle.name}\\n\\n${handle.description}\\n`,\n frontmatter,\n )\n if (!opts.dryRun) {\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, rendered, \"utf8\")\n }\n return { path, handle, rendered }\n}\n","/**\n * AIP-14 doctype spec — fed to `@agentproto/manifest.createVerbs`\n * to derive create / load / list / update / resolve / delete in one\n * place. Keeping the spec separate from `define-tool.ts` lets the\n * manifest layer (and the future MCP server) iterate over a uniform\n * descriptor without each package re-implementing the wiring.\n */\n\nimport { createVerbs, type DoctypeSpec } from \"@agentproto/manifest\"\nimport { defineTool } from \"./define-tool.js\"\nimport { parseToolManifest } from \"./manifest/index.js\"\nimport type { ToolDefinition, ToolHandle } from \"./types.js\"\n\nexport const toolSpec: DoctypeSpec<\n ToolDefinition<unknown, unknown>,\n ToolHandle<unknown, unknown>\n> = {\n name: \"tool\",\n aip: 14,\n schemaLiteral: \"agentproto/tool/v1\",\n pathOf: (h) => `${h.id}/TOOL.md`,\n define: (params) =>\n defineTool(params) as ToolHandle<unknown, unknown>,\n parse: (source) => {\n const m = parseToolManifest(source)\n const fm = m.frontmatter\n // `createVerbs.load` feeds this frontmatter straight to `define`\n // (= `defineTool`), which reads camelCase keys. The manifest uses\n // snake_case for multi-word fields, so they must be renamed here or\n // `defineTool` silently falls back to its defaults. Single-word fields\n // (mutates, approval, idempotent, tags, metadata, requires) share the\n // same key in both conventions and pass through unchanged.\n const frontmatter: Record<string, unknown> = {\n id: fm.id,\n name: fm.name,\n description: fm.description,\n version: fm.version,\n ...(fm.mutates !== undefined && { mutates: fm.mutates }),\n ...(fm.requires !== undefined && { requires: fm.requires }),\n ...(fm.approval !== undefined && { approval: fm.approval }),\n ...(fm.risk_level !== undefined && { riskLevel: fm.risk_level }),\n ...(fm.cost_class !== undefined && { costClass: fm.cost_class }),\n ...(fm.timeout_ms !== undefined && { timeoutMs: fm.timeout_ms }),\n ...(fm.idempotent !== undefined && { idempotent: fm.idempotent }),\n ...(fm.tags !== undefined && { tags: fm.tags }),\n ...(fm.metadata !== undefined && { metadata: fm.metadata }),\n // AIP-16 IO blocks pass through under the same keys.\n ...(fm.inputs !== undefined && { inputs: fm.inputs }),\n ...(fm.outputs !== undefined && { outputs: fm.outputs }),\n }\n return { frontmatter, body: m.body }\n },\n}\n\nexport const toolVerbs = createVerbs(toolSpec)\n","/**\n * @agentproto/tool — AIP-14 TOOL.md `defineTool` reference impl.\n *\n * Vendor-neutral tool **contract** registration: an author writes\n * `defineTool({...})` and the runtime returns a `ToolHandle` carrying\n * identity, schemas, side-effect profile, approval class, and\n * provider routing hints. Bodies live on AIP-30 PROVIDER manifests;\n * invocation goes through `@agentproto/driver`.\n *\n * Spec: https://agentproto.sh/docs/aip-14\n */\n\nexport const SPEC_NAME = \"agenttool/v1\" as const\nexport const SPEC_VERSION = \"1.0.0-alpha\" as const\n\nexport {\n defineTool,\n validateInput,\n validateContext,\n validateOutput,\n} from \"./define-tool.js\"\n// Standalone create-tool kept for back-compat; new code should import\n// the unified verb surface (`toolVerbs.create`, `.load`, `.list`,\n// `.update`, `.resolve`, `.delete`) from `./spec.js`.\nexport {\n createTool,\n type CreateToolOptions,\n type CreateToolResult,\n} from \"./create-tool.js\"\nexport { toolSpec, toolVerbs } from \"./spec.js\"\nexport {\n parseToolManifest,\n toolFromManifest,\n toolFromManifestOnly,\n type ToolManifest,\n type ToolManifestFrontmatter,\n} from \"./manifest/index.js\"\nexport {\n ToolError,\n toToolError,\n toToolResult,\n type ToolErrorCode,\n type ToolErrorPayload,\n} from \"./errors.js\"\nexport type {\n ToolDefinition,\n ToolHandle,\n ToolContext,\n ToolCapabilities,\n ApprovalClass,\n DriverConstraints,\n DriverKind,\n RetryPolicy,\n ToolResult,\n ValidationResult,\n ValidationFailure,\n ValidationSuccess,\n} from \"./types.js\"\n"]}
@@ -1,82 +1,2 @@
1
- import { z, ZodType } from 'zod';
2
- import { A as ApprovalClass, T as ToolContext, b as ToolHandle } from '../types-Ce8BEvMm.js';
3
-
4
- /**
5
- * AIP-14 TOOL.md sidecar parser.
6
- *
7
- * Reads frontmatter (host-relevant metadata) + body (long-form
8
- * description / examples / errors). The TS module's `defineTool(...)`
9
- * supplies the schemas and execute body; this manifest supplies the
10
- * runtime metadata that overrides or augments the in-code defaults.
11
- *
12
- * Field set covers AIP-14 §"Frontmatter" — required and optional fields
13
- * normalised to snake_case → camelCase.
14
- */
15
- declare const toolManifestFrontmatterSchema: z.ZodObject<{
16
- schema: z.ZodOptional<z.ZodLiteral<"agentproto/tool/v1">>;
17
- name: z.ZodString;
18
- id: z.ZodString;
19
- description: z.ZodString;
20
- version: z.ZodString;
21
- mutates: z.ZodOptional<z.ZodArray<z.ZodString>>;
22
- requires: z.ZodOptional<z.ZodObject<{
23
- network: z.ZodOptional<z.ZodArray<z.ZodString>>;
24
- secrets: z.ZodOptional<z.ZodArray<z.ZodString>>;
25
- tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
26
- }, z.core.$strip>>;
27
- approval: z.ZodOptional<z.ZodCustom<ApprovalClass, ApprovalClass>>;
28
- risk_level: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>]>>;
29
- cost_class: z.ZodOptional<z.ZodEnum<{
30
- trivial: "trivial";
31
- metered: "metered";
32
- expensive: "expensive";
33
- }>>;
34
- timeout_ms: z.ZodOptional<z.ZodNumber>;
35
- idempotent: z.ZodOptional<z.ZodBoolean>;
36
- tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
37
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
38
- code: z.ZodOptional<z.ZodUnknown>;
39
- run: z.ZodOptional<z.ZodUnknown>;
40
- runner: z.ZodOptional<z.ZodUnknown>;
41
- secrets: z.ZodOptional<z.ZodUnknown>;
42
- network: z.ZodOptional<z.ZodUnknown>;
43
- }, z.core.$strip>;
44
- type ToolManifestFrontmatter = z.infer<typeof toolManifestFrontmatterSchema>;
45
- interface ToolManifest {
46
- frontmatter: ToolManifestFrontmatter;
47
- body: string;
48
- }
49
- /**
50
- * Parse a TOOL.md source string into structured frontmatter + body.
51
- * Throws on missing frontmatter or schema-invalid frontmatter.
52
- */
53
- declare function parseToolManifest(source: string): ToolManifest;
54
- /**
55
- * Build a fully-typed {@link ToolHandle} from a parsed `TOOL.md` manifest
56
- * + caller-supplied schemas. The .md is the single source of truth for
57
- * metadata (id, name, description, version, mutates, approval, …); the
58
- * schemas live in the TS module that ships alongside the .md.
59
- *
60
- * Both inputs are revalidated by `defineTool`'s shared invariants
61
- * (id pattern, description length, top-level freeze) — `parseToolManifest`
62
- * already enforces a stricter id pattern + version semver, so a
63
- * well-formed manifest passes through cleanly. Mismatches between the
64
- * manifest's id-shape and `defineTool`'s pattern surface a
65
- * descriptive error from the same validation pipeline as the TS path.
66
- *
67
- * @example
68
- * const manifest = parseToolManifest(readFileSync("./echo/TOOL.md", "utf8"))
69
- * const echo = toolFromManifest({
70
- * manifest,
71
- * inputSchema: z.object({ msg: z.string() }),
72
- * outputSchema: z.object({ msg: z.string() }),
73
- * })
74
- */
75
- declare function toolFromManifest<TInput, TOutput, TContext extends ToolContext = ToolContext>(args: {
76
- manifest: ToolManifest;
77
- inputSchema: ZodType<TInput>;
78
- outputSchema: ZodType<TOutput>;
79
- contextSchema?: ZodType<TContext>;
80
- }): ToolHandle<TInput, TOutput, TContext>;
81
-
82
- export { type ToolManifest, type ToolManifestFrontmatter, parseToolManifest, toolFromManifest, toolManifestFrontmatterSchema };
1
+ import 'zod';
2
+ export { f as ToolManifest, g as ToolManifestFrontmatter, p as parseToolManifest, t as toolFromManifest, j as toolFromManifestOnly, k as toolManifestFrontmatterSchema } from '../index-63aR8ryG.js';
@@ -1,3 +1,3 @@
1
- export { parseToolManifest, toolFromManifest, toolManifestFrontmatterSchema } from '../chunk-ZFIMSZXN.mjs';
1
+ export { parseToolManifest, toolFromManifest, toolFromManifestOnly, toolManifestFrontmatterSchema } from '../chunk-VCLSUUB5.mjs';
2
2
  //# sourceMappingURL=index.mjs.map
3
3
  //# sourceMappingURL=index.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentproto/tool",
3
- "version": "0.1.1",
3
+ "version": "0.2.1",
4
4
  "description": "agentproto/tool-runtime — reference implementation of AIP-14 TOOL.md `defineTool` contract. Vendor-neutral tool registration with validated input/output schemas, structured error envelopes, and side-effect declarations. Per-framework adapters (Mastra, LangChain, A2A) consume the produced ToolHandle.",
5
5
  "keywords": [
6
6
  "agentproto",
@@ -19,7 +19,7 @@
19
19
  "bugs": {
20
20
  "url": "https://github.com/agentproto/ts/issues"
21
21
  },
22
- "license": "MIT",
22
+ "license": "Apache-2.0",
23
23
  "type": "module",
24
24
  "main": "dist/index.mjs",
25
25
  "module": "dist/index.mjs",
@@ -49,8 +49,8 @@
49
49
  "ajv": "^8.20.0",
50
50
  "gray-matter": "^4.0.3",
51
51
  "zod": "^4.4.3",
52
- "@agentproto/define-doctype": "0.1.0",
53
- "@agentproto/manifest": "0.2.0"
52
+ "@agentproto/define-doctype": "0.1.1",
53
+ "@agentproto/manifest": "0.2.1"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@types/node": "^25.6.2",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/define-tool.ts","../src/manifest/index.ts"],"names":[],"mappings":"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","file":"chunk-ZFIMSZXN.mjs","sourcesContent":["import type { ToolResult } from \"./types.js\"\n\n/**\n * AIP-14 conventional error codes. Tool-specific codes MAY use a domain\n * prefix (`\"stripe:card_declined\"`).\n */\nexport type ToolErrorCode =\n | \"input_invalid\"\n | \"output_invalid\"\n | \"unauthorised\"\n | \"not_found\"\n | \"rate_limited\"\n | \"timeout\"\n | \"upstream_error\"\n | \"internal\"\n | (string & {})\n\nexport interface ToolErrorPayload {\n code: ToolErrorCode\n message: string\n retryable?: boolean\n cause?: unknown\n}\n\n/**\n * Structured error thrown by tool bodies. Adapters wrap this into the\n * standard {@link ToolResult} envelope; bodies MUST throw it (never\n * return error objects).\n */\nexport class ToolError extends Error {\n readonly code: ToolErrorCode\n readonly retryable: boolean\n readonly cause: unknown\n\n constructor(payload: ToolErrorPayload) {\n super(payload.message)\n this.name = \"ToolError\"\n this.code = payload.code\n this.retryable = payload.retryable ?? false\n this.cause = payload.cause\n }\n\n toJSON(): ToolErrorPayload {\n return {\n code: this.code,\n message: this.message,\n retryable: this.retryable,\n ...(this.cause !== undefined ? { cause: this.cause } : {}),\n }\n }\n}\n\n/**\n * Wrap an unknown thrown value into a {@link ToolError}. Used by adapters\n * to normalise non-ToolError throws into the standard envelope.\n */\nexport function toToolError(thrown: unknown): ToolError {\n if (thrown instanceof ToolError) return thrown\n if (thrown instanceof Error) {\n return new ToolError({\n code: \"internal\",\n message: thrown.message,\n cause: thrown,\n })\n }\n return new ToolError({\n code: \"internal\",\n message: String(thrown),\n cause: thrown,\n })\n}\n\n/**\n * Adapter helper: project a thrown ToolError (or any throw) into the\n * standard {@link ToolResult} envelope. Adapters MUST do this; bodies MUST NOT.\n */\nexport function toToolResult<T>(\n value: T | undefined,\n thrown: unknown\n): ToolResult<T> {\n if (thrown !== undefined) {\n const err = toToolError(thrown)\n return { ok: false, error: err.toJSON() }\n }\n return { ok: true, value: value as T }\n}\n","import { createDoctype } from \"@agentproto/define-doctype\"\nimport type { ZodType } from \"zod\"\nimport { ToolError } from \"./errors.js\"\nimport type {\n ApprovalClass,\n DriverConstraints,\n DriverKind,\n ToolCapabilities,\n ToolContext,\n ToolDefinition,\n ToolHandle,\n ValidationResult,\n} from \"./types.js\"\n\nconst PROVIDER_KINDS: readonly DriverKind[] = [\n \"cli\",\n \"http\",\n \"mcp\",\n \"sdk\",\n \"builtin\",\n]\n\n/**\n * AIP-14 reference implementation of `defineTool`.\n *\n * Returns a {@link ToolHandle} with defaults applied. The handle is a\n * pure contract — schemas, governance metadata, provider routing\n * hints. Bodies live on AIP-30 PROVIDER manifests; invocation goes\n * through provider-runtime's resolver.\n *\n * Built on `createDoctype` from `@agentproto/define-doctype`: the\n * id-pattern + description-length validation and the top-level\n * `Object.freeze` are shared with every other AIP defineX. The\n * spec-14-specific parts (migration guard for `execute`, defaulting\n * `approval` from `mutates`, freezing nested arrays/objects) live in\n * `validate` and `build` below.\n *\n * Conformance highlights ([§ Conformance rules](https://agentproto.sh/docs/aip-14)):\n * - No `execute` field on the contract — bodies are providers' job.\n * - `defineTool` MUST refuse a definition carrying `execute` (migration error).\n * - No I/O at module load — `defineTool(...)` is pure construction.\n */\nconst constructTool = createDoctype<\n ToolDefinition<unknown, unknown, ToolContext>,\n ToolHandle<unknown, unknown, ToolContext>\n>({\n aip: 14,\n name: \"tool\",\n validate(def) {\n // Migration guard: catch authors trying to ship a body on the contract.\n // The body lives on a PROVIDER (per AIP-30); reject at construction.\n if (\"execute\" in (def as unknown as Record<string, unknown>)) {\n throw new Error(\n `defineTool: id='${def.id}' carries an 'execute' property. ` +\n `Bodies live on AIP-30 PROVIDER manifests, not on the TOOL contract. ` +\n `See https://agentproto.sh/docs/aip-30 for migration.`,\n )\n }\n },\n build(def) {\n return {\n id: def.id,\n name: def.name ?? def.id,\n description: def.description,\n version: def.version,\n inputSchema: def.inputSchema,\n outputSchema: def.outputSchema,\n contextSchema: def.contextSchema,\n mutates: Object.freeze([...(def.mutates ?? [])]),\n requires: freezeCapabilities(def.requires),\n approval: defaultApproval(def.approval, def.mutates),\n riskLevel: def.riskLevel ?? 0,\n costClass: def.costClass ?? \"trivial\",\n timeoutMs: def.timeoutMs ?? 30_000,\n retry: def.retry,\n tags: Object.freeze([...(def.tags ?? [])]),\n metadata: Object.freeze({ ...(def.metadata ?? {}) }),\n idempotent: def.idempotent ?? false,\n defaultImplementation: def.defaultImplementation,\n driverConstraints: freezeProviderConstraints(def.driverConstraints),\n }\n },\n})\n\n/**\n * Public-facing `defineTool` — typed wrapper around `constructTool`\n * that preserves the per-call `<TInput, TOutput, TContext>` inference\n * so callers don't write any generics. The wrapper exists purely for\n * generic propagation; the runtime body is the meta-factory above.\n */\nexport function defineTool<\n TInput,\n TOutput,\n TContext extends ToolContext = ToolContext,\n>(\n definition: ToolDefinition<TInput, TOutput, TContext>,\n): ToolHandle<TInput, TOutput, TContext> {\n return constructTool(\n definition as ToolDefinition<unknown, unknown, ToolContext>,\n ) as unknown as ToolHandle<TInput, TOutput, TContext>\n}\n\n/**\n * Validate input against a tool's `inputSchema`. Returns a typed\n * {@link ValidationResult}; provider runtimes MUST call this BEFORE\n * dispatching to the provider's body.\n */\nexport function validateInput<TInput>(\n handle: Pick<ToolHandle<TInput>, \"id\" | \"inputSchema\">,\n input: unknown,\n): ValidationResult<TInput> {\n const result = handle.inputSchema.safeParse(input)\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"input_invalid\",\n message: `id='${handle.id}': ${formatZodIssues(result.error.issues)}`,\n cause: result.error.issues,\n },\n }\n }\n return { ok: true, value: result.data as TInput }\n}\n\n/**\n * Validate context against a tool's `contextSchema` (when declared).\n * Returns a typed {@link ValidationResult}; provider runtimes MUST\n * call this BEFORE dispatching when the contract has a contextSchema.\n *\n * Tools without a contextSchema accept any context shape; this helper\n * returns the input verbatim in that case.\n */\nexport function validateContext<TContext extends ToolContext = ToolContext>(\n handle: Pick<ToolHandle<unknown, unknown, TContext>, \"id\" | \"contextSchema\">,\n context: unknown,\n): ValidationResult<TContext> {\n if (!handle.contextSchema) {\n return { ok: true, value: context as TContext }\n }\n const result = handle.contextSchema.safeParse(context)\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"input_invalid\",\n message: `id='${handle.id}': context does not match contextSchema — ${formatZodIssues(result.error.issues)}`,\n field: \"context\",\n cause: result.error.issues,\n },\n }\n }\n return { ok: true, value: result.data as TContext }\n}\n\n/**\n * Validate output against a tool's `outputSchema`. Returns the typed\n * {@link ValidationResult}; provider runtimes MUST call this AFTER\n * the body returns and BEFORE handing the value to the caller.\n *\n * On failure, hosts SHOULD throw {@link ToolError} with code\n * `\"output_invalid\"` — the tool produced a contract violation.\n */\nexport function validateOutput<TOutput>(\n handle: Pick<ToolHandle<unknown, TOutput>, \"id\" | \"outputSchema\">,\n output: unknown,\n): TOutput {\n const result = handle.outputSchema.safeParse(output)\n if (!result.success) {\n throw new ToolError({\n code: \"output_invalid\",\n message: `id='${handle.id}': provider produced output that does not match outputSchema — ${formatZodIssues(result.error.issues)}`,\n cause: result.error.issues,\n })\n }\n return result.data as TOutput\n}\n\nfunction defaultApproval(\n declared: ApprovalClass | undefined,\n mutates: readonly string[] | undefined,\n): ApprovalClass {\n if (declared) return declared\n return mutates && mutates.length > 0 ? \"on-mutate\" : \"auto\"\n}\n\nfunction freezeCapabilities(\n caps: ToolCapabilities | undefined,\n): Readonly<ToolCapabilities> {\n return Object.freeze({\n network: Object.freeze([...(caps?.network ?? [])]),\n secrets: Object.freeze([...(caps?.secrets ?? [])]),\n tools: Object.freeze([...(caps?.tools ?? [])]),\n })\n}\n\nfunction freezeProviderConstraints(\n c: DriverConstraints | undefined,\n): Required<DriverConstraints> {\n const forbid = (c?.forbid ?? []).filter((k): k is DriverKind =>\n PROVIDER_KINDS.includes(k as DriverKind),\n )\n const requireKind = (c?.requireKind ?? []).filter((k): k is DriverKind =>\n PROVIDER_KINDS.includes(k as DriverKind),\n )\n return Object.freeze({\n forbid: Object.freeze(forbid) as readonly DriverKind[],\n requireKind: Object.freeze(requireKind) as readonly DriverKind[],\n })\n}\n\nfunction formatZodIssues(\n issues: ReadonlyArray<{ path: ReadonlyArray<PropertyKey>; message: string }>,\n): string {\n return issues\n .map((i) => `${i.path.length > 0 ? i.path.join(\".\") + \": \" : \"\"}${i.message}`)\n .join(\"; \")\n}\n\nexport type { ZodType }\n","import matter from \"gray-matter\"\nimport { z, type ZodType } from \"zod\"\nimport { defineTool } from \"../define-tool.js\"\nimport type { ApprovalClass, ToolContext, ToolHandle } from \"../types.js\"\n\n/**\n * AIP-14 TOOL.md sidecar parser.\n *\n * Reads frontmatter (host-relevant metadata) + body (long-form\n * description / examples / errors). The TS module's `defineTool(...)`\n * supplies the schemas and execute body; this manifest supplies the\n * runtime metadata that overrides or augments the in-code defaults.\n *\n * Field set covers AIP-14 §\"Frontmatter\" — required and optional fields\n * normalised to snake_case → camelCase.\n */\n\nexport const toolManifestFrontmatterSchema = z.object({\n schema: z.literal(\"agentproto/tool/v1\").optional(),\n name: z.string().min(1).max(80),\n id: z.string().regex(/^[a-z][a-z0-9._-]{1,63}$/),\n description: z.string().min(1).max(2000),\n version: z.string().regex(/^\\d+\\.\\d+\\.\\d+/),\n\n // Optional metadata\n mutates: z.array(z.string()).optional(),\n requires: z\n .object({\n network: z.array(z.string()).optional(),\n secrets: z.array(z.string()).optional(),\n tools: z.array(z.string()).optional(),\n })\n .optional(),\n // `ApprovalClass` is `\"auto\" | \"always\" | \"on-mutate\" | \\`policy:${string}\\``.\n // z.union widens the regex branch to plain `string` (zod can't express\n // template literal types), so we use `z.custom` to keep the inferred\n // type exact — matters because `defineTool` accepts `ApprovalClass`.\n approval: z\n .custom<ApprovalClass>(\n (v): v is ApprovalClass =>\n typeof v === \"string\" &&\n (v === \"auto\" ||\n v === \"always\" ||\n v === \"on-mutate\" ||\n /^policy:/.test(v)),\n { message: \"expected 'auto' | 'always' | 'on-mutate' | 'policy:<name>'\" },\n )\n .optional(),\n risk_level: z\n .union([z.literal(0), z.literal(1), z.literal(2), z.literal(3)])\n .optional(),\n cost_class: z.enum([\"trivial\", \"metered\", \"expensive\"]).optional(),\n timeout_ms: z.number().int().positive().optional(),\n idempotent: z.boolean().optional(),\n tags: z.array(z.string()).optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n\n // AIP-26 / AIP-17 / AIP-19 references — kept loose; validated by their\n // respective AIPs' adapters when consumed.\n code: z.unknown().optional(),\n run: z.unknown().optional(),\n runner: z.unknown().optional(),\n secrets: z.unknown().optional(),\n network: z.unknown().optional(),\n})\n\nexport type ToolManifestFrontmatter = z.infer<\n typeof toolManifestFrontmatterSchema\n>\n\nexport interface ToolManifest {\n frontmatter: ToolManifestFrontmatter\n body: string\n}\n\n/**\n * Parse a TOOL.md source string into structured frontmatter + body.\n * Throws on missing frontmatter or schema-invalid frontmatter.\n */\nexport function parseToolManifest(source: string): ToolManifest {\n const parsed = matter(source)\n if (Object.keys(parsed.data).length === 0) {\n throw new Error(\"parseToolManifest: missing or empty frontmatter\")\n }\n const result = toolManifestFrontmatterSchema.safeParse(parsed.data)\n if (!result.success) {\n throw new Error(\n `parseToolManifest: invalid frontmatter — ${result.error.issues\n .map(i => `${i.path.join(\".\")}: ${i.message}`)\n .join(\"; \")}`\n )\n }\n return { frontmatter: result.data, body: parsed.content }\n}\n\n/**\n * Build a fully-typed {@link ToolHandle} from a parsed `TOOL.md` manifest\n * + caller-supplied schemas. The .md is the single source of truth for\n * metadata (id, name, description, version, mutates, approval, …); the\n * schemas live in the TS module that ships alongside the .md.\n *\n * Both inputs are revalidated by `defineTool`'s shared invariants\n * (id pattern, description length, top-level freeze) — `parseToolManifest`\n * already enforces a stricter id pattern + version semver, so a\n * well-formed manifest passes through cleanly. Mismatches between the\n * manifest's id-shape and `defineTool`'s pattern surface a\n * descriptive error from the same validation pipeline as the TS path.\n *\n * @example\n * const manifest = parseToolManifest(readFileSync(\"./echo/TOOL.md\", \"utf8\"))\n * const echo = toolFromManifest({\n * manifest,\n * inputSchema: z.object({ msg: z.string() }),\n * outputSchema: z.object({ msg: z.string() }),\n * })\n */\nexport function toolFromManifest<\n TInput,\n TOutput,\n TContext extends ToolContext = ToolContext,\n>(args: {\n manifest: ToolManifest\n inputSchema: ZodType<TInput>\n outputSchema: ZodType<TOutput>\n contextSchema?: ZodType<TContext>\n}): ToolHandle<TInput, TOutput, TContext> {\n const fm = args.manifest.frontmatter\n return defineTool<TInput, TOutput, TContext>({\n id: fm.id,\n name: fm.name,\n description: fm.description,\n version: fm.version,\n inputSchema: args.inputSchema,\n outputSchema: args.outputSchema,\n contextSchema: args.contextSchema,\n mutates: fm.mutates,\n requires: fm.requires,\n approval: fm.approval,\n riskLevel: fm.risk_level,\n costClass: fm.cost_class,\n timeoutMs: fm.timeout_ms,\n idempotent: fm.idempotent,\n tags: fm.tags,\n metadata: fm.metadata,\n })\n}\n"]}
@@ -1,161 +0,0 @@
1
- import { ZodType } from 'zod';
2
-
3
- /**
4
- * AIP-14 ToolDefinition — the abstract agent contract.
5
- *
6
- * Field set mirrors `TOOL.md` frontmatter so a manifest and a TS
7
- * module are interchangeable inputs to the runtime. The contract
8
- * carries identity, schemas, side-effect profile, approval class,
9
- * and resource budget — but **not** the body. Bodies live on
10
- * AIP-30 PROVIDER manifests + their `execute[<toolId>]` entries.
11
- *
12
- * Generic over context: tools that depend on host-injected state
13
- * (database connections, governance config, …) declare a
14
- * `contextSchema` — analogous to `inputSchema` but for the per-call
15
- * context object — and the host validates context against it before
16
- * dispatching to the resolved provider's body.
17
- */
18
- interface ToolDefinition<TInput = unknown, TOutput = unknown, TContext extends ToolContext = ToolContext> {
19
- /** Machine identifier. Lowercase, digits, dashes, dots. 2–80 chars. */
20
- id: string;
21
- /** Human-readable display name. Optional; falls back to `id`. */
22
- name?: string;
23
- /** One-paragraph purpose, written for the LLM caller. */
24
- description: string;
25
- /** Spec version of THIS tool (semver). */
26
- version?: string;
27
- /**
28
- * Input shape — zod schema in v0.1. Hosts validate args.input against
29
- * it before dispatching to the resolved provider; bodies MUST NOT
30
- * re-validate.
31
- *
32
- * v0.2 will also accept JSON Schema directly.
33
- */
34
- inputSchema: ZodType<TInput>;
35
- outputSchema: ZodType<TOutput>;
36
- /**
37
- * Optional context schema. When provided, the host validates
38
- * `args.context` against it before dispatching to the provider,
39
- * rejecting with `input_invalid` (field=`context`) on mismatch.
40
- * Providers receive the narrowed, typed context.
41
- */
42
- contextSchema?: ZodType<TContext>;
43
- /** Resources the tool may modify. Format: `<class>:<scope>`. */
44
- mutates?: readonly string[];
45
- /** Capability requirements (governance/gating per AIP-7). */
46
- requires?: ToolCapabilities;
47
- approval?: ApprovalClass;
48
- riskLevel?: 0 | 1 | 2 | 3;
49
- costClass?: "trivial" | "metered" | "expensive";
50
- /** Hard wall-clock contract ceiling. Providers MAY narrow; never widen. */
51
- timeoutMs?: number;
52
- retry?: RetryPolicy;
53
- /** Free-form discovery tags. */
54
- tags?: readonly string[];
55
- /** Free-form metadata under namespaced keys (`mastra.…`, `langchain.…`). */
56
- metadata?: Record<string, unknown>;
57
- /** Whether retries are observably free of extra effect. Defaults to `false`. */
58
- idempotent?: boolean;
59
- /**
60
- * Optional pin for the canonical provider. The AIP-30 resolver uses
61
- * this in Phase 5 (cost ranking) when no other signal differentiates
62
- * candidates. Null/undefined = pick by resolver policy.
63
- */
64
- defaultImplementation?: string;
65
- /**
66
- * Author-side allowlist/denylist on which provider kinds the contract
67
- * permits. Use to express "this tool MUST NOT be served via untrusted
68
- * HTTP" (`forbid: ["http"]`) for self-hosted-only contracts.
69
- */
70
- driverConstraints?: DriverConstraints;
71
- }
72
- type DriverKind = "cli" | "http" | "mcp" | "sdk" | "builtin";
73
- interface DriverConstraints {
74
- /** Provider kinds the contract refuses. */
75
- forbid?: readonly DriverKind[];
76
- /** Whitelist of allowed provider kinds. Empty/missing = all permitted. */
77
- requireKind?: readonly DriverKind[];
78
- }
79
- type ToolContext = Record<string, unknown> & {
80
- signal?: AbortSignal;
81
- };
82
- type ApprovalClass = "auto" | "always" | "on-mutate" | `policy:${string}`;
83
- interface ToolCapabilities {
84
- network?: readonly string[];
85
- secrets?: readonly string[];
86
- tools?: readonly string[];
87
- }
88
- interface RetryPolicy {
89
- maxAttempts: number;
90
- backoff: "fixed" | "exponential";
91
- initialMs: number;
92
- }
93
- /**
94
- * The host-registrable contract handle returned by `defineTool`.
95
- *
96
- * Adapters (`toMastraTool`, …) AND provider runtimes (`http-runtime`,
97
- * `cli-runtime`, …) consume this shape. The handle does **not** carry
98
- * an invoke method — invocation goes through provider-runtime, which
99
- * resolves a provider per call and dispatches to its `execute[id]`.
100
- */
101
- interface ToolHandle<TInput = unknown, TOutput = unknown, TContext extends ToolContext = ToolContext> {
102
- readonly id: string;
103
- readonly name: string;
104
- readonly description: string;
105
- readonly version?: string;
106
- readonly inputSchema: ZodType<TInput>;
107
- readonly outputSchema: ZodType<TOutput>;
108
- readonly contextSchema?: ZodType<TContext>;
109
- readonly mutates: readonly string[];
110
- readonly requires: ToolCapabilities;
111
- readonly approval: ApprovalClass;
112
- readonly riskLevel: 0 | 1 | 2 | 3;
113
- readonly costClass: "trivial" | "metered" | "expensive";
114
- readonly timeoutMs: number;
115
- readonly retry?: RetryPolicy;
116
- readonly tags: readonly string[];
117
- readonly metadata: Record<string, unknown>;
118
- readonly idempotent: boolean;
119
- readonly defaultImplementation?: string;
120
- readonly driverConstraints: Required<DriverConstraints>;
121
- }
122
- /**
123
- * Standard out-of-band result envelope. Provider runtimes wrap thrown
124
- * errors into this shape; consumers consume `ToolResult<T>` rather than
125
- * `Promise<T>`.
126
- */
127
- type ToolResult<T> = {
128
- ok: true;
129
- value: T;
130
- } | {
131
- ok: false;
132
- error: {
133
- code: string;
134
- message: string;
135
- retryable?: boolean;
136
- cause?: unknown;
137
- };
138
- };
139
- /**
140
- * Validation helpers exposed for provider-runtime to reuse the same
141
- * input/output/context validation logic AIP-14 prescribes. Provider
142
- * runtimes MUST validate args.input against `tool.inputSchema` and
143
- * (when declared) args.context against `tool.contextSchema` BEFORE
144
- * dispatching to a provider's body.
145
- */
146
- interface ValidationFailure {
147
- ok: false;
148
- error: {
149
- code: "input_invalid";
150
- message: string;
151
- field?: string;
152
- cause?: unknown;
153
- };
154
- }
155
- interface ValidationSuccess<T> {
156
- ok: true;
157
- value: T;
158
- }
159
- type ValidationResult<T> = ValidationSuccess<T> | ValidationFailure;
160
-
161
- export type { ApprovalClass as A, DriverConstraints as D, RetryPolicy as R, ToolContext as T, ValidationResult as V, ToolDefinition as a, ToolHandle as b, ToolResult as c, DriverKind as d, ToolCapabilities as e, ValidationFailure as f, ValidationSuccess as g };