@ai-matrx/content-ir 0.9.0 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/README.md +24 -5
  3. package/dist/convert.cjs +1680 -0
  4. package/dist/convert.cjs.map +1 -0
  5. package/dist/convert.d.cts +230 -0
  6. package/dist/convert.d.ts +230 -0
  7. package/dist/convert.js +1666 -0
  8. package/dist/convert.js.map +1 -0
  9. package/dist/core.cjs +2493 -0
  10. package/dist/core.cjs.map +1 -0
  11. package/dist/core.d.cts +370 -0
  12. package/dist/core.d.ts +370 -0
  13. package/dist/core.js +2452 -0
  14. package/dist/core.js.map +1 -0
  15. package/dist/index.cjs +3 -1
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.d.cts +9 -2030
  18. package/dist/index.d.ts +9 -2030
  19. package/dist/index.js +3 -1
  20. package/dist/index.js.map +1 -1
  21. package/dist/ir-tree-DbLVxbf1.d.cts +441 -0
  22. package/dist/ir-tree-Dsc_66ek.d.ts +441 -0
  23. package/dist/ir-types-95bA2cXH.d.cts +119 -0
  24. package/dist/ir-types-95bA2cXH.d.ts +119 -0
  25. package/dist/kind-schema.types-CwncWj9U.d.cts +139 -0
  26. package/dist/kind-schema.types-CwncWj9U.d.ts +139 -0
  27. package/dist/registry.cjs +468 -0
  28. package/dist/registry.cjs.map +1 -0
  29. package/dist/registry.d.cts +357 -0
  30. package/dist/registry.d.ts +357 -0
  31. package/dist/registry.js +456 -0
  32. package/dist/registry.js.map +1 -0
  33. package/dist/session.cjs +2052 -0
  34. package/dist/session.cjs.map +1 -0
  35. package/dist/session.d.cts +75 -0
  36. package/dist/session.d.ts +75 -0
  37. package/dist/session.js +2047 -0
  38. package/dist/session.js.map +1 -0
  39. package/dist/wire.cjs +310 -0
  40. package/dist/wire.cjs.map +1 -0
  41. package/dist/wire.d.cts +326 -0
  42. package/dist/wire.d.ts +326 -0
  43. package/dist/wire.js +291 -0
  44. package/dist/wire.js.map +1 -0
  45. package/package.json +73 -1
