@womp/spark-agent 5.2.3 → 5.4.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 (42) hide show
  1. package/dist/agent-run.d.ts +1 -1
  2. package/dist/agent-tools.js +30 -12
  3. package/dist/capabilities/materials.d.ts +45 -0
  4. package/dist/capabilities/materials.js +89 -0
  5. package/dist/capabilities/scene.d.ts +21 -0
  6. package/dist/capabilities/scene.js +13 -13
  7. package/dist/capabilities.d.ts +1 -0
  8. package/dist/capabilities.js +1 -0
  9. package/dist/error-diagnostics.d.ts +24 -0
  10. package/dist/error-diagnostics.js +53 -0
  11. package/dist/generated/materials-declarations.d.ts +1 -0
  12. package/dist/generated/materials-declarations.js +3 -0
  13. package/dist/kakapo.d.ts +1 -0
  14. package/dist/kakapo.js +1 -0
  15. package/dist/materials/composition.d.ts +64 -0
  16. package/dist/materials/composition.js +121 -0
  17. package/dist/materials/graph.d.ts +79 -0
  18. package/dist/materials/graph.js +336 -0
  19. package/dist/materials/inspection.d.ts +40 -0
  20. package/dist/materials/inspection.js +54 -0
  21. package/dist/materials/recipes.d.ts +12 -0
  22. package/dist/materials/recipes.js +284 -0
  23. package/dist/materials/reference.d.ts +2 -0
  24. package/dist/materials/reference.js +97 -0
  25. package/dist/materials/shaping.d.ts +294 -0
  26. package/dist/materials/shaping.js +184 -0
  27. package/dist/materials/structure.d.ts +2 -0
  28. package/dist/materials/structure.js +12 -0
  29. package/dist/materials/surface-recipes.d.ts +78 -0
  30. package/dist/materials/surface-recipes.js +193 -0
  31. package/dist/materials/types.d.ts +222 -0
  32. package/dist/materials/types.js +1 -0
  33. package/dist/models.d.ts +7 -0
  34. package/dist/models.js +8 -0
  35. package/dist/pricing.js +5 -0
  36. package/dist/prompt.d.ts +1 -1
  37. package/dist/prompt.js +32 -32
  38. package/dist/sdk-materials-host.d.ts +9 -0
  39. package/dist/sdk-materials-host.js +360 -0
  40. package/dist/server/standalone.js +6 -1
  41. package/dist/ui.d.ts +50 -6
  42. package/package.json +2 -2
