@kindgi/tools 0.0.0-bootstrap.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +86 -1
  3. package/dist/define.d.ts +138 -0
  4. package/dist/define.d.ts.map +1 -0
  5. package/dist/define.js +318 -0
  6. package/dist/define.js.map +1 -0
  7. package/dist/errors.d.ts +113 -0
  8. package/dist/errors.d.ts.map +1 -0
  9. package/dist/errors.js +4 -0
  10. package/dist/errors.js.map +1 -0
  11. package/dist/http.d.ts +2 -0
  12. package/dist/http.d.ts.map +1 -0
  13. package/dist/http.js +213 -0
  14. package/dist/http.js.map +1 -0
  15. package/dist/index.d.ts +15 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +14 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/invoke.d.ts +27 -0
  20. package/dist/invoke.d.ts.map +1 -0
  21. package/dist/invoke.js +127 -0
  22. package/dist/invoke.js.map +1 -0
  23. package/dist/manifest.d.ts +23 -0
  24. package/dist/manifest.d.ts.map +1 -0
  25. package/dist/manifest.js +37 -0
  26. package/dist/manifest.js.map +1 -0
  27. package/dist/precondition.d.ts +25 -0
  28. package/dist/precondition.d.ts.map +1 -0
  29. package/dist/precondition.js +34 -0
  30. package/dist/precondition.js.map +1 -0
  31. package/dist/registry.d.ts +87 -0
  32. package/dist/registry.d.ts.map +1 -0
  33. package/dist/registry.js +171 -0
  34. package/dist/registry.js.map +1 -0
  35. package/dist/spec-registry.d.ts +48 -0
  36. package/dist/spec-registry.d.ts.map +1 -0
  37. package/dist/spec-registry.js +37 -0
  38. package/dist/spec-registry.js.map +1 -0
  39. package/dist/tool.schema.json +297 -0
  40. package/dist/types.d.ts +508 -0
  41. package/dist/types.d.ts.map +1 -0
  42. package/dist/types.js +14 -0
  43. package/dist/types.js.map +1 -0
  44. package/package.json +64 -4
  45. package/src/define.ts +537 -0
  46. package/src/errors.ts +139 -0
  47. package/src/http.ts +268 -0
  48. package/src/index.ts +68 -0
  49. package/src/invoke.ts +165 -0
  50. package/src/manifest.ts +40 -0
  51. package/src/precondition.ts +40 -0
  52. package/src/registry.ts +262 -0
  53. package/src/spec-registry.ts +78 -0
  54. package/src/tool.schema.json +297 -0
  55. package/src/types.ts +538 -0