@@ -0,0 +1,230 @@
1
+ import { F as FieldSchema, a as KindSchema } from './kind-schema.types-CwncWj9U.js';
2
+
3
+ /**
4
+ * OpenAI/provider JSON Schema → KindSchema converter + __kind injection.
5
+ *
6
+ * The strategic keystone: `buildAgentSchemaWithRenderBlockSupport` turns "a
7
+ * user/agent defined an output schema" into "the platform has a render
8
+ * contract for it" by injecting the `__kind` discriminator into the agent's
9
+ * output schema (root + array items), so the model emits self-identifying
10
+ * objects from then on.
11
+ *
12
+ * Moved from app/(dev)/demos/json-block-detector/schema-converter.ts.
13
+ */
14
+
15
+ type JsonSchemaNode = Record<string, unknown>;
16
+ type ConversionProblem = {
17
+ severity: "error" | "warning" | "info";
18
+ path: string;
19
+ message: string;
20
+ };
21
+ type DroppedMetadata = {
22
+ path: string;
23
+ dropped: Record<string, unknown>;
24
+ };
25
+ type FieldComparison = {
26
+ field: string;
27
+ aiPresent: boolean;
28
+ blockPresent: boolean;
29
+ aiSummary: string | null;
30
+ blockSummary: string | null;
31
+ status: "match" | "ai_only" | "block_only" | "type_mismatch" | "ai_richer" | "block_richer";
32
+ detail?: string;
33
+ };
34
+ /** One standalone flexible_data block schema row. */
35
+ type BlockSchemaDraft = {
36
+ slug: string;
37
+ label: string;
38
+ fields: Record<string, FieldSchema>;
39
+ /**
40
+ * NON-OBJECT ROOT form (KindSchema.root): the kind's value is this field's
41
+ * shape at the top level (scalar / array / json / OPEN object). When set,
42
+ * `fields` is empty — mirror of `KindSchema.root`.
43
+ */
44
+ root?: FieldSchema;
45
+ };
46
+ type ArrayItemKindBinding = {
47
+ arrayField: string;
48
+ itemKindSlug: string;
49
+ };
50
+ type SchemaConversionResult = {
51
+ schemaName: string | null;
52
+ strict: boolean | null;
53
+ /** Every block schema row required for the converted shape (1..n). */
54
+ blockSchemas: BlockSchemaDraft[];
55
+ /** OPTION 2 — same input shape with __kind injected for agent output. */
56
+ agentSchemaWithKinds: unknown | null;
57
+ problems: ConversionProblem[];
58
+ droppedMetadata: DroppedMetadata[];
59
+ comparisons: FieldComparison[];
60
+ };
61
+ type SavePlanEntry = {
62
+ draft: BlockSchemaDraft;
63
+ existsInDb: boolean;
64
+ willSave: boolean;
65
+ };
66
+ type ItemKindRefCheck = {
67
+ parentSlug: string;
68
+ field: string;
69
+ itemKind: string;
70
+ satisfied: boolean;
71
+ source: "batch" | "database" | "missing";
72
+ };
73
+ type SavePlanValidation = {
74
+ entries: SavePlanEntry[];
75
+ itemKindRefs: ItemKindRefCheck[];
76
+ newCount: number;
77
+ canSave: boolean;
78
+ errors: string[];
79
+ };
80
+ /**
81
+ * Inject the `__kind` discriminator into one object schema (const when
82
+ * strict, enum otherwise; `__kind` prepended to required; strict also pins
83
+ * additionalProperties:false). Shared with the REVERSE converter
84
+ * (kind-to-json-schema.ts) so both directions stamp identical discriminators.
85
+ */
86
+ declare function injectKindIntoObjectSchema(objectSchema: JsonSchemaNode, kindSlug: string, strict: boolean): JsonSchemaNode;
87
+ declare function buildAgentSchemaWithRenderBlockSupport(input: unknown, rootKindSlug: string, arrayBindings: ArrayItemKindBinding[], strict: boolean): unknown | null;
88
+ declare function normalizeAiSchemaInput(input: unknown): {
89
+ name: string | null;
90
+ strict: boolean | null;
91
+ rootSchema: JsonSchemaNode | null;
92
+ parseErrors: string[];
93
+ };
94
+ type ConversionCore = {
95
+ schemaName: string | null;
96
+ strict: boolean | null;
97
+ blockSchemas: BlockSchemaDraft[];
98
+ problems: ConversionProblem[];
99
+ droppedMetadata: DroppedMetadata[];
100
+ };
101
+ declare function convertAiSchemaToBlockFields(schemaName: string, rootSchema: JsonSchemaNode, strict: boolean): ConversionCore;
102
+ declare function compareWithExistingKindSchema(convertedFields: Record<string, FieldSchema>, existing: KindSchema | null): FieldComparison[];
103
+ declare function runSchemaConversion(input: unknown, existingSchemas: Record<string, KindSchema>): SchemaConversionResult & {
104
+ parseErrors: string[];
105
+ };
106
+ declare function validateBlockSchemaSavePlan(blockSchemas: BlockSchemaDraft[], existingSlugs: string[], hasConversionErrors: boolean): SavePlanValidation;
107
+ declare function fieldsToDbPayload(fields: Record<string, FieldSchema>): Record<string, unknown>;
108
+ declare function isDuplicateBlockSlug(slug: string, entries: Array<{
109
+ slug: string;
110
+ }>): boolean;
111
+
112
+ /**
113
+ * KindSchema → provider-ready JSON Schema — the REVERSE of the OpenAI
114
+ * converter in openai-schema-converter.ts.
115
+ *
116
+ * The requested root kind renders INLINE as the top-level object; every
117
+ * OTHER kind it transitively references (via `{type:"object", kind}` and
118
+ * `{type:"array", itemKinds}` fields, including inside inline_objects)
119
+ * becomes a `$defs` entry referenced with `$ref: "#/$defs/<slug>"`.
120
+ * References back to the ROOT kind use `"#"` — the standard JSON Schema
121
+ * recursive-root reference (OpenAI structured outputs support both forms).
122
+ * Collection is cycle-safe: each kind enters the closure exactly once.
123
+ *
124
+ * Round-trip contract — output fed through `runSchemaConversion`
125
+ * (openai-schema-converter.ts) reproduces the source KindSchemas for the
126
+ * root and every array-item child (enforced by
127
+ * __tests__/kind-to-json-schema.test.ts). The 2026-07-15 expressivity
128
+ * extension closed the three historical asymmetries: `record` now has a
129
+ * forward target (properties-less objects → record scalar/json), multi-
130
+ * itemKind arrays read back through items-anyOf when each variant declares
131
+ * its `__kind`, and nullable anyOf preserves the member list + nullable flag
132
+ * instead of flattening to `string`. Remaining accepted narrowings:
133
+ * - multi-kind array items emitted as $refs (not inline __kind objects)
134
+ * still cannot be read back — the forward converter rejects $ref.
135
+ * - a nullable object-REF (`anyOf: [$ref, {type:"null"}]`) degrades for the
136
+ * same $ref reason.
137
+ * - JSON Schema `integer` narrows to `number` (the map_result precedent).
138
+ */
139
+
140
+ type KindJsonSchemaOptions = {
141
+ /**
142
+ * Provider strict mode: additionalProperties:false on every kind object
143
+ * and inline object, and `const` (vs `enum`) __kind discriminators —
144
+ * mirrors makeKindJsonSchemaProperty / injectKindIntoObjectSchema.
145
+ */
146
+ strict?: boolean;
147
+ /**
148
+ * Inject the `__kind` discriminator (+ required) into the root and every
149
+ * $defs kind object. Default true — this is what makes the emitted
150
+ * objects self-identifying for the render pipeline.
151
+ */
152
+ injectKind?: boolean;
153
+ };
154
+ type KindJsonSchemaExport = {
155
+ /** The root kind slug — doubles as the provider schema name. */
156
+ name: string;
157
+ schema: JsonSchemaNode;
158
+ strict: boolean;
159
+ /**
160
+ * Referenced kinds the resolver could not supply. Each still gets a
161
+ * permissive `$defs` object stub (never additionalProperties:false, even
162
+ * in strict mode — a __kind-only strict object would reject every real
163
+ * payload) so the export stays structurally valid. Surface these loudly.
164
+ */
165
+ unresolved: string[];
166
+ };
167
+ /**
168
+ * Every kind referenced by a field map — `{type:"object", kind}` refs and
169
+ * `{type:"array", itemKinds}` members, recursing through inline_objects.
170
+ * First-sighting order, deduplicated. Shared read helper (the registry
171
+ * catalog builds its uses / used-by graph from this).
172
+ */
173
+ declare function collectReferencedKinds(fields: Record<string, FieldSchema>): string[];
174
+ /**
175
+ * Schema-level referenced kinds — field-map refs PLUS the refs a non-object
176
+ * root form carries. Use this (not `collectReferencedKinds(schema.fields)`)
177
+ * whenever the schema in hand may be root-form.
178
+ */
179
+ declare function collectSchemaReferencedKinds(schema: KindSchema): string[];
180
+ declare function kindSchemaToJsonSchema(kind: string, resolve: (kind: string) => KindSchema | undefined, options?: KindJsonSchemaOptions): KindJsonSchemaExport | null;
181
+
182
+ /**
183
+ * JSON Schema → KindSchema — THE registry-facing direction.
184
+ *
185
+ * 🚨 WHY THIS FILE IS THE POINT OF THE WHOLE CONVERT LAYER (Arman's ruling,
186
+ * 2026-08-29): a kind's fields must be DERIVED from its schema, never stored a
187
+ * second time. `content_ir.kind_definition` used to carry both — a JSON Schema
188
+ * AND a flattened field list written beside it — and the two had already
189
+ * diverged on 13 of the 62 live kinds that carried both: stored lists holding
190
+ * `__kind` as if it were a data field, enums flattened to bare strings,
191
+ * min/max bounds and required flags the schema states and the copy never
192
+ * learned. A cache that can disagree with its source is not a cache.
193
+ *
194
+ * The heavy lifting lives in `openai-schema-converter.ts` (it also serves the
195
+ * agent-authoring flow, which needs the problems/dropped-metadata detail).
196
+ * This module is the narrow, honest door the registry calls: one schema in,
197
+ * one `KindSchema` out, plus whatever child kinds the schema declared inline
198
+ * or through `$defs`.
199
+ *
200
+ * Accepts both storage shapes seen in the wild: a bare JSON Schema, and the
201
+ * provider `{name, schema, strict}` response-format envelope that 5 live rows
202
+ * carry.
203
+ */
204
+
205
+ type KindSchemaFromJsonResult = {
206
+ /**
207
+ * The requested kind's schema, or null when the input could not be read as
208
+ * an object contract at all. NEVER a partial guess: a field the vocabulary
209
+ * cannot express degrades to `json` (widening, always safe), and only a
210
+ * structurally unusable root yields null.
211
+ */
212
+ schema: KindSchema | null;
213
+ /**
214
+ * Child kinds the schema declared inline or via `$defs`, keyed by slug.
215
+ * A registry that ingests these gets the whole tree from ONE row's schema —
216
+ * which is how a nested kind renders before its children's rows load.
217
+ */
218
+ children: Record<string, KindSchema>;
219
+ /** Conversion notes. `severity: "error"` entries are worth screaming about. */
220
+ problems: ConversionProblem[];
221
+ };
222
+ /**
223
+ * Derive `kind`'s field schema from its JSON Schema.
224
+ *
225
+ * Pure and synchronous — no registry, no IO — so a host can call it from a
226
+ * warm load, a cold fetch, a reducer, or a test.
227
+ */
228
+ declare function kindSchemaFromJsonSchema(kind: string, jsonSchema: unknown): KindSchemaFromJsonResult;
229
+
230
+ export { type ArrayItemKindBinding, type BlockSchemaDraft, type ConversionProblem, type DroppedMetadata, type FieldComparison, type ItemKindRefCheck, type JsonSchemaNode, type KindJsonSchemaExport, type KindJsonSchemaOptions, type KindSchemaFromJsonResult, type SavePlanEntry, type SavePlanValidation, type SchemaConversionResult, buildAgentSchemaWithRenderBlockSupport, collectReferencedKinds, collectSchemaReferencedKinds, compareWithExistingKindSchema, convertAiSchemaToBlockFields, fieldsToDbPayload, injectKindIntoObjectSchema, isDuplicateBlockSlug, kindSchemaFromJsonSchema, kindSchemaToJsonSchema, normalizeAiSchemaInput, runSchemaConversion, validateBlockSchemaSavePlan };