stitchkit 0.24.0 → 0.25.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.
- package/dist/cli.js +1 -1
- package/dist/{index-x8m8e7dc.js → index-h9d1fm0p.js} +114 -65
- package/dist/tools/coerce.d.ts +2 -1
- package/dist/tools/coerce.d.ts.map +1 -1
- package/dist/tools/flatten.d.ts +16 -6
- package/dist/tools/flatten.d.ts.map +1 -1
- package/dist/tools/mount.d.ts.map +1 -1
- package/dist/tools/schema.d.ts +43 -1
- package/dist/tools/schema.d.ts.map +1 -1
- package/dist/tools.js +1 -1
- package/llms-full.txt +16 -4
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -76,13 +76,66 @@ function coerceJsonArgs(args, schema) {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
// src/tools/flatten.ts
|
|
79
|
+
import { z as z3 } from "zod";
|
|
80
|
+
|
|
81
|
+
// src/tools/schema.ts
|
|
79
82
|
import { z as z2 } from "zod";
|
|
83
|
+
function objectShapeKeys(schema) {
|
|
84
|
+
return schema instanceof z2.ZodObject ? Object.keys(schema.shape) : [];
|
|
85
|
+
}
|
|
86
|
+
function keyPolicyOf(schema) {
|
|
87
|
+
return schema.def.catchall;
|
|
88
|
+
}
|
|
89
|
+
function rebuildObject(source, shape) {
|
|
90
|
+
return withKeyPolicy(z2.object(shape), keyPolicyOf(source));
|
|
91
|
+
}
|
|
92
|
+
function withKeyPolicy(object, policy) {
|
|
93
|
+
if (policy === undefined)
|
|
94
|
+
return object;
|
|
95
|
+
return object.catchall(representable(policy));
|
|
96
|
+
}
|
|
97
|
+
function representable(policy) {
|
|
98
|
+
if (policy instanceof z2.ZodNever || policy instanceof z2.ZodUnknown)
|
|
99
|
+
return policy;
|
|
100
|
+
if (!(policy instanceof z2.ZodType))
|
|
101
|
+
return z2.unknown();
|
|
102
|
+
try {
|
|
103
|
+
toJsonSchema(policy, "input");
|
|
104
|
+
return policy;
|
|
105
|
+
} catch {
|
|
106
|
+
return z2.unknown();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function mergeSchemas(paramsSchema, inputSchema) {
|
|
110
|
+
if (paramsSchema && !(paramsSchema instanceof z2.ZodObject)) {
|
|
111
|
+
throw new Error("Tool params schema must be a z.object()");
|
|
112
|
+
}
|
|
113
|
+
const paramsObject = paramsSchema instanceof z2.ZodObject ? paramsSchema : undefined;
|
|
114
|
+
if (!inputSchema) {
|
|
115
|
+
return paramsObject ?? z2.object({});
|
|
116
|
+
}
|
|
117
|
+
if (inputSchema instanceof z2.ZodObject) {
|
|
118
|
+
if (paramsObject) {
|
|
119
|
+
const conflicts = Object.keys(paramsObject.shape).filter((key) => (key in inputSchema.shape));
|
|
120
|
+
if (conflicts.length > 0) {
|
|
121
|
+
throw new Error(`Schema merge conflict: ${conflicts.join(", ")} appear in both params and input`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return rebuildObject(inputSchema, {
|
|
125
|
+
...paramsObject?.shape ?? {},
|
|
126
|
+
...inputSchema.shape
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
return paramsObject ? z2.intersection(paramsObject, inputSchema) : inputSchema;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// src/tools/flatten.ts
|
|
80
133
|
function flattenDiscriminatedUnion(union) {
|
|
81
134
|
const discriminator = union.def.discriminator;
|
|
82
135
|
const allDiscValues = [];
|
|
83
136
|
const perKey = new Map;
|
|
84
137
|
for (const opt of union.def.options) {
|
|
85
|
-
if (!(opt instanceof
|
|
138
|
+
if (!(opt instanceof z3.ZodObject)) {
|
|
86
139
|
throw new Error(`flattenDiscriminatedUnion: variant for discriminator '${discriminator}' is not a ZodObject`);
|
|
87
140
|
}
|
|
88
141
|
const discValues = stringLiteralOrEnumValues(opt.shape[discriminator]);
|
|
@@ -95,7 +148,7 @@ function flattenDiscriminatedUnion(union) {
|
|
|
95
148
|
if (key === discriminator)
|
|
96
149
|
continue;
|
|
97
150
|
const entry = perKey.get(key) ?? { schemas: [], variants: [] };
|
|
98
|
-
entry.schemas.push(
|
|
151
|
+
entry.schemas.push(unwrapField(field));
|
|
99
152
|
entry.variants.push(label);
|
|
100
153
|
perKey.set(key, entry);
|
|
101
154
|
}
|
|
@@ -106,23 +159,44 @@ function flattenDiscriminatedUnion(union) {
|
|
|
106
159
|
throw new Error("flattenDiscriminatedUnion: union has no options");
|
|
107
160
|
}
|
|
108
161
|
const shape = {
|
|
109
|
-
[discriminator]:
|
|
162
|
+
[discriminator]: z3.enum([firstLiteral, ...restLiterals])
|
|
110
163
|
};
|
|
111
164
|
for (const [key, entry] of perKey) {
|
|
112
165
|
const advertised = mergeCollidingFields(entry.schemas);
|
|
113
166
|
const hint = `Required if ${discriminator} = ${[...new Set(entry.variants)].join(" | ")}`;
|
|
114
|
-
shape[key] =
|
|
167
|
+
shape[key] = z3.optional(advertised).describe(hint);
|
|
168
|
+
}
|
|
169
|
+
return withKeyPolicy(z3.object(shape), mergeVariantKeyPolicies(union.def.options));
|
|
170
|
+
}
|
|
171
|
+
function mergeVariantKeyPolicies(options) {
|
|
172
|
+
let strict = 0;
|
|
173
|
+
let counted = 0;
|
|
174
|
+
for (const option of options) {
|
|
175
|
+
const policy = option instanceof z3.ZodObject ? keyPolicyOf(option) : undefined;
|
|
176
|
+
if (policy !== undefined && !(policy instanceof z3.ZodNever))
|
|
177
|
+
return z3.unknown();
|
|
178
|
+
counted++;
|
|
179
|
+
if (policy instanceof z3.ZodNever)
|
|
180
|
+
strict++;
|
|
181
|
+
}
|
|
182
|
+
if (counted === 0 || strict === 0)
|
|
183
|
+
return;
|
|
184
|
+
return strict === counted ? z3.never() : z3.unknown();
|
|
185
|
+
}
|
|
186
|
+
function unwrapField(field) {
|
|
187
|
+
if (field instanceof z3.ZodOptional || field instanceof z3.ZodDefault) {
|
|
188
|
+
return unwrapField(field.unwrap());
|
|
115
189
|
}
|
|
116
|
-
return
|
|
190
|
+
return field;
|
|
117
191
|
}
|
|
118
192
|
function preserveDescription(from, to) {
|
|
119
193
|
return from.description === undefined ? to : to.describe(from.description);
|
|
120
194
|
}
|
|
121
195
|
function stringLiteralOrEnumValues(field) {
|
|
122
196
|
let raw = null;
|
|
123
|
-
if (field instanceof
|
|
197
|
+
if (field instanceof z3.ZodLiteral)
|
|
124
198
|
raw = field.def.values;
|
|
125
|
-
else if (field instanceof
|
|
199
|
+
else if (field instanceof z3.ZodEnum)
|
|
126
200
|
raw = field.options;
|
|
127
201
|
if (raw === null)
|
|
128
202
|
return null;
|
|
@@ -134,7 +208,7 @@ function isFlattenableDU(union) {
|
|
|
134
208
|
if (union.def.options.length === 0)
|
|
135
209
|
return false;
|
|
136
210
|
for (const opt of union.def.options) {
|
|
137
|
-
if (!(opt instanceof
|
|
211
|
+
if (!(opt instanceof z3.ZodObject))
|
|
138
212
|
return false;
|
|
139
213
|
if (stringLiteralOrEnumValues(opt.shape[disc]) === null)
|
|
140
214
|
return false;
|
|
@@ -156,31 +230,31 @@ function stripAnnotations(node) {
|
|
|
156
230
|
}
|
|
157
231
|
}
|
|
158
232
|
function hasChecks(schema) {
|
|
159
|
-
if (!(schema instanceof
|
|
233
|
+
if (!(schema instanceof z3.ZodType))
|
|
160
234
|
return false;
|
|
161
235
|
const def = schema.def;
|
|
162
236
|
if (isRecord(def) && Array.isArray(def.checks) && def.checks.length > 0)
|
|
163
237
|
return true;
|
|
164
|
-
if (schema instanceof
|
|
238
|
+
if (schema instanceof z3.ZodOptional || schema instanceof z3.ZodNullable || schema instanceof z3.ZodDefault) {
|
|
165
239
|
return hasChecks(schema.unwrap());
|
|
166
240
|
}
|
|
167
|
-
if (schema instanceof
|
|
241
|
+
if (schema instanceof z3.ZodPipe)
|
|
168
242
|
return hasChecks(schema.def.in) || hasChecks(schema.def.out);
|
|
169
|
-
if (schema instanceof
|
|
243
|
+
if (schema instanceof z3.ZodObject)
|
|
170
244
|
return Object.values(schema.shape).some(hasChecks);
|
|
171
|
-
if (schema instanceof
|
|
245
|
+
if (schema instanceof z3.ZodArray)
|
|
172
246
|
return hasChecks(schema.element);
|
|
173
|
-
if (schema instanceof
|
|
247
|
+
if (schema instanceof z3.ZodUnion)
|
|
174
248
|
return schema.def.options.some(hasChecks);
|
|
175
|
-
if (schema instanceof
|
|
249
|
+
if (schema instanceof z3.ZodRecord)
|
|
176
250
|
return hasChecks(schema.valueType);
|
|
177
|
-
if (schema instanceof
|
|
251
|
+
if (schema instanceof z3.ZodIntersection) {
|
|
178
252
|
return hasChecks(schema.def.left) || hasChecks(schema.def.right);
|
|
179
253
|
}
|
|
180
254
|
return false;
|
|
181
255
|
}
|
|
182
256
|
function normalizedJson(schema) {
|
|
183
|
-
if (!(schema instanceof
|
|
257
|
+
if (!(schema instanceof z3.ZodType))
|
|
184
258
|
return "{}";
|
|
185
259
|
const json = toJsonSchema(schema, "input", "any");
|
|
186
260
|
stripAnnotations(json);
|
|
@@ -197,8 +271,8 @@ function mergeCollidingFields(schemas) {
|
|
|
197
271
|
const only = values[0];
|
|
198
272
|
if (values.length <= 1) {
|
|
199
273
|
if (only === undefined)
|
|
200
|
-
return
|
|
201
|
-
return schemas.length > 1 && hasChecks(only) ?
|
|
274
|
+
return z3.unknown();
|
|
275
|
+
return schemas.length > 1 && hasChecks(only) ? z3.unknown() : only;
|
|
202
276
|
}
|
|
203
277
|
const merged = [];
|
|
204
278
|
let allEnum = true;
|
|
@@ -214,47 +288,47 @@ function mergeCollidingFields(schemas) {
|
|
|
214
288
|
const uniq = [...new Set(merged)];
|
|
215
289
|
const [first, ...rest] = uniq;
|
|
216
290
|
if (first !== undefined)
|
|
217
|
-
return
|
|
291
|
+
return z3.enum([first, ...rest]);
|
|
218
292
|
}
|
|
219
|
-
return
|
|
293
|
+
return z3.unknown();
|
|
220
294
|
}
|
|
221
295
|
function flattenUnionsDeep(schema) {
|
|
222
|
-
if (!(schema instanceof
|
|
223
|
-
return
|
|
224
|
-
if (schema instanceof
|
|
296
|
+
if (!(schema instanceof z3.ZodType))
|
|
297
|
+
return z3.unknown();
|
|
298
|
+
if (schema instanceof z3.ZodDiscriminatedUnion) {
|
|
225
299
|
if (!isFlattenableDU(schema))
|
|
226
300
|
return schema;
|
|
227
301
|
return preserveDescription(schema, flattenUnionsDeep(flattenDiscriminatedUnion(schema)));
|
|
228
302
|
}
|
|
229
|
-
if (schema instanceof
|
|
303
|
+
if (schema instanceof z3.ZodObject) {
|
|
230
304
|
const shape = {};
|
|
231
305
|
for (const [key, field] of Object.entries(schema.shape)) {
|
|
232
306
|
shape[key] = flattenUnionsDeep(field);
|
|
233
307
|
}
|
|
234
|
-
return preserveDescription(schema,
|
|
308
|
+
return preserveDescription(schema, rebuildObject(schema, shape));
|
|
235
309
|
}
|
|
236
|
-
if (schema instanceof
|
|
237
|
-
return preserveDescription(schema,
|
|
310
|
+
if (schema instanceof z3.ZodArray) {
|
|
311
|
+
return preserveDescription(schema, z3.array(flattenUnionsDeep(schema.element)));
|
|
238
312
|
}
|
|
239
|
-
if (schema instanceof
|
|
313
|
+
if (schema instanceof z3.ZodUnion) {
|
|
240
314
|
const opts = schema.def.options.map((option) => flattenUnionsDeep(option));
|
|
241
315
|
const [a, b, ...rest] = opts;
|
|
242
|
-
return a && b ? preserveDescription(schema,
|
|
316
|
+
return a && b ? preserveDescription(schema, z3.union([a, b, ...rest])) : schema;
|
|
243
317
|
}
|
|
244
|
-
if (schema instanceof
|
|
245
|
-
return preserveDescription(schema,
|
|
318
|
+
if (schema instanceof z3.ZodRecord) {
|
|
319
|
+
return preserveDescription(schema, z3.record(schema.keyType, flattenUnionsDeep(schema.valueType)));
|
|
246
320
|
}
|
|
247
|
-
if (schema instanceof
|
|
248
|
-
return preserveDescription(schema,
|
|
321
|
+
if (schema instanceof z3.ZodOptional) {
|
|
322
|
+
return preserveDescription(schema, z3.optional(flattenUnionsDeep(schema.unwrap())));
|
|
249
323
|
}
|
|
250
|
-
if (schema instanceof
|
|
251
|
-
return preserveDescription(schema,
|
|
324
|
+
if (schema instanceof z3.ZodNullable) {
|
|
325
|
+
return preserveDescription(schema, z3.nullable(flattenUnionsDeep(schema.unwrap())));
|
|
252
326
|
}
|
|
253
|
-
if (schema instanceof
|
|
327
|
+
if (schema instanceof z3.ZodDefault) {
|
|
254
328
|
return preserveDescription(schema, flattenUnionsDeep(schema.unwrap()).default(schema.def.defaultValue));
|
|
255
329
|
}
|
|
256
|
-
if (schema instanceof
|
|
257
|
-
return preserveDescription(schema,
|
|
330
|
+
if (schema instanceof z3.ZodIntersection) {
|
|
331
|
+
return preserveDescription(schema, z3.intersection(flattenUnionsDeep(schema.def.left), flattenUnionsDeep(schema.def.right)));
|
|
258
332
|
}
|
|
259
333
|
return schema;
|
|
260
334
|
}
|
|
@@ -262,31 +336,6 @@ function flattenUnionsDeep(schema) {
|
|
|
262
336
|
// src/tools/mount.ts
|
|
263
337
|
import { z as z4 } from "zod";
|
|
264
338
|
|
|
265
|
-
// src/tools/schema.ts
|
|
266
|
-
import { z as z3 } from "zod";
|
|
267
|
-
function objectShapeKeys(schema) {
|
|
268
|
-
return schema instanceof z3.ZodObject ? Object.keys(schema.shape) : [];
|
|
269
|
-
}
|
|
270
|
-
function mergeSchemas(paramsSchema, inputSchema) {
|
|
271
|
-
if (paramsSchema && !(paramsSchema instanceof z3.ZodObject)) {
|
|
272
|
-
throw new Error("Tool params schema must be a z.object()");
|
|
273
|
-
}
|
|
274
|
-
const paramsObject = paramsSchema instanceof z3.ZodObject ? paramsSchema : undefined;
|
|
275
|
-
if (!inputSchema) {
|
|
276
|
-
return paramsObject ?? z3.object({});
|
|
277
|
-
}
|
|
278
|
-
if (inputSchema instanceof z3.ZodObject) {
|
|
279
|
-
if (paramsObject) {
|
|
280
|
-
const conflicts = Object.keys(paramsObject.shape).filter((key) => (key in inputSchema.shape));
|
|
281
|
-
if (conflicts.length > 0) {
|
|
282
|
-
throw new Error(`Schema merge conflict: ${conflicts.join(", ")} appear in both params and input`);
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
return z3.object({ ...paramsObject?.shape ?? {}, ...inputSchema.shape });
|
|
286
|
-
}
|
|
287
|
-
return paramsObject ? z3.intersection(paramsObject, inputSchema) : inputSchema;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
339
|
// src/tools/execute.ts
|
|
291
340
|
function toolResultFromError(err) {
|
|
292
341
|
const appErr = normalizeError(err);
|
|
@@ -421,7 +470,7 @@ function applyExtend(base, extra) {
|
|
|
421
470
|
if (conflicts.length > 0) {
|
|
422
471
|
throw new Error(`Tool extend conflict: ${conflicts.join(", ")} already declared by the contract`);
|
|
423
472
|
}
|
|
424
|
-
return
|
|
473
|
+
return rebuildObject(base, { ...extra, ...base.shape });
|
|
425
474
|
}
|
|
426
475
|
return z4.intersection(z4.object(extra), base);
|
|
427
476
|
}
|
package/dist/tools/coerce.d.ts
CHANGED
|
@@ -6,7 +6,8 @@ import { z } from 'zod';
|
|
|
6
6
|
* Operates recursively against the schema (object fields, array items, and the
|
|
7
7
|
* matching variant of a discriminated union) so a stringified value at any depth
|
|
8
8
|
* is repaired, not just a top-level field. The transform touches the **arguments**
|
|
9
|
-
* only —
|
|
9
|
+
* only — it never rebuilds a schema, so it cannot alter what an object does with
|
|
10
|
+
* an undeclared key (→ ADR 0034).
|
|
10
11
|
*/
|
|
11
12
|
export declare function coerceJsonArgs(args: Record<string, unknown>, schema: z.ZodType | undefined): Record<string, unknown>;
|
|
12
13
|
//# sourceMappingURL=coerce.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coerce.d.ts","sourceRoot":"","sources":["../../src/tools/coerce.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAoFxB
|
|
1
|
+
{"version":3,"file":"coerce.d.ts","sourceRoot":"","sources":["../../src/tools/coerce.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAoFxB;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,CAAC,CAAC,OAAO,GAAG,SAAS,GAC5B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAGzB"}
|
package/dist/tools/flatten.d.ts
CHANGED
|
@@ -18,10 +18,18 @@ import { z } from 'zod';
|
|
|
18
18
|
* 0033) **and** a superset of the original union, so a model can always produce a
|
|
19
19
|
* value that passes both the transport SDK and validation.
|
|
20
20
|
*
|
|
21
|
-
* **
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
21
|
+
* **Key policy is merged, not dropped.** The flat object stands in for every
|
|
22
|
+
* variant, so it takes the policy that cannot remove what any variant would have
|
|
23
|
+
* kept: every variant `.strict()` → strict (sound, because the flat shape is the
|
|
24
|
+
* union of all variant keys); any variant with a catchall → loose; otherwise
|
|
25
|
+
* plain. A *typed* catchall is never copied onto the flat object — it would
|
|
26
|
+
* reject a sibling variant's differently-typed extra key.
|
|
27
|
+
*
|
|
28
|
+
* **Still lossy:** per-variant strictness (a key legal in variant A and illegal
|
|
29
|
+
* in B) is unrepresentable in one flat object, as are object-level refinements.
|
|
30
|
+
* Those stay enforced only by the original union in `executeToolMethod`. What is
|
|
31
|
+
* *not* lossy any more is deletion — the advertised schema can no longer drop a
|
|
32
|
+
* key the contract would have seen. → ADR 0034.
|
|
25
33
|
*/
|
|
26
34
|
export declare function flattenDiscriminatedUnion(union: z.ZodDiscriminatedUnion): z.ZodObject<z.ZodRawShape>;
|
|
27
35
|
/**
|
|
@@ -30,8 +38,10 @@ export declare function flattenDiscriminatedUnion(union: z.ZodDiscriminatedUnion
|
|
|
30
38
|
* and `optional` / `nullable` / `default` / intersection wrappers — so the
|
|
31
39
|
* advertised JSON Schema carries no `oneOf` / `anyOf` at any depth. A union that
|
|
32
40
|
* cannot be flattened (non-string discriminator, non-object variant) is left
|
|
33
|
-
* untouched rather than crashing the mount (→ ADR 0033).
|
|
34
|
-
*
|
|
41
|
+
* untouched rather than crashing the mount (→ ADR 0033).
|
|
42
|
+
*
|
|
43
|
+
* Every object is rebuilt **with its key policy** (`rebuildObject`) — the walk
|
|
44
|
+
* changes union shape, never what an object does with an undeclared key. → ADR 0034.
|
|
35
45
|
*/
|
|
36
46
|
export declare function flattenUnionsDeep(schema: z.core.$ZodType): z.ZodType;
|
|
37
47
|
//# sourceMappingURL=flatten.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flatten.d.ts","sourceRoot":"","sources":["../../src/tools/flatten.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"flatten.d.ts","sourceRoot":"","sources":["../../src/tools/flatten.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,CAAC,CAAC,qBAAqB,GAC7B,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAiD5B;AAsKD;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,OAAO,CAqDpE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../../src/tools/mount.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EACL,KAAK,WAAW,EAEhB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,UAAU,EAChB,MAAM,WAAW,CAAC;AAKnB;;;;;;;GAOG;AACH,MAAM,WAAW,UAAU,CACzB,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAElE,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;IAClC,qEAAqE;IACrE,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3F,uEAAuE;IACvE,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,KAAK,OAAO,CAAC;CAC9D;AAED,2DAA2D;AAC3D,MAAM,WAAW,aAAa;IAC5B,2CAA2C;IAC3C,MAAM,EAAE,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC7C,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,sFAAsF;IACtF,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC;IAClB,mDAAmD;IACnD,YAAY,EAAE,OAAO,CAAC;CACvB;
|
|
1
|
+
{"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../../src/tools/mount.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EACL,KAAK,WAAW,EAEhB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,UAAU,EAChB,MAAM,WAAW,CAAC;AAKnB;;;;;;;GAOG;AACH,MAAM,WAAW,UAAU,CACzB,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAElE,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;IAClC,qEAAqE;IACrE,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3F,uEAAuE;IACvE,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,KAAK,OAAO,CAAC;CAC9D;AAED,2DAA2D;AAC3D,MAAM,WAAW,aAAa;IAC5B,2CAA2C;IAC3C,MAAM,EAAE,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC7C,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,sFAAsF;IACtF,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC;IAClB,mDAAmD;IACnD,YAAY,EAAE,OAAO,CAAC;CACvB;AAyBD,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,uFAAuF;IACvF,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,UAAU,EACnB,SAAS,EAAE,SAAS,EACpB,MAAM,GAAE,kBAAuB,GAC9B,aAAa,EAAE,CAmCjB;AAED,kDAAkD;AAClD,MAAM,WAAW,gBAAgB;IAC/B,iDAAiD;IACjD,MAAM,EAAE,eAAe,CAAC;IACxB,0EAA0E;IAC1E,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,qCAAqC;IACrC,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,yEAAyE;IACzE,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,gEAAgE;IAChE,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,+EAA+E;IAC/E,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,gBAAgB,GACvB,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,CA4BhF;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE;IAAE,EAAE,EAAE,KAAK,CAAA;CAAE,CAAC,EAC1C,QAAQ,CAAC,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,WAAW,GACtB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAazB"}
|
package/dist/tools/schema.d.ts
CHANGED
|
@@ -1,6 +1,39 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
/** Keys of a Zod object schema's shape — `[]` for a non-object or absent schema. */
|
|
3
3
|
export declare function objectShapeKeys(schema?: z.ZodType): string[];
|
|
4
|
+
/**
|
|
5
|
+
* An object schema's own key policy — what it does with a key its shape does not
|
|
6
|
+
* declare. Zod stores it in `def.catchall`: `ZodNever` for `.strict()` (reject),
|
|
7
|
+
* `ZodUnknown` for `.loose()` / `.passthrough()` (keep), a concrete type for
|
|
8
|
+
* `.catchall(T)` (keep and validate), `undefined` for a plain object (strip).
|
|
9
|
+
*/
|
|
10
|
+
export type KeyPolicy = z.core.$ZodType | undefined;
|
|
11
|
+
/** The key policy of an object schema. */
|
|
12
|
+
export declare function keyPolicyOf(schema: z.ZodObject): KeyPolicy;
|
|
13
|
+
/**
|
|
14
|
+
* Rebuild an object schema with a new shape, **carrying the source object's key
|
|
15
|
+
* policy over**.
|
|
16
|
+
*
|
|
17
|
+
* Load-bearing, not cosmetic: the advertised tool schema is not
|
|
18
|
+
* advertised-only. Both transport SDKs parse the caller's arguments *with it* and
|
|
19
|
+
* hand the handler the parsed result (MCP `validateToolInput` →
|
|
20
|
+
* `parseResult.data`; the AI SDK's `doParseToolCall` → `parseResult.value`), so
|
|
21
|
+
* an object rebuilt as a bare `z.object()` silently **deletes** every key the
|
|
22
|
+
* contract schema would have rejected (`.strict()`) or kept (`.loose()` /
|
|
23
|
+
* `.catchall()`) — the caller gets a success and never learns its argument was
|
|
24
|
+
* wrong. → ADR 0034.
|
|
25
|
+
*
|
|
26
|
+
* A plain source (`undefined` policy) needs no special case: the rebuilt object
|
|
27
|
+
* strips exactly as the contract object would have.
|
|
28
|
+
*
|
|
29
|
+
* A policy JSON Schema cannot represent (`.catchall(z.date())`) degrades to
|
|
30
|
+
* `z.unknown()`: copying it verbatim would fail the mount's JSON Schema probe and
|
|
31
|
+
* take every tool down with it, while dropping it would silently delete data.
|
|
32
|
+
* Loose keeps the invariant — nothing the contract would have kept is removed.
|
|
33
|
+
*/
|
|
34
|
+
export declare function rebuildObject(source: z.ZodObject, shape: Record<string, z.core.$ZodType>): z.ZodObject;
|
|
35
|
+
/** Apply a key policy to a freshly built object, degrading what JSON Schema cannot carry. */
|
|
36
|
+
export declare function withKeyPolicy(object: z.ZodObject<z.ZodRawShape>, policy: KeyPolicy): z.ZodObject;
|
|
4
37
|
/**
|
|
5
38
|
* Merge an endpoint's `params` and `input` schemas into the single schema a
|
|
6
39
|
* tool advertises.
|
|
@@ -10,12 +43,21 @@ export declare function objectShapeKeys(schema?: z.ZodType): string[];
|
|
|
10
43
|
* - A non-object `input` (a union, a discriminated union, a refined / piped
|
|
11
44
|
* schema) is kept intact and intersected with `params` when present — the
|
|
12
45
|
* transport SDK converts it natively (a discriminated union becomes a clean
|
|
13
|
-
* `oneOf`).
|
|
46
|
+
* `oneOf`). ⚠️ Zod drops both sides' key policy when it intersects objects, so
|
|
47
|
+
* this branch still strips (MCP rejects a non-object merged schema at mount;
|
|
48
|
+
* the agent surface does not). → ADR 0034, "Not covered".
|
|
14
49
|
*
|
|
15
50
|
* The merged schema is exactly the two source schemas side by side: nothing is
|
|
16
51
|
* coerced, flattened or transformed, so the schema a tool advertises is the
|
|
17
52
|
* schema its arguments are validated against (`executeToolMethod` parses each
|
|
18
53
|
* source schema over its own slice of the args).
|
|
54
|
+
*
|
|
55
|
+
* The merged object takes the **input** schema's key policy, never the params
|
|
56
|
+
* one. `executeToolMethod` slices the flat args by the params shape's keys and
|
|
57
|
+
* routes *everything else* into the input slice, so a params catchall can never
|
|
58
|
+
* fire (its slice is built from its own shape) while an undeclared top-level key
|
|
59
|
+
* is judged by the input schema. A params-only tool returns the params object
|
|
60
|
+
* untouched, policy included.
|
|
19
61
|
*/
|
|
20
62
|
export declare function mergeSchemas(paramsSchema?: z.ZodType<unknown>, inputSchema?: z.ZodType<unknown>): z.ZodType;
|
|
21
63
|
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/tools/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/tools/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,oFAAoF;AACpF,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,GAAG,MAAM,EAAE,CAE5D;AAED;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;AAEpD,0CAA0C;AAC1C,wBAAgB,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,SAAS,GAAG,SAAS,CAE1D;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,CAAC,CAAC,SAAS,EACnB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GACrC,CAAC,CAAC,SAAS,CAEb;AAED,6FAA6F;AAC7F,wBAAgB,aAAa,CAC3B,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,EAClC,MAAM,EAAE,SAAS,GAChB,CAAC,CAAC,SAAS,CAGb;AAcD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,YAAY,CAC1B,YAAY,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EACjC,WAAW,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAC/B,CAAC,CAAC,OAAO,CA8BX"}
|
package/dist/tools.js
CHANGED
package/llms-full.txt
CHANGED
|
@@ -1303,11 +1303,23 @@ each variant's fields become optional with a `Required if <disc> = …` hint.
|
|
|
1303
1303
|
It is **deep**: unions are flattened at every depth — top level, object fields,
|
|
1304
1304
|
array items, and through `optional` / `nullable` / `default` / intersection
|
|
1305
1305
|
wrappers — so no `oneOf` survives anywhere (e.g. a `content.parts[]` that is an
|
|
1306
|
-
array of a discriminated union).
|
|
1307
|
-
schemas stay the validation schemas in `executeToolMethod`, so requests are still
|
|
1308
|
-
validated against the real union. Schemas a transform cannot safely rebuild
|
|
1306
|
+
array of a discriminated union). Schemas a transform cannot safely rebuild
|
|
1309
1307
|
(refined / piped / lazy / plain non-discriminated unions) are left as-is.
|
|
1310
1308
|
|
|
1309
|
+
The flattened form is **lossy but never destructive**. Lossy: per-variant
|
|
1310
|
+
strictness and object-level refinements are not advertised — the original schemas
|
|
1311
|
+
enforce them in `executeToolMethod`. Not destructive: every object keeps its own
|
|
1312
|
+
**key policy** (`.strict()` stays strict, `.loose()` / `.catchall()` still keep
|
|
1313
|
+
extra keys), because the advertised schema is not advertised-only — the MCP and
|
|
1314
|
+
AI SDKs parse the caller's arguments *with it* and hand the handler the parsed
|
|
1315
|
+
result. An object advertised without its policy would silently delete keys the
|
|
1316
|
+
contract would have rejected. → [ADR 0034](../decisions/0034-advertised-schema-key-policy.md).
|
|
1317
|
+
|
|
1318
|
+
A consequence worth knowing when you read logs: a `.strict()` violation is caught
|
|
1319
|
+
by the SDK **before** the tool callback runs, so it comes back as an MCP
|
|
1320
|
+
`InvalidParams` protocol error rather than a stitchkit `VALIDATION_ERROR`
|
|
1321
|
+
envelope, and `beforeToolCall` / `afterToolCall` do not fire for it.
|
|
1322
|
+
|
|
1311
1323
|
## `mountMcp`
|
|
1312
1324
|
|
|
1313
1325
|
If you already run an `McpServer` from the SDK, `mountMcp` adds contract tools
|
|
@@ -3529,7 +3541,7 @@ Advanced building blocks — the shared machinery the mounts are built on.
|
|
|
3529
3541
|
| `TransportCounts` | _type_ | per-transport counts (`{ HTTP, MCP, AGENT, CLI }`) |
|
|
3530
3542
|
| `coerceJsonArgs` | function | coerce JSON-stringified array/object tool arguments |
|
|
3531
3543
|
| `flattenDiscriminatedUnion` | function | flatten one discriminated union into a single object schema |
|
|
3532
|
-
| `flattenUnionsDeep` | function | flatten discriminated unions at every depth
|
|
3544
|
+
| `flattenUnionsDeep` | function | flatten discriminated unions at every depth — union shape only; each object keeps its own key policy (`.strict()` / `.loose()` / `.catchall()`) |
|
|
3533
3545
|
| `MountableTool` | _type_ | one contract method resolved for mounting |
|
|
3534
3546
|
| `ToolManifestEntry` | _type_ | one `buildToolManifest` row |
|
|
3535
3547
|
|
package/package.json
CHANGED