@agentproto/tool 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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":"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","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.0",
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",
@@ -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/manifest": "0.2.0",
53
+ "@agentproto/define-doctype": "0.1.0"
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":";;;;;;;;;;;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;;;ACvEA,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,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;AAOO,SAAS,aAAA,CACd,QACA,KAAA,EAC0B;AAC1B,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,WAAA,CAAY,SAAA,CAAU,KAAK,CAAA;AACjD,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,MAAM,eAAA,CAAgB,MAAA,CAAO,KAAA,CAAM,MAAM,CAAC,CAAA,CAAA;AAAA,QACnE,KAAA,EAAO,OAAO,KAAA,CAAM;AAAA;AACtB,KACF;AAAA,EACF;AACA,EAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,KAAA,EAAO,OAAO,IAAA,EAAe;AAClD;AAUO,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;AAUO,SAAS,cAAA,CACd,QACA,MAAA,EACS;AACT,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,YAAA,CAAa,SAAA,CAAU,MAAM,CAAA;AACnD,EAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,IAAA,MAAM,IAAI,SAAA,CAAU;AAAA,MAClB,IAAA,EAAM,gBAAA;AAAA,MACN,OAAA,EAAS,OAAO,MAAA,CAAO,EAAE,uEAAkE,eAAA,CAAgB,MAAA,CAAO,KAAA,CAAM,MAAM,CAAC,CAAA,CAAA;AAAA,MAC/H,KAAA,EAAO,OAAO,KAAA,CAAM;AAAA,KACrB,CAAA;AAAA,EACH;AACA,EAAA,OAAO,MAAA,CAAO,IAAA;AAChB;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;;;ACxMO,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,EAIrD,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;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,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-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 };