@@ -0,0 +1,360 @@
1
+ import { sparkErrorDiagnostics } from "./error-diagnostics.js";
2
+ import { graphSchema, materialId, parseMaterialCatalog, validateMaterialGraph, writeSchema, value3, } from "./materials/graph.js";
3
+ function record(value, label) {
4
+ if (!value || typeof value !== "object" || Array.isArray(value))
5
+ throw new Error(`Invalid ${label}`);
6
+ return value;
7
+ }
8
+ function storage(source) {
9
+ const data = source.getSceneStorage();
10
+ return {
11
+ materials: record(data.materials ?? {}, "material storage"),
12
+ shaders: record(data.shaders ?? {}, "shader storage"),
13
+ };
14
+ }
15
+ function rawMaterial(source, id) {
16
+ return record(storage(source).materials[String(id)], `material ${id}`);
17
+ }
18
+ function layers(source, id) {
19
+ const data = storage(source);
20
+ const material = rawMaterial(source, id);
21
+ if (material.shaders === undefined)
22
+ return [];
23
+ if (!Array.isArray(material.shaders) || material.shaders.length > 8)
24
+ throw new Error(`Material ${id} has invalid shader slots`);
25
+ return material.shaders.map((value) => value === 0
26
+ ? null
27
+ : graphSchema.parse(data.shaders[String(materialId.parse(value))]));
28
+ }
29
+ function directUsers(source, id) {
30
+ return source
31
+ .listNodes()
32
+ .filter((node) => ("materialId" in node && node.materialId === id) ||
33
+ (node.kind === "curve" && node.points.some((p) => p.materialId === id)))
34
+ .map((node) => node.id);
35
+ }
36
+ function unusedId(entries) {
37
+ for (let id = 1; id <= 65535; id++)
38
+ if (!(String(id) in entries))
39
+ return id;
40
+ throw new Error("No free 16-bit shader IDs remain");
41
+ }
42
+ function freshReference(used) {
43
+ // Same reference IDs survive save/reopen; random IDs also avoid retired native cache entries.
44
+ for (;;) {
45
+ const bits = globalThis.crypto.getRandomValues(new Uint32Array(2));
46
+ const id = (bits[0] & 0x1fffff) * 4294967296 + bits[1];
47
+ if (id > 0 && !used.has(id)) {
48
+ used.add(id);
49
+ return id;
50
+ }
51
+ }
52
+ }
53
+ function allReferences(source) {
54
+ const data = storage(source);
55
+ const used = new Set();
56
+ for (const graph of Object.values(data.shaders)) {
57
+ const nodes = record(graph, "shader").nodes;
58
+ if (Array.isArray(nodes))
59
+ for (const node of nodes) {
60
+ if (node &&
61
+ typeof node === "object" &&
62
+ !Array.isArray(node) &&
63
+ typeof node.reference_id === "number")
64
+ used.add(node.reference_id);
65
+ }
66
+ }
67
+ for (const material of Object.values(data.materials)) {
68
+ const constants = record(record(material, "material").data, "material data").constants;
69
+ if (constants && typeof constants === "object")
70
+ for (const id of Object.keys(constants))
71
+ used.add(Number(id));
72
+ }
73
+ return used;
74
+ }
75
+ function patchEntry(draft, collection, id, value) {
76
+ if (!(collection in draft.getSceneStorage()))
77
+ draft.patchSceneStorage([{ op: "add", path: `/${collection}`, value: {} }]);
78
+ draft.patchSceneStorage([
79
+ { op: "add", path: `/${collection}/${id}`, value: value },
80
+ ]);
81
+ }
82
+ export function createSdkMaterialsHost(options) {
83
+ const initialized = new WeakSet();
84
+ const catalogue = async (api, context, refresh) => {
85
+ await options.assertAvailable(context);
86
+ context.signal.throwIfAborted();
87
+ if (refresh || !initialized.has(api)) {
88
+ await api.rpc("reload_textures", []);
89
+ context.signal.throwIfAborted();
90
+ initialized.add(api);
91
+ }
92
+ const nodes = parseMaterialCatalog(await api.rpc("get_procedural_nodes", []));
93
+ context.signal.throwIfAborted();
94
+ return nodes;
95
+ };
96
+ const snapshot = async (api, id) => {
97
+ const items = api.listMaterials().map((material) => ({
98
+ id: material.id,
99
+ shaderIds: material.shaderIds,
100
+ objectIds: directUsers(api, material.id),
101
+ }));
102
+ return {
103
+ materials: items,
104
+ ...(id === undefined
105
+ ? {}
106
+ : {
107
+ material: {
108
+ id,
109
+ data: record(rawMaterial(api, id).data, "material data"),
110
+ layers: layers(api, id),
111
+ },
112
+ }),
113
+ diagnostics: [
114
+ "Object IDs list direct assignments and curve points. Geometry Nodes/OpenSCAD can also refer to a material ID; existing-material edits affect all references.",
115
+ ],
116
+ };
117
+ };
118
+ return {
119
+ catalog: (settings, context) => options.editor.read(context, async (api) => {
120
+ const nodes = await catalogue(api, context, settings.refreshTextures === true);
121
+ const selected = {};
122
+ for (const op of settings.operations ?? []) {
123
+ if (!nodes[op])
124
+ throw new Error(`Material operation ${op} is unavailable`);
125
+ selected[op] = nodes[op];
126
+ }
127
+ return {
128
+ operations: Object.entries(nodes).map(([op, node]) => ({
129
+ op,
130
+ category: node.type,
131
+ title: node.title,
132
+ })),
133
+ nodes: selected,
134
+ textureCount: nodes.PredefinedTexture?.inputs[2]?.values?.length ?? 0,
135
+ ...(settings.includeTextures
136
+ ? {
137
+ textures: nodes.PredefinedTexture?.inputs[2]?.values ?? [],
138
+ textureMetadata: {
139
+ channels: "unknown",
140
+ colorSpace: "unknown",
141
+ normalConvention: "unknown",
142
+ reason: "The SDK texture catalogue supplies names, not channel or encoding metadata.",
143
+ },
144
+ }
145
+ : {}),
146
+ };
147
+ }),
148
+ read: (id, context) => options.editor.read(context, async (api) => {
149
+ await options.assertAvailable(context);
150
+ context.signal.throwIfAborted();
151
+ return snapshot(api, id === undefined ? undefined : materialId.parse(id));
152
+ }),
153
+ status: (context) => options.editor.read(context, async (api) => {
154
+ await options.assertAvailable(context);
155
+ context.signal.throwIfAborted();
156
+ const errors = [];
157
+ let remaining = null;
158
+ let pendingResources = null;
159
+ try {
160
+ const result = await api.rpc("get_procedural_materials_progress", []);
161
+ const data = record(typeof result === "string" ? JSON.parse(result) : result, "compiler progress");
162
+ if (typeof data.remaining !== "number" ||
163
+ !Number.isSafeInteger(data.remaining) || data.remaining < 0)
164
+ throw new Error("Invalid compiler progress counter");
165
+ remaining = data.remaining;
166
+ }
167
+ catch (error) {
168
+ context.signal.throwIfAborted();
169
+ errors.push({ source: "compiler-progress", message: sparkErrorDiagnostics(error).message });
170
+ }
171
+ context.signal.throwIfAborted();
172
+ await options.assertAvailable(context);
173
+ context.signal.throwIfAborted();
174
+ try {
175
+ const pending = record(await api.getPendingResources(), "pending resources");
176
+ const validated = {};
177
+ for (const [kind, names] of Object.entries(pending)) {
178
+ if (!Array.isArray(names) || !names.every((name) => typeof name === "string"))
179
+ throw new Error("Invalid pending resource list");
180
+ Object.defineProperty(validated, kind, { value: names, enumerable: true });
181
+ }
182
+ pendingResources = validated;
183
+ }
184
+ catch (error) {
185
+ context.signal.throwIfAborted();
186
+ errors.push({ source: "pending-resources", message: sparkErrorDiagnostics(error).message });
187
+ }
188
+ context.signal.throwIfAborted();
189
+ await options.assertAvailable(context);
190
+ context.signal.throwIfAborted();
191
+ return {
192
+ remaining,
193
+ pendingResources,
194
+ errors,
195
+ shaderDiagnostics: {
196
+ status: "unavailable",
197
+ reason: "The current SDK/native RPC exposes global queue length, not per-shader compiler results or errors bound to a scene revision.",
198
+ },
199
+ rendering: "unverified",
200
+ explanation: "A zero queue does not prove compilation, texture loading or the new rendered appearance succeeded. Inspect a scene screenshot.",
201
+ };
202
+ }),
203
+ write: async (input, context) => {
204
+ const request = writeSchema.parse(input);
205
+ await options.assertAvailable(context);
206
+ let resultId = request.materialId;
207
+ const edited = await options.editor.access({
208
+ capability: "materials",
209
+ operation: "write",
210
+ target: () => resultId === undefined ? {} : { materialId: resultId },
211
+ }, async (api, draft) => {
212
+ await options.assertAvailable(context);
213
+ context.signal.throwIfAborted();
214
+ if (request.materialId !== undefined &&
215
+ request.layers === undefined &&
216
+ request.constants === undefined) {
217
+ draft.getMaterial(request.materialId);
218
+ for (const id of request.objectIds ?? [])
219
+ draft.setNodeMaterial(id, request.materialId);
220
+ return {
221
+ materialId: request.materialId,
222
+ objectIds: directUsers(draft, request.materialId),
223
+ referenceIdChanges: {},
224
+ };
225
+ }
226
+ const catalog = await catalogue(api, context, false);
227
+ const sourceId = request.materialId ?? request.cloneFrom;
228
+ const original = sourceId === undefined ? undefined : rawMaterial(draft, sourceId);
229
+ const graphs = (request.layers ??
230
+ (sourceId === undefined ? [] : layers(draft, sourceId))).map((graph) => graph === null ? null : validateMaterialGraph(graph, catalog));
231
+ let rewriteGraphs = request.layers !== undefined || request.materialId === undefined;
232
+ const used = allReferences(draft);
233
+ const refs = new Map();
234
+ for (const graph of graphs)
235
+ for (const node of graph?.nodes ?? [])
236
+ if (node.op === "Constant") {
237
+ const id = typeof node.reference_id === "number" && node.reference_id > 0
238
+ ? node.reference_id
239
+ : freshReference(used);
240
+ if (refs.has(id))
241
+ throw new Error(`Constant reference ${id} is duplicated across layers; give independent constants unique IDs`);
242
+ if (node.reference_id !== id)
243
+ rewriteGraphs = true;
244
+ node.reference_id = id;
245
+ used.add(id);
246
+ refs.set(id, node);
247
+ }
248
+ const sourceData = original
249
+ ? record(original.data, "material data")
250
+ : undefined;
251
+ const constants = record(sourceData?.constants ?? {}, "material constants");
252
+ const referenceIdChanges = {};
253
+ for (const [key, override] of Object.entries(request.constants ?? {})) {
254
+ const node = refs.get(Number(key));
255
+ if (!node)
256
+ throw new Error(`Constant reference ${key} does not exist in the resulting layers`);
257
+ if (override === null)
258
+ delete constants[key];
259
+ else
260
+ constants[key] = override;
261
+ }
262
+ for (const [reference, node] of refs) {
263
+ const key = String(reference);
264
+ // Replaced graphs can reuse IDs whose deleted overrides remain in the native cache.
265
+ if (request.constants?.[key] === null ||
266
+ (request.materialId !== undefined &&
267
+ request.layers !== undefined &&
268
+ constants[key] === undefined)) {
269
+ const id = freshReference(used);
270
+ rewriteGraphs = true;
271
+ node.reference_id = id;
272
+ referenceIdChanges[key] = id;
273
+ }
274
+ }
275
+ context.signal.throwIfAborted();
276
+ if (resultId === undefined)
277
+ resultId = materialId.parse(draft.createMaterial(sourceId === undefined
278
+ ? undefined
279
+ : api.getMaterial(sourceId).data, Array(8).fill(0)).id);
280
+ const target = rawMaterial(draft, resultId);
281
+ const data = sourceData ?? record(target.data, "material data");
282
+ // Keep complete override pairs; unoverridden replacement nodes use fresh references.
283
+ data.constants = constants;
284
+ const current = storage(draft);
285
+ const oldSlots = original && Array.isArray(original.shaders) ? original.shaders : [];
286
+ const slots = graphs.map((graph, slot) => {
287
+ if (graph === null)
288
+ return 0;
289
+ if (!rewriteGraphs)
290
+ return materialId.parse(oldSlots[slot]);
291
+ const oldId = oldSlots[slot];
292
+ const references = Object.values(current.materials).reduce((count, entry) => {
293
+ const ids = record(entry, "material").shaders;
294
+ return (count +
295
+ (Array.isArray(ids)
296
+ ? ids.filter((id) => id === oldId).length
297
+ : 0));
298
+ }, 0);
299
+ // A clone or shared shader gets independent storage; other materials keep their graph.
300
+ const shaderId = request.materialId !== undefined &&
301
+ typeof oldId === "number" &&
302
+ oldId > 0 &&
303
+ references === 1
304
+ ? materialId.parse(oldId)
305
+ : unusedId(current.shaders);
306
+ current.shaders[String(shaderId)] =
307
+ graph;
308
+ patchEntry(draft, "shaders", shaderId, graph);
309
+ return shaderId;
310
+ });
311
+ while (slots.length < 8)
312
+ slots.push(0);
313
+ patchEntry(draft, "materials", resultId, {
314
+ ...target,
315
+ ...(original ?? {}),
316
+ data,
317
+ shaders: slots,
318
+ });
319
+ if (request.cloneFrom !== undefined) {
320
+ const ext = draft.getSceneExt();
321
+ const metadata = record(ext.materialsExt ?? {}, "material metadata");
322
+ if (metadata[String(request.cloneFrom)] !== undefined) {
323
+ if (ext.materialsExt === undefined)
324
+ draft.patchSceneExt([
325
+ { op: "add", path: "/materialsExt", value: {} },
326
+ ]);
327
+ draft.patchSceneExt([
328
+ {
329
+ op: "add",
330
+ path: `/materialsExt/${resultId}`,
331
+ value: metadata[String(request.cloneFrom)],
332
+ },
333
+ ]);
334
+ }
335
+ }
336
+ for (const id of request.objectIds ?? [])
337
+ draft.setNodeMaterial(id, resultId);
338
+ return {
339
+ materialId: resultId,
340
+ objectIds: directUsers(draft, resultId),
341
+ referenceIdChanges,
342
+ parameters: graphs.flatMap(graph => graph?.nodes.filter(node => node.op === "Constant").map(node => {
343
+ const referenceId = node.reference_id;
344
+ const override = constants[String(referenceId)];
345
+ return { name: node.name ?? "", referenceId,
346
+ exposed: node.in3?.x !== undefined && node.in3.x > 0,
347
+ value: override?.value ?? node.in1 ?? value3(0),
348
+ color: override?.color ?? node.in2 ?? value3(0),
349
+ };
350
+ }) ?? []),
351
+ };
352
+ }, context);
353
+ return {
354
+ ...edited.value,
355
+ status: "applied",
356
+ rendering: "unverified",
357
+ };
358
+ },
359
+ };
360
+ }
@@ -5,10 +5,11 @@ import express from "express";
5
5
  import { getSparkModel, SPARK_MODELS } from "../models.js";
