@aeye/core 0.5.4 → 0.7.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/README.md +790 -724
- package/aeye-core-prompts.md +179 -178
- package/aeye-core-schema.md +43 -16
- package/aeye-core-tools.md +179 -177
- package/aeye-core-types.md +1 -0
- package/dist/common.d.ts +30 -5
- package/dist/common.d.ts.map +1 -1
- package/dist/common.js +134 -129
- package/dist/common.js.map +1 -1
- package/dist/delivery.d.ts +39 -0
- package/dist/delivery.d.ts.map +1 -0
- package/dist/delivery.js +127 -0
- package/dist/delivery.js.map +1 -0
- package/dist/errors.d.ts +60 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +84 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/prompt.d.ts +134 -15
- package/dist/prompt.d.ts.map +1 -1
- package/dist/prompt.js +220 -164
- package/dist/prompt.js.map +1 -1
- package/dist/schema/analyze.d.ts +94 -0
- package/dist/schema/analyze.d.ts.map +1 -0
- package/dist/schema/analyze.js +221 -0
- package/dist/schema/analyze.js.map +1 -0
- package/dist/schema/any-value.d.ts +32 -0
- package/dist/schema/any-value.d.ts.map +1 -0
- package/dist/schema/any-value.js +77 -0
- package/dist/schema/any-value.js.map +1 -0
- package/dist/schema/budget.d.ts +114 -0
- package/dist/schema/budget.d.ts.map +1 -0
- package/dist/schema/budget.js +223 -0
- package/dist/schema/budget.js.map +1 -0
- package/dist/schema/check-bag.d.ts +28 -0
- package/dist/schema/check-bag.d.ts.map +1 -0
- package/dist/schema/check-bag.js +129 -0
- package/dist/schema/check-bag.js.map +1 -0
- package/dist/schema/consistency.d.ts +27 -0
- package/dist/schema/consistency.d.ts.map +1 -0
- package/dist/schema/consistency.js +110 -0
- package/dist/schema/consistency.js.map +1 -0
- package/dist/schema/cycle-breaker.d.ts +14 -0
- package/dist/schema/cycle-breaker.d.ts.map +1 -0
- package/dist/schema/cycle-breaker.js +157 -0
- package/dist/schema/cycle-breaker.js.map +1 -0
- package/dist/schema/decode.d.ts +31 -0
- package/dist/schema/decode.d.ts.map +1 -0
- package/dist/schema/decode.js +207 -0
- package/dist/schema/decode.js.map +1 -0
- package/dist/schema/descriptor.d.ts +300 -0
- package/dist/schema/descriptor.d.ts.map +1 -0
- package/dist/schema/descriptor.js +15 -0
- package/dist/schema/descriptor.js.map +1 -0
- package/dist/schema/dialects/anthropic.d.ts +34 -0
- package/dist/schema/dialects/anthropic.d.ts.map +1 -0
- package/dist/schema/dialects/anthropic.js +77 -0
- package/dist/schema/dialects/anthropic.js.map +1 -0
- package/dist/schema/dialects/google.d.ts +47 -0
- package/dist/schema/dialects/google.d.ts.map +1 -0
- package/dist/schema/dialects/google.js +91 -0
- package/dist/schema/dialects/google.js.map +1 -0
- package/dist/schema/dialects/lenient.d.ts +4 -0
- package/dist/schema/dialects/lenient.d.ts.map +1 -0
- package/dist/schema/dialects/lenient.js +26 -0
- package/dist/schema/dialects/lenient.js.map +1 -0
- package/dist/schema/dialects/openai.d.ts +40 -0
- package/dist/schema/dialects/openai.d.ts.map +1 -0
- package/dist/schema/dialects/openai.js +81 -0
- package/dist/schema/dialects/openai.js.map +1 -0
- package/dist/schema/dialects/xai.d.ts +23 -0
- package/dist/schema/dialects/xai.d.ts.map +1 -0
- package/dist/schema/dialects/xai.js +53 -0
- package/dist/schema/dialects/xai.js.map +1 -0
- package/dist/schema/enum-values.d.ts +44 -0
- package/dist/schema/enum-values.d.ts.map +1 -0
- package/dist/schema/enum-values.js +56 -0
- package/dist/schema/enum-values.js.map +1 -0
- package/dist/schema/expressible.d.ts +59 -0
- package/dist/schema/expressible.d.ts.map +1 -0
- package/dist/schema/expressible.js +161 -0
- package/dist/schema/expressible.js.map +1 -0
- package/dist/schema/index.d.ts +20 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +20 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/json-schema.d.ts +64 -0
- package/dist/schema/json-schema.d.ts.map +1 -0
- package/dist/schema/json-schema.js +2 -0
- package/dist/schema/json-schema.js.map +1 -0
- package/dist/schema/registry.d.ts +73 -0
- package/dist/schema/registry.d.ts.map +1 -0
- package/dist/schema/registry.js +135 -0
- package/dist/schema/registry.js.map +1 -0
- package/dist/schema/strictify.d.ts +19 -0
- package/dist/schema/strictify.d.ts.map +1 -0
- package/dist/schema/strictify.js +237 -0
- package/dist/schema/strictify.js.map +1 -0
- package/dist/schema/to-json-schema.d.ts +29 -0
- package/dist/schema/to-json-schema.d.ts.map +1 -0
- package/dist/schema/to-json-schema.js +692 -0
- package/dist/schema/to-json-schema.js.map +1 -0
- package/dist/schema/walk-key.d.ts +24 -0
- package/dist/schema/walk-key.d.ts.map +1 -0
- package/dist/schema/walk-key.js +33 -0
- package/dist/schema/walk-key.js.map +1 -0
- package/dist/to.js +1 -1
- package/dist/to.js.map +1 -1
- package/dist/tool.d.ts +38 -4
- package/dist/tool.d.ts.map +1 -1
- package/dist/tool.js +52 -8
- package/dist/tool.js.map +1 -1
- package/dist/types.d.ts +265 -8
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +4 -1
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
- package/dist/schema.d.ts +0 -840
- package/dist/schema.d.ts.map +0 -1
- package/dist/schema.js +0 -2478
- package/dist/schema.js.map +0 -1
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { DescriptorFamily } from './descriptor';
|
|
2
|
+
/**
|
|
3
|
+
* Format specification for JSON Schema generation
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Family name for `ToJSONSchemaOptions.format`. Alias of `DescriptorFamily`
|
|
7
|
+
* — the three built-in dialects (`'openai'`, `'anthropic'`, `'google'`)
|
|
8
|
+
* plus any string registered via `registerDescriptor`.
|
|
9
|
+
*
|
|
10
|
+
* @deprecated Prefer `DescriptorFamily`. Both refer to the same widened type.
|
|
11
|
+
*/
|
|
12
|
+
export type JSONSchemaFormat = DescriptorFamily;
|
|
13
|
+
/**
|
|
14
|
+
* Options for toJSONSchema
|
|
15
|
+
*/
|
|
16
|
+
export interface ToJSONSchemaOptions {
|
|
17
|
+
/**
|
|
18
|
+
* Whether to use strict mode (all fields required, additionalProperties: false)
|
|
19
|
+
*/
|
|
20
|
+
strict: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* The target format for the JSON Schema. Resolves to a named FormatDescriptor.
|
|
23
|
+
* Built-in (`'openai'` / `'anthropic'` / `'google'`) or any string
|
|
24
|
+
* registered via `registerDescriptor`.
|
|
25
|
+
*/
|
|
26
|
+
format?: DescriptorFamily;
|
|
27
|
+
}
|
|
28
|
+
export type JSONSchemaType = 'string' | 'number' | 'boolean' | 'array' | 'object' | 'null' | 'integer';
|
|
29
|
+
/**
|
|
30
|
+
* JSON Schema type definition
|
|
31
|
+
*/
|
|
32
|
+
export interface JSONSchema {
|
|
33
|
+
type?: JSONSchemaType | JSONSchemaType[];
|
|
34
|
+
properties?: Record<string, JSONSchema>;
|
|
35
|
+
items?: JSONSchema;
|
|
36
|
+
prefixItems?: JSONSchema[];
|
|
37
|
+
required?: string[];
|
|
38
|
+
additionalProperties?: boolean | JSONSchema;
|
|
39
|
+
propertyNames?: JSONSchema;
|
|
40
|
+
enum?: any[];
|
|
41
|
+
anyOf?: JSONSchema[];
|
|
42
|
+
allOf?: JSONSchema[];
|
|
43
|
+
additionalItems?: boolean | JSONSchema;
|
|
44
|
+
not?: JSONSchema;
|
|
45
|
+
$ref?: string;
|
|
46
|
+
description?: string;
|
|
47
|
+
default?: any;
|
|
48
|
+
pattern?: string;
|
|
49
|
+
format?: string;
|
|
50
|
+
minimum?: number;
|
|
51
|
+
maximum?: number;
|
|
52
|
+
exclusiveMinimum?: number;
|
|
53
|
+
exclusiveMaximum?: number;
|
|
54
|
+
multipleOf?: number;
|
|
55
|
+
minItems?: number;
|
|
56
|
+
maxItems?: number;
|
|
57
|
+
const?: any;
|
|
58
|
+
title?: string;
|
|
59
|
+
$defs?: Record<string, JSONSchema>;
|
|
60
|
+
/** Gemini-specific: deterministic property emission order for strict mode. */
|
|
61
|
+
propertyOrdering?: string[];
|
|
62
|
+
[metadata: string]: unknown;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=json-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-schema.d.ts","sourceRoot":"","sources":["../../src/schema/json-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD;;GAEG;AACH;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,GAAG,gBAAgB,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC3B;AAED,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;AAEvG;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,cAAc,GAAG,cAAc,EAAE,CAAC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACxC,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,oBAAoB,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAC5C,aAAa,CAAC,EAAE,UAAU,CAAC;IAC3B,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IACb,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IACvC,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnC,8EAA8E;IAC9E,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;CAC7B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-schema.js","sourceRoot":"","sources":["../../src/schema/json-schema.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { DescriptorFamily, FormatDescriptor } from './descriptor';
|
|
2
|
+
import type { ToJSONSchemaOptions } from './json-schema';
|
|
3
|
+
/**
|
|
4
|
+
* Register a custom `FormatDescriptor` so it can be looked up by `id` or
|
|
5
|
+
* by `(family, strict)`. Useful for adding support for a new provider
|
|
6
|
+
* dialect or for registering a tweaked variant of an existing family.
|
|
7
|
+
*
|
|
8
|
+
* The descriptor's `id` and `family` become the lookup keys. If a
|
|
9
|
+
* descriptor with the same id is already registered, the new one
|
|
10
|
+
* replaces it. The family slot tracks one strict and one lenient
|
|
11
|
+
* variant; registering a third variant overwrites the matching slot.
|
|
12
|
+
*
|
|
13
|
+
* Built-in descriptors (`OPENAI_STRICT`, `LENIENT`, etc.) are seeded at
|
|
14
|
+
* module load — you don't need to register them manually. They CAN be
|
|
15
|
+
* overridden by registering a same-id descriptor afterwards, but doing
|
|
16
|
+
* so is generally a sign that you should pick a different id.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { registerDescriptor, OPENAI_STRICT } from '@aeye/core';
|
|
21
|
+
*
|
|
22
|
+
* // A tighter OpenAI-flavored descriptor: same wire shape but with
|
|
23
|
+
* // pattern support disabled (some downstream tools choke on regex).
|
|
24
|
+
* registerDescriptor({
|
|
25
|
+
* ...OPENAI_STRICT,
|
|
26
|
+
* id: 'openai-no-regex',
|
|
27
|
+
* family: 'openai-no-regex',
|
|
28
|
+
* allowPattern: false,
|
|
29
|
+
* allowMultiplePatterns: false,
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* // Now resolvable:
|
|
33
|
+
* getDescriptor('openai-no-regex', true); // → the registered descriptor
|
|
34
|
+
* getDescriptorById('openai-no-regex'); // → same
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* A descriptor that contradicts itself (see `checkDescriptorConsistency`) is
|
|
38
|
+
* still registered — the caller may know something we don't — but each
|
|
39
|
+
* problem is warned once at registration, because the alternative is finding
|
|
40
|
+
* out from a provider's HTTP 400.
|
|
41
|
+
*/
|
|
42
|
+
export declare function registerDescriptor(descriptor: FormatDescriptor): void;
|
|
43
|
+
/**
|
|
44
|
+
* Resolve a descriptor by family + strictness.
|
|
45
|
+
*
|
|
46
|
+
* Built-in families (`'openai'`, `'anthropic'`, `'google'`) always
|
|
47
|
+
* resolve. Custom families registered via `registerDescriptor` resolve
|
|
48
|
+
* once they're registered. Unknown families fall back to `LENIENT`
|
|
49
|
+
* (safe default — strict mode silently degrades for unrecognized models).
|
|
50
|
+
*
|
|
51
|
+
* @param family - provider family (built-in or registered)
|
|
52
|
+
* @param strict - whether the strict variant is wanted
|
|
53
|
+
*/
|
|
54
|
+
export declare function getDescriptor(family: DescriptorFamily, strict: boolean): FormatDescriptor;
|
|
55
|
+
/**
|
|
56
|
+
* Look up a descriptor by id. Returns LENIENT for unknown ids (safe default).
|
|
57
|
+
* Custom descriptors registered via `registerDescriptor` are reachable here
|
|
58
|
+
* by their `id`.
|
|
59
|
+
*/
|
|
60
|
+
export declare function getDescriptorById(id: string | undefined): FormatDescriptor;
|
|
61
|
+
/**
|
|
62
|
+
* True if `family` has at least one registered descriptor (strict or
|
|
63
|
+
* lenient). Used by `@aeye/ai`'s `resolveStrictFormat` fallback chain to
|
|
64
|
+
* decide whether a model id prefix or provider name is a recognized
|
|
65
|
+
* dialect.
|
|
66
|
+
*/
|
|
67
|
+
export declare function hasDescriptorFamily(family: string | undefined): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Resolve descriptor from various input shapes (boolean, options object, or descriptor).
|
|
70
|
+
* Used by `toJSONSchema` to support its overloaded signature.
|
|
71
|
+
*/
|
|
72
|
+
export declare function resolveDescriptor(input: FormatDescriptor | ToJSONSchemaOptions | boolean | undefined): FormatDescriptor;
|
|
73
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/schema/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAuCzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,gBAAgB,GAAG,IAAI,CAKrE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,OAAO,GAAG,gBAAgB,CAOzF;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,gBAAgB,CAG1E;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAGvE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,gBAAgB,GAAG,mBAAmB,GAAG,OAAO,GAAG,SAAS,GAClE,gBAAgB,CAMlB"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { checkDescriptorConsistency } from './consistency';
|
|
2
|
+
import { LENIENT } from './dialects/lenient';
|
|
3
|
+
import { OPENAI_STRICT, OPENAI_NON_STRICT } from './dialects/openai';
|
|
4
|
+
import { ANTHROPIC_STRICT, ANTHROPIC_NON_STRICT } from './dialects/anthropic';
|
|
5
|
+
import { GOOGLE_STRICT, GOOGLE_NON_STRICT } from './dialects/google';
|
|
6
|
+
import { XAI_STRICT, XAI_NON_STRICT } from './dialects/xai';
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// Descriptor registry — mutable lookup tables for built-in + user-registered
|
|
9
|
+
// descriptors. `registerDescriptor` adds to both maps; `getDescriptor` /
|
|
10
|
+
// `getDescriptorById` consult them on every lookup so newly-registered
|
|
11
|
+
// descriptors are immediately addressable by family or id.
|
|
12
|
+
// ============================================================================
|
|
13
|
+
const DESCRIPTORS_BY_ID = new Map();
|
|
14
|
+
// Keyed by family name. Each family slot holds its strict and lenient variants.
|
|
15
|
+
// `'lenient'` always points to `LENIENT` for both keys.
|
|
16
|
+
const DESCRIPTORS_BY_FAMILY = new Map();
|
|
17
|
+
function indexDescriptor(d) {
|
|
18
|
+
DESCRIPTORS_BY_ID.set(d.id, d);
|
|
19
|
+
const slot = DESCRIPTORS_BY_FAMILY.get(d.family) ?? {};
|
|
20
|
+
if (d.strict)
|
|
21
|
+
slot.strict = d;
|
|
22
|
+
else
|
|
23
|
+
slot.lenient = d;
|
|
24
|
+
DESCRIPTORS_BY_FAMILY.set(d.family, slot);
|
|
25
|
+
}
|
|
26
|
+
// Seed the registry with built-ins.
|
|
27
|
+
for (const d of [
|
|
28
|
+
LENIENT,
|
|
29
|
+
OPENAI_STRICT, OPENAI_NON_STRICT,
|
|
30
|
+
ANTHROPIC_STRICT, ANTHROPIC_NON_STRICT,
|
|
31
|
+
GOOGLE_STRICT, GOOGLE_NON_STRICT,
|
|
32
|
+
XAI_STRICT, XAI_NON_STRICT,
|
|
33
|
+
]) {
|
|
34
|
+
indexDescriptor(d);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Register a custom `FormatDescriptor` so it can be looked up by `id` or
|
|
38
|
+
* by `(family, strict)`. Useful for adding support for a new provider
|
|
39
|
+
* dialect or for registering a tweaked variant of an existing family.
|
|
40
|
+
*
|
|
41
|
+
* The descriptor's `id` and `family` become the lookup keys. If a
|
|
42
|
+
* descriptor with the same id is already registered, the new one
|
|
43
|
+
* replaces it. The family slot tracks one strict and one lenient
|
|
44
|
+
* variant; registering a third variant overwrites the matching slot.
|
|
45
|
+
*
|
|
46
|
+
* Built-in descriptors (`OPENAI_STRICT`, `LENIENT`, etc.) are seeded at
|
|
47
|
+
* module load — you don't need to register them manually. They CAN be
|
|
48
|
+
* overridden by registering a same-id descriptor afterwards, but doing
|
|
49
|
+
* so is generally a sign that you should pick a different id.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* import { registerDescriptor, OPENAI_STRICT } from '@aeye/core';
|
|
54
|
+
*
|
|
55
|
+
* // A tighter OpenAI-flavored descriptor: same wire shape but with
|
|
56
|
+
* // pattern support disabled (some downstream tools choke on regex).
|
|
57
|
+
* registerDescriptor({
|
|
58
|
+
* ...OPENAI_STRICT,
|
|
59
|
+
* id: 'openai-no-regex',
|
|
60
|
+
* family: 'openai-no-regex',
|
|
61
|
+
* allowPattern: false,
|
|
62
|
+
* allowMultiplePatterns: false,
|
|
63
|
+
* });
|
|
64
|
+
*
|
|
65
|
+
* // Now resolvable:
|
|
66
|
+
* getDescriptor('openai-no-regex', true); // → the registered descriptor
|
|
67
|
+
* getDescriptorById('openai-no-regex'); // → same
|
|
68
|
+
* ```
|
|
69
|
+
*
|
|
70
|
+
* A descriptor that contradicts itself (see `checkDescriptorConsistency`) is
|
|
71
|
+
* still registered — the caller may know something we don't — but each
|
|
72
|
+
* problem is warned once at registration, because the alternative is finding
|
|
73
|
+
* out from a provider's HTTP 400.
|
|
74
|
+
*/
|
|
75
|
+
export function registerDescriptor(descriptor) {
|
|
76
|
+
for (const problem of checkDescriptorConsistency(descriptor)) {
|
|
77
|
+
console.warn(`FormatDescriptor '${descriptor.id}' is inconsistent: ${problem}`);
|
|
78
|
+
}
|
|
79
|
+
indexDescriptor(descriptor);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Resolve a descriptor by family + strictness.
|
|
83
|
+
*
|
|
84
|
+
* Built-in families (`'openai'`, `'anthropic'`, `'google'`) always
|
|
85
|
+
* resolve. Custom families registered via `registerDescriptor` resolve
|
|
86
|
+
* once they're registered. Unknown families fall back to `LENIENT`
|
|
87
|
+
* (safe default — strict mode silently degrades for unrecognized models).
|
|
88
|
+
*
|
|
89
|
+
* @param family - provider family (built-in or registered)
|
|
90
|
+
* @param strict - whether the strict variant is wanted
|
|
91
|
+
*/
|
|
92
|
+
export function getDescriptor(family, strict) {
|
|
93
|
+
if (!strict) {
|
|
94
|
+
const slot = DESCRIPTORS_BY_FAMILY.get(family);
|
|
95
|
+
return slot?.lenient ?? LENIENT;
|
|
96
|
+
}
|
|
97
|
+
const slot = DESCRIPTORS_BY_FAMILY.get(family);
|
|
98
|
+
return slot?.strict ?? LENIENT;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Look up a descriptor by id. Returns LENIENT for unknown ids (safe default).
|
|
102
|
+
* Custom descriptors registered via `registerDescriptor` are reachable here
|
|
103
|
+
* by their `id`.
|
|
104
|
+
*/
|
|
105
|
+
export function getDescriptorById(id) {
|
|
106
|
+
if (!id)
|
|
107
|
+
return LENIENT;
|
|
108
|
+
return DESCRIPTORS_BY_ID.get(id) ?? LENIENT;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* True if `family` has at least one registered descriptor (strict or
|
|
112
|
+
* lenient). Used by `@aeye/ai`'s `resolveStrictFormat` fallback chain to
|
|
113
|
+
* decide whether a model id prefix or provider name is a recognized
|
|
114
|
+
* dialect.
|
|
115
|
+
*/
|
|
116
|
+
export function hasDescriptorFamily(family) {
|
|
117
|
+
if (family === undefined)
|
|
118
|
+
return false;
|
|
119
|
+
return DESCRIPTORS_BY_FAMILY.has(family);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Resolve descriptor from various input shapes (boolean, options object, or descriptor).
|
|
123
|
+
* Used by `toJSONSchema` to support its overloaded signature.
|
|
124
|
+
*/
|
|
125
|
+
export function resolveDescriptor(input) {
|
|
126
|
+
if (input === undefined)
|
|
127
|
+
return OPENAI_STRICT;
|
|
128
|
+
if (typeof input === 'boolean')
|
|
129
|
+
return input ? OPENAI_STRICT : LENIENT;
|
|
130
|
+
if ('id' in input && 'family' in input)
|
|
131
|
+
return input;
|
|
132
|
+
const opts = input;
|
|
133
|
+
return getDescriptor(opts.format ?? 'openai', opts.strict);
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/schema/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import z from 'zod';
|
|
2
|
+
import type { FormatDescriptor } from './descriptor';
|
|
3
|
+
/**
|
|
4
|
+
* Recursively transforms a Zod schema to a target dialect.
|
|
5
|
+
*
|
|
6
|
+
* For LENIENT, returns the input schema unchanged (no rewrites). For strict
|
|
7
|
+
* descriptors, installs preprocesses that accept the dialect's wire shape
|
|
8
|
+
* (e.g. array-of-pairs records, numeric-key tuple objects) and normalize them
|
|
9
|
+
* back to the natural Zod shape before validation.
|
|
10
|
+
*
|
|
11
|
+
* Repeated calls with the same `(schema, descriptor)` return the cached
|
|
12
|
+
* transformed schema. Different descriptors share the same outer entry but
|
|
13
|
+
* map to different inner values — bounded by the small descriptor count.
|
|
14
|
+
*
|
|
15
|
+
* @param schema - input Zod schema
|
|
16
|
+
* @param descriptor - target dialect descriptor (defaults to OPENAI_STRICT)
|
|
17
|
+
*/
|
|
18
|
+
export declare function strictify<S extends z.ZodType>(schema: S, descriptor?: FormatDescriptor): S;
|
|
19
|
+
//# sourceMappingURL=strictify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strictify.d.ts","sourceRoot":"","sources":["../../src/schema/strictify.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAC;AACpB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAcrD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,UAAU,GAAE,gBAAgC,GAAG,CAAC,CAezG"}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import z from 'zod';
|
|
2
|
+
import { LENIENT } from './dialects/lenient';
|
|
3
|
+
import { OPENAI_STRICT } from './dialects/openai';
|
|
4
|
+
/**
|
|
5
|
+
* Module-scope cache. Per-source-schema entry survives only as long as the
|
|
6
|
+
* source schema does — the WeakMap entry is gc'd with it, so all per-format
|
|
7
|
+
* strictified clones go with it. The inner Map is keyed by descriptor.id
|
|
8
|
+
* (small bounded set) so it cannot grow unboundedly.
|
|
9
|
+
*/
|
|
10
|
+
const strictifyCache = new WeakMap();
|
|
11
|
+
/**
|
|
12
|
+
* Recursively transforms a Zod schema to a target dialect.
|
|
13
|
+
*
|
|
14
|
+
* For LENIENT, returns the input schema unchanged (no rewrites). For strict
|
|
15
|
+
* descriptors, installs preprocesses that accept the dialect's wire shape
|
|
16
|
+
* (e.g. array-of-pairs records, numeric-key tuple objects) and normalize them
|
|
17
|
+
* back to the natural Zod shape before validation.
|
|
18
|
+
*
|
|
19
|
+
* Repeated calls with the same `(schema, descriptor)` return the cached
|
|
20
|
+
* transformed schema. Different descriptors share the same outer entry but
|
|
21
|
+
* map to different inner values — bounded by the small descriptor count.
|
|
22
|
+
*
|
|
23
|
+
* @param schema - input Zod schema
|
|
24
|
+
* @param descriptor - target dialect descriptor (defaults to OPENAI_STRICT)
|
|
25
|
+
*/
|
|
26
|
+
export function strictify(schema, descriptor = OPENAI_STRICT) {
|
|
27
|
+
// LENIENT is a no-op: same reference, no cache entry needed.
|
|
28
|
+
if (descriptor.id === LENIENT.id)
|
|
29
|
+
return schema;
|
|
30
|
+
let perSchema = strictifyCache.get(schema);
|
|
31
|
+
if (!perSchema) {
|
|
32
|
+
perSchema = new Map();
|
|
33
|
+
strictifyCache.set(schema, perSchema);
|
|
34
|
+
}
|
|
35
|
+
const cached = perSchema.get(descriptor.id);
|
|
36
|
+
if (cached)
|
|
37
|
+
return cached;
|
|
38
|
+
const result = strictifyWithDescriptor(schema, descriptor);
|
|
39
|
+
perSchema.set(descriptor.id, result);
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
function strictifyWithDescriptor(schema, descriptor) {
|
|
43
|
+
// Per-call cycle map. Same scheme as before: cache lazy-thunks for in-flight
|
|
44
|
+
// schemas so recursive references emit a `z.lazy(() => result)` rather than
|
|
45
|
+
// recursing forever.
|
|
46
|
+
const map = new Map();
|
|
47
|
+
const transform = (s) => {
|
|
48
|
+
const cached = map.get(s);
|
|
49
|
+
if (cached) {
|
|
50
|
+
if (typeof cached === 'function') {
|
|
51
|
+
return z.lazy(cached);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
return cached;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
let result;
|
|
58
|
+
map.set(s, () => result);
|
|
59
|
+
result = strictifySimple(s, transform, descriptor);
|
|
60
|
+
map.set(s, result);
|
|
61
|
+
return result;
|
|
62
|
+
};
|
|
63
|
+
return transform(schema);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Transfer description and metadata from source Zod schema to target Zod schema.
|
|
67
|
+
*
|
|
68
|
+
* A declared `id` moves to `aid`: zod's global registry refuses a second schema
|
|
69
|
+
* with the same `id` ("ID X already exists in the registry"), and the clone is
|
|
70
|
+
* that second schema. `aid` names the same definition everywhere an `id` does.
|
|
71
|
+
*/
|
|
72
|
+
function transferMetadata(target, source) {
|
|
73
|
+
if (source.description) {
|
|
74
|
+
target = target.describe(source.description);
|
|
75
|
+
}
|
|
76
|
+
const meta = source.meta();
|
|
77
|
+
if (meta) {
|
|
78
|
+
const { id, ...rest } = meta;
|
|
79
|
+
target = target.meta(id === undefined ? meta : { ...rest, aid: rest.aid ?? id });
|
|
80
|
+
}
|
|
81
|
+
return target;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Per-node strictify dispatch. Each branch consults the descriptor to decide
|
|
85
|
+
* whether to install the dialect-specific preprocess.
|
|
86
|
+
*/
|
|
87
|
+
function strictifySimple(schema, transform, descriptor) {
|
|
88
|
+
// Handle ZodOptional
|
|
89
|
+
if (schema instanceof z.ZodOptional) {
|
|
90
|
+
const innerSchema = schema.unwrap();
|
|
91
|
+
const transformed = transform(innerSchema);
|
|
92
|
+
// Only install the null→undefined preprocess for dialects that rewrite
|
|
93
|
+
// optional to nullable on the wire (OpenAI strict). For other dialects,
|
|
94
|
+
// optional stays optional and the preprocess is unnecessary.
|
|
95
|
+
if (!descriptor.optionalAsNullable) {
|
|
96
|
+
return transferMetadata(transformed.optional(), schema);
|
|
97
|
+
}
|
|
98
|
+
const isNullable = innerSchema instanceof z.ZodNullable;
|
|
99
|
+
return transferMetadata(z.preprocess((val) => (!isNullable && val === null) ? undefined : val, transformed.optional()), schema);
|
|
100
|
+
}
|
|
101
|
+
// Handle ZodObject
|
|
102
|
+
if (schema instanceof z.ZodObject) {
|
|
103
|
+
const transformedShape = {};
|
|
104
|
+
for (const key in schema.shape) {
|
|
105
|
+
transformedShape[key] = transform(schema.shape[key]);
|
|
106
|
+
}
|
|
107
|
+
// Carry the catchall through. `z.object(shape)` alone DROPS it, so every
|
|
108
|
+
// `.catchall(...)` / `z.looseObject(...)` / `z.strictObject(...)` schema
|
|
109
|
+
// silently lost its open (or explicitly closed) tail the moment a strict
|
|
110
|
+
// dialect was selected — while `toJSONSchema` kept emitting that same
|
|
111
|
+
// catchall as `additionalProperties` and `analyzeSchema` kept walking it.
|
|
112
|
+
// strictify and the emitter were describing different schemas, and the
|
|
113
|
+
// mismatch surfaced only as keys stripped at validation time.
|
|
114
|
+
//
|
|
115
|
+
// Dialects that close objects (`objectClosedByDefault`: OpenAI/Anthropic
|
|
116
|
+
// strict) still emit `additionalProperties: false` regardless, so no wire
|
|
117
|
+
// shape changes for them — this restores the open tail exactly where the
|
|
118
|
+
// dialect permits one (Google).
|
|
119
|
+
const catchall = schema.def.catchall;
|
|
120
|
+
return transferMetadata(catchall
|
|
121
|
+
? z.object(transformedShape).catchall(transform(catchall))
|
|
122
|
+
: z.object(transformedShape), schema);
|
|
123
|
+
}
|
|
124
|
+
// Handle ZodCodec
|
|
125
|
+
if (schema instanceof z.ZodCodec) {
|
|
126
|
+
return transferMetadata(z.codec(transform(schema.def.in), transform(schema.def.out), {
|
|
127
|
+
decode: schema.def.transform,
|
|
128
|
+
encode: schema.def.reverseTransform,
|
|
129
|
+
}), schema);
|
|
130
|
+
}
|
|
131
|
+
// Handle ZodPipe
|
|
132
|
+
if (schema instanceof z.ZodPipe) {
|
|
133
|
+
return transferMetadata(z.pipe(transform(schema.def.in), transform(schema.def.out)), schema);
|
|
134
|
+
}
|
|
135
|
+
// Handle ZodNullable
|
|
136
|
+
if (schema instanceof z.ZodNullable) {
|
|
137
|
+
return transferMetadata(transform(schema.unwrap()).nullable(), schema);
|
|
138
|
+
}
|
|
139
|
+
// Handle ZodArray
|
|
140
|
+
if (schema instanceof z.ZodArray) {
|
|
141
|
+
return transferMetadata(z.array(transform(schema.element)), schema);
|
|
142
|
+
}
|
|
143
|
+
// Handle ZodRecord
|
|
144
|
+
// Strict-mode JSON Schema represents records as `array of {key, value}` —
|
|
145
|
+
// OpenAI's structured outputs has no native pattern for open records, so
|
|
146
|
+
// we rewrite. Previously this used `z.codec(arrayIn, recordOut, decode)`,
|
|
147
|
+
// but z.codec proved fragile inside recursive lazy unions: the inner
|
|
148
|
+
// codec's transform doesn't always run when validation traverses a
|
|
149
|
+
// sibling branch, leaving the data in array form when later code expects
|
|
150
|
+
// record form (and vice-versa) — surfacing as "expected array, received
|
|
151
|
+
// object" union failures.
|
|
152
|
+
//
|
|
153
|
+
// `z.preprocess` is more robust here: it normalizes the input to record
|
|
154
|
+
// shape BEFORE the record schema sees it. Either array-of-pairs (from a
|
|
155
|
+
// strict-mode model) or already-a-record (when the schema is reused
|
|
156
|
+
// outside strict context) is accepted; both arrive at the record schema
|
|
157
|
+
// as a record.
|
|
158
|
+
//
|
|
159
|
+
// Only installed when the descriptor wants the array-of-pairs encoding.
|
|
160
|
+
if (schema instanceof z.ZodRecord) {
|
|
161
|
+
const keyTransformed = schema.keyType ? transform(schema.keyType) : z.string();
|
|
162
|
+
const valueTransformed = transform(schema.valueType);
|
|
163
|
+
if (descriptor.recordEncoding !== 'array-of-pairs') {
|
|
164
|
+
return transferMetadata(z.record(keyTransformed, valueTransformed), schema);
|
|
165
|
+
}
|
|
166
|
+
return transferMetadata(z.preprocess((val) => {
|
|
167
|
+
if (Array.isArray(val)) {
|
|
168
|
+
const record = {};
|
|
169
|
+
for (const entry of val) {
|
|
170
|
+
if (entry && typeof entry === 'object' && 'key' in entry && 'value' in entry) {
|
|
171
|
+
record[entry.key] = entry.value;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return record;
|
|
175
|
+
}
|
|
176
|
+
return val;
|
|
177
|
+
}, z.record(keyTransformed, valueTransformed)), schema);
|
|
178
|
+
}
|
|
179
|
+
// Handle ZodUnion
|
|
180
|
+
if (schema instanceof z.ZodUnion) {
|
|
181
|
+
return transferMetadata(z.union(schema.options.map(transform)), schema);
|
|
182
|
+
}
|
|
183
|
+
// Handle ZodDiscriminatedUnion
|
|
184
|
+
if (schema instanceof z.ZodDiscriminatedUnion) {
|
|
185
|
+
return transferMetadata(z.discriminatedUnion(schema.def.discriminator, schema.options.map(transform)), schema);
|
|
186
|
+
}
|
|
187
|
+
// Handle ZodIntersection
|
|
188
|
+
if (schema instanceof z.ZodIntersection) {
|
|
189
|
+
return transferMetadata(z.intersection(transform(schema.def.left), transform(schema.def.right)), schema);
|
|
190
|
+
}
|
|
191
|
+
// Handle ZodTuple
|
|
192
|
+
// Strict-mode JSON Schema represents tuples as an object with numeric
|
|
193
|
+
// string keys (`{"0": <T0>, "1": <T1>, ...}`) — OpenAI's structured
|
|
194
|
+
// outputs has no positional `prefixItems` support and would otherwise
|
|
195
|
+
// collapse a `[string, number, bool]` to an array of `(string|number|bool)`,
|
|
196
|
+
// losing the per-position type. Encoding as an object preserves it.
|
|
197
|
+
// The strictified schema accepts EITHER form: an object with "0".."n-1"
|
|
198
|
+
// keys (what a strict-mode model produces) or an array (what a callsite
|
|
199
|
+
// outside strict context would pass). Both arrive at the tuple schema as
|
|
200
|
+
// an array.
|
|
201
|
+
//
|
|
202
|
+
// Only installed when the descriptor wants the numeric-keys encoding.
|
|
203
|
+
if (schema instanceof z.ZodTuple) {
|
|
204
|
+
const items = schema.def.items.map(transform);
|
|
205
|
+
const rest = schema.def.rest ? transform(schema.def.rest) : undefined;
|
|
206
|
+
const tupleSchema = rest ? z.tuple(items, rest) : z.tuple(items);
|
|
207
|
+
if (descriptor.tupleEncoding !== 'object-numeric-keys') {
|
|
208
|
+
return transferMetadata(tupleSchema, schema);
|
|
209
|
+
}
|
|
210
|
+
return transferMetadata(z.preprocess((val) => {
|
|
211
|
+
if (val && typeof val === 'object' && !Array.isArray(val)) {
|
|
212
|
+
const obj = val;
|
|
213
|
+
const keys = Object.keys(obj);
|
|
214
|
+
if (keys.length > 0 && keys.every((k) => /^\d+$/.test(k))) {
|
|
215
|
+
const indices = keys.map((k) => parseInt(k, 10));
|
|
216
|
+
const len = Math.max(...indices) + 1;
|
|
217
|
+
const arr = new Array(len);
|
|
218
|
+
for (const k of keys)
|
|
219
|
+
arr[parseInt(k, 10)] = obj[k];
|
|
220
|
+
return arr;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return val;
|
|
224
|
+
}, tupleSchema), schema);
|
|
225
|
+
}
|
|
226
|
+
// Handle ZodDefault
|
|
227
|
+
if (schema instanceof z.ZodDefault) {
|
|
228
|
+
return z.preprocess((val) => val === null ? undefined : val, transferMetadata(transform(schema.def.innerType).default(schema.def.defaultValue), schema));
|
|
229
|
+
}
|
|
230
|
+
// Handle ZodLazy
|
|
231
|
+
if (schema instanceof z.ZodLazy) {
|
|
232
|
+
return transferMetadata(z.lazy(() => transform(schema.def.getter())), schema);
|
|
233
|
+
}
|
|
234
|
+
// For all other types (primitives, etc.), return as-is
|
|
235
|
+
return schema;
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=strictify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strictify.js","sourceRoot":"","sources":["../../src/schema/strictify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import z from 'zod';
|
|
2
|
+
import type { FormatDescriptor } from './descriptor';
|
|
3
|
+
import type { JSONSchema, ToJSONSchemaOptions } from './json-schema';
|
|
4
|
+
/**
|
|
5
|
+
* Converts a Zod schema to JSON Schema with support for different provider dialects.
|
|
6
|
+
*
|
|
7
|
+
* Accepts either a boolean (legacy: true = OPENAI_STRICT, false = LENIENT),
|
|
8
|
+
* an options object `{ strict, format? }`, or a `FormatDescriptor` directly.
|
|
9
|
+
*
|
|
10
|
+
* @param schema - The Zod schema to convert
|
|
11
|
+
* @param options - Configuration options for the conversion
|
|
12
|
+
* @returns JSON Schema object compatible with the resolved dialect
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const schema = z.object({
|
|
17
|
+
* name: z.string(),
|
|
18
|
+
* age: z.number().optional(),
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* // For OpenAI strict mode
|
|
22
|
+
* const jsonSchema = toJSONSchema(schema, { strict: true, format: 'openai' });
|
|
23
|
+
*
|
|
24
|
+
* // For Anthropic strict mode
|
|
25
|
+
* const anthropic = toJSONSchema(schema, ANTHROPIC_STRICT);
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare function toJSONSchema(schema: z.ZodType, options: ToJSONSchemaOptions | boolean | FormatDescriptor): JSONSchema;
|
|
29
|
+
//# sourceMappingURL=to-json-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"to-json-schema.d.ts","sourceRoot":"","sources":["../../src/schema/to-json-schema.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAC;AACpB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AA0BrE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,CAAC,CAAC,OAAO,EACjB,OAAO,EAAE,mBAAmB,GAAG,OAAO,GAAG,gBAAgB,GACxD,UAAU,CAqBZ"}
|