package/dist/http.js ADDED
@@ -0,0 +1,213 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+ import { registerToolSpecSynthesizer } from './spec-registry.js';
4
+ /**
5
+ * First-party synthesizer for `HttpToolSpec` (kind: 'http').
6
+ *
7
+ * `defineTool({spec: {kind: 'http', ...}})` produces a runtime
8
+ * `Tool` whose handler is auto-generated to perform the outbound
9
+ * HTTP call. The registered tool dispatches, validates, and travels
10
+ * identically to a hand-written in-process tool — kernel, invoke
11
+ * pipeline, and MCP discovery treat it as a normal `Tool`. The
12
+ * declarative `spec` field on the manifest is preserved for
13
+ * middleware and for JSON export / cross-process registration.
14
+ *
15
+ * Behavior at invoke time:
16
+ *
17
+ * 1. Input JSON-Schema validation runs (via the standard invoke
18
+ * pipeline); handler receives a validated input.
19
+ * 2. `urlTemplate` placeholders are substituted from input keys.
20
+ * Missing key → throw. Substituted keys are still available in
21
+ * the request body (unless `requestBody.kind === 'input-passthrough'`
22
+ * with different semantics documented below).
23
+ * 3. `authorization` is resolved via `ctx.resolveSecret(secretRef)`.
24
+ * If the tool declares authorization but `ctx.resolveSecret` is
25
+ * undefined, the handler throws a clear error rather than
26
+ * silently dropping the credential.
27
+ * 4. Static headers are added as-is.
28
+ * 5. Request body is built per `requestBody.kind`:
29
+ * - `'json-input'` (default when `requestBody` absent for
30
+ * POST/PUT/PATCH): JSON-serialize the tool's input MINUS
31
+ * keys already consumed by `urlTemplate`.
32
+ * - `'input-passthrough'`: JSON-serialize the entire input
33
+ * without removing URL-consumed keys.
34
+ * - `'text'`: substitute `{param}` placeholders in `template`
35
+ * from input; send as `Content-Type: text/plain`.
36
+ * 6. `fetch()` with an AbortController that inherits from
37
+ * `ctx.abortSignal` and adds a `timeoutMs` deadline (default
38
+ * 30_000). Aborts propagate as `handler-error`.
39
+ * 7. Status is checked against `successStatus` (default 200-299).
40
+ * Failures throw with the response body as the message.
41
+ * 8. Response body is parsed as JSON (default) or returned as
42
+ * text. Output JSON-Schema validation runs in the invoke
43
+ * pipeline; handler doesn't validate.
44
+ */
45
+ function buildHttpHandler(spec, toolId, options = {}) {
46
+ const doFetch = options.fetch ?? fetch;
47
+ return async (input, ctx) => {
48
+ const inputObj = coerceInputToObject(input, toolId);
49
+ const { url, consumedKeys } = substituteUrl(spec.urlTemplate, inputObj, toolId);
50
+ const headers = {};
51
+ for (const h of spec.headers ?? []) {
52
+ headers[h.name] = substituteTemplate(h.value, inputObj);
53
+ }
54
+ if (spec.authorization !== undefined) {
55
+ applyAuth(headers, spec.authorization, ctx, toolId, await resolveAuthSecret(spec.authorization, ctx, toolId));
56
+ }
57
+ const { body, contentType } = buildBody(spec, inputObj, consumedKeys);
58
+ if (body !== undefined && contentType !== undefined && headers['Content-Type'] === undefined) {
59
+ headers['Content-Type'] = contentType;
60
+ }
61
+ const timeoutMs = spec.timeoutMs ?? 30_000;
62
+ const controller = new AbortController();
63
+ const timeoutHandle = setTimeout(() => controller.abort(new Error(`http-tool "${toolId}" timed out after ${timeoutMs}ms`)), timeoutMs);
64
+ // Chain the caller's abort signal into ours — if the run is
65
+ // cancelled mid-flight, the outbound request cancels too.
66
+ const upstreamAbort = () => controller.abort(ctx.abortSignal.reason);
67
+ if (ctx.abortSignal.aborted) {
68
+ clearTimeout(timeoutHandle);
69
+ throw ctx.abortSignal.reason ?? new Error('aborted');
70
+ }
71
+ ctx.abortSignal.addEventListener('abort', upstreamAbort, { once: true });
72
+ let response;
73
+ try {
74
+ response = await doFetch(url, {
75
+ method: spec.method,
76
+ headers,
77
+ ...(body !== undefined && { body }),
78
+ signal: controller.signal,
79
+ });
80
+ }
81
+ finally {
82
+ clearTimeout(timeoutHandle);
83
+ ctx.abortSignal.removeEventListener('abort', upstreamAbort);
84
+ }
85
+ const successMin = spec.successStatus?.min ?? 200;
86
+ const successMax = spec.successStatus?.max ?? 299;
87
+ if (response.status < successMin || response.status > successMax) {
88
+ const text = await safeText(response);
89
+ throw new Error(`http-tool "${toolId}" got status ${response.status} ${response.statusText || ''} — ${text.slice(0, 512)}`);
90
+ }
91
+ const parseJson = spec.parseJson ?? true;
92
+ if (!parseJson) {
93
+ return await response.text();
94
+ }
95
+ const rawText = await response.text();
96
+ if (rawText.length === 0)
97
+ return null;
98
+ try {
99
+ return JSON.parse(rawText);
100
+ }
101
+ catch (cause) {
102
+ throw new Error(`http-tool "${toolId}" response was not valid JSON: ${cause instanceof Error ? cause.message : String(cause)}`);
103
+ }
104
+ };
105
+ }
106
+ // Register at module load. Framework barrel imports this module
107
+ // (`packages/tools/src/index.ts`) so any consumer that pulls in
108
+ // `@kindgi/tools` gets the 'http' kind registered automatically.
109
+ registerToolSpecSynthesizer('http', buildHttpHandler);
110
+ function coerceInputToObject(input, toolId) {
111
+ if (input === null || typeof input !== 'object' || Array.isArray(input)) {
112
+ throw new Error(`http-tool "${toolId}" requires an object input for URL substitution; got ${typeof input}`);
113
+ }
114
+ return input;
115
+ }
116
+ /**
117
+ * Substitute `{name}` placeholders in `template` with values from
118
+ * `input`. Returns the substituted URL plus the set of keys that
119
+ * were consumed (used by `buildBody` to strip them from a
120
+ * `json-input` body).
121
+ *
122
+ * URL-safe encoding: values are `encodeURIComponent`'d. Numeric,
123
+ * boolean, and string primitives are coerced via `String()`; nested
124
+ * objects or arrays throw.
125
+ */
126
+ function substituteUrl(template, input, toolId) {
127
+ const consumed = new Set();
128
+ const url = template.replace(/\{(\w+)\}/g, (_, key) => {
129
+ if (!(key in input)) {
130
+ throw new Error(`http-tool "${toolId}" urlTemplate references "{${key}}" but input has no such key`);
131
+ }
132
+ const value = input[key];
133
+ if (value === null ||
134
+ value === undefined ||
135
+ typeof value === 'object' ||
136
+ typeof value === 'function' ||
137
+ typeof value === 'symbol') {
138
+ throw new Error(`http-tool "${toolId}" urlTemplate key "{${key}}" must be a primitive; got ${typeof value}`);
139
+ }
140
+ consumed.add(key);
141
+ return encodeURIComponent(String(value));
142
+ });
143
+ return { url, consumedKeys: consumed };
144
+ }
145
+ /**
146
+ * Substitute `{name}` placeholders in a plain string (used for
147
+ * header values + `text` body templates). Unlike `substituteUrl`,
148
+ * this does NOT URL-encode values — headers/text bodies want raw
149
+ * strings. Missing keys throw.
150
+ */
151
+ function substituteTemplate(template, input) {
152
+ return template.replace(/\{(\w+)\}/g, (_, key) => {
153
+ if (!(key in input))
154
+ return `{${key}}`; // preserve if not in input (may be literal braces)
155
+ const value = input[key];
156
+ if (value === null || value === undefined)
157
+ return '';
158
+ return String(value);
159
+ });
160
+ }
161
+ async function resolveAuthSecret(auth, ctx, toolId) {
162
+ if (ctx.resolveSecret === undefined) {
163
+ throw new Error(`http-tool "${toolId}" declares authorization but ToolContext.resolveSecret is not wired. The dispatch site must populate resolveSecret from the deployment's SecretBinding.`);
164
+ }
165
+ return ctx.resolveSecret(auth.secretRef);
166
+ }
167
+ function applyAuth(headers, auth, _ctx, _toolId, resolvedSecret) {
168
+ switch (auth.kind) {
169
+ case 'bearer':
170
+ headers.Authorization = `Bearer ${resolvedSecret}`;
171
+ return;
172
+ case 'header':
173
+ headers[auth.headerName] = resolvedSecret;
174
+ return;
175
+ }
176
+ }
177
+ function buildBody(spec, input, consumedKeys) {
178
+ // Methods that don't carry a body by convention.
179
+ if (spec.method === 'GET' && spec.requestBody === undefined) {
180
+ return { body: undefined, contentType: undefined };
181
+ }
182
+ const kind = spec.requestBody?.kind ?? 'json-input';
183
+ if (kind === 'json-input') {
184
+ const remaining = {};
185
+ for (const [k, v] of Object.entries(input)) {
186
+ if (!consumedKeys.has(k))
187
+ remaining[k] = v;
188
+ }
189
+ // Empty remaining input → still send an empty body so servers
190
+ // can distinguish "no body" from "empty body". For POST-with-only-
191
+ // URL-params the caller can explicitly configure `input-passthrough`
192
+ // or a `text` body if the server expects that shape.
193
+ if (Object.keys(remaining).length === 0) {
194
+ return { body: '', contentType: undefined };
195
+ }
196
+ return { body: JSON.stringify(remaining), contentType: 'application/json' };
197
+ }
198
+ if (kind === 'input-passthrough') {
199
+ return { body: JSON.stringify(input), contentType: 'application/json' };
200
+ }
201
+ // kind === 'text'
202
+ const template = spec.requestBody.template;
203
+ return { body: substituteTemplate(template, input), contentType: 'text/plain' };
204
+ }
205
+ async function safeText(response) {
206
+ try {
207
+ return await response.text();
208
+ }
209
+ catch {
210
+ return '<no body>';
211
+ }
212
+ }
213
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ export { defineTool, defineToolAsync, validateToolManifest, TOOL_SCHEMA_URI_EXPORTED as TOOL_SCHEMA_URI, } from './define.js';
2
+ export type { DefineToolOptions, DefineToolSpec, DefinedTool, InferInput, InferOutput, } from './define.js';
3
+ import './http.js';
4
+ export { registerToolSpecSynthesizer, getToolSpecSynthesizer } from './spec-registry.js';
5
+ export type { ToolSpecSynthesizer, ToolSpecSynthesizerOptions } from './spec-registry.js';
6
+ export { invokeTool } from './invoke.js';
7
+ export { ToolPreconditionError, isToolPreconditionError } from './precondition.js';
8
+ export type { InvokeToolOptions } from './invoke.js';
9
+ export { createToolRegistry } from './registry.js';
10
+ export type { ToolRegistry, ToolResolution } from './registry.js';
11
+ export { toManifest, toMcpManifest } from './manifest.js';
12
+ export { EFFECT_KINDS } from './types.js';
13
+ export type { AnyTool, CodeArtifactRef, Effect, EffectKind, HttpAuthSpec, HttpHeaderSpec, HttpMethod, HttpRequestBodySpec, HttpToolSpec, JsonSchema, McpToolManifest, Need, NetworkPolicy, RuntimeLimits, SandboxMode, Tool, ToolContext, ToolManifest, ToolSecretRef, ToolSpec, TypedNeeds, } from './types.js';
14
+ export type { DuplicateToolError, DuplicateToolVersionError, HandlerError, InputValidationError, InvalidSchemaError, InvalidToolDefinitionError, InvalidVersionRangeError, OutputValidationError, PreconditionFailedError, ToolError, ToolNotFoundError, ToolVersionNotFoundError, ToolVersionUnresolvableError, UnknownEffectError, } from './errors.js';
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,UAAU,EACV,eAAe,EACf,oBAAoB,EACpB,wBAAwB,IAAI,eAAe,GAC5C,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,iBAAiB,EACjB,cAAc,EACd,WAAW,EACX,UAAU,EACV,WAAW,GACZ,MAAM,aAAa,CAAC;AAIrB,OAAO,WAAW,CAAC;AACnB,OAAO,EAAE,2BAA2B,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AACzF,YAAY,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AACnF,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,YAAY,EACV,OAAO,EACP,eAAe,EACf,MAAM,EACN,UAAU,EACV,YAAY,EACZ,cAAc,EACd,UAAU,EACV,mBAAmB,EACnB,YAAY,EACZ,UAAU,EACV,eAAe,EACf,IAAI,EACJ,aAAa,EACb,aAAa,EACb,WAAW,EACX,IAAI,EACJ,WAAW,EACX,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,UAAU,GACX,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,kBAAkB,EAClB,yBAAyB,EACzB,YAAY,EACZ,oBAAoB,EACpB,kBAAkB,EAClB,0BAA0B,EAC1B,wBAAwB,EACxB,qBAAqB,EACrB,uBAAuB,EACvB,SAAS,EACT,iBAAiB,EACjB,wBAAwB,EACxB,4BAA4B,EAC5B,kBAAkB,GACnB,MAAM,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+ export { defineTool, defineToolAsync, validateToolManifest, TOOL_SCHEMA_URI_EXPORTED as TOOL_SCHEMA_URI, } from './define.js';
4
+ // Side-effect import — registers the 'http' spec synthesizer at
5
+ // package load so `defineTool({spec: {kind: 'http', ...}})` works
6
+ // out of the box for any consumer that imports @kindgi/tools.
7
+ import './http.js';
8
+ export { registerToolSpecSynthesizer, getToolSpecSynthesizer } from './spec-registry.js';
9
+ export { invokeTool } from './invoke.js';
10
+ export { ToolPreconditionError, isToolPreconditionError } from './precondition.js';
11
+ export { createToolRegistry } from './registry.js';
12
+ export { toManifest, toMcpManifest } from './manifest.js';
13
+ export { EFFECT_KINDS } from './types.js';
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC,OAAO,EACL,UAAU,EACV,eAAe,EACf,oBAAoB,EACpB,wBAAwB,IAAI,eAAe,GAC5C,MAAM,aAAa,CAAC;AAQrB,gEAAgE;AAChE,kEAAkE;AAClE,8DAA8D;AAC9D,OAAO,WAAW,CAAC;AACnB,OAAO,EAAE,2BAA2B,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAEzF,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAEnF,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { Result } from '@kindgi/types';
2
+ import type { ToolError } from './errors.js';
3
+ import type { Tool, ToolContext } from './types.js';
4
+ export interface InvokeToolOptions {
5
+ /**
6
+ * Skip validation of the handler's return value against `tool.output`.
7
+ * Trade-off: faster, but a broken handler can produce data that violates
8
+ * the declared contract without the runtime noticing. Default: false.
9
+ */
10
+ readonly skipOutputValidation?: boolean;
11
+ }
12
+ /**
13
+ * Invoke a tool with a caller-supplied input and context. The path is:
14
+ * 1. Validate a copy of `input` against `tool.input`, filling in its
15
+ * defaults, and — for a Zod-authored tool — parse it with
16
+ * `tool.inputZod` (defaults, transforms, refinements). Reject on
17
+ * failure.
18
+ * 2. Call `tool.handler(prepared, ctx)`. Catch any throw and return
19
+ * `handler-error` — invocation is total, throws don't escape.
20
+ * 3. Validate the return value against `tool.output` schema (unless the
21
+ * caller opts out).
22
+ *
23
+ * Validation cost is amortised via a schema-object-keyed cache — the second
24
+ * invocation of the same tool reuses the compiled Ajv validator.
25
+ */
26
+ export declare function invokeTool<TInput = unknown, TOutput = unknown>(tool: Tool<TInput, TOutput>, input: unknown, ctx: ToolContext, options?: InvokeToolOptions): Promise<Result<TOutput, ToolError>>;
27
+ //# sourceMappingURL=invoke.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoke.d.ts","sourceRoot":"","sources":["../src/invoke.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,KAAK,EAKV,SAAS,EACV,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EAAc,IAAI,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AA6EhE,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;CACzC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,UAAU,CAAC,MAAM,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO,EAClE,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3B,KAAK,EAAE,OAAO,EACd,GAAG,EAAE,WAAW,EAChB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAyCrC"}
package/dist/invoke.js ADDED
@@ -0,0 +1,127 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+ import * as addFormatsModule from 'ajv-formats';
4
+ import { Ajv2020 } from 'ajv/dist/2020.js';
5
+ import { parseWithSchema } from '@kindgi/schema';
6
+ import { isToolPreconditionError } from './precondition.js';
7
+ const addFormatsRaw = addFormatsModule;
8
+ const addFormats = typeof addFormatsRaw === 'function'
9
+ ? addFormatsRaw
10
+ : addFormatsRaw.default;
11
+ /**
12
+ * Cache compiled validators keyed by the schema *object reference*. Tools
13
+ * are defined once and reused, so schema identity is stable — the WeakMap
14
+ * releases entries when the tool is dropped.
15
+ */
16
+ const inputCache = new WeakMap();
17
+ const outputCache = new WeakMap();
18
+ /**
19
+ * A compiled validator. Input validators fill in each property's JSON
20
+ * Schema `default` (`useDefaults`) — the data they check is a copy of the
21
+ * caller's.
22
+ */
23
+ function compile(schema, side) {
24
+ const cache = side === 'input' ? inputCache : outputCache;
25
+ const cached = cache.get(schema);
26
+ if (cached !== undefined)
27
+ return cached;
28
+ const ajv = new Ajv2020({
29
+ strict: true,
30
+ allErrors: true,
31
+ allowUnionTypes: false,
32
+ ...(side === 'input' && { useDefaults: true }),
33
+ });
34
+ addFormats(ajv);
35
+ const validator = ajv.compile(schema);
36
+ cache.set(schema, validator);
37
+ return validator;
38
+ }
39
+ /**
40
+ * The input a handler receives: validated against `tool.input` with its
41
+ * defaults filled in, then — for a Zod-authored tool — parsed by its Zod
42
+ * schema, so defaults, transforms and refinements apply and the handler
43
+ * gets what its `z.infer` type says.
44
+ */
45
+ async function prepareInput(tool, input) {
46
+ const candidate = structuredClone(input);
47
+ const validator = compile(tool.input, 'input');
48
+ if (!validator(candidate)) {
49
+ return { kind: 'err', error: inputError(tool.id, validator.errors ?? []) };
50
+ }
51
+ if (tool.inputZod === undefined)
52
+ return { kind: 'ok', value: candidate };
53
+ const parsed = await parseWithSchema(tool.inputZod, candidate);
54
+ if (parsed.kind === 'ok')
55
+ return parsed;
56
+ return {
57
+ kind: 'err',
58
+ error: inputError(tool.id, parsed.issues.map((i) => ({
59
+ instancePath: (i.path ?? []).map((p) => `/${String(p)}`).join(''),
60
+ message: i.message,
61
+ }))),
62
+ };
63
+ }
64
+ function inputError(toolId, errors) {
65
+ return {
66
+ code: 'input-validation-failed',
67
+ message: `Input for tool "${toolId}" failed validation`,
68
+ toolId,
69
+ errors,
70
+ };
71
+ }
72
+ /**
73
+ * Invoke a tool with a caller-supplied input and context. The path is:
74
+ * 1. Validate a copy of `input` against `tool.input`, filling in its
75
+ * defaults, and — for a Zod-authored tool — parse it with
76
+ * `tool.inputZod` (defaults, transforms, refinements). Reject on
77
+ * failure.
78
+ * 2. Call `tool.handler(prepared, ctx)`. Catch any throw and return
79
+ * `handler-error` — invocation is total, throws don't escape.
80
+ * 3. Validate the return value against `tool.output` schema (unless the
81
+ * caller opts out).
82
+ *
83
+ * Validation cost is amortised via a schema-object-keyed cache — the second
84
+ * invocation of the same tool reuses the compiled Ajv validator.
85
+ */
86
+ export async function invokeTool(tool, input, ctx, options = {}) {
87
+ const prepared = await prepareInput(tool, input);
88
+ if (prepared.kind === 'err')
89
+ return prepared;
90
+ let output;
91
+ try {
92
+ output = await tool.handler(prepared.value, ctx);
93
+ }
94
+ catch (cause) {
95
+ if (isToolPreconditionError(cause)) {
96
+ const refused = {
97
+ code: 'precondition-failed',
98
+ message: `Tool "${tool.id}" was not run: ${cause.reason}: ${cause.message}`,
99
+ toolId: tool.id,
100
+ reason: cause.reason,
101
+ cause,
102
+ };
103
+ return { kind: 'err', error: refused };
104
+ }
105
+ const err = {
106
+ code: 'handler-error',
107
+ message: `Tool "${tool.id}" handler threw: ${cause instanceof Error ? cause.message : String(cause)}`,
108
+ toolId: tool.id,
109
+ cause,
110
+ };
111
+ return { kind: 'err', error: err };
112
+ }
113
+ if (!options.skipOutputValidation) {
114
+ const outputValidator = compile(tool.output, 'output');
115
+ if (!outputValidator(output)) {
116
+ const err = {
117
+ code: 'output-validation-failed',
118
+ message: `Tool "${tool.id}" handler produced output that failed validation`,
119
+ toolId: tool.id,
120
+ errors: outputValidator.errors ?? [],
121
+ };
122
+ return { kind: 'err', error: err };
123
+ }
124
+ }
125
+ return { kind: 'ok', value: output };
126
+ }
127
+ //# sourceMappingURL=invoke.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoke.js","sourceRoot":"","sources":["../src/invoke.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { AnyTool, McpToolManifest, ToolManifest } from './types.js';
2
+ /**
3
+ * Project a runtime `Tool` to its serialisable manifest — everything
4
+ * declared in `@kindgi/specs/tool.schema.json` minus the `handler` binding.
5
+ *
6
+ * Use for wire transport, MCP exposure (via `toMcpManifest`), and
7
+ * discovery endpoints. The result round-trips through JSON.
8
+ */
9
+ export declare function toManifest(tool: AnyTool): ToolManifest;
10
+ /**
11
+ * Project a `Tool` to the MCP `tools/list` shape:
12
+ * `{ name, description, inputSchema, outputSchema? }`.
13
+ *
14
+ * MCP's tool discovery format is narrower than our own — no needs, no
15
+ * effects, no transport hint. Those stay on the Kindgi side (used by
16
+ * policy, capabilities, scheduling); the MCP client sees only what the
17
+ * spec exposes.
18
+ *
19
+ * `outputSchema` is optional in MCP; we always emit it so clients that
20
+ * read it get typed returns.
21
+ */
22
+ export declare function toMcpManifest(tool: AnyTool): McpToolManifest;
23
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEzE;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY,CAMtD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,eAAe,CAO5D"}
@@ -0,0 +1,37 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+ /**
4
+ * Project a runtime `Tool` to its serialisable manifest — everything
5
+ * declared in `@kindgi/specs/tool.schema.json` minus the `handler` binding.
6
+ *
7
+ * Use for wire transport, MCP exposure (via `toMcpManifest`), and
8
+ * discovery endpoints. The result round-trips through JSON.
9
+ */
10
+ export function toManifest(tool) {
11
+ // Strip runtime-only bindings that never cross the wire: the handler
12
+ // function itself, and the optional Zod authoring schemas preserved
13
+ // for TS type inference on the runtime object.
14
+ const { handler: _handler, inputZod: _inputZod, outputZod: _outputZod, ...manifest } = tool;
15
+ return manifest;
16
+ }
17
+ /**
18
+ * Project a `Tool` to the MCP `tools/list` shape:
19
+ * `{ name, description, inputSchema, outputSchema? }`.
20
+ *
21
+ * MCP's tool discovery format is narrower than our own — no needs, no
22
+ * effects, no transport hint. Those stay on the Kindgi side (used by
23
+ * policy, capabilities, scheduling); the MCP client sees only what the
24
+ * spec exposes.
25
+ *
26
+ * `outputSchema` is optional in MCP; we always emit it so clients that
27
+ * read it get typed returns.
28
+ */
29
+ export function toMcpManifest(tool) {
30
+ return {
31
+ name: tool.id,
32
+ description: tool.description,
33
+ inputSchema: tool.input,
34
+ outputSchema: tool.output,
35
+ };
36
+ }
37
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAIjC;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,IAAa;IACtC,qEAAqE;IACrE,oEAAoE;IACpE,+CAA+C;IAC/C,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,QAAQ,EAAE,GAAG,IAAI,CAAC;IAC5F,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAAC,IAAa;IACzC,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,EAAE;QACb,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,WAAW,EAAE,IAAI,CAAC,KAAK;QACvB,YAAY,EAAE,IAAI,CAAC,MAAM;KAC1B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * A runtime's refusal to run a tool: something the tool declares wasn't
3
+ * there — a secret it declares couldn't be resolved, say. A runtime that
4
+ * wraps a tool's handler throws it before calling the tool's own code;
5
+ * `invokeTool` reports it as `precondition-failed` (not `handler-error`:
6
+ * the handler never ran), with the runtime's `reason` code.
7
+ *
8
+ * Recognized by a registered symbol, not `instanceof`, so a runtime and
9
+ * a tool that load different copies of this package still agree.
10
+ */
11
+ declare const PRECONDITION_FAILED: unique symbol;
12
+ export declare class ToolPreconditionError extends Error {
13
+ readonly reason: string;
14
+ readonly [PRECONDITION_FAILED] = true;
15
+ /**
16
+ * @param reason The runtime's code for what was missing
17
+ * (`secret-unavailable`, `env-not-configured`, …).
18
+ * @param message What was missing, by name; never a secret's value.
19
+ */
20
+ constructor(reason: string, message: string);
21
+ }
22
+ /** Is `value` a `ToolPreconditionError` (from any copy of this package)? */
23
+ export declare function isToolPreconditionError(value: unknown): value is ToolPreconditionError;
24
+ export {};
25
+ //# sourceMappingURL=precondition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"precondition.d.ts","sourceRoot":"","sources":["../src/precondition.ts"],"names":[],"mappings":"AAGA;;;;;;;;;GASG;AACH,QAAA,MAAM,mBAAmB,eAAiD,CAAC;AAE3E,qBAAa,qBAAsB,SAAQ,KAAK;IAS5C,QAAQ,CAAC,MAAM,EAAE,MAAM;IARzB,QAAQ,CAAC,CAAC,mBAAmB,CAAC,QAAQ;IAEtC;;;;OAIG;gBAEQ,MAAM,EAAE,MAAM,EACvB,OAAO,EAAE,MAAM;CAKlB;AAED,4EAA4E;AAC5E,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,qBAAqB,CAMtF"}
@@ -0,0 +1,34 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+ /**
4
+ * A runtime's refusal to run a tool: something the tool declares wasn't
5
+ * there — a secret it declares couldn't be resolved, say. A runtime that
6
+ * wraps a tool's handler throws it before calling the tool's own code;
7
+ * `invokeTool` reports it as `precondition-failed` (not `handler-error`:
8
+ * the handler never ran), with the runtime's `reason` code.
9
+ *
10
+ * Recognized by a registered symbol, not `instanceof`, so a runtime and
11
+ * a tool that load different copies of this package still agree.
12
+ */
13
+ const PRECONDITION_FAILED = Symbol.for('kindgi.tools.precondition-failed');
14
+ export class ToolPreconditionError extends Error {
15
+ reason;
16
+ [PRECONDITION_FAILED] = true;
17
+ /**
18
+ * @param reason The runtime's code for what was missing
19
+ * (`secret-unavailable`, `env-not-configured`, …).
20
+ * @param message What was missing, by name; never a secret's value.
21
+ */
22
+ constructor(reason, message) {
23
+ super(message);
24
+ this.reason = reason;
25
+ this.name = 'ToolPreconditionError';
26
+ }
27
+ }
28
+ /** Is `value` a `ToolPreconditionError` (from any copy of this package)? */
29
+ export function isToolPreconditionError(value) {
30
+ return (typeof value === 'object' &&
31
+ value !== null &&
32
+ value[PRECONDITION_FAILED] === true);
33
+ }
34
+ //# sourceMappingURL=precondition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"precondition.js","sourceRoot":"","sources":["../src/precondition.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC;;;;;;;;;GASG;AACH,MAAM,mBAAmB,GAAG,MAAM,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;AAE3E,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IASnC;IARF,CAAC,mBAAmB,CAAC,GAAG,IAAI,CAAC;IAEtC;;;;OAIG;IACH,YACW,MAAc,EACvB,OAAe;QAEf,KAAK,CAAC,OAAO,CAAC,CAAC;QAHN,WAAM,GAAN,MAAM,CAAQ;QAIvB,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;IACtC,CAAC;CACF;AAED,4EAA4E;AAC5E,MAAM,UAAU,uBAAuB,CAAC,KAAc;IACpD,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACb,KAAsD,CAAC,mBAAmB,CAAC,KAAK,IAAI,CACtF,CAAC;AACJ,CAAC"}