6
6
  import { KakapoAPI, KakapoRpcError, KakapoSceneCommitError } from "@womp/kakapo-sdk";
7
7
  import { captureSdkSceneScreenshot } from "../sdk-scene-screenshot.js";
8
- import { composeCapabilities, createAccountCapability, createGeometryCapability, createOpenScadCapability, createSceneCapability, } from "../capabilities.js";
8
+ import { composeCapabilities, createAccountCapability, createGeometryCapability, createMaterialsCapability, createOpenScadCapability, createSceneCapability, } from "../capabilities.js";
9
9
  import { loadDemoSceneMaterials } from "./demo-scene-materials.js";
10
10
  import { createDemoAccountHost } from "./demo-account.js";
11
11
  import { createSdkSceneEditor, createSdkSceneHost, } from "../sdk-scene-host.js";
12
+ import { createSdkMaterialsHost } from "../sdk-materials-host.js";
12
13
  import { createSdkGeometryHost } from "../sdk-geometry-host.js";
13
14
  import { createSdkOpenScadHost } from "../sdk-openscad-host.js";
14
15
  import { createSdkSceneHealthHost } from "../sdk-scene-health-host.js";
@@ -114,6 +115,10 @@ export async function createStandaloneSparkAgentApp(options) {
114
115
  });
