@womp/spark-agent 3.0.0 → 3.0.2

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.
@@ -82,7 +82,7 @@ export function createSparkTools(options) {
82
82
  },
83
83
  };
84
84
  const logs = [];
85
- const receipts = [];
85
+ const receipts = new Map();
86
86
  const artifacts = [];
87
87
  const pending = new Set();
88
88
  let outputBytes = 0;
@@ -117,7 +117,7 @@ export function createSparkTools(options) {
117
117
  }
118
118
  }),
119
119
  recordReceipt: (receipt) => {
120
- receipts.push(receipt);
120
+ receipts.set(receipt.id, structuredClone(receipt));
121
121
  options.write({
122
122
  type: "data-execution-receipt",
123
123
  id: receipt.id,
@@ -169,7 +169,7 @@ export function createSparkTools(options) {
169
169
  purpose: input.purpose,
170
170
  value: jsonValue(value),
171
171
  logs,
172
- receipts,
172
+ receipts: [...receipts.values()],
173
173
  artifacts,
174
174
  };
175
175
  }
@@ -182,7 +182,7 @@ export function createSparkTools(options) {
182
182
  purpose: input.purpose,
183
183
  value: null,
184
184
  logs,
185
- receipts,
185
+ receipts: [...receipts.values()],
186
186
  artifacts,
187
187
  error: errorMessage(error),
188
188
  };
package/dist/agent.js CHANGED
@@ -144,6 +144,7 @@ export function runSparkAgent(options) {
144
144
  toolNames: step.toolCalls.map(({ toolName }) => toolName),
145
145
  responseTimeMs: step.performance.responseTimeMs,
146
146
  cost: calculateStepCost(options.modelId, step.usage),
147
+ usage: step.usage,
147
148
  },
148
149
  });