115
116
  const capabilityBindings = {
116
117
  scene: createSceneCapability(sceneHost),
118
+ materials: createMaterialsCapability(createSdkMaterialsHost({
119
+ editor,
120
+ assertAvailable: editorOptions.assertEditable,
121
+ }), sceneHost),
117
122
  geometry: createGeometryCapability(createSdkGeometryHost({
118
123
  editor,
119
124
  repairs,
package/dist/ui.d.ts CHANGED
@@ -116,16 +116,24 @@ export type SparkUITools = {
116
116
  read_skill: {
117
117
  input: {
118
118
  name: string;
119
+ names?: never;
120
+ } | {
121
+ names: string[];
122
+ name?: never;
119
123
  };
120
- output: ({
121
- ok: true;
122
- } & SparkSkill) | {
123
- ok: false;
124
- error: string;
125
- available: string[];
124
+ output: SkillReadResult | {
125
+ ok: boolean;
126
+ skills: SkillReadResult[];
126
127
  };
127
128
  };
128
129
  };
130
+ export type SkillReadResult = ({
131
+ ok: true;
132
+ } & SparkSkill) | {
133
+ ok: false;
134
+ error: string;
135
+ available: string[];
136
+ };
129
137
  export type SparkUIMessage = UIMessage<SparkMessageMetadata, SparkDataParts, SparkUITools>;
130
138
  export type SparkUIMessageChunk = InferUIMessageChunk<SparkUIMessage>;
131
139
  export type StoredSparkChunk = {
@@ -168,12 +176,24 @@ export declare const sparkMessageMetadataSchema: z.ZodObject<{
168
176
  code: z.ZodOptional<z.ZodString>;
169
177
  status: z.ZodOptional<z.ZodNumber>;
170
178
  requestId: z.ZodOptional<z.ZodString>;
179
+ eventType: z.ZodOptional<z.ZodString>;
180
+ issues: z.ZodOptional<z.ZodArray<z.ZodObject<{
181
+ code: z.ZodString;
182
+ path: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
183
+ expected: z.ZodOptional<z.ZodString>;
184
+ }, z.core.$strip>>>;
171
185
  cause: z.ZodOptional<z.ZodObject<{
172
186
  message: z.ZodString;
173
187
  name: z.ZodOptional<z.ZodString>;
174
188
  code: z.ZodOptional<z.ZodString>;
175
189
  status: z.ZodOptional<z.ZodNumber>;
176
190
  requestId: z.ZodOptional<z.ZodString>;
191
+ eventType: z.ZodOptional<z.ZodString>;
192
+ issues: z.ZodOptional<z.ZodArray<z.ZodObject<{
193
+ code: z.ZodString;
194
+ path: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
195
+ expected: z.ZodOptional<z.ZodString>;
196
+ }, z.core.$strip>>>;
177
197
  }, z.core.$strip>>;
178
198
  }, z.core.$strip>>;
179
199
  message: z.ZodString;
@@ -181,6 +201,12 @@ export declare const sparkMessageMetadataSchema: z.ZodObject<{
181
201
  code: z.ZodOptional<z.ZodString>;
182
202
  status: z.ZodOptional<z.ZodNumber>;
183
203
  requestId: z.ZodOptional<z.ZodString>;
204
+ eventType: z.ZodOptional<z.ZodString>;
205
+ issues: z.ZodOptional<z.ZodArray<z.ZodObject<{
206
+ code: z.ZodString;
207
+ path: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
208
+ expected: z.ZodOptional<z.ZodString>;
209
+ }, z.core.$strip>>>;
184
210
  }, z.core.$strip>>;
185
211
  }, z.core.$strip>;
186
212
  export declare const sparkDataPartSchemas: {
@@ -243,12 +269,24 @@ export declare const sparkDataPartSchemas: {
243
269
  code: z.ZodOptional<z.ZodString>;
244
270
  status: z.ZodOptional<z.ZodNumber>;
245
271
  requestId: z.ZodOptional<z.ZodString>;
272
+ eventType: z.ZodOptional<z.ZodString>;
273
+ issues: z.ZodOptional<z.ZodArray<z.ZodObject<{
274
+ code: z.ZodString;
275
+ path: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
276
+ expected: z.ZodOptional<z.ZodString>;
277
+ }, z.core.$strip>>>;
246
278
  cause: z.ZodOptional<z.ZodObject<{
247
279
  message: z.ZodString;
248
280
  name: z.ZodOptional<z.ZodString>;
249
281
  code: z.ZodOptional<z.ZodString>;
250
282
  status: z.ZodOptional<z.ZodNumber>;
251
283
  requestId: z.ZodOptional<z.ZodString>;
284
+ eventType: z.ZodOptional<z.ZodString>;
285
+ issues: z.ZodOptional<z.ZodArray<z.ZodObject<{
286
+ code: z.ZodString;
287
+ path: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
288
+ expected: z.ZodOptional<z.ZodString>;
289
+ }, z.core.$strip>>>;
252
290
  }, z.core.$strip>>;
253
291
  }, z.core.$strip>>;
254
292
  message: z.ZodString;
@@ -256,6 +294,12 @@ export declare const sparkDataPartSchemas: {
256
294
  code: z.ZodOptional<z.ZodString>;
257
295
  status: z.ZodOptional<z.ZodNumber>;
258
296
  requestId: z.ZodOptional<z.ZodString>;
297
+ eventType: z.ZodOptional<z.ZodString>;
298
+ issues: z.ZodOptional<z.ZodArray<z.ZodObject<{
299
+ code: z.ZodString;
300
+ path: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
301
+ expected: z.ZodOptional<z.ZodString>;
302
+ }, z.core.$strip>>>;
259
303
  }, z.core.$strip>>;
260
304
  label: z.ZodOptional<z.ZodString>;
261
305
  }, z.core.$strip>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@womp/spark-agent",
3
- "version": "5.2.3",
3
+ "version": "5.4.0",
4
4
  "description": "Portable skills-based AI agent with local and durable chat transports for Womp",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -110,7 +110,7 @@
110
110
  "@ai-sdk/openai": "4.0.63",
111
111
  "@jitl/quickjs-wasmfile-release-sync": "0.32.0",
112
112
  "@womp/flowir": "0.3.0",
113
- "@womp/kakapo-sdk": "0.7.2",
113
+ "@womp/kakapo-sdk": "0.7.3",
114
114
  "ai": "7.0.95",
115
115
  "eventsource-parser": "^3.0.6",
116
116
  "express": "^5.2.1",