149
150
  if (options.persistence?.saveMessage !== undefined) {
@@ -7,7 +7,7 @@ export function createSceneHealthCapability(host) {
7
7
  name: "scene-health",
8
8
  version: "1",
9
9
  description: "Required before scene checks or procedural edits: engine limits, empty Areas, fresh geometry feedback, and bounded repairs.",
10
- instructions: `Before checking or editing a model, call womp.health.read([]) for current scene health. A health read is a snapshot and does not prove that the latest edit finished evaluating. Inspect scene edit receipts before claiming success.
10
+ instructions: `Before checking or editing a model, call womp.health.read([]) for current scene health. A health read is a snapshot and does not prove that the latest edit finished evaluating. Inspect scene edit receipts before claiming success.
11
11
  For confirmed primitive or depth overflow, repair the same target while preserving design, dimensions, active parameter overrides, and unrelated objects. At most two geometry repairs are allowed per target in one logical run. Unverified feedback must not trigger blind regeneration or a claim that the model passed. Empty Areas may be pending, intentionally empty, mesh-only, or failed. Overflow flags take precedence over possibly stale counts. max_total_depth is a scene hierarchy limit, not measured Boolean depth.`,
12
12
  declarations: WOMP_HEALTH_DECLARATIONS,
13
13
  examples: ["print(await womp.health.read([]));"],
@@ -79,34 +79,34 @@ export function createOperationsCapability(host) {
79
79
  name: "generation",
80
80
  version: "5",
81
81
  description: "Generate or edit images and meshes, inspect jobs, and wait for their outputs.",
82
- instructions: `Read operations.catalog() for the currently available models and selected defaults.
83
- Use generation for inline chat results. If the user is working in their Flow graph and flow-graphs is available,
84
- add the generation to that graph instead unless they request an inline result. When they want repeated variations,
85
- offer a reusable Flow workflow if available; accepting that offer means editing the graph, not submitting another inline job.
86
- Use generate() for image/mesh generation, image editing, upscaling, or background removal. Model IDs must
87
- come from the catalog and support the requested operation. An unavailable or restricted explicit choice
88
- is an error; do not silently substitute another model. Omit model IDs to use the user's defaults.
89
- For text-to-mesh, imageParams configures the image step and params configures the mesh step. For
90
- image-to-mesh, an optional prompt requests an image-editing step first. Advanced params are JSON
91
- values passed to the existing service; use documented options and do not invent provider settings.
92
- Author the full text-to-mesh image prompt yourself, preserving the user's requested subject and details.
93
- For a standalone object, describe a clear three-quarter view with a plain background and even lighting
94
- unless the user requests otherwise. Do not rely on another model to expand or rewrite this prompt.
95
- Inputs are image references returned by the available assets API or a previous completed operation.
96
- Do not fabricate references, replace a missing input with another image, or pass arbitrary URLs.
97
- Assign a short, distinct key to each intended job. Reuse that key when checking the same submission;
98
- never choose a new key merely to retry a timeout or unknown outcome. A key cannot identify two
99
- different requests. Host receipts and saved message IDs record submitted effects.
100
- generate() waits for cost confirmation and then for completion, failure, or cancellation.
101
- Use exactly one generation per execute_javascript call and print its result. Put follow-up work in
102
- another call. Do not poll, start background work, use Promise.all, or report success before completion.
103
- The host waits without consuming model steps. Pause ends the local wait, not an accepted backend job.
104
- Refresh recovery reconnects the same job. It never resumes the interrupted JavaScript stack.
105
- Inspect a recovered result and continue remaining work in a new call; do not repeat generation.
106
- Use list() to discover existing jobs. Follow nextFrom even when a page has no jobs.
107
- An uncertain submission requires inspection, never a replacement request.
108
- Only returned outputs exist. Emit images/files to inspect or show them; generating a mesh does not
109
- import it into the scene. Use the assets skill for importing. Stopping the agent ends its wait and
82
+ instructions: `Read operations.catalog() for the currently available models and selected defaults.
83
+ Use generation for inline chat results. If the user is working in their Flow graph and flow-graphs is available,
84
+ add the generation to that graph instead unless they request an inline result. When they want repeated variations,
85
+ offer a reusable Flow workflow if available; accepting that offer means editing the graph, not submitting another inline job.
86
+ Use generate() for image/mesh generation, image editing, upscaling, or background removal. Model IDs must
87
+ come from the catalog and support the requested operation. An unavailable or restricted explicit choice
88
+ is an error; do not silently substitute another model. Omit model IDs to use the user's defaults.
89
+ For text-to-mesh, imageParams configures the image step and params configures the mesh step. For
90
+ image-to-mesh, an optional prompt requests an image-editing step first. Advanced params are JSON
91
+ values passed to the existing service; use documented options and do not invent provider settings.
92
+ Author the full text-to-mesh image prompt yourself, preserving the user's requested subject and details.
93
+ For a standalone object, describe a clear three-quarter view with a plain background and even lighting
94
+ unless the user requests otherwise. Do not rely on another model to expand or rewrite this prompt.
95
+ Inputs are image references returned by the available assets API or a previous completed operation.
96
+ Do not fabricate references, replace a missing input with another image, or pass arbitrary URLs.
97
+ Assign a short, distinct key to each intended job. Reuse that key when checking the same submission;
98
+ never choose a new key merely to retry a timeout or unknown outcome. A key cannot identify two
99
+ different requests. Host receipts and saved message IDs record submitted effects.
100
+ generate() waits for cost confirmation and then for completion, failure, or cancellation.
101
+ Use exactly one generation per execute_javascript call and print its result. Put follow-up work in
102
+ another call. Do not poll, start background work, use Promise.all, or report success before completion.
103
+ The host waits without consuming model steps. Pause ends the local wait, not an accepted backend job.
104
+ Refresh recovery reconnects the same job. It never resumes the interrupted JavaScript stack.
105
+ Inspect a recovered result and continue remaining work in a new call; do not repeat generation.
106
+ Use list() to discover existing jobs. Follow nextFrom even when a page has no jobs.
107
+ An uncertain submission requires inspection, never a replacement request.
108
+ Only returned outputs exist. Emit images/files to inspect or show them; generating a mesh does not
109
+ import it into the scene. Use the assets skill for importing. Stopping the agent ends its wait and
110
110
  prevents further submissions; it does not claim to cancel a job already accepted by the service.`,
111
111
  declarations: WOMP_OPERATIONS_DECLARATIONS,
112
112
  examples: [
@@ -11,34 +11,34 @@ export function createSceneCapability(host) {
11
11
  name: "scene-editing",
12
12
  version: "5",
13
13
  description: "Inspect the open scene and edit its objects, materials, curves, and environment.",
14
- instructions: `Read the scene first and keep its revision and object IDs. Call scene.edit(callback, expectedRevision)
15
- for one coherent undoable change. The callback receives a draft; all node/material/curve functions and enums
16
- are properties of that draft. The draft expires when the callback ends. Await asynchronous methods.
17
- Do not start unrelated operations from inside an edit. A stale revision requires reading again.
18
- Preserve the existing scene unless asked to remove or replace content. Use semantic object names and reuse
19
- known IDs when editing rather than creating duplicates. Distances follow the current project's units
20
- (read().unitMultiplier is 1 for millimetres, 0.1 for centimetres, approximately 0.0393701 for inches).
21
- Convert a dimension in millimetres to project units by multiplying it by read().unitMultiplier.
22
- Area size is a dimensionless scale; Group size stays fixed at one. Light size has x/y dimensions.
23
- Blend and mirror goop use millimetres regardless of project units. V1/V2 curve transforms are read-only;
24
- edit their points instead. Handles and closure are available only on V3 Bezier curves.
25
- Rotations use degrees and colors use RGB values from 0 to 255. Use the exposed enums instead of guessing values.
26
- For visible geometry color, create or clone a material, call materialSetColor, and assign it with nodeSetMaterialId.
27
- nodeSetColor writes the node color field (used by lights); it does not replace a geometry object's material color.
28
- Do not recolor a shared material unless every object using it should change. Create and assign the material in the same edit as the geometry.
29
- Create primitives, curves, and text inside Areas/Unions. Respect tree order for subtraction and intersection.
30
- Use groups for organization and unions for blended masses. Build silhouette and proportions before detail.
31
- For organic joins, overlap primitives and use appropriate blend; keep crisp accessories separate.
32
- Check font, HDR, and material catalogs before selecting names. A host can explicitly report a catalog as
33
- unavailable. Selecting an HDR resets its intensity; apply a custom intensity after selecting it.
34
- For library materials, use listSuperMaterials(), then await materialImport(name) inside scene.edit and assign the returned numeric ID with nodeSetMaterialId or curvePointSetMaterialId. Await the import before returning from the edit; a failed import rolls back the draft.
35
- Filter large read results with JavaScript and print only useful details. Never dump the entire scene by default.
36
- After a major edit, capture a screenshot outside the transaction and emitImage its reference. To inspect a
37
- new object, frame its owning Area with screenshot({ targetId: areaId, view: 'isometric' }); omit these options
38
- to preserve the current camera view. Do not change a locked camera without the user's instruction. Verify silhouette,
39
- connections, openings, proportions, and materials before claiming completion. Renderer bounds and resize calls
40
- must finish before subsequent writes. Inside scene.edit, complete renderer-backed bounds reads before the first
41
- draft mutation; the SDK rejects them once the draft is dirty. Inspect committed results when renderer state has not caught up.
14
+ instructions: `Read the scene first and keep its revision and object IDs. Call scene.edit(callback, expectedRevision)
15
+ for one coherent undoable change. The callback receives a draft; all node/material/curve functions and enums
16
+ are properties of that draft. The draft expires when the callback ends. Await asynchronous methods.
17
+ Do not start unrelated operations from inside an edit. A stale revision requires reading again.
18
+ Preserve the existing scene unless asked to remove or replace content. Use semantic object names and reuse
19
+ known IDs when editing rather than creating duplicates. Distances follow the current project's units
20
+ (read().unitMultiplier is 1 for millimetres, 0.1 for centimetres, approximately 0.0393701 for inches).
21
+ Convert a dimension in millimetres to project units by multiplying it by read().unitMultiplier.
22
+ Area size is a dimensionless scale; Group size stays fixed at one. Light size has x/y dimensions.
23
+ Blend and mirror goop use millimetres regardless of project units. V1/V2 curve transforms are read-only;
24
+ edit their points instead. Handles and closure are available only on V3 Bezier curves.
25
+ Rotations use degrees and colors use RGB values from 0 to 255. Use the exposed enums instead of guessing values.
26
+ For visible geometry color, create or clone a material, call materialSetColor, and assign it with nodeSetMaterialId.
27
+ nodeSetColor writes the node color field (used by lights); it does not replace a geometry object's material color.
28
+ Do not recolor a shared material unless every object using it should change. Create and assign the material in the same edit as the geometry.
29
+ Create primitives, curves, and text inside Areas/Unions. Respect tree order for subtraction and intersection.
30
+ Use groups for organization and unions for blended masses. Build silhouette and proportions before detail.
31
+ For organic joins, overlap primitives and use appropriate blend; keep crisp accessories separate.
32
+ Check font, HDR, and material catalogs before selecting names. A host can explicitly report a catalog as
33
+ unavailable. Selecting an HDR resets its intensity; apply a custom intensity after selecting it.
34
+ For library materials, use listSuperMaterials(), then await materialImport(name) inside scene.edit and assign the returned numeric ID with nodeSetMaterialId or curvePointSetMaterialId. Await the import before returning from the edit; a failed import rolls back the draft.
35
+ Filter large read results with JavaScript and print only useful details. Never dump the entire scene by default.
36
+ After a major edit, capture a screenshot outside the transaction and emitImage its reference. To inspect a
37
+ new object, frame its owning Area with screenshot({ targetId: areaId, view: 'isometric' }); omit these options
38
+ to preserve the current camera view. Do not change a locked camera without the user's instruction. Verify silhouette,
39
+ connections, openings, proportions, and materials before claiming completion. Renderer bounds and resize calls
40
+ must finish before subsequent writes. Inside scene.edit, complete renderer-backed bounds reads before the first
41
+ draft mutation; the SDK rejects them once the draft is dirty. Inspect committed results when renderer state has not caught up.
42
42
  A failed script can retain earlier committed effects. Use receipts and inspect unknown outcomes before retrying.`,
43
43
  declarations: WOMP_SCENE_DECLARATIONS,
44
44
  examples: [