@womp/spark-agent 4.3.0 → 4.4.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.
- package/README.md +37 -95
- package/dist/bench-camera.d.ts +9 -0
- package/dist/bench-camera.js +32 -0
- package/dist/bounded-output.js +8 -19
- package/dist/capabilities/scene.js +20 -11
- package/dist/generated/scene-declarations.d.ts +1 -1
- package/dist/generated/scene-declarations.js +1 -1
- package/dist/run-metrics.js +21 -7
- package/dist/scene-health.js +13 -5
- package/dist/scene-metadata.js +8 -8
- package/dist/sdk-scene-host.d.ts +9 -0
- package/dist/sdk-scene-host.js +1 -3
- package/dist/sdk-scene-screenshot.js +1 -0
- package/dist/simple-bench-prompts.d.ts +5 -28
- package/dist/simple-bench-prompts.js +2 -1
- package/dist/simple-bench.js +11 -23
- package/dist/womp-scene-api.d.ts +17 -2
- package/dist/womp-scene-api.js +94 -30
- package/package.json +2 -2
- package/.env.example +0 -6
package/README.md
CHANGED
|
@@ -102,11 +102,12 @@ A failed barrier aborts the loop. The default model-step limit is 100; a limit r
|
|
|
102
102
|
|
|
103
103
|
Spark does not estimate or limit input tokens or automatically shorten conversation history.
|
|
104
104
|
The provider enforces its context limit; rejections follow the normal provider-error path.
|
|
105
|
-
Provider-reported usage and cost tracking are unchanged.
|
|
106
105
|
|
|
107
|
-
Screenshot and file APIs return serializable artifact references. `emitImage` and `emitFile` resolve
|
|
108
|
-
them through the host's artifact resolver. Keep references resolvable when reloading history, and
|
|
109
|
-
pass `createSparkTools(...)` to AI SDK's `convertToModelMessages` to reconstruct multimodal results.
|
|
106
|
+
Screenshot and file APIs return serializable artifact references. `emitImage` and `emitFile` resolve
|
|
107
|
+
them through the host's artifact resolver. Keep references resolvable when reloading history, and
|
|
108
|
+
pass `createSparkTools(...)` to AI SDK's `convertToModelMessages` to reconstruct multimodal results.
|
|
109
|
+
`emitImage(artifact, { inspect: false })` displays an image without adding its bytes to model input,
|
|
110
|
+
including restored history. Inspection is enabled by default.
|
|
110
111
|
Kakapo skill declarations are generated from its actual typed API during the build and packaged as
|
|
111
112
|
JavaScript strings; they do not need filesystem or Markdown loading in the browser.
|
|
112
113
|
|
|
@@ -142,9 +143,11 @@ const chat = useChat<SparkUIMessage>({
|
|
|
142
143
|
```
|
|
143
144
|
|
|
144
145
|
Render `message.parts`. Standard AI SDK parts represent text, reasoning, files, tool inputs, tool
|
|
145
|
-
outputs, approvals, and step boundaries. Spark adds typed `data-console`, `data-artifact`,
|
|
146
|
-
`data-run-status`, `data-step-metrics`, and `data-execution-receipt` parts. Receipts are emitted before
|
|
147
|
-
their storage barrier, keeping known effects visible even when saving the tool result fails.
|
|
146
|
+
outputs, approvals, and step boundaries. Spark adds typed `data-console`, `data-artifact`,
|
|
147
|
+
`data-run-status`, `data-step-metrics`, and `data-execution-receipt` parts. Receipts are emitted before
|
|
148
|
+
their storage barrier, keeping known effects visible even when saving the tool result fails.
|
|
149
|
+
Hosts can consume `data-tool-input-label` once the tool's label field is complete, while the
|
|
150
|
+
remaining input is still streaming.
|
|
148
151
|
|
|
149
152
|
An explicit Stop action must cancel the durable run before stopping local observation:
|
|
150
153
|
|
|
@@ -174,7 +177,7 @@ that turn, independently of the selector.
|
|
|
174
177
|
|
|
175
178
|
Custom stores must implement `saveConversationSettings` as a settings-only update, and preserve
|
|
176
179
|
stored settings during `saveConversation` so streaming history saves cannot overwrite preferences.
|
|
177
|
-
The built-in memory and SQLite stores
|
|
180
|
+
The built-in memory and SQLite stores implement this contract.
|
|
178
181
|
|
|
179
182
|
The SSE response contains ordered persistence envelopes around standard AI SDK chunks:
|
|
180
183
|
|
|
@@ -219,9 +222,17 @@ app.use(
|
|
|
219
222
|
);
|
|
220
223
|
```
|
|
221
224
|
|
|
222
|
-
`MemorySparkAgentStore` and `MemorySparkArtifactStore` are development implementations. Production
|
|
223
|
-
hosts must supply durable implementations backed by their database/object storage and must preserve
|
|
224
|
-
the ordering contract of `appendRunChunk()`.
|
|
225
|
+
`MemorySparkAgentStore` and `MemorySparkArtifactStore` are development implementations. Production
|
|
226
|
+
hosts must supply durable implementations backed by their database/object storage and must preserve
|
|
227
|
+
the ordering contract of `appendRunChunk()`.
|
|
228
|
+
|
|
229
|
+
`SparkAgentServiceOptions.endOrphanedRuns` defaults to `false`. Enable it only when one process
|
|
230
|
+
owns the store: a message or Stop then ends unfinished runs not held by that process. On a shared
|
|
231
|
+
store, enabling it could end another process's live run.
|
|
232
|
+
|
|
233
|
+
Custom stores can implement `releaseActiveRun(conversationId, runId, updatedAt)` to clear the active
|
|
234
|
+
run only if its ID still matches. Memory and SQLite stores implement it. Without it, the service
|
|
235
|
+
serializes read-and-save release against its own submissions.
|
|
225
236
|
|
|
226
237
|
## Standalone development server
|
|
227
238
|
|
|
@@ -257,8 +268,8 @@ acknowledgement proves only renderer-local history, not durable backend storage.
|
|
|
257
268
|
The standalone server persists conversations, run streams, and screenshot bytes in SQLite. Only
|
|
258
269
|
one local process can execute against a database. After a terminated process is replaced, startup
|
|
259
270
|
preserves recorded output and marks abandoned queued/running runs incomplete without replaying
|
|
260
|
-
scene edits. Pending approvals remain pending
|
|
261
|
-
|
|
271
|
+
scene edits. Pending approvals remain pending; startup does not resume abandoned runs.
|
|
272
|
+
Node 22 reports an experimental warning for its built-in SQLite module.
|
|
262
273
|
|
|
263
274
|
Set `SPARK_SCENE_IDENTITY` only when the host can verify that the value names the same durable
|
|
264
275
|
scene across renderer reconnects. Without it, Spark uses a process-scoped identity and does not
|
|
@@ -267,9 +278,8 @@ authorize interrupted scene mutations to continue after a server restart.
|
|
|
267
278
|
`createStandaloneSparkAgentApp(options)` is asynchronous. Await it before listening, and call
|
|
268
279
|
`await app.dispose()` on shutdown to settle active runs and release storage ownership.
|
|
269
280
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
dependency before release; no new package has been published by this migration.
|
|
281
|
+
When using a sibling `kakapo-sdk` dependency, run `yarn build` in `../kakapo-sdk` before installing
|
|
282
|
+
Spark dependencies. Replace local dependencies with registry versions before publishing.
|
|
273
283
|
|
|
274
284
|
For the explicit fictional account profile, use `yarn dev:demo-account` or
|
|
275
285
|
`spark-agent --profile demo-account`. It adds the `account` skill and `womp.account.read`
|
|
@@ -345,85 +355,17 @@ yarn test
|
|
|
345
355
|
yarn web:build
|
|
346
356
|
```
|
|
347
357
|
|
|
348
|
-
## Release procedure
|
|
349
|
-
|
|
350
|
-
Releases use a manual package publication; no separate release service is required.
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
-
|
|
355
|
-
|
|
356
|
-
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
- Replace fixed scene/screenshot tool history with the host's history adapter. Use
|
|
360
|
-
`convertSparkMessages` when rebuilding model input from current Spark UI messages so artifact
|
|
361
|
-
references become model-visible content. Preserve old records; do not replay historical tools.
|
|
362
|
-
- Custom server executors receive `uiMessages` and convert them using their actual capability
|
|
363
|
-
tools. `SparkRunExecutionContext.modelMessages` has been removed.
|
|
364
|
-
- Custom JavaScript executors must honor cancellation and host-owned user waits. Callback-based
|
|
365
|
-
scene edits and artifact references work with both the native and QuickJS executors.
|
|
366
|
-
|
|
367
|
-
### 4.1.0
|
|
368
|
-
|
|
369
|
-
- `emitImage(artifact, { inspect: false })` displays an image without adding its bytes to model input, including restored history. Inspection remains the default.
|
|
370
|
-
- Generation instructions use completed outputs directly and avoid redundant listing or emission; explicit inspection and follow-up imports remain supported.
|
|
371
|
-
- Streamed tool labels are emitted only after their label field is complete. Hosts can consume `data-tool-input-label` while the rest of the input streams.
|
|
372
|
-
- Server cancellation waits for active execution to settle before reporting its terminal state.
|
|
373
|
-
- Includes the latest geometry material, scalar-port, and primitive improvements from main.
|
|
374
|
-
|
|
375
|
-
### 4.2.2
|
|
376
|
-
|
|
377
|
-
The published 4.2.1 was packed from the 4.2.0 sources and differs from 4.2.0 only in its version
|
|
378
|
-
number, so none of the changes below are in it. Use 4.2.2.
|
|
379
|
-
|
|
380
|
-
Compatible: both additions are optional, and a host that sets neither behaves as before except that a
|
|
381
|
-
run whose progress cannot be stored now ends instead of staying `running`.
|
|
382
|
-
|
|
383
|
-
- A run whose stream chunk, `running` status or ending cannot be stored ends `failed` with a sentence
|
|
384
|
-
instead of staying `running` until a restart. The final status and the conversation release are
|
|
385
|
-
retried in the background for about five minutes; a message or a Stop for that conversation stores
|
|
386
|
-
the ending at once.
|
|
387
|
-
- `SparkAgentServiceOptions.endOrphanedRuns` (default `false`): a message or a Stop ends an unfinished
|
|
388
|
-
active run that no execution in this process holds, with "This run stopped unexpectedly and could
|
|
389
|
-
not be finished." Turn it on only when one process owns the store; on a shared store it would end
|
|
390
|
-
another process's live runs.
|
|
391
|
-
- `SparkAgentStore.releaseActiveRun(conversationId, runId, updatedAt)` (optional): clears the active
|
|
392
|
-
run only while it still names that run. The memory and SQLite stores implement it. A store without
|
|
393
|
-
it has the read-and-save release serialised against the service's own submits, so a late retry
|
|
394
|
-
cannot overwrite a newer message.
|
|
395
|
-
|
|
396
|
-
### 4.2.0
|
|
397
|
-
|
|
398
|
-
Incompatible: a color that can only be a 0-1 one is now refused where it used to be stored as
|
|
399
|
-
near-black, and the `scene-editing` skill payload changed. Hosts that pin the skill surface in a
|
|
400
|
-
fixture must regenerate it.
|
|
401
|
-
|
|
402
|
-
- Model-facing colors state their domain in the declared parameter name: `nodeSetColor`,
|
|
403
|
-
`materialSetColor`, `materialSetSecondaryColor`, `materialSetSubsurfaceColor` and
|
|
404
|
-
`setBackgroundColor` take `rgb255`, and the internal type is `Color255`. The `scene-editing` skill
|
|
405
|
-
version is 30.
|
|
406
|
-
- A color whose every component is strictly between 0 and 1 and none an integer throws, naming the
|
|
407
|
-
0-255 conversion (`{r:0.2, g:0.4, b:0.6}` → "use `{r:51, g:102, b:153}` … or `{r:0, g:0, b:0}` for
|
|
408
|
-
black"). Nothing is auto-scaled: `{r:1, g:0, b:0}`, `{r:0, g:0, b:0}`, `{r:0.5, g:0, b:0}` and
|
|
409
|
-
every 0-255 color write exactly as before.
|
|
410
|
-
- `scene.health` accepts the object ids `scene.read()` publishes, including `0`; a value that is not
|
|
411
|
-
an id is refused with a sentence naming it instead of a serialized schema error. Ids belonging to
|
|
412
|
-
no Area (the root, a root-level Group, a Light) are dropped and reported rather than making the
|
|
413
|
-
whole reading `unverified`.
|
|
414
|
-
- A tool result can no longer cost a turn. Geometry diagnostics quote a source line once per line
|
|
415
|
-
and cap at 5 diagnostics and 4 KiB; the `execute_javascript` envelope bounds the error to 8 KiB and
|
|
416
|
-
the receipts to a 1 MiB model input, always as valid JSON. Only model input is bounded —
|
|
417
|
-
`persistence.afterToolCall`, the UI stream and the host's own receipts keep the original object.
|
|
418
|
-
- A scene-health receipt keeps its totals, limits and overflow flags whole and bounds the per-Area
|
|
419
|
-
rows to 8, affected and overflowing Areas first, naming the omission in `reason`. Health read for a
|
|
420
|
-
decision (`hasGeometryOverflow`, `hasSceneResourcePressure`, `options.onHealth`) still sees every
|
|
421
|
-
row, so no repair decision changes. A consumer fixture that recorded a receipt with more than 8
|
|
422
|
-
Areas will differ.
|
|
423
|
-
- `operations.generate` keeps a host's own cancellation message on a stopped generation instead of
|
|
424
|
-
replacing it with the bare abort reason.
|
|
425
|
-
|
|
426
|
-
### Publishing
|
|
358
|
+
## Release procedure
|
|
359
|
+
|
|
360
|
+
Releases use a manual package publication; no separate release service is required.
|
|
361
|
+
|
|
362
|
+
Versions follow **MAJOR.MINOR.PATCH** (for example, `4.4.0`):
|
|
363
|
+
|
|
364
|
+
- **Major:** breaking changes.
|
|
365
|
+
- **Minor:** backward-compatible new features.
|
|
366
|
+
- **Patch:** backward-compatible bug fixes.
|
|
367
|
+
|
|
368
|
+
### Publishing
|
|
427
369
|
|
|
428
370
|
1. Choose an unused package version after checking `npm view @womp/spark-agent versions --json`.
|
|
429
371
|
Update `package.json` and record public API changes and migration notes. Use a new minor version
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { KakapoAPI, Vec3, CameraConfiguration } from "@womp/kakapo-sdk";
|
|
2
|
+
export type BenchBounds = {
|
|
3
|
+
min: Vec3;
|
|
4
|
+
max: Vec3;
|
|
5
|
+
};
|
|
6
|
+
/** Groups organize geometry; query their visible renderable children, not Group bounds. */
|
|
7
|
+
export declare function benchGeometryIds(api: Pick<KakapoAPI, "listNodes">, parentId?: number): number[];
|
|
8
|
+
/** Fixed Spark-space three-quarter view, fitted against all eight native-world bounding-box corners. */
|
|
9
|
+
export declare function benchCamera(bounds: BenchBounds, aspect: number): CameraConfiguration;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { toEnginePosition } from "./coordinates.js";
|
|
2
|
+
/** Groups organize geometry; query their visible renderable children, not Group bounds. */
|
|
3
|
+
export function benchGeometryIds(api, parentId = 0) {
|
|
4
|
+
return api.listNodes({ parentId }).flatMap(node => {
|
|
5
|
+
if (("hidden" in node && node.hidden) || node.kind === "light")
|
|
6
|
+
return [];
|
|
7
|
+
return node.kind === "group" ? benchGeometryIds(api, node.id) : [node.id];
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
/** Fixed Spark-space three-quarter view, fitted against all eight native-world bounding-box corners. */
|
|
11
|
+
export function benchCamera(bounds, aspect) {
|
|
12
|
+
const axes = ["x", "y", "z"];
|
|
13
|
+
if (!Number.isFinite(aspect) || aspect <= 0 || axes.some(a => !Number.isFinite(bounds.min[a]) || !Number.isFinite(bounds.max[a]) || bounds.min[a] > bounds.max[a]))
|
|
14
|
+
throw new Error("Benchmark framing requires finite ordered bounds and a positive aspect ratio.");
|
|
15
|
+
const target = { x: (bounds.min.x + bounds.max.x) / 2, y: (bounds.min.y + bounds.max.y) / 2, z: (bounds.min.z + bounds.max.z) / 2 };
|
|
16
|
+
const offset = toEnginePosition({ x: 1, y: 0.65, z: 1 });
|
|
17
|
+
const length = Math.hypot(offset.x, offset.y, offset.z);
|
|
18
|
+
const back = { x: offset.x / length, y: offset.y / length, z: offset.z / length };
|
|
19
|
+
const horizontal = Math.hypot(back.x, back.z);
|
|
20
|
+
const right = { x: back.z / horizontal, y: 0, z: -back.x / horizontal };
|
|
21
|
+
const up = { x: -back.x * back.y / horizontal, y: horizontal, z: -back.z * back.y / horizontal };
|
|
22
|
+
const dot = (a, b) => a.x * b.x + a.y * b.y + a.z * b.z;
|
|
23
|
+
const tanH = Math.tan(Math.PI / 6);
|
|
24
|
+
let distance = 0.1;
|
|
25
|
+
for (const x of [bounds.min.x, bounds.max.x])
|
|
26
|
+
for (const y of [bounds.min.y, bounds.max.y])
|
|
27
|
+
for (const z of [bounds.min.z, bounds.max.z]) {
|
|
28
|
+
const point = { x: x - target.x, y: y - target.y, z: z - target.z };
|
|
29
|
+
distance = Math.max(distance, dot(point, back) + 1.1 * Math.max(Math.abs(dot(point, right)) / tanH, Math.abs(dot(point, up)) * aspect / tanH));
|
|
30
|
+
}
|
|
31
|
+
return { position: { x: target.x + back.x * distance, y: target.y + back.y * distance, z: target.z + back.z * distance }, target, projection: "perspective", horizontalFovDegrees: 60 };
|
|
32
|
+
}
|
package/dist/bounded-output.js
CHANGED
|
@@ -1,18 +1,5 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
// WHY THIS FILE EXISTS. `execute_javascript` already refuses a printed payload
|
|
4
|
-
// or a returned value over 1 MiB (agent-tools.ts `jsonValue` and `print`), but
|
|
5
|
-
// nothing bounded the rest of the envelope: the `error` string and the receipts.
|
|
6
|
-
// One rejected `geometry.write` over a one-character enum value produced a
|
|
7
|
-
// compiler diagnostic that repeated the offending source line once per
|
|
8
|
-
// diagnostic, and the resulting tool result cost a whole turn -- 65,136 output
|
|
9
|
-
// tokens, a run that ended `incomplete`, ~235 KB rendered into the panel and an
|
|
10
|
-
// unresponsive tab. A bad argument must cost one tool result, not a turn, so the
|
|
11
|
-
// same budget that guards `print` now guards the whole serialized result.
|
|
12
|
-
//
|
|
13
|
-
// These helpers truncate and say so. They never throw: an over-long diagnostic
|
|
14
|
-
// is still the most useful thing the model can read, so it is cut and labelled
|
|
15
|
-
// rather than replaced.
|
|
1
|
+
// Bound the full serialized tool result, including errors and receipts, before
|
|
2
|
+
// handing it to the model. Oversized diagnostics are cut and labelled.
|
|
16
3
|
const encoder = new TextEncoder();
|
|
17
4
|
const decoder = new TextDecoder();
|
|
18
5
|
export const MODEL_RESULT_BYTE_LIMIT = 1024 * 1024;
|
|
@@ -37,10 +24,11 @@ export function truncateUtf8(text, limit) {
|
|
|
37
24
|
* incomplete rather than wrong.
|
|
38
25
|
*/
|
|
39
26
|
export function boundedText(text, limit, label) {
|
|
40
|
-
const
|
|
27
|
+
const bytes = encoder.encode(text);
|
|
28
|
+
const total = bytes.byteLength;
|
|
41
29
|
if (total <= limit)
|
|
42
30
|
return text;
|
|
43
|
-
const kept =
|
|
31
|
+
const kept = decoder.decode(bytes.subarray(0, limit)).replace(/�$/u, "");
|
|
44
32
|
return `${kept}\n[${label} truncated at ${limit} bytes; ${total - byteLength(kept)} bytes omitted.]`;
|
|
45
33
|
}
|
|
46
34
|
/**
|
|
@@ -67,12 +55,13 @@ export function boundedResultText(output, limit = MODEL_RESULT_BYTE_LIMIT) {
|
|
|
67
55
|
if (receipt.details === undefined)
|
|
68
56
|
return receipt;
|
|
69
57
|
const details = asText(receipt.details);
|
|
70
|
-
|
|
58
|
+
const detailsBytes = byteLength(details);
|
|
59
|
+
if (detailsBytes <= detailsLimit)
|
|
71
60
|
return receipt;
|
|
72
61
|
return {
|
|
73
62
|
...receipt,
|
|
74
63
|
details: {
|
|
75
|
-
omitted: `This receipt's details were ${
|
|
64
|
+
omitted: `This receipt's details were ${detailsBytes} bytes, over the ${detailsLimit} byte limit for one receipt in a tool result. Read the receipt from the host if the outcome matters.`,
|
|
76
65
|
},
|
|
77
66
|
};
|
|
78
67
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { maxLightIntensity } from "@womp/kakapo-sdk";
|
|
2
3
|
import { WOMP_SCENE_DECLARATIONS } from "../generated/scene-declarations.js";
|
|
3
4
|
import { unverifiedSceneHealth } from "../scene-health.js";
|
|
4
5
|
// A node id, as `scene.read()` publishes them: the scene root is 0, so a health
|
|
@@ -37,7 +38,7 @@ export function createSceneCapability(host) {
|
|
|
37
38
|
skills: [
|
|
38
39
|
{
|
|
39
40
|
name: "scene-editing",
|
|
40
|
-
version: "
|
|
41
|
+
version: "42",
|
|
41
42
|
description: "Inspect the open scene and edit its objects, materials, curves, and environment.",
|
|
42
43
|
instructions: `Read the scene first and keep its revision and object IDs. read() includes health.
|
|
43
44
|
Use womp.scene.health() to refresh whole-scene health or womp.scene.health(objectIds) to check specific objects (mapped to their owning Areas).
|
|
@@ -56,13 +57,16 @@ known IDs when editing rather than creating duplicates. Distances follow the cur
|
|
|
56
57
|
Convert a dimension in millimetres to project units by multiplying it by read().unitMultiplier.
|
|
57
58
|
The SDK-backed draft clamps dimension writes to 0.01–1000 mm per component before converting to native units; this is an adapter limit, not a scene-wide size limit. Read back dimensions when physical size matters.
|
|
58
59
|
Area size is a dimensionless scale; Group size stays fixed at one. Lights must be created at root (parentId 0); their size has x/y dimensions.
|
|
59
|
-
Light power
|
|
60
|
+
Light power is linear emitted intensity before collimation, not a percentage or physical unit: doubling it doubles emission, not tone-mapped pixel brightness. Valid ranges are 0–${maxLightIntensity("rect")} for Rect/Sphere and 0–${maxLightIntensity("distant")} for Distant; these limits are not brightness targets. A light-type change preserves intensity and rejects values outside the new type's range; lower intensity first if needed. Rect size is width/height; Sphere uses x as diameter; Distant uses direction, not position or size.
|
|
61
|
+
Use nodeSetFacing(id, target - position) to aim light emission or the readable face of text/decals at a target in the same parent-local space. It keeps Y up (Z up for vertical directions); generic lookAt aligns a different axis and does not aim these faces.
|
|
62
|
+
For text, nodeSetTextSize(id, {fontSize, depth}) sets font em size and extrusion in project units, not a bounding box. Layout width and additional letter spacing also use project units; spacing clamps to ±25 mm. Line height is a multiplier clamped to 0.5–3. The origin anchors the first baseline; alignment uses the layout width. Empty text clears its geometry.
|
|
63
|
+
Decals require an existing loaded image and receiving geometry. Projection is a uniform cube: native scale.x (public size.z) controls all dimensions, not independent width/height/depth. Restriction to an Area requires that parent Area; root decals project globally. Missing image data can yield no projection even when no resource is pending.
|
|
60
64
|
nodeCreate(Curve, parentId) creates an empty curve with zero blend. curvePointAdd(curveId, point, index?) returns the new index; omit index to append or supply an integer from 0 through point count to insert before that position.
|
|
61
65
|
Point defaults: position/rotation/handles zero, profile size {x:1,y:1,z:1} in project units, the curve's material, fixed false, round 0. Pass {} for defaults.
|
|
62
66
|
Removing all points is supported. One point renders a single profile primitive, not a path.
|
|
63
67
|
Curves render sampled profiles, not a continuous sweep. For smooth curves, start with nodeSetDensity(curveId, 250) and nodeSetBlend(curveId, 3).
|
|
64
68
|
Density increases sampling and primitive cost; the 3 mm blend softens joins, not sample positions. Adjust blend to preserve thin features and the intended silhouette; these settings do not guarantee continuity.
|
|
65
|
-
nodeSetUnionResolution(unionId, resolution) sets
|
|
69
|
+
nodeSetUnionResolution(unionId, resolution) sets a dimensionless detail level, clamped to 0.01–0.65: higher is finer and costs more voxels. Set the owning outermost Area, not a nested Union. Material emission ranges from 0 to 1.
|
|
66
70
|
nodeSetBlend and mirror goop take radii in millimetres before parent scaling, regardless of project units, and clamp to 0–500 mm. This does not apply to the FlowIR Boolean Blend port, which takes native units; geometry-nodes-reference gives its conversion.
|
|
67
71
|
V1/V2 curve transforms are read-only;
|
|
68
72
|
edit their points instead. Handles and closure are available only on V3 Bezier curves.
|
|
@@ -81,35 +85,40 @@ Never replace a parametric graph with ordinary primitives to color it. Ordinary
|
|
|
81
85
|
nodeSetColor writes the node color field (used by lights); it does not replace a geometry object's material color.
|
|
82
86
|
Do not recolor a shared material unless every object using it should change. Create and assign the material in the same edit as the scene geometry that uses it; a Geometry Nodes graph instead consumes a material ID created in an earlier edit.
|
|
83
87
|
Create primitives, curves, and text inside Areas/Unions. Respect tree order for subtraction and intersection.
|
|
84
|
-
Groups are organizational only; move and rotate their child Areas individually, not the Group.
|
|
88
|
+
Groups are organizational only; move and rotate their child Areas individually, not the Group.
|
|
89
|
+
An Area is an outermost Union with no Union ancestor: it has its own modeller, bounds, and volumetric resolution. Nested Unions share that Area's resolution, even through Groups.
|
|
90
|
+
Choose Area boundaries for evaluation needs, not individual editability: parts within an Area remain independently editable. Sibling Areas under a Group can overlap without blending together, while each blends internally and has independent resolution. Keep required shared smooth joins or Boolean evaluation within one Area; overlapping independent Areas are not a watertight Boolean union.
|
|
91
|
+
Prioritize requested visual fidelity over minimizing voxel use. If correctly placed thin features render fragmented or missing, increase their owning Area's resolution, up to 0.65 as needed, and compare the same camera; distinguish sampling loss from material/lighting contrast or authored gaps. A higher voxel count is acceptable when detail improves within engine limits. If resolution is insufficient or hits resource limits/downscaling, consider smaller independent Areas where shared blending or Booleans are unnecessary.
|
|
85
92
|
Sphere uses size.x as uniform diameter (y/z do not stretch it), including new or resized spherical curve points. Cylinder/Cone/Pyramid use x as base diameter/width and y as height;
|
|
86
|
-
Torus
|
|
87
|
-
Build and verify coarse geometry and unfamiliar operations before replicating details. Check one representative result, then repeat it.
|
|
88
|
-
|
|
93
|
+
Torus lies in local XZ (axis +Y), with x as outer diameter and y as tube thickness. For these four primitives, nodeSetSize accepts {x, y}; z follows x even when supplied. Cube uses all three dimensions. Node and curve-point round are dimensionless fractions clamped to [0, 1], not radii in project units; rounding does not set size. Cube rounding reaches half its shortest dimension at 1, so a shallow Cube retains broad flat faces rather than becoming an ellipsoid.
|
|
94
|
+
Build and verify coarse geometry and unfamiliar operations before replicating details. Check one representative result, then repeat it.
|
|
95
|
+
Construct both sides of a joint from shared attachment points and axes. Create each mounted part together with its contact or mounting geometry, derived from the supporting surface; preserve intended clearances and separate editability. If contact is uncertain, check the authored positions, dimensions, and axes in 3D: projected overlap is not a connection.
|
|
96
|
+
Fix unintended gaps, floating attachments, and fragmented geometry before decorative detail or presentation. Use inspection to identify a concrete defect and verify its correction, not merely to collect screenshots or healthy receipts.
|
|
97
|
+
Reference fidelity:
|
|
89
98
|
When recreating an image, treat its visible geometry and level of detail as the target—not merely its subject, colors, or list of parts. Preserve the user's chosen workflow and editability requirements.
|
|
90
99
|
Establish a comparison view matching the reference's angle, projection, and subject framing as closely as practical. Match silhouette, proportions, pose, and negative spaces first; then local contours, thickness, curvature, surface transitions, and defining details. Infer unseen geometry conservatively.
|
|
91
100
|
Compare each rendered pass directly with the source. Identify the largest remaining visible shape mismatch, edit it, and verify that it improved before moving to smaller details. Use close-ups when the comparison view cannot resolve a feature; return to the comparison view afterward. Adjust sampling or resolution when visible faceting or segmentation requires it—not as a substitute for reshaping.
|
|
92
|
-
Do not stop at semantic resemblance or after a fixed number of screenshots. Continue while substantial visible mismatches remain and supported edits are making progress, within the available budget. If progress stalls or the chosen representation cannot achieve the requested fidelity, explain the specific limitation and ask before changing workflows. Before finishing, compare the latest render with the reference and address the largest remaining visible mismatch; if substantial differences remain, identify the concrete stopping reason rather than treating an approximation disclaimer as completion.
|
|
101
|
+
Do not stop at semantic resemblance or after a fixed number of screenshots. Continue while substantial visible mismatches remain and supported edits are making progress, within the available budget. If progress stalls or the chosen representation cannot achieve the requested fidelity, explain the specific limitation and ask before changing workflows. Before finishing, compare the latest render with the reference and address the largest remaining visible mismatch; if substantial differences remain, identify the concrete stopping reason rather than treating an approximation disclaimer as completion.
|
|
93
102
|
|
|
94
103
|
nodeClone is shallow (no children). await cloneSubtree(id, { parentId?, name?, index? }) copies the complete hierarchy with fresh IDs,
|
|
95
104
|
preserving local transforms, order and metadata, remapping internal references and sharing external materials/assets.
|
|
96
105
|
Cloning requires a host transport with atomic scene patches; an unsupported host rejects it without changing the draft.
|
|
97
106
|
For primitives, nodeSetBlend joins against all accumulated preceding geometry in the Area, not only the nearest part. A Union's blend affects its outer join, not joins between its children; top-level Area blend does not smooth its contents.
|
|
98
|
-
For organic joins, overlap primitives and tune blend on the joining children while preserving intended gaps
|
|
107
|
+
For organic joins, overlap primitives and tune blend on the joining children while preserving intended gaps.
|
|
99
108
|
Check font, HDR, and material catalogs before selecting names. A host can explicitly report a catalog as
|
|
100
109
|
unavailable. Selecting an HDR resets its intensity; apply a custom intensity after selecting it.
|
|
101
110
|
For library materials, use listSuperMaterials(), then await materialImport(name) inside scene.edit and assign the returned numeric ID the way that object requires: nodeSetMaterialId or curvePointSetMaterialId for scene nodes, the FlowIR SetMaterial node for a Geometry Nodes graph. A failed import rolls back the draft.
|
|
102
111
|
Filter large read results with JavaScript and print only useful details.
|
|
103
112
|
After a major edit, capture a screenshot outside the transaction and emitImage its reference.
|
|
104
113
|
screenshot({ camera: { position: {x,y,z}, target: {x,y,z}, projection: 'perspective', horizontalFovDegrees: 60 } })
|
|
105
|
-
sets a world-space camera in the same Womp coordinates and project units as scene positions (Y-up).
|
|
114
|
+
sets a world-space camera in the same Womp coordinates and project units as scene positions (Y-up).
|
|
106
115
|
For orthographic framing use projection: 'orthographic' and orthographicWidth in project units instead of FOV.
|
|
107
116
|
Direction is derived from position/target; do not use coincident points or an exactly vertical viewing direction.
|
|
108
117
|
Omitted projection/lens settings come from the active camera. Pass the camera again for repeatable captures.
|
|
109
118
|
For object-focused screenshots, identify the requested object and frame it with an explicit camera position and target using its bounds; reuse established framing when appropriate. Choose a view that reveals the requested features without clipping the subject.
|
|
110
119
|
Omitting camera captures the active viewport without auto-fit. Use it when the user asks about the current viewport or clearly refers to what is visible on screen, not on the assumption that it shows the requested object.
|
|
111
120
|
Respect the host's camera-lock restrictions. Verify silhouette,
|
|
112
|
-
connections, openings, proportions, and materials before claiming completion. Use the owning top-level Area for scene-space bounds;
|
|
121
|
+
connections, openings, proportions, and materials before claiming completion. Use the owning top-level Area for scene-space bounds;
|
|
113
122
|
OpenSCAD part bounds are local to the part; individual primitive and curve bounds are unsupported. Renderer bounds and resize calls
|
|
114
123
|
must finish before subsequent writes. Inside scene.edit, complete renderer-backed bounds reads before the first
|
|
115
124
|
draft mutation; the SDK rejects them once the draft is dirty. Inspect committed results when renderer state has not caught up.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const WOMP_SCENE_DECLARATIONS = "declare const womp: { scene: {\n\"read\": (() => Promise<{\n\"health\": {\n\"status\": \"within_limits\" | \"overflow\" | \"unverified\";\n\"freshness\": \"unverified\" | \"snapshot\" | \"post_ack_event\";\n\"revisionVerified\": false;\n\"affectedAreaIds\": Array<string>;\n\"emptyAreaIds\"?: undefined | Array<string>;\n\"thermometer\"?: undefined | {\n\"objects\": {\n[key: string]: {\n\"num_prims\": number;\n\"flag_prim_overflow\": number;\n\"flag_depth_overflow\": number;\n\"flag_vox_overflow\": number;\n\"voxels\": number;\n};\n};\n\"max_num_prims\": number;\n\"max_total_depth\": number;\n\"max_per_object\": number;\n\"total\": number;\n\"max_total\": number;\n\"assets_budget_used\": number;\n\"assets_budget_total\": number;\n\"mesh_instances_used\"?: undefined | number;\n\"mesh_instances_total\"?: undefined | number;\n\"decal_instances_used\"?: undefined | number;\n\"decal_instances_total\"?: undefined | number;\n\"field_instances_used\"?: undefined | number;\n\"field_instances_total\"?: undefined | number;\n};\n\"reason\"?: undefined | string;\n};\n\"revision\": string;\n\"projectId\"?: undefined | number;\n\"unitMultiplier\": number;\n\"nodes\": Array<{\n\"id\": number;\n\"name\": string;\n\"type\": number;\n\"parentId\": number;\n}>;\n}>);\n\"health\": ((objectIds?: undefined | Array<number>) => Promise<{\n\"status\": \"within_limits\" | \"overflow\" | \"unverified\";\n\"freshness\": \"unverified\" | \"snapshot\" | \"post_ack_event\";\n\"revisionVerified\": false;\n\"affectedAreaIds\": Array<string>;\n\"emptyAreaIds\"?: undefined | Array<string>;\n\"thermometer\"?: undefined | {\n\"objects\": {\n[key: string]: {\n\"num_prims\": number;\n\"flag_prim_overflow\": number;\n\"flag_depth_overflow\": number;\n\"flag_vox_overflow\": number;\n\"voxels\": number;\n};\n};\n\"max_num_prims\": number;\n\"max_total_depth\": number;\n\"max_per_object\": number;\n\"total\": number;\n\"max_total\": number;\n\"assets_budget_used\": number;\n\"assets_budget_total\": number;\n\"mesh_instances_used\"?: undefined | number;\n\"mesh_instances_total\"?: undefined | number;\n\"decal_instances_used\"?: undefined | number;\n\"decal_instances_total\"?: undefined | number;\n\"field_instances_used\"?: undefined | number;\n\"field_instances_total\"?: undefined | number;\n};\n\"reason\"?: undefined | string;\n}>);\n\"edit\": (<T>(callback: ((draft: {\n\"listSuperMaterials\": (() => Array<string>);\n\"_getParentId\": ((childId: number) => number);\n\"_getScaleProductUpTo\": ((nodeId: number, includeNodeSelfUnion?: false | true) => number);\n\"NodeType\": {\n\"Primitive\": 0;\n\"Union\": 1;\n\"Light\": 2;\n\"Curve\": 3;\n\"Group\": 4;\n\"Text\": 5;\n\"Field\": 6;\n\"SVG\": 7;\n\"Mesh\": 8;\n\"Decal\": 9;\n\"OpenSCAD\": 10;\n\"Socket\": 11;\n} & {\n[key: number]: string;\n};\n\"PrimitiveType\": {\n\"Sphere\": 0;\n\"Cylinder\": 1;\n\"Cube\": 2;\n\"Cone\": 3;\n\"Torus\": 4;\n\"Pyramid\": 9;\n} & {\n[key: number]: string;\n};\n\"OperationType\": {\n\"Subtract\": 0;\n\"Union\": 1;\n\"Stain\": 2;\n\"Intersect\": 3;\n} & {\n[key: number]: string;\n};\n\"LightType\": {\n\"Rect\": 0;\n\"Sphere\": 1;\n\"Distant\": 2;\n} & {\n[key: number]: string;\n};\n\"nodeCreate\": ((type: number, parentId?: number) => number);\n\"nodeDelete\": ((id: number) => void);\n\"nodeClone\": ((id: number) => number);\n\"cloneSubtree\": ((id: number, options?: {\n\"parentId\"?: undefined | number;\n\"name\"?: undefined | string;\n\"index\"?: undefined | number;\n}) => Promise<number>);\n\"nodeList\": (() => Array<number>);\n\"nodeChildren\": ((parentId: number) => Array<number>);\n\"nodeSetParent\": ((id: number, parentId: number, index?: undefined | number) => void);\n\"nodeGetType\": ((id: number) => number);\n\"nodeGetName\": ((id: number) => string);\n\"nodeSetName\": ((id: number, name: string) => void);\n\"nodeGetParentId\": ((id: number) => number);\n\"nodeGetPos\": ((id: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"nodeGetLock\": ((id: number) => false | true);\n\"nodeSetLock\": ((id: number, locked: false | true) => void);\n\"nodeSetPos\": ((id: number, position: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"nodeGetRot\": ((id: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"nodeSetRot\": ((id: number, rotation: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"nodeGetSize\": ((id: number) => {\n\"x\": number;\n\"y\": number;\n} | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"nodeSetSize\": ((id: number, sizeValue: {\n\"x\": number;\n\"y\": number;\n} | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"nodeGetHide\": ((id: number) => false | true);\n\"nodeSetHide\": ((id: number, hidden: false | true) => void);\n\"nodeGetOp\": ((id: number) => number);\n\"nodeSetOp\": ((id: number, operation: number) => void);\n\"nodeGetBlend\": ((id: number) => number);\n\"nodeSetBlend\": ((id: number, blend: number) => void);\n\"nodeGetRound\": ((id: number) => number);\n\"nodeSetRound\": ((id: number, round: number) => void);\n\"nodeGetColor\": ((id: number) => {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n});\n\"nodeSetColor\": ((id: number, rgb255: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n} | {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n}) => void);\n\"nodeGetMaterialId\": ((id: number) => null | number);\n\"nodeSetMaterialId\": ((id: number, materialId: number) => void);\n\"nodeGetResolution\": ((id: number) => number);\n\"nodeSetUnionResolution\": ((unionId: number, resolution: number) => void);\n\"nodeGetLightType\": ((id: number) => number);\n\"nodeSetLightType\": ((id: number, lightType: number) => void);\n\"nodeGetPower\": ((id: number) => number);\n\"nodeSetPower\": ((id: number, power: number) => void);\n\"nodeGetText\": ((id: number) => string);\n\"nodeSetText\": ((id: number, text: string) => void);\n\"nodeGetFont\": ((id: number) => string);\n\"nodeSetFont\": ((id: number, font: string) => void);\n\"nodeGetWeight\": ((id: number) => number);\n\"nodeSetWeight\": ((id: number, weight: number) => void);\n\"nodeGetItalic\": ((id: number) => false | true);\n\"nodeSetItalic\": ((id: number, italic: false | true) => void);\n\"nodeGetAlign\": ((id: number) => number);\n\"nodeSetAlign\": ((id: number, align: number) => void);\n\"nodeGetWrap\": ((id: number) => number);\n\"nodeSetWrap\": ((id: number, wrap: number) => void);\n\"nodeGetWidth\": ((id: number) => number);\n\"nodeSetWidth\": ((id: number, width: number) => void);\n\"nodeGetSpacing\": ((id: number) => number);\n\"nodeSetSpacing\": ((id: number, spacing: number) => void);\n\"nodeGetLineHeight\": ((id: number) => number);\n\"nodeSetLineHeight\": ((id: number, lineHeight: number) => void);\n\"nodeGetDensity\": ((id: number) => number);\n\"nodeSetDensity\": ((id: number, density: number) => void);\n\"nodeGetRoundness\": ((id: number) => number);\n\"nodeSetRoundness\": ((id: number, roundness: number) => void);\n\"nodeGetSmoothing\": ((id: number) => number);\n\"nodeSetSmoothing\": ((id: number, smoothing: number) => void);\n\"nodeGetPrimType\": ((id: number) => number);\n\"nodeSetPrimType\": ((id: number, primitive: number) => void);\n\"nodeGetMirror\": ((id: number, slot: number) => {\n\"axis\": \"custom\" | \"x\" | \"y\" | \"z\" | \"disabled\";\n\"planePosition\": number;\n\"goop\": number;\n});\n\"nodeSetMirror\": ((id: number, slot: number, axis: \"x\" | \"y\" | \"z\" | \"disabled\", planePosition?: number, goop?: number) => void);\n\"nodeGetThickness\": ((id: number) => number);\n\"nodeSetThickness\": ((id: number, thickness: number) => void);\n\"curveGetClosed\": ((curveId: number) => false | true);\n\"curveSetClosed\": ((curveId: number, closed: false | true) => void);\n\"curvePointGetHandleIn\": ((curveId: number, pointIndex: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"curvePointGetHandleOut\": ((curveId: number, pointIndex: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"curvePointSetHandleIn\": ((curveId: number, pointIndex: number, value: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"curvePointSetHandleOut\": ((curveId: number, pointIndex: number, value: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"curvePointCount\": ((curveId: number) => number);\n\"curvePointAdd\": ((curveId: number, point: {\n\"name\"?: undefined | string;\n\"pos\"?: undefined | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"rot\"?: undefined | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"size\"?: undefined | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"fixed\"?: undefined | false | true;\n\"round\"?: undefined | number;\n\"materialId\"?: undefined | number;\n}, pointIndex?: undefined | number) => number);\n\"curvePointRemove\": ((curveId: number, pointIndex: number) => void);\n\"curvePointGetName\": ((curveId: number, pointIndex: number) => string);\n\"curvePointSetName\": ((curveId: number, pointIndex: number, name: string) => void);\n\"curvePointGetPos\": ((curveId: number, pointIndex: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"curvePointSetPos\": ((curveId: number, pointIndex: number, position: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"curvePointGetRot\": ((curveId: number, pointIndex: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"curvePointSetRot\": ((curveId: number, pointIndex: number, rotation: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"curvePointGetSize\": ((curveId: number, pointIndex: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"curvePointSetSize\": ((curveId: number, pointIndex: number, sizeValue: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"curvePointGetFixed\": ((curveId: number, pointIndex: number) => false | true);\n\"curvePointSetFixed\": ((curveId: number, pointIndex: number, fixed: false | true) => void);\n\"curvePointGetRound\": ((curveId: number, pointIndex: number) => number);\n\"curvePointSetRound\": ((curveId: number, pointIndex: number, round: number) => void);\n\"curvePointGetMaterialId\": ((curveId: number, pointIndex: number) => null | number);\n\"curvePointSetMaterialId\": ((curveId: number, pointIndex: number, materialId: number) => void);\n\"materialImport\": ((name: string) => Promise<number>);\n\"materialCreate\": (() => number);\n\"materialDelete\": ((id: number) => void);\n\"materialList\": (() => Array<number>);\n\"materialGetName\": ((id: number) => string);\n\"materialSetName\": ((id: number, name: string) => void);\n\"materialGetTier\": ((id: number) => number);\n\"materialSetTier\": ((id: number, tier: number) => void);\n\"materialGetColor\": ((id: number) => {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n});\n\"materialSetColor\": ((id: number, rgb255: {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n}) => void);\n\"materialGetSecondaryColor\": ((id: number) => {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n});\n\"materialSetSecondaryColor\": ((id: number, rgb255: {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n}) => void);\n\"materialGetSubsurfaceColor\": ((id: number) => {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n});\n\"materialSetSubsurfaceColor\": ((id: number, rgb255: {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n}) => void);\n\"materialGetRoughness\": ((id: number) => number);\n\"materialSetRoughness\": ((id: number, value: number) => void);\n\"materialGetMetalness\": ((id: number) => number);\n\"materialSetMetalness\": ((id: number, value: number) => void);\n\"materialGetTransmittance\": ((id: number) => number);\n\"materialSetTransmittance\": ((id: number, value: number) => void);\n\"materialGetTranslucency\": ((id: number) => number);\n\"materialSetTranslucency\": ((id: number, value: number) => void);\n\"materialGetIor\": ((id: number) => number);\n\"materialSetIor\": ((id: number, value: number) => void);\n\"materialGetSheen\": ((id: number) => number);\n\"materialSetSheen\": ((id: number, value: number) => void);\n\"materialGetSheenRoughness\": ((id: number) => number);\n\"materialSetSheenRoughness\": ((id: number, value: number) => void);\n\"materialGetSpecularTint\": ((id: number) => number);\n\"materialSetSpecularTint\": ((id: number, value: number) => void);\n\"materialGetAbsorption\": ((id: number) => number);\n\"materialSetAbsorption\": ((id: number, value: number) => void);\n\"materialGetEmission\": ((id: number) => number);\n\"materialSetEmission\": ((id: number, value: number) => void);\n\"materialGetIridescence\": ((id: number) => number);\n\"materialSetIridescence\": ((id: number, value: number) => void);\n\"materialGetTranslucencyWeight\": ((id: number) => number);\n\"materialSetTranslucencyWeight\": ((id: number, value: number) => void);\n\"materialGetDispersion\": ((id: number) => number);\n\"materialSetDispersion\": ((id: number, value: number) => void);\n\"materialGetSurfaceOpacity\": ((id: number) => number);\n\"materialSetSurfaceOpacity\": ((id: number, value: number) => void);\n\"listFontFamilies\": (() => Array<{\n\"name\": string;\n\"variants\": Array<{\n\"weight\": string;\n\"italic\": false | true;\n}>;\n}>);\n\"print\": ((...values: Array<unknown>) => void);\n\"nodeGetAABB\": ((id: number) => Promise<{\n\"min\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"max\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n}>);\n\"nodeResize\": ((id: number, dimensions: {\n\"x\"?: undefined | number;\n\"y\"?: undefined | number;\n\"z\"?: undefined | number;\n}) => Promise<void>);\n\"aabbCenter\": ((box: {\n\"min\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"max\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n}) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"aabbRadius\": ((box: {\n\"min\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"max\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n}) => number);\n\"lookAt\": ((origin: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}, target: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"alignAxis\": ((direction: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}, axis: \"x\" | \"y\" | \"z\") => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"scenePropertiesRead\": (() => {\n\"hdr_name\": undefined | string;\n\"hdr_multiplier\": undefined | number;\n\"hdr_orientation\": undefined | {\n\"x\": number;\n\"y\": number;\n};\n\"backdrop_color1\": undefined | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"backdrop_color2\": undefined | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"backdrop_grad_offset\": undefined | {\n\"x\": number;\n\"y\": number;\n};\n});\n\"listHDRs\": (() => Array<string>);\n\"setHdrName\": ((name: string) => void);\n\"setHdrMultiplier\": ((multiplier: number) => void);\n\"setHdrOrientation\": ((orientation: {\n\"x\": number;\n\"y\": number;\n}) => void);\n\"setBackgroundColor\": ((rgb255: {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n}) => void);\n}) => T | Promise<T>), expectedRevision: string) => Promise<T>);\n\"screenshot\": ((options?: undefined | {\n\"camera\"?: undefined | {\n\"position\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"target\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"projection\"?: undefined | \"perspective\" | \"orthographic\";\n\"horizontalFovDegrees\"?: undefined | number;\n\"orthographicWidth\"?: undefined | number;\n};\n}) => Promise<{\n\"id\": string;\n\"mediaType\": string;\n\"name\"?: undefined | string;\n}>);\n} };\ndeclare function print(...values: unknown[]): void;\ndeclare function emitImage(ref: { id: string; mediaType: string; name?: string }, options?: { inspect?: boolean }): Promise<void>;\ndeclare function emitFile(ref: { id: string; mediaType: string; name?: string }): Promise<void>;\n";
|
|
1
|
+
export declare const WOMP_SCENE_DECLARATIONS = "declare const womp: { scene: {\n\"read\": (() => Promise<{\n\"health\": {\n\"status\": \"within_limits\" | \"overflow\" | \"unverified\";\n\"freshness\": \"unverified\" | \"snapshot\" | \"post_ack_event\";\n\"revisionVerified\": false;\n\"affectedAreaIds\": Array<string>;\n\"emptyAreaIds\"?: undefined | Array<string>;\n\"thermometer\"?: undefined | {\n\"objects\": {\n[key: string]: {\n\"num_prims\": number;\n\"flag_prim_overflow\": number;\n\"flag_depth_overflow\": number;\n\"flag_vox_overflow\": number;\n\"voxels\": number;\n};\n};\n\"max_num_prims\": number;\n\"max_total_depth\": number;\n\"max_per_object\": number;\n\"total\": number;\n\"max_total\": number;\n\"assets_budget_used\": number;\n\"assets_budget_total\": number;\n\"mesh_instances_used\"?: undefined | number;\n\"mesh_instances_total\"?: undefined | number;\n\"decal_instances_used\"?: undefined | number;\n\"decal_instances_total\"?: undefined | number;\n\"field_instances_used\"?: undefined | number;\n\"field_instances_total\"?: undefined | number;\n};\n\"reason\"?: undefined | string;\n};\n\"revision\": string;\n\"projectId\"?: undefined | number;\n\"unitMultiplier\": number;\n\"nodes\": Array<{\n\"id\": number;\n\"name\": string;\n\"type\": number;\n\"parentId\": number;\n}>;\n}>);\n\"health\": ((objectIds?: undefined | Array<number>) => Promise<{\n\"status\": \"within_limits\" | \"overflow\" | \"unverified\";\n\"freshness\": \"unverified\" | \"snapshot\" | \"post_ack_event\";\n\"revisionVerified\": false;\n\"affectedAreaIds\": Array<string>;\n\"emptyAreaIds\"?: undefined | Array<string>;\n\"thermometer\"?: undefined | {\n\"objects\": {\n[key: string]: {\n\"num_prims\": number;\n\"flag_prim_overflow\": number;\n\"flag_depth_overflow\": number;\n\"flag_vox_overflow\": number;\n\"voxels\": number;\n};\n};\n\"max_num_prims\": number;\n\"max_total_depth\": number;\n\"max_per_object\": number;\n\"total\": number;\n\"max_total\": number;\n\"assets_budget_used\": number;\n\"assets_budget_total\": number;\n\"mesh_instances_used\"?: undefined | number;\n\"mesh_instances_total\"?: undefined | number;\n\"decal_instances_used\"?: undefined | number;\n\"decal_instances_total\"?: undefined | number;\n\"field_instances_used\"?: undefined | number;\n\"field_instances_total\"?: undefined | number;\n};\n\"reason\"?: undefined | string;\n}>);\n\"edit\": (<T>(callback: ((draft: {\n\"listSuperMaterials\": (() => Array<string>);\n\"_getParentId\": ((childId: number) => number);\n\"_getScaleProductUpTo\": ((nodeId: number, includeNodeSelfUnion?: false | true) => number);\n\"NodeType\": {\n\"Primitive\": 0;\n\"Union\": 1;\n\"Light\": 2;\n\"Curve\": 3;\n\"Group\": 4;\n\"Text\": 5;\n\"Field\": 6;\n\"SVG\": 7;\n\"Mesh\": 8;\n\"Decal\": 9;\n\"OpenSCAD\": 10;\n\"Socket\": 11;\n} & {\n[key: number]: string;\n};\n\"PrimitiveType\": {\n\"Sphere\": 0;\n\"Cylinder\": 1;\n\"Cube\": 2;\n\"Cone\": 3;\n\"Torus\": 4;\n\"Pyramid\": 9;\n} & {\n[key: number]: string;\n};\n\"OperationType\": {\n\"Subtract\": 0;\n\"Union\": 1;\n\"Stain\": 2;\n\"Intersect\": 3;\n} & {\n[key: number]: string;\n};\n\"LightType\": {\n\"Rect\": 0;\n\"Sphere\": 1;\n\"Distant\": 2;\n} & {\n[key: number]: string;\n};\n\"nodeCreate\": ((type: number, parentId?: number) => number);\n\"nodeDelete\": ((id: number) => void);\n\"nodeClone\": ((id: number) => number);\n\"cloneSubtree\": ((id: number, options?: {\n\"parentId\"?: undefined | number;\n\"name\"?: undefined | string;\n\"index\"?: undefined | number;\n}) => Promise<number>);\n\"nodeList\": (() => Array<number>);\n\"nodeChildren\": ((parentId: number) => Array<number>);\n\"nodeSetParent\": ((id: number, parentId: number, index?: undefined | number) => void);\n\"nodeGetType\": ((id: number) => number);\n\"nodeGetName\": ((id: number) => string);\n\"nodeSetName\": ((id: number, name: string) => void);\n\"nodeGetParentId\": ((id: number) => number);\n\"nodeGetPos\": ((id: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"nodeGetLock\": ((id: number) => false | true);\n\"nodeSetLock\": ((id: number, locked: false | true) => void);\n\"nodeSetPos\": ((id: number, position: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"nodeGetRot\": ((id: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"nodeSetRot\": ((id: number, rotation: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"nodeGetSize\": ((id: number) => {\n\"x\": number;\n\"y\": number;\n} | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"nodeSetSize\": ((id: number, sizeValue: {\n\"x\": number;\n\"y\": number;\n} | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"nodeGetHide\": ((id: number) => false | true);\n\"nodeSetHide\": ((id: number, hidden: false | true) => void);\n\"nodeGetOp\": ((id: number) => number);\n\"nodeSetOp\": ((id: number, operation: number) => void);\n\"nodeGetBlend\": ((id: number) => number);\n\"nodeSetBlend\": ((id: number, blend: number) => void);\n\"nodeGetRound\": ((id: number) => number);\n\"nodeSetRound\": ((id: number, round: number) => void);\n\"nodeGetColor\": ((id: number) => {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n});\n\"nodeSetColor\": ((id: number, rgb255: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n} | {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n}) => void);\n\"nodeGetMaterialId\": ((id: number) => null | number);\n\"nodeSetMaterialId\": ((id: number, materialId: number) => void);\n\"nodeGetResolution\": ((id: number) => number);\n\"nodeSetUnionResolution\": ((unionId: number, resolution: number) => void);\n\"nodeGetLightType\": ((id: number) => number);\n\"nodeSetLightType\": ((id: number, lightType: number) => void);\n\"nodeGetPower\": ((id: number) => number);\n\"nodeSetPower\": ((id: number, power: number) => void);\n\"nodeGetText\": ((id: number) => string);\n\"nodeSetFacing\": ((id: number, direction: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"nodeSetTextSize\": ((id: number, size: {\n\"fontSize\": number;\n\"depth\": number;\n}) => void);\n\"nodeGetTextSize\": ((id: number) => {\n\"fontSize\": number;\n\"depth\": number;\n});\n\"nodeSetText\": ((id: number, text: string) => void);\n\"nodeGetFont\": ((id: number) => string);\n\"nodeSetFont\": ((id: number, font: string) => void);\n\"nodeGetWeight\": ((id: number) => number);\n\"nodeSetWeight\": ((id: number, weight: number) => void);\n\"nodeGetItalic\": ((id: number) => false | true);\n\"nodeSetItalic\": ((id: number, italic: false | true) => void);\n\"nodeGetAlign\": ((id: number) => number);\n\"nodeSetAlign\": ((id: number, align: number) => void);\n\"nodeGetWrap\": ((id: number) => number);\n\"nodeSetWrap\": ((id: number, wrap: number) => void);\n\"nodeGetWidth\": ((id: number) => number);\n\"nodeSetWidth\": ((id: number, width: number) => void);\n\"nodeGetSpacing\": ((id: number) => number);\n\"nodeSetSpacing\": ((id: number, spacing: number) => void);\n\"nodeGetLineHeight\": ((id: number) => number);\n\"nodeSetLineHeight\": ((id: number, lineHeight: number) => void);\n\"nodeGetDensity\": ((id: number) => number);\n\"nodeSetDensity\": ((id: number, density: number) => void);\n\"nodeGetRoundness\": ((id: number) => number);\n\"nodeSetRoundness\": ((id: number, roundness: number) => void);\n\"nodeGetSmoothing\": ((id: number) => number);\n\"nodeSetSmoothing\": ((id: number, smoothing: number) => void);\n\"nodeGetPrimType\": ((id: number) => number);\n\"nodeSetPrimType\": ((id: number, primitive: number) => void);\n\"nodeGetMirror\": ((id: number, slot: number) => {\n\"axis\": \"custom\" | \"x\" | \"y\" | \"z\" | \"disabled\";\n\"planePosition\": number;\n\"goop\": number;\n});\n\"nodeSetMirror\": ((id: number, slot: number, axis: \"x\" | \"y\" | \"z\" | \"disabled\", planePosition?: number, goop?: number) => void);\n\"nodeGetThickness\": ((id: number) => number);\n\"nodeSetThickness\": ((id: number, thickness: number) => void);\n\"curveGetClosed\": ((curveId: number) => false | true);\n\"curveSetClosed\": ((curveId: number, closed: false | true) => void);\n\"curvePointGetHandleIn\": ((curveId: number, pointIndex: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"curvePointGetHandleOut\": ((curveId: number, pointIndex: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"curvePointSetHandleIn\": ((curveId: number, pointIndex: number, value: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"curvePointSetHandleOut\": ((curveId: number, pointIndex: number, value: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"curvePointCount\": ((curveId: number) => number);\n\"curvePointAdd\": ((curveId: number, point: {\n\"name\"?: undefined | string;\n\"pos\"?: undefined | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"rot\"?: undefined | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"size\"?: undefined | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"fixed\"?: undefined | false | true;\n\"round\"?: undefined | number;\n\"materialId\"?: undefined | number;\n}, pointIndex?: undefined | number) => number);\n\"curvePointRemove\": ((curveId: number, pointIndex: number) => void);\n\"curvePointGetName\": ((curveId: number, pointIndex: number) => string);\n\"curvePointSetName\": ((curveId: number, pointIndex: number, name: string) => void);\n\"curvePointGetPos\": ((curveId: number, pointIndex: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"curvePointSetPos\": ((curveId: number, pointIndex: number, position: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"curvePointGetRot\": ((curveId: number, pointIndex: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"curvePointSetRot\": ((curveId: number, pointIndex: number, rotation: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"curvePointGetSize\": ((curveId: number, pointIndex: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"curvePointSetSize\": ((curveId: number, pointIndex: number, sizeValue: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"curvePointGetFixed\": ((curveId: number, pointIndex: number) => false | true);\n\"curvePointSetFixed\": ((curveId: number, pointIndex: number, fixed: false | true) => void);\n\"curvePointGetRound\": ((curveId: number, pointIndex: number) => number);\n\"curvePointSetRound\": ((curveId: number, pointIndex: number, round: number) => void);\n\"curvePointGetMaterialId\": ((curveId: number, pointIndex: number) => null | number);\n\"curvePointSetMaterialId\": ((curveId: number, pointIndex: number, materialId: number) => void);\n\"materialImport\": ((name: string) => Promise<number>);\n\"materialCreate\": (() => number);\n\"materialDelete\": ((id: number) => void);\n\"materialList\": (() => Array<number>);\n\"materialGetName\": ((id: number) => string);\n\"materialSetName\": ((id: number, name: string) => void);\n\"materialGetTier\": ((id: number) => number);\n\"materialSetTier\": ((id: number, tier: number) => void);\n\"materialGetColor\": ((id: number) => {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n});\n\"materialSetColor\": ((id: number, rgb255: {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n}) => void);\n\"materialGetSecondaryColor\": ((id: number) => {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n});\n\"materialSetSecondaryColor\": ((id: number, rgb255: {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n}) => void);\n\"materialGetSubsurfaceColor\": ((id: number) => {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n});\n\"materialSetSubsurfaceColor\": ((id: number, rgb255: {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n}) => void);\n\"materialGetRoughness\": ((id: number) => number);\n\"materialSetRoughness\": ((id: number, value: number) => void);\n\"materialGetMetalness\": ((id: number) => number);\n\"materialSetMetalness\": ((id: number, value: number) => void);\n\"materialGetTransmittance\": ((id: number) => number);\n\"materialSetTransmittance\": ((id: number, value: number) => void);\n\"materialGetTranslucency\": ((id: number) => number);\n\"materialSetTranslucency\": ((id: number, value: number) => void);\n\"materialGetIor\": ((id: number) => number);\n\"materialSetIor\": ((id: number, value: number) => void);\n\"materialGetSheen\": ((id: number) => number);\n\"materialSetSheen\": ((id: number, value: number) => void);\n\"materialGetSheenRoughness\": ((id: number) => number);\n\"materialSetSheenRoughness\": ((id: number, value: number) => void);\n\"materialGetSpecularTint\": ((id: number) => number);\n\"materialSetSpecularTint\": ((id: number, value: number) => void);\n\"materialGetAbsorption\": ((id: number) => number);\n\"materialSetAbsorption\": ((id: number, value: number) => void);\n\"materialGetEmission\": ((id: number) => number);\n\"materialSetEmission\": ((id: number, value: number) => void);\n\"materialGetIridescence\": ((id: number) => number);\n\"materialSetIridescence\": ((id: number, value: number) => void);\n\"materialGetTranslucencyWeight\": ((id: number) => number);\n\"materialSetTranslucencyWeight\": ((id: number, value: number) => void);\n\"materialGetDispersion\": ((id: number) => number);\n\"materialSetDispersion\": ((id: number, value: number) => void);\n\"materialGetSurfaceOpacity\": ((id: number) => number);\n\"materialSetSurfaceOpacity\": ((id: number, value: number) => void);\n\"listFontFamilies\": (() => Array<{\n\"name\": string;\n\"variants\": Array<{\n\"weight\": string;\n\"italic\": false | true;\n}>;\n}>);\n\"print\": ((...values: Array<unknown>) => void);\n\"nodeGetAABB\": ((id: number) => Promise<{\n\"min\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"max\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n}>);\n\"nodeResize\": ((id: number, dimensions: {\n\"x\"?: undefined | number;\n\"y\"?: undefined | number;\n\"z\"?: undefined | number;\n}) => Promise<void>);\n\"aabbCenter\": ((box: {\n\"min\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"max\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n}) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"aabbRadius\": ((box: {\n\"min\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"max\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n}) => number);\n\"lookAt\": ((origin: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}, target: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"alignAxis\": ((direction: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}, axis: \"x\" | \"y\" | \"z\") => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"scenePropertiesRead\": (() => {\n\"hdr_name\": undefined | string;\n\"hdr_multiplier\": undefined | number;\n\"hdr_orientation\": undefined | {\n\"x\": number;\n\"y\": number;\n};\n\"backdrop_color1\": undefined | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"backdrop_color2\": undefined | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"backdrop_grad_offset\": undefined | {\n\"x\": number;\n\"y\": number;\n};\n});\n\"listHDRs\": (() => Array<string>);\n\"setHdrName\": ((name: string) => void);\n\"setHdrMultiplier\": ((multiplier: number) => void);\n\"setHdrOrientation\": ((orientation: {\n\"x\": number;\n\"y\": number;\n}) => void);\n\"setBackgroundColor\": ((rgb255: {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n}) => void);\n}) => T | Promise<T>), expectedRevision: string) => Promise<T>);\n\"screenshot\": ((options?: undefined | {\n\"camera\"?: undefined | {\n\"position\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"target\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"projection\"?: undefined | \"perspective\" | \"orthographic\";\n\"horizontalFovDegrees\"?: undefined | number;\n\"orthographicWidth\"?: undefined | number;\n};\n}) => Promise<{\n\"id\": string;\n\"mediaType\": string;\n\"name\"?: undefined | string;\n}>);\n} };\ndeclare function print(...values: unknown[]): void;\ndeclare function emitImage(ref: { id: string; mediaType: string; name?: string }, options?: { inspect?: boolean }): Promise<void>;\ndeclare function emitFile(ref: { id: string; mediaType: string; name?: string }): Promise<void>;\n";
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// Generated by scripts/generate-skill-declarations.mjs.
|
|
2
2
|
// prettier-ignore
|
|
3
|
-
export const WOMP_SCENE_DECLARATIONS = "declare const womp: { scene: {\n\"read\": (() => Promise<{\n\"health\": {\n\"status\": \"within_limits\" | \"overflow\" | \"unverified\";\n\"freshness\": \"unverified\" | \"snapshot\" | \"post_ack_event\";\n\"revisionVerified\": false;\n\"affectedAreaIds\": Array<string>;\n\"emptyAreaIds\"?: undefined | Array<string>;\n\"thermometer\"?: undefined | {\n\"objects\": {\n[key: string]: {\n\"num_prims\": number;\n\"flag_prim_overflow\": number;\n\"flag_depth_overflow\": number;\n\"flag_vox_overflow\": number;\n\"voxels\": number;\n};\n};\n\"max_num_prims\": number;\n\"max_total_depth\": number;\n\"max_per_object\": number;\n\"total\": number;\n\"max_total\": number;\n\"assets_budget_used\": number;\n\"assets_budget_total\": number;\n\"mesh_instances_used\"?: undefined | number;\n\"mesh_instances_total\"?: undefined | number;\n\"decal_instances_used\"?: undefined | number;\n\"decal_instances_total\"?: undefined | number;\n\"field_instances_used\"?: undefined | number;\n\"field_instances_total\"?: undefined | number;\n};\n\"reason\"?: undefined | string;\n};\n\"revision\": string;\n\"projectId\"?: undefined | number;\n\"unitMultiplier\": number;\n\"nodes\": Array<{\n\"id\": number;\n\"name\": string;\n\"type\": number;\n\"parentId\": number;\n}>;\n}>);\n\"health\": ((objectIds?: undefined | Array<number>) => Promise<{\n\"status\": \"within_limits\" | \"overflow\" | \"unverified\";\n\"freshness\": \"unverified\" | \"snapshot\" | \"post_ack_event\";\n\"revisionVerified\": false;\n\"affectedAreaIds\": Array<string>;\n\"emptyAreaIds\"?: undefined | Array<string>;\n\"thermometer\"?: undefined | {\n\"objects\": {\n[key: string]: {\n\"num_prims\": number;\n\"flag_prim_overflow\": number;\n\"flag_depth_overflow\": number;\n\"flag_vox_overflow\": number;\n\"voxels\": number;\n};\n};\n\"max_num_prims\": number;\n\"max_total_depth\": number;\n\"max_per_object\": number;\n\"total\": number;\n\"max_total\": number;\n\"assets_budget_used\": number;\n\"assets_budget_total\": number;\n\"mesh_instances_used\"?: undefined | number;\n\"mesh_instances_total\"?: undefined | number;\n\"decal_instances_used\"?: undefined | number;\n\"decal_instances_total\"?: undefined | number;\n\"field_instances_used\"?: undefined | number;\n\"field_instances_total\"?: undefined | number;\n};\n\"reason\"?: undefined | string;\n}>);\n\"edit\": (<T>(callback: ((draft: {\n\"listSuperMaterials\": (() => Array<string>);\n\"_getParentId\": ((childId: number) => number);\n\"_getScaleProductUpTo\": ((nodeId: number, includeNodeSelfUnion?: false | true) => number);\n\"NodeType\": {\n\"Primitive\": 0;\n\"Union\": 1;\n\"Light\": 2;\n\"Curve\": 3;\n\"Group\": 4;\n\"Text\": 5;\n\"Field\": 6;\n\"SVG\": 7;\n\"Mesh\": 8;\n\"Decal\": 9;\n\"OpenSCAD\": 10;\n\"Socket\": 11;\n} & {\n[key: number]: string;\n};\n\"PrimitiveType\": {\n\"Sphere\": 0;\n\"Cylinder\": 1;\n\"Cube\": 2;\n\"Cone\": 3;\n\"Torus\": 4;\n\"Pyramid\": 9;\n} & {\n[key: number]: string;\n};\n\"OperationType\": {\n\"Subtract\": 0;\n\"Union\": 1;\n\"Stain\": 2;\n\"Intersect\": 3;\n} & {\n[key: number]: string;\n};\n\"LightType\": {\n\"Rect\": 0;\n\"Sphere\": 1;\n\"Distant\": 2;\n} & {\n[key: number]: string;\n};\n\"nodeCreate\": ((type: number, parentId?: number) => number);\n\"nodeDelete\": ((id: number) => void);\n\"nodeClone\": ((id: number) => number);\n\"cloneSubtree\": ((id: number, options?: {\n\"parentId\"?: undefined | number;\n\"name\"?: undefined | string;\n\"index\"?: undefined | number;\n}) => Promise<number>);\n\"nodeList\": (() => Array<number>);\n\"nodeChildren\": ((parentId: number) => Array<number>);\n\"nodeSetParent\": ((id: number, parentId: number, index?: undefined | number) => void);\n\"nodeGetType\": ((id: number) => number);\n\"nodeGetName\": ((id: number) => string);\n\"nodeSetName\": ((id: number, name: string) => void);\n\"nodeGetParentId\": ((id: number) => number);\n\"nodeGetPos\": ((id: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"nodeGetLock\": ((id: number) => false | true);\n\"nodeSetLock\": ((id: number, locked: false | true) => void);\n\"nodeSetPos\": ((id: number, position: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"nodeGetRot\": ((id: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"nodeSetRot\": ((id: number, rotation: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"nodeGetSize\": ((id: number) => {\n\"x\": number;\n\"y\": number;\n} | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"nodeSetSize\": ((id: number, sizeValue: {\n\"x\": number;\n\"y\": number;\n} | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"nodeGetHide\": ((id: number) => false | true);\n\"nodeSetHide\": ((id: number, hidden: false | true) => void);\n\"nodeGetOp\": ((id: number) => number);\n\"nodeSetOp\": ((id: number, operation: number) => void);\n\"nodeGetBlend\": ((id: number) => number);\n\"nodeSetBlend\": ((id: number, blend: number) => void);\n\"nodeGetRound\": ((id: number) => number);\n\"nodeSetRound\": ((id: number, round: number) => void);\n\"nodeGetColor\": ((id: number) => {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n});\n\"nodeSetColor\": ((id: number, rgb255: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n} | {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n}) => void);\n\"nodeGetMaterialId\": ((id: number) => null | number);\n\"nodeSetMaterialId\": ((id: number, materialId: number) => void);\n\"nodeGetResolution\": ((id: number) => number);\n\"nodeSetUnionResolution\": ((unionId: number, resolution: number) => void);\n\"nodeGetLightType\": ((id: number) => number);\n\"nodeSetLightType\": ((id: number, lightType: number) => void);\n\"nodeGetPower\": ((id: number) => number);\n\"nodeSetPower\": ((id: number, power: number) => void);\n\"nodeGetText\": ((id: number) => string);\n\"nodeSetText\": ((id: number, text: string) => void);\n\"nodeGetFont\": ((id: number) => string);\n\"nodeSetFont\": ((id: number, font: string) => void);\n\"nodeGetWeight\": ((id: number) => number);\n\"nodeSetWeight\": ((id: number, weight: number) => void);\n\"nodeGetItalic\": ((id: number) => false | true);\n\"nodeSetItalic\": ((id: number, italic: false | true) => void);\n\"nodeGetAlign\": ((id: number) => number);\n\"nodeSetAlign\": ((id: number, align: number) => void);\n\"nodeGetWrap\": ((id: number) => number);\n\"nodeSetWrap\": ((id: number, wrap: number) => void);\n\"nodeGetWidth\": ((id: number) => number);\n\"nodeSetWidth\": ((id: number, width: number) => void);\n\"nodeGetSpacing\": ((id: number) => number);\n\"nodeSetSpacing\": ((id: number, spacing: number) => void);\n\"nodeGetLineHeight\": ((id: number) => number);\n\"nodeSetLineHeight\": ((id: number, lineHeight: number) => void);\n\"nodeGetDensity\": ((id: number) => number);\n\"nodeSetDensity\": ((id: number, density: number) => void);\n\"nodeGetRoundness\": ((id: number) => number);\n\"nodeSetRoundness\": ((id: number, roundness: number) => void);\n\"nodeGetSmoothing\": ((id: number) => number);\n\"nodeSetSmoothing\": ((id: number, smoothing: number) => void);\n\"nodeGetPrimType\": ((id: number) => number);\n\"nodeSetPrimType\": ((id: number, primitive: number) => void);\n\"nodeGetMirror\": ((id: number, slot: number) => {\n\"axis\": \"custom\" | \"x\" | \"y\" | \"z\" | \"disabled\";\n\"planePosition\": number;\n\"goop\": number;\n});\n\"nodeSetMirror\": ((id: number, slot: number, axis: \"x\" | \"y\" | \"z\" | \"disabled\", planePosition?: number, goop?: number) => void);\n\"nodeGetThickness\": ((id: number) => number);\n\"nodeSetThickness\": ((id: number, thickness: number) => void);\n\"curveGetClosed\": ((curveId: number) => false | true);\n\"curveSetClosed\": ((curveId: number, closed: false | true) => void);\n\"curvePointGetHandleIn\": ((curveId: number, pointIndex: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"curvePointGetHandleOut\": ((curveId: number, pointIndex: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"curvePointSetHandleIn\": ((curveId: number, pointIndex: number, value: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"curvePointSetHandleOut\": ((curveId: number, pointIndex: number, value: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"curvePointCount\": ((curveId: number) => number);\n\"curvePointAdd\": ((curveId: number, point: {\n\"name\"?: undefined | string;\n\"pos\"?: undefined | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"rot\"?: undefined | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"size\"?: undefined | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"fixed\"?: undefined | false | true;\n\"round\"?: undefined | number;\n\"materialId\"?: undefined | number;\n}, pointIndex?: undefined | number) => number);\n\"curvePointRemove\": ((curveId: number, pointIndex: number) => void);\n\"curvePointGetName\": ((curveId: number, pointIndex: number) => string);\n\"curvePointSetName\": ((curveId: number, pointIndex: number, name: string) => void);\n\"curvePointGetPos\": ((curveId: number, pointIndex: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"curvePointSetPos\": ((curveId: number, pointIndex: number, position: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"curvePointGetRot\": ((curveId: number, pointIndex: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"curvePointSetRot\": ((curveId: number, pointIndex: number, rotation: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"curvePointGetSize\": ((curveId: number, pointIndex: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"curvePointSetSize\": ((curveId: number, pointIndex: number, sizeValue: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"curvePointGetFixed\": ((curveId: number, pointIndex: number) => false | true);\n\"curvePointSetFixed\": ((curveId: number, pointIndex: number, fixed: false | true) => void);\n\"curvePointGetRound\": ((curveId: number, pointIndex: number) => number);\n\"curvePointSetRound\": ((curveId: number, pointIndex: number, round: number) => void);\n\"curvePointGetMaterialId\": ((curveId: number, pointIndex: number) => null | number);\n\"curvePointSetMaterialId\": ((curveId: number, pointIndex: number, materialId: number) => void);\n\"materialImport\": ((name: string) => Promise<number>);\n\"materialCreate\": (() => number);\n\"materialDelete\": ((id: number) => void);\n\"materialList\": (() => Array<number>);\n\"materialGetName\": ((id: number) => string);\n\"materialSetName\": ((id: number, name: string) => void);\n\"materialGetTier\": ((id: number) => number);\n\"materialSetTier\": ((id: number, tier: number) => void);\n\"materialGetColor\": ((id: number) => {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n});\n\"materialSetColor\": ((id: number, rgb255: {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n}) => void);\n\"materialGetSecondaryColor\": ((id: number) => {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n});\n\"materialSetSecondaryColor\": ((id: number, rgb255: {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n}) => void);\n\"materialGetSubsurfaceColor\": ((id: number) => {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n});\n\"materialSetSubsurfaceColor\": ((id: number, rgb255: {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n}) => void);\n\"materialGetRoughness\": ((id: number) => number);\n\"materialSetRoughness\": ((id: number, value: number) => void);\n\"materialGetMetalness\": ((id: number) => number);\n\"materialSetMetalness\": ((id: number, value: number) => void);\n\"materialGetTransmittance\": ((id: number) => number);\n\"materialSetTransmittance\": ((id: number, value: number) => void);\n\"materialGetTranslucency\": ((id: number) => number);\n\"materialSetTranslucency\": ((id: number, value: number) => void);\n\"materialGetIor\": ((id: number) => number);\n\"materialSetIor\": ((id: number, value: number) => void);\n\"materialGetSheen\": ((id: number) => number);\n\"materialSetSheen\": ((id: number, value: number) => void);\n\"materialGetSheenRoughness\": ((id: number) => number);\n\"materialSetSheenRoughness\": ((id: number, value: number) => void);\n\"materialGetSpecularTint\": ((id: number) => number);\n\"materialSetSpecularTint\": ((id: number, value: number) => void);\n\"materialGetAbsorption\": ((id: number) => number);\n\"materialSetAbsorption\": ((id: number, value: number) => void);\n\"materialGetEmission\": ((id: number) => number);\n\"materialSetEmission\": ((id: number, value: number) => void);\n\"materialGetIridescence\": ((id: number) => number);\n\"materialSetIridescence\": ((id: number, value: number) => void);\n\"materialGetTranslucencyWeight\": ((id: number) => number);\n\"materialSetTranslucencyWeight\": ((id: number, value: number) => void);\n\"materialGetDispersion\": ((id: number) => number);\n\"materialSetDispersion\": ((id: number, value: number) => void);\n\"materialGetSurfaceOpacity\": ((id: number) => number);\n\"materialSetSurfaceOpacity\": ((id: number, value: number) => void);\n\"listFontFamilies\": (() => Array<{\n\"name\": string;\n\"variants\": Array<{\n\"weight\": string;\n\"italic\": false | true;\n}>;\n}>);\n\"print\": ((...values: Array<unknown>) => void);\n\"nodeGetAABB\": ((id: number) => Promise<{\n\"min\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"max\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n}>);\n\"nodeResize\": ((id: number, dimensions: {\n\"x\"?: undefined | number;\n\"y\"?: undefined | number;\n\"z\"?: undefined | number;\n}) => Promise<void>);\n\"aabbCenter\": ((box: {\n\"min\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"max\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n}) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"aabbRadius\": ((box: {\n\"min\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"max\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n}) => number);\n\"lookAt\": ((origin: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}, target: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"alignAxis\": ((direction: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}, axis: \"x\" | \"y\" | \"z\") => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"scenePropertiesRead\": (() => {\n\"hdr_name\": undefined | string;\n\"hdr_multiplier\": undefined | number;\n\"hdr_orientation\": undefined | {\n\"x\": number;\n\"y\": number;\n};\n\"backdrop_color1\": undefined | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"backdrop_color2\": undefined | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"backdrop_grad_offset\": undefined | {\n\"x\": number;\n\"y\": number;\n};\n});\n\"listHDRs\": (() => Array<string>);\n\"setHdrName\": ((name: string) => void);\n\"setHdrMultiplier\": ((multiplier: number) => void);\n\"setHdrOrientation\": ((orientation: {\n\"x\": number;\n\"y\": number;\n}) => void);\n\"setBackgroundColor\": ((rgb255: {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n}) => void);\n}) => T | Promise<T>), expectedRevision: string) => Promise<T>);\n\"screenshot\": ((options?: undefined | {\n\"camera\"?: undefined | {\n\"position\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"target\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"projection\"?: undefined | \"perspective\" | \"orthographic\";\n\"horizontalFovDegrees\"?: undefined | number;\n\"orthographicWidth\"?: undefined | number;\n};\n}) => Promise<{\n\"id\": string;\n\"mediaType\": string;\n\"name\"?: undefined | string;\n}>);\n} };\ndeclare function print(...values: unknown[]): void;\ndeclare function emitImage(ref: { id: string; mediaType: string; name?: string }, options?: { inspect?: boolean }): Promise<void>;\ndeclare function emitFile(ref: { id: string; mediaType: string; name?: string }): Promise<void>;\n";
|
|
3
|
+
export const WOMP_SCENE_DECLARATIONS = "declare const womp: { scene: {\n\"read\": (() => Promise<{\n\"health\": {\n\"status\": \"within_limits\" | \"overflow\" | \"unverified\";\n\"freshness\": \"unverified\" | \"snapshot\" | \"post_ack_event\";\n\"revisionVerified\": false;\n\"affectedAreaIds\": Array<string>;\n\"emptyAreaIds\"?: undefined | Array<string>;\n\"thermometer\"?: undefined | {\n\"objects\": {\n[key: string]: {\n\"num_prims\": number;\n\"flag_prim_overflow\": number;\n\"flag_depth_overflow\": number;\n\"flag_vox_overflow\": number;\n\"voxels\": number;\n};\n};\n\"max_num_prims\": number;\n\"max_total_depth\": number;\n\"max_per_object\": number;\n\"total\": number;\n\"max_total\": number;\n\"assets_budget_used\": number;\n\"assets_budget_total\": number;\n\"mesh_instances_used\"?: undefined | number;\n\"mesh_instances_total\"?: undefined | number;\n\"decal_instances_used\"?: undefined | number;\n\"decal_instances_total\"?: undefined | number;\n\"field_instances_used\"?: undefined | number;\n\"field_instances_total\"?: undefined | number;\n};\n\"reason\"?: undefined | string;\n};\n\"revision\": string;\n\"projectId\"?: undefined | number;\n\"unitMultiplier\": number;\n\"nodes\": Array<{\n\"id\": number;\n\"name\": string;\n\"type\": number;\n\"parentId\": number;\n}>;\n}>);\n\"health\": ((objectIds?: undefined | Array<number>) => Promise<{\n\"status\": \"within_limits\" | \"overflow\" | \"unverified\";\n\"freshness\": \"unverified\" | \"snapshot\" | \"post_ack_event\";\n\"revisionVerified\": false;\n\"affectedAreaIds\": Array<string>;\n\"emptyAreaIds\"?: undefined | Array<string>;\n\"thermometer\"?: undefined | {\n\"objects\": {\n[key: string]: {\n\"num_prims\": number;\n\"flag_prim_overflow\": number;\n\"flag_depth_overflow\": number;\n\"flag_vox_overflow\": number;\n\"voxels\": number;\n};\n};\n\"max_num_prims\": number;\n\"max_total_depth\": number;\n\"max_per_object\": number;\n\"total\": number;\n\"max_total\": number;\n\"assets_budget_used\": number;\n\"assets_budget_total\": number;\n\"mesh_instances_used\"?: undefined | number;\n\"mesh_instances_total\"?: undefined | number;\n\"decal_instances_used\"?: undefined | number;\n\"decal_instances_total\"?: undefined | number;\n\"field_instances_used\"?: undefined | number;\n\"field_instances_total\"?: undefined | number;\n};\n\"reason\"?: undefined | string;\n}>);\n\"edit\": (<T>(callback: ((draft: {\n\"listSuperMaterials\": (() => Array<string>);\n\"_getParentId\": ((childId: number) => number);\n\"_getScaleProductUpTo\": ((nodeId: number, includeNodeSelfUnion?: false | true) => number);\n\"NodeType\": {\n\"Primitive\": 0;\n\"Union\": 1;\n\"Light\": 2;\n\"Curve\": 3;\n\"Group\": 4;\n\"Text\": 5;\n\"Field\": 6;\n\"SVG\": 7;\n\"Mesh\": 8;\n\"Decal\": 9;\n\"OpenSCAD\": 10;\n\"Socket\": 11;\n} & {\n[key: number]: string;\n};\n\"PrimitiveType\": {\n\"Sphere\": 0;\n\"Cylinder\": 1;\n\"Cube\": 2;\n\"Cone\": 3;\n\"Torus\": 4;\n\"Pyramid\": 9;\n} & {\n[key: number]: string;\n};\n\"OperationType\": {\n\"Subtract\": 0;\n\"Union\": 1;\n\"Stain\": 2;\n\"Intersect\": 3;\n} & {\n[key: number]: string;\n};\n\"LightType\": {\n\"Rect\": 0;\n\"Sphere\": 1;\n\"Distant\": 2;\n} & {\n[key: number]: string;\n};\n\"nodeCreate\": ((type: number, parentId?: number) => number);\n\"nodeDelete\": ((id: number) => void);\n\"nodeClone\": ((id: number) => number);\n\"cloneSubtree\": ((id: number, options?: {\n\"parentId\"?: undefined | number;\n\"name\"?: undefined | string;\n\"index\"?: undefined | number;\n}) => Promise<number>);\n\"nodeList\": (() => Array<number>);\n\"nodeChildren\": ((parentId: number) => Array<number>);\n\"nodeSetParent\": ((id: number, parentId: number, index?: undefined | number) => void);\n\"nodeGetType\": ((id: number) => number);\n\"nodeGetName\": ((id: number) => string);\n\"nodeSetName\": ((id: number, name: string) => void);\n\"nodeGetParentId\": ((id: number) => number);\n\"nodeGetPos\": ((id: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"nodeGetLock\": ((id: number) => false | true);\n\"nodeSetLock\": ((id: number, locked: false | true) => void);\n\"nodeSetPos\": ((id: number, position: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"nodeGetRot\": ((id: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"nodeSetRot\": ((id: number, rotation: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"nodeGetSize\": ((id: number) => {\n\"x\": number;\n\"y\": number;\n} | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"nodeSetSize\": ((id: number, sizeValue: {\n\"x\": number;\n\"y\": number;\n} | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"nodeGetHide\": ((id: number) => false | true);\n\"nodeSetHide\": ((id: number, hidden: false | true) => void);\n\"nodeGetOp\": ((id: number) => number);\n\"nodeSetOp\": ((id: number, operation: number) => void);\n\"nodeGetBlend\": ((id: number) => number);\n\"nodeSetBlend\": ((id: number, blend: number) => void);\n\"nodeGetRound\": ((id: number) => number);\n\"nodeSetRound\": ((id: number, round: number) => void);\n\"nodeGetColor\": ((id: number) => {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n});\n\"nodeSetColor\": ((id: number, rgb255: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n} | {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n}) => void);\n\"nodeGetMaterialId\": ((id: number) => null | number);\n\"nodeSetMaterialId\": ((id: number, materialId: number) => void);\n\"nodeGetResolution\": ((id: number) => number);\n\"nodeSetUnionResolution\": ((unionId: number, resolution: number) => void);\n\"nodeGetLightType\": ((id: number) => number);\n\"nodeSetLightType\": ((id: number, lightType: number) => void);\n\"nodeGetPower\": ((id: number) => number);\n\"nodeSetPower\": ((id: number, power: number) => void);\n\"nodeGetText\": ((id: number) => string);\n\"nodeSetFacing\": ((id: number, direction: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"nodeSetTextSize\": ((id: number, size: {\n\"fontSize\": number;\n\"depth\": number;\n}) => void);\n\"nodeGetTextSize\": ((id: number) => {\n\"fontSize\": number;\n\"depth\": number;\n});\n\"nodeSetText\": ((id: number, text: string) => void);\n\"nodeGetFont\": ((id: number) => string);\n\"nodeSetFont\": ((id: number, font: string) => void);\n\"nodeGetWeight\": ((id: number) => number);\n\"nodeSetWeight\": ((id: number, weight: number) => void);\n\"nodeGetItalic\": ((id: number) => false | true);\n\"nodeSetItalic\": ((id: number, italic: false | true) => void);\n\"nodeGetAlign\": ((id: number) => number);\n\"nodeSetAlign\": ((id: number, align: number) => void);\n\"nodeGetWrap\": ((id: number) => number);\n\"nodeSetWrap\": ((id: number, wrap: number) => void);\n\"nodeGetWidth\": ((id: number) => number);\n\"nodeSetWidth\": ((id: number, width: number) => void);\n\"nodeGetSpacing\": ((id: number) => number);\n\"nodeSetSpacing\": ((id: number, spacing: number) => void);\n\"nodeGetLineHeight\": ((id: number) => number);\n\"nodeSetLineHeight\": ((id: number, lineHeight: number) => void);\n\"nodeGetDensity\": ((id: number) => number);\n\"nodeSetDensity\": ((id: number, density: number) => void);\n\"nodeGetRoundness\": ((id: number) => number);\n\"nodeSetRoundness\": ((id: number, roundness: number) => void);\n\"nodeGetSmoothing\": ((id: number) => number);\n\"nodeSetSmoothing\": ((id: number, smoothing: number) => void);\n\"nodeGetPrimType\": ((id: number) => number);\n\"nodeSetPrimType\": ((id: number, primitive: number) => void);\n\"nodeGetMirror\": ((id: number, slot: number) => {\n\"axis\": \"custom\" | \"x\" | \"y\" | \"z\" | \"disabled\";\n\"planePosition\": number;\n\"goop\": number;\n});\n\"nodeSetMirror\": ((id: number, slot: number, axis: \"x\" | \"y\" | \"z\" | \"disabled\", planePosition?: number, goop?: number) => void);\n\"nodeGetThickness\": ((id: number) => number);\n\"nodeSetThickness\": ((id: number, thickness: number) => void);\n\"curveGetClosed\": ((curveId: number) => false | true);\n\"curveSetClosed\": ((curveId: number, closed: false | true) => void);\n\"curvePointGetHandleIn\": ((curveId: number, pointIndex: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"curvePointGetHandleOut\": ((curveId: number, pointIndex: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"curvePointSetHandleIn\": ((curveId: number, pointIndex: number, value: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"curvePointSetHandleOut\": ((curveId: number, pointIndex: number, value: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"curvePointCount\": ((curveId: number) => number);\n\"curvePointAdd\": ((curveId: number, point: {\n\"name\"?: undefined | string;\n\"pos\"?: undefined | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"rot\"?: undefined | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"size\"?: undefined | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"fixed\"?: undefined | false | true;\n\"round\"?: undefined | number;\n\"materialId\"?: undefined | number;\n}, pointIndex?: undefined | number) => number);\n\"curvePointRemove\": ((curveId: number, pointIndex: number) => void);\n\"curvePointGetName\": ((curveId: number, pointIndex: number) => string);\n\"curvePointSetName\": ((curveId: number, pointIndex: number, name: string) => void);\n\"curvePointGetPos\": ((curveId: number, pointIndex: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"curvePointSetPos\": ((curveId: number, pointIndex: number, position: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"curvePointGetRot\": ((curveId: number, pointIndex: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"curvePointSetRot\": ((curveId: number, pointIndex: number, rotation: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"curvePointGetSize\": ((curveId: number, pointIndex: number) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"curvePointSetSize\": ((curveId: number, pointIndex: number, sizeValue: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => void);\n\"curvePointGetFixed\": ((curveId: number, pointIndex: number) => false | true);\n\"curvePointSetFixed\": ((curveId: number, pointIndex: number, fixed: false | true) => void);\n\"curvePointGetRound\": ((curveId: number, pointIndex: number) => number);\n\"curvePointSetRound\": ((curveId: number, pointIndex: number, round: number) => void);\n\"curvePointGetMaterialId\": ((curveId: number, pointIndex: number) => null | number);\n\"curvePointSetMaterialId\": ((curveId: number, pointIndex: number, materialId: number) => void);\n\"materialImport\": ((name: string) => Promise<number>);\n\"materialCreate\": (() => number);\n\"materialDelete\": ((id: number) => void);\n\"materialList\": (() => Array<number>);\n\"materialGetName\": ((id: number) => string);\n\"materialSetName\": ((id: number, name: string) => void);\n\"materialGetTier\": ((id: number) => number);\n\"materialSetTier\": ((id: number, tier: number) => void);\n\"materialGetColor\": ((id: number) => {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n});\n\"materialSetColor\": ((id: number, rgb255: {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n}) => void);\n\"materialGetSecondaryColor\": ((id: number) => {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n});\n\"materialSetSecondaryColor\": ((id: number, rgb255: {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n}) => void);\n\"materialGetSubsurfaceColor\": ((id: number) => {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n});\n\"materialSetSubsurfaceColor\": ((id: number, rgb255: {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n}) => void);\n\"materialGetRoughness\": ((id: number) => number);\n\"materialSetRoughness\": ((id: number, value: number) => void);\n\"materialGetMetalness\": ((id: number) => number);\n\"materialSetMetalness\": ((id: number, value: number) => void);\n\"materialGetTransmittance\": ((id: number) => number);\n\"materialSetTransmittance\": ((id: number, value: number) => void);\n\"materialGetTranslucency\": ((id: number) => number);\n\"materialSetTranslucency\": ((id: number, value: number) => void);\n\"materialGetIor\": ((id: number) => number);\n\"materialSetIor\": ((id: number, value: number) => void);\n\"materialGetSheen\": ((id: number) => number);\n\"materialSetSheen\": ((id: number, value: number) => void);\n\"materialGetSheenRoughness\": ((id: number) => number);\n\"materialSetSheenRoughness\": ((id: number, value: number) => void);\n\"materialGetSpecularTint\": ((id: number) => number);\n\"materialSetSpecularTint\": ((id: number, value: number) => void);\n\"materialGetAbsorption\": ((id: number) => number);\n\"materialSetAbsorption\": ((id: number, value: number) => void);\n\"materialGetEmission\": ((id: number) => number);\n\"materialSetEmission\": ((id: number, value: number) => void);\n\"materialGetIridescence\": ((id: number) => number);\n\"materialSetIridescence\": ((id: number, value: number) => void);\n\"materialGetTranslucencyWeight\": ((id: number) => number);\n\"materialSetTranslucencyWeight\": ((id: number, value: number) => void);\n\"materialGetDispersion\": ((id: number) => number);\n\"materialSetDispersion\": ((id: number, value: number) => void);\n\"materialGetSurfaceOpacity\": ((id: number) => number);\n\"materialSetSurfaceOpacity\": ((id: number, value: number) => void);\n\"listFontFamilies\": (() => Array<{\n\"name\": string;\n\"variants\": Array<{\n\"weight\": string;\n\"italic\": false | true;\n}>;\n}>);\n\"print\": ((...values: Array<unknown>) => void);\n\"nodeGetAABB\": ((id: number) => Promise<{\n\"min\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"max\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n}>);\n\"nodeResize\": ((id: number, dimensions: {\n\"x\"?: undefined | number;\n\"y\"?: undefined | number;\n\"z\"?: undefined | number;\n}) => Promise<void>);\n\"aabbCenter\": ((box: {\n\"min\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"max\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n}) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"aabbRadius\": ((box: {\n\"min\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"max\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n}) => number);\n\"lookAt\": ((origin: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}, target: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}) => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"alignAxis\": ((direction: {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n}, axis: \"x\" | \"y\" | \"z\") => {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n});\n\"scenePropertiesRead\": (() => {\n\"hdr_name\": undefined | string;\n\"hdr_multiplier\": undefined | number;\n\"hdr_orientation\": undefined | {\n\"x\": number;\n\"y\": number;\n};\n\"backdrop_color1\": undefined | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"backdrop_color2\": undefined | {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"backdrop_grad_offset\": undefined | {\n\"x\": number;\n\"y\": number;\n};\n});\n\"listHDRs\": (() => Array<string>);\n\"setHdrName\": ((name: string) => void);\n\"setHdrMultiplier\": ((multiplier: number) => void);\n\"setHdrOrientation\": ((orientation: {\n\"x\": number;\n\"y\": number;\n}) => void);\n\"setBackgroundColor\": ((rgb255: {\n\"r\": number;\n\"g\": number;\n\"b\": number;\n}) => void);\n}) => T | Promise<T>), expectedRevision: string) => Promise<T>);\n\"screenshot\": ((options?: undefined | {\n\"camera\"?: undefined | {\n\"position\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"target\": {\n\"x\": number;\n\"y\": number;\n\"z\": number;\n};\n\"projection\"?: undefined | \"perspective\" | \"orthographic\";\n\"horizontalFovDegrees\"?: undefined | number;\n\"orthographicWidth\"?: undefined | number;\n};\n}) => Promise<{\n\"id\": string;\n\"mediaType\": string;\n\"name\"?: undefined | string;\n}>);\n} };\ndeclare function print(...values: unknown[]): void;\ndeclare function emitImage(ref: { id: string; mediaType: string; name?: string }, options?: { inspect?: boolean }): Promise<void>;\ndeclare function emitFile(ref: { id: string; mediaType: string; name?: string }): Promise<void>;\n";
|
package/dist/run-metrics.js
CHANGED
|
@@ -15,15 +15,29 @@ export function createBenchMetrics() {
|
|
|
15
15
|
return { toolCounts, steps: Array.from(steps.values()) };
|
|
16
16
|
},
|
|
17
17
|
snapshot() {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
let readSkill = 0;
|
|
19
|
+
let executeJavaScript = 0;
|
|
20
|
+
for (const name of calls.values()) {
|
|
21
|
+
if (name === "read_skill")
|
|
22
|
+
readSkill++;
|
|
23
|
+
if (name === "execute_javascript")
|
|
24
|
+
executeJavaScript++;
|
|
25
|
+
}
|
|
26
|
+
let pricedSteps = 0;
|
|
27
|
+
let costUsd = 0;
|
|
28
|
+
for (const step of steps.values()) {
|
|
29
|
+
const cost = step.cost?.totalUsd ?? null;
|
|
30
|
+
if (cost === null)
|
|
31
|
+
continue;
|
|
32
|
+
pricedSteps++;
|
|
33
|
+
costUsd += cost;
|
|
34
|
+
}
|
|
21
35
|
return {
|
|
22
36
|
steps: steps.size,
|
|
23
|
-
readSkill
|
|
24
|
-
executeJavaScript
|
|
25
|
-
costUsd:
|
|
26
|
-
costStatus: (
|
|
37
|
+
readSkill,
|
|
38
|
+
executeJavaScript,
|
|
39
|
+
costUsd: pricedSteps ? costUsd : null,
|
|
40
|
+
costStatus: (pricedSteps === 0 ? "unavailable" : pricedSteps < steps.size ? "partial" : "estimated"),
|
|
27
41
|
};
|
|
28
42
|
},
|
|
29
43
|
};
|
package/dist/scene-health.js
CHANGED
|
@@ -65,11 +65,19 @@ export function receiptSceneHealth(health, limit = MAX_RECEIPT_THERMOMETER_OBJEC
|
|
|
65
65
|
object.num_prims >= thermometer.max_num_prims ||
|
|
66
66
|
object.voxels >= thermometer.max_per_object));
|
|
67
67
|
};
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
68
|
+
const affected = health.affectedAreaIds.filter((id) => thermometer.objects[id] !== undefined);
|
|
69
|
+
const affectedIds = new Set(health.affectedAreaIds);
|
|
70
|
+
const overflowingIds = [];
|
|
71
|
+
const remainingIds = [];
|
|
72
|
+
for (const id of ids) {
|
|
73
|
+
if (affectedIds.has(id))
|
|
74
|
+
continue;
|
|
75
|
+
if (overflowing(id))
|
|
76
|
+
overflowingIds.push(id);
|
|
77
|
+
else
|
|
78
|
+
remainingIds.push(id);
|
|
79
|
+
}
|
|
80
|
+
const ordered = [...affected, ...overflowingIds, ...remainingIds];
|
|
73
81
|
const kept = ordered.slice(0, limit);
|
|
74
82
|
const objects = {};
|
|
75
83
|
for (const id of kept)
|
package/dist/scene-metadata.js
CHANGED
|
@@ -4,21 +4,21 @@ export function metadataObject(value) {
|
|
|
4
4
|
: {};
|
|
5
5
|
}
|
|
6
6
|
export function readMaterialMetadata(scene, id) {
|
|
7
|
-
return metadataObject(metadataObject(scene.getSceneExt().materialsExt)[String(id)]);
|
|
7
|
+
return metadataObject(metadataObject(scene.getSceneExt(["materialsExt"]).materialsExt)[String(id)]);
|
|
8
8
|
}
|
|
9
9
|
export function writeMaterialMetadata(scene, id, changes) {
|
|
10
|
-
const materials = metadataObject(scene.getSceneExt().materialsExt);
|
|
10
|
+
const materials = metadataObject(scene.getSceneExt(["materialsExt"]).materialsExt);
|
|
11
11
|
scene.patchSceneExt([{
|
|
12
12
|
op: "add",
|
|
13
13
|
path: "/materialsExt",
|
|
14
14
|
value: { ...materials, [id]: { ...metadataObject(materials[String(id)]), ...changes } },
|
|
15
|
-
}]);
|
|
15
|
+
}], { returnScene: false });
|
|
16
16
|
}
|
|
17
17
|
export function removeMaterialMetadata(scene, id) {
|
|
18
|
-
const materials = metadataObject(scene.getSceneExt().materialsExt);
|
|
18
|
+
const materials = metadataObject(scene.getSceneExt(["materialsExt"]).materialsExt);
|
|
19
19
|
if (!Object.hasOwn(materials, id))
|
|
20
20
|
return;
|
|
21
|
-
scene.patchSceneExt([{ op: "remove", path: `/materialsExt/${id}` }]);
|
|
21
|
+
scene.patchSceneExt([{ op: "remove", path: `/materialsExt/${id}` }], { returnScene: false });
|
|
22
22
|
}
|
|
23
23
|
export function shiftCurvePointMetadata(scene, curveId, index, direction) {
|
|
24
24
|
const shift = (value) => {
|
|
@@ -35,7 +35,7 @@ export function shiftCurvePointMetadata(scene, curveId, index, direction) {
|
|
|
35
35
|
}
|
|
36
36
|
return result;
|
|
37
37
|
};
|
|
38
|
-
const ext = scene.getSceneExt();
|
|
38
|
+
const ext = scene.getSceneExt([String(curveId), "perUserExt"]);
|
|
39
39
|
const curve = metadataObject(ext[String(curveId)]);
|
|
40
40
|
const points = shift(curve.pointsExt);
|
|
41
41
|
if (direction === 1) {
|
|
@@ -45,7 +45,7 @@ export function shiftCurvePointMetadata(scene, curveId, index, direction) {
|
|
|
45
45
|
name: `Point ${index + 1}`,
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
|
-
scene.patchSceneExt([{ op: "add", path: `/${curveId}`, value: { ...curve, pointsExt: points } }]);
|
|
48
|
+
scene.patchSceneExt([{ op: "add", path: `/${curveId}`, value: { ...curve, pointsExt: points } }], { returnScene: false });
|
|
49
49
|
const users = metadataObject(ext.perUserExt);
|
|
50
50
|
const updatedUsers = { ...users };
|
|
51
51
|
let changed = false;
|
|
@@ -61,5 +61,5 @@ export function shiftCurvePointMetadata(scene, curveId, index, direction) {
|
|
|
61
61
|
changed = true;
|
|
62
62
|
}
|
|
63
63
|
if (changed)
|
|
64
|
-
scene.patchSceneExt([{ op: "add", path: "/perUserExt", value: updatedUsers }]);
|
|
64
|
+
scene.patchSceneExt([{ op: "add", path: "/perUserExt", value: updatedUsers }], { returnScene: false });
|
|
65
65
|
}
|
package/dist/sdk-scene-host.d.ts
CHANGED
|
@@ -129,6 +129,15 @@ export declare function createSdkSceneDraft(api: KakapoAPI, scene: SceneEdit, se
|
|
|
129
129
|
nodeGetPower: (id: number) => number;
|
|
130
130
|
nodeSetPower: (id: number, power: number) => void;
|
|
131
131
|
nodeGetText: (id: number) => string;
|
|
132
|
+
nodeSetFacing: (id: number, direction: import("@womp/kakapo-sdk").Vec3) => void;
|
|
133
|
+
nodeSetTextSize: (id: number, size: {
|
|
134
|
+
fontSize: number;
|
|
135
|
+
depth: number;
|
|
136
|
+
}) => void;
|
|
137
|
+
nodeGetTextSize: (id: number) => {
|
|
138
|
+
fontSize: number;
|
|
139
|
+
depth: number;
|
|
140
|
+
};
|
|
132
141
|
nodeSetText: (id: number, text: string) => void;
|
|
133
142
|
nodeGetFont: (id: number) => string;
|
|
134
143
|
nodeSetFont: (id: number, font: string) => void;
|
package/dist/sdk-scene-host.js
CHANGED
|
@@ -12,5 +12,6 @@ export async function captureSdkSceneScreenshot(api, input) {
|
|
|
12
12
|
};
|
|
13
13
|
if (camera.orthographicWidth !== undefined)
|
|
14
14
|
camera.orthographicWidth *= INTERNAL_UNITS_PER_MM / units;
|
|
15
|
+
await api.setCamera(camera);
|
|
15
16
|
return api.captureScreenshot({ camera, timeoutMs: 30_000 });
|
|
16
17
|
}
|
|
@@ -1,28 +1,5 @@
|
|
|
1
|
-
export declare const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
readonly prompt: "Make a matte-black desk lamp, 45 cm tall, with a circular base 18 cm in diameter, two slender articulated arms, and a conical shade 15 cm wide. Give the shade a white interior and a warm-white bulb.";
|
|
7
|
-
}, {
|
|
8
|
-
readonly id: "coffee-mug";
|
|
9
|
-
readonly prompt: "Make a teal ceramic mug, 10 cm tall and 9 cm in diameter, with a gently rounded base, an open top, a thick rim, and a large C-shaped handle. Give it a cream-colored interior.";
|
|
10
|
-
}, {
|
|
11
|
-
readonly id: "bookshelf";
|
|
12
|
-
readonly prompt: "Make a light-oak bookshelf, 180 cm tall, 90 cm wide, and 30 cm deep. Give it five evenly spaced open compartments, thick rectangular side panels, a solid back panel, and a recessed base.";
|
|
13
|
-
}, {
|
|
14
|
-
readonly id: "backpack";
|
|
15
|
-
readonly prompt: "Make a navy-blue backpack, 45 cm tall, 30 cm wide, and 18 cm deep. Give it a rounded rectangular body, a large front zipper pocket, two padded shoulder straps, a top carry handle, and light-gray zipper pulls.";
|
|
16
|
-
}, {
|
|
17
|
-
readonly id: "toaster";
|
|
18
|
-
readonly prompt: "Make a cream-colored two-slot toaster, 28 cm wide, 18 cm deep, and 20 cm tall. Give it rounded corners, a brushed-metal top, two long bread slots, a silver side lever, and a circular browning dial.";
|
|
19
|
-
}, {
|
|
20
|
-
readonly id: "plant-pot";
|
|
21
|
-
readonly prompt: "Make a terracotta plant pot, 25 cm tall, tapering from a 30 cm opening to a 20 cm base. Give it a thick rolled rim and dark soil containing a small plant with six broad green leaves on short stems.";
|
|
22
|
-
}, {
|
|
23
|
-
readonly id: "suitcase";
|
|
24
|
-
readonly prompt: "Make a burgundy hard-shell suitcase, 65 cm tall, 42 cm wide, and 26 cm deep. Give it rounded corners, five vertical ribs on each broad face, four black spinner wheels, a silver telescoping handle, and a black side carry handle.";
|
|
25
|
-
}, {
|
|
26
|
-
readonly id: "dining-table";
|
|
27
|
-
readonly prompt: "Make a rectangular walnut dining table, 160 cm long, 90 cm wide, and 75 cm tall. Give it a 4 cm thick tabletop with softly rounded corners, four square tapered legs, and a recessed wooden apron beneath the top.";
|
|
28
|
-
}];
|
|
1
|
+
export declare const BENCH_ORIENTATION = "Orient the object upright (+Y), with its front facing +Z and its base centered at the origin.";
|
|
2
|
+
export declare const BENCH_PROMPTS: {
|
|
3
|
+
prompt: string;
|
|
4
|
+
id: string;
|
|
5
|
+
}[];
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export const BENCH_ORIENTATION = "Orient the object upright (+Y), with its front facing +Z and its base centered at the origin.";
|
|
1
2
|
export const BENCH_PROMPTS = [
|
|
2
3
|
{ id: "armchair", prompt: "Make a mustard-yellow upholstered armchair, 85 cm wide, 90 cm deep, and 85 cm tall. Give it a thick square seat cushion, a slightly reclined backrest, rounded armrests, and four short tapered wooden legs." },
|
|
3
4
|
{ id: "desk-lamp", prompt: "Make a matte-black desk lamp, 45 cm tall, with a circular base 18 cm in diameter, two slender articulated arms, and a conical shade 15 cm wide. Give the shade a white interior and a warm-white bulb." },
|
|
@@ -8,4 +9,4 @@ export const BENCH_PROMPTS = [
|
|
|
8
9
|
{ id: "plant-pot", prompt: "Make a terracotta plant pot, 25 cm tall, tapering from a 30 cm opening to a 20 cm base. Give it a thick rolled rim and dark soil containing a small plant with six broad green leaves on short stems." },
|
|
9
10
|
{ id: "suitcase", prompt: "Make a burgundy hard-shell suitcase, 65 cm tall, 42 cm wide, and 26 cm deep. Give it rounded corners, five vertical ribs on each broad face, four black spinner wheels, a silver telescoping handle, and a black side carry handle." },
|
|
10
11
|
{ id: "dining-table", prompt: "Make a rectangular walnut dining table, 160 cm long, 90 cm wide, and 75 cm tall. Give it a 4 cm thick tabletop with softly rounded corners, four square tapered legs, and a recessed wooden apron beneath the top." },
|
|
11
|
-
];
|
|
12
|
+
].map(item => ({ ...item, prompt: `${item.prompt} ${BENCH_ORIENTATION}` }));
|
package/dist/simple-bench.js
CHANGED
|
@@ -2,7 +2,7 @@ import { once } from "node:events";
|
|
|
2
2
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { KakapoAPI } from "@womp/kakapo-sdk";
|
|
5
|
-
import {
|
|
5
|
+
import { benchCamera, benchGeometryIds } from "./bench-camera.js";
|
|
6
6
|
import { SparkChatTransport } from "./client.js";
|
|
7
7
|
import { createStandaloneSparkAgentApp } from "./server/standalone.js";
|
|
8
8
|
import { BENCH_PROMPTS } from "./simple-bench-prompts.js";
|
|
@@ -40,7 +40,7 @@ export async function runSimpleBench(options) {
|
|
|
40
40
|
const report = async () => {
|
|
41
41
|
await writeFile(path.join(options.output, "results.json"), JSON.stringify({
|
|
42
42
|
version: 1, startedAt, nodeVersion: process.version, settings: options.settings,
|
|
43
|
-
timeoutMs: options.timeoutMs, camera: "
|
|
43
|
+
timeoutMs: options.timeoutMs, camera: "fixed-three-quarter-v3", plannedPrompts: prompts.map((item) => item.id),
|
|
44
44
|
totalCost: totalBenchCost(results), results,
|
|
45
45
|
}, null, 2));
|
|
46
46
|
const columns = ["id", "status", "steps", "readSkill", "executeJavaScript", "screenshots", "durationMs", "costUsd", "costStatus", "image", "error"];
|
|
@@ -100,30 +100,18 @@ export async function runSimpleBench(options) {
|
|
|
100
100
|
const api = new KakapoAPI({ url: options.kakapoUrl, requestTimeoutMs: 30_000 });
|
|
101
101
|
try {
|
|
102
102
|
await api.connect();
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
103
|
+
const snapshot = await api.rpc("scene_state_get");
|
|
104
|
+
await writeFile(path.join(options.output, `${item.id}.scene.json`), typeof snapshot === "string" ? snapshot : JSON.stringify(snapshot));
|
|
105
|
+
const ids = benchGeometryIds(api);
|
|
106
106
|
const bounds = await api.getNodesBoundingBox(ids);
|
|
107
107
|
const viewport = await api.captureScreenshot({});
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
const
|
|
111
|
-
if (
|
|
112
|
-
throw new Error("
|
|
113
|
-
|
|
114
|
-
x: (bounds.min.x + bounds.max.x) / 2,
|
|
115
|
-
y: (bounds.min.y + bounds.max.y) / 2,
|
|
116
|
-
z: (bounds.min.z + bounds.max.z) / 2,
|
|
117
|
-
};
|
|
118
|
-
const radius = Math.hypot(bounds.max.x - bounds.min.x, bounds.max.y - bounds.min.y, bounds.max.z - bounds.min.z) / 2;
|
|
119
|
-
const halfAngle = Math.atan(Math.tan(Math.PI / 6) * Math.min(1, viewport.height / viewport.width));
|
|
120
|
-
const offset = Math.max(0.1, radius * 1.1 / Math.sin(halfAngle)) / directionLength;
|
|
121
|
-
const image = await api.captureScreenshot({ camera: {
|
|
122
|
-
position: { x: target.x - direction.x * offset, y: target.y - direction.y * offset, z: target.z - direction.z * offset },
|
|
123
|
-
target, projection: "perspective", horizontalFovDegrees: 60,
|
|
124
|
-
}, timeoutMs: 30_000 });
|
|
108
|
+
const camera = benchCamera(bounds, viewport.width / viewport.height);
|
|
109
|
+
await writeFile(path.join(options.output, `${item.id}.framing.json`), JSON.stringify({ ids, bounds, width: viewport.width, height: viewport.height, cameras: { "three-quarter": camera } }, null, 2));
|
|
110
|
+
const image = await api.captureScreenshot({ camera, timeoutMs: 30_000 });
|
|
111
|
+
if (image.width !== viewport.width || image.height !== viewport.height)
|
|
112
|
+
throw new Error("Viewport changed during benchmark capture.");
|
|
113
|
+
await writeFile(path.join(options.output, `${item.id}.jpg`), image.data);
|
|
125
114
|
result.image = `${item.id}.jpg`;
|
|
126
|
-
await writeFile(path.join(options.output, result.image), image.data);
|
|
127
115
|
}
|
|
128
116
|
finally {
|
|
129
117
|
api.disconnect();
|
package/dist/womp-scene-api.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FontFamily, KakapoAPI, NodeKind, SceneEdit, Vec2, Vec3 } from "@womp/kakapo-sdk";
|
|
1
|
+
import type { FontFamily, KakapoAPI, KakapoNode, NodeKind, SceneEdit, Vec2, Vec3 } from "@womp/kakapo-sdk";
|
|
2
2
|
import { type SceneHdr } from "./scene-environment.js";
|
|
3
3
|
import { type MirrorAxis } from "./coordinates.js";
|
|
4
4
|
export declare const NodeType: {
|
|
@@ -68,7 +68,7 @@ export type WompSceneApiContext = {
|
|
|
68
68
|
importLibraryMaterial?(name: string): Promise<number>;
|
|
69
69
|
getDefaultMaterialId(): number;
|
|
70
70
|
fonts: FontFamily[];
|
|
71
|
-
requireNode(id: number): void;
|
|
71
|
+
requireNode(id: number): KakapoNode | void;
|
|
72
72
|
trackNode(id: number): void;
|
|
73
73
|
trackMaterial(id: number): void;
|
|
74
74
|
untrackMaterial(id: number): void;
|
|
@@ -164,8 +164,20 @@ export declare function createWompSceneApi(context: WompSceneApiContext): {
|
|
|
164
164
|
nodeGetLightType: (id: number) => number;
|
|
165
165
|
nodeSetLightType: (id: number, lightType: number) => void;
|
|
166
166
|
nodeGetPower: (id: number) => number;
|
|
167
|
+
/** Linear emitted intensity before collimation; not a percentage or physical unit. */
|
|
167
168
|
nodeSetPower: (id: number, power: number) => void;
|
|
168
169
|
nodeGetText: (id: number) => string;
|
|
170
|
+
/** Aim light emission or the readable text/decal face using target minus node position in parent-local coordinates. Use instead of generic lookAt for these faces. Y-up, Z-up when vertical. */
|
|
171
|
+
nodeSetFacing: (id: number, direction: Vec3) => void;
|
|
172
|
+
/** Font em size and extrusion depth in project units, not text bounding-box dimensions. */
|
|
173
|
+
nodeSetTextSize: (id: number, size: {
|
|
174
|
+
fontSize: number;
|
|
175
|
+
depth: number;
|
|
176
|
+
}) => void;
|
|
177
|
+
nodeGetTextSize: (id: number) => {
|
|
178
|
+
fontSize: number;
|
|
179
|
+
depth: number;
|
|
180
|
+
};
|
|
169
181
|
nodeSetText: (id: number, text: string) => void;
|
|
170
182
|
nodeGetFont: (id: number) => string;
|
|
171
183
|
nodeSetFont: (id: number, font: string) => void;
|
|
@@ -177,8 +189,10 @@ export declare function createWompSceneApi(context: WompSceneApiContext): {
|
|
|
177
189
|
nodeSetAlign: (id: number, align: number) => void;
|
|
178
190
|
nodeGetWrap: (id: number) => number;
|
|
179
191
|
nodeSetWrap: (id: number, wrap: number) => void;
|
|
192
|
+
/** Text layout width in project units, including owning Area scale. */
|
|
180
193
|
nodeGetWidth: (id: number) => number;
|
|
181
194
|
nodeSetWidth: (id: number, width: number) => void;
|
|
195
|
+
/** Additional letter spacing in project units, including owning Area scale. */
|
|
182
196
|
nodeGetSpacing: (id: number) => number;
|
|
183
197
|
nodeSetSpacing: (id: number, spacing: number) => void;
|
|
184
198
|
nodeGetLineHeight: (id: number) => number;
|
|
@@ -272,6 +286,7 @@ export declare function createWompSceneApi(context: WompSceneApiContext): {
|
|
|
272
286
|
nodeResize: (id: number, dimensions: Partial<Vec3>) => Promise<void>;
|
|
273
287
|
aabbCenter: (box: AABB) => Vec3;
|
|
274
288
|
aabbRadius: (box: AABB) => number;
|
|
289
|
+
/** Align local +Z from origin toward target, not a light's emission or a text/decal face; use nodeSetFacing for those. */
|
|
275
290
|
lookAt: typeof lookAt;
|
|
276
291
|
alignAxis: typeof alignAxis;
|
|
277
292
|
scenePropertiesRead: () => {
|
package/dist/womp-scene-api.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { xyzRotationFromMatrix, MAX_BLEND_RADIUS_MM, MAX_MIRROR_BLEND_RADIUS_MM } from "@womp/kakapo-sdk";
|
|
1
|
+
import { xyzRotationFromMatrix, MAX_BLEND_RADIUS_MM, MAX_MIRROR_BLEND_RADIUS_MM, maxLightIntensity } from "@womp/kakapo-sdk";
|
|
2
2
|
import { metadataObject, readMaterialMetadata, removeMaterialMetadata, shiftCurvePointMetadata, writeMaterialMetadata, } from "./scene-metadata.js";
|
|
3
3
|
import { createSceneEnvironment } from "./scene-environment.js";
|
|
4
4
|
import { assertColor255 } from "./color.js";
|
|
5
|
-
import { convertRotationBasis, sceneUnitMultiplier, fromEngineDimensions, fromEngineMirrorRotation, fromEnginePosition, toEngineDimensions, toEngineMirrorRotation, toEnginePosition, } from "./coordinates.js";
|
|
5
|
+
import { INTERNAL_UNITS_PER_MM, convertRotationBasis, sceneUnitMultiplier, fromEngineDimensions, fromEngineMirrorRotation, fromEnginePosition, toEngineDimensions, toEngineMirrorRotation, toEnginePosition, } from "./coordinates.js";
|
|
6
6
|
export const NodeType = {
|
|
7
7
|
Primitive: 0,
|
|
8
8
|
Union: 1,
|
|
@@ -200,8 +200,7 @@ export function createWompSceneApi(context) {
|
|
|
200
200
|
const actualParent = (parentId) => (parentId === 0 ? context.rootId : parentId);
|
|
201
201
|
const publicParent = (parentId) => parentId === null || parentId === context.rootId ? 0 : parentId;
|
|
202
202
|
const requireNode = (id) => {
|
|
203
|
-
context.requireNode(id);
|
|
204
|
-
return scene.getNode(id);
|
|
203
|
+
return context.requireNode(id) ?? scene.getNode(id);
|
|
205
204
|
};
|
|
206
205
|
const requireEditableTransform = (id) => {
|
|
207
206
|
const node = requireNode(id);
|
|
@@ -336,7 +335,7 @@ export function createWompSceneApi(context) {
|
|
|
336
335
|
throw new Error("Name cannot be empty");
|
|
337
336
|
if (Array.from(normalized).length > 120)
|
|
338
337
|
throw new Error("Name is too long (max 120 characters)");
|
|
339
|
-
const curve = metadataObject(scene.getSceneExt()[String(curveId)]);
|
|
338
|
+
const curve = metadataObject(scene.getSceneExt([String(curveId)])[String(curveId)]);
|
|
340
339
|
const points = metadataObject(curve.pointsExt);
|
|
341
340
|
scene.patchSceneExt([{
|
|
342
341
|
op: "add",
|
|
@@ -348,7 +347,7 @@ export function createWompSceneApi(context) {
|
|
|
348
347
|
[index]: { ...metadataObject(points[String(index)]), name: normalized },
|
|
349
348
|
},
|
|
350
349
|
},
|
|
351
|
-
}]);
|
|
350
|
+
}], { returnScene: false });
|
|
352
351
|
};
|
|
353
352
|
const addCurvePoint = (curveId, point, pointIndex) => {
|
|
354
353
|
const curve = requireCurve(curveId);
|
|
@@ -396,6 +395,8 @@ export function createWompSceneApi(context) {
|
|
|
396
395
|
const y = finite(sizeValue?.y, "size.y");
|
|
397
396
|
if (x <= 0 || y <= 0)
|
|
398
397
|
throw new Error("Light size.x and size.y must be positive");
|
|
398
|
+
if ("z" in sizeValue)
|
|
399
|
+
finite(sizeValue.z, "size.z");
|
|
399
400
|
const converted = toEngineDimensions({ x, y, z: 1 }, unitMultiplier);
|
|
400
401
|
update(id, { size: { x: converted.z, y: converted.y } });
|
|
401
402
|
return;
|
|
@@ -605,11 +606,11 @@ export function createWompSceneApi(context) {
|
|
|
605
606
|
nodeGetPos: nodePosition,
|
|
606
607
|
nodeGetLock: (id) => {
|
|
607
608
|
requireNode(id);
|
|
608
|
-
return Boolean(metadataObject(scene.getSceneExt()[String(id)]).locked);
|
|
609
|
+
return Boolean(metadataObject(scene.getSceneExt([String(id)])[String(id)]).locked);
|
|
609
610
|
},
|
|
610
611
|
nodeSetLock: (id, locked) => {
|
|
611
612
|
requireNode(id);
|
|
612
|
-
const current = metadataObject(scene.getSceneExt()[String(id)]);
|
|
613
|
+
const current = metadataObject(scene.getSceneExt([String(id)])[String(id)]);
|
|
613
614
|
scene.patchSceneExt([{ op: "add", path: `/${id}`, value: { ...current, locked: Boolean(locked) } }]);
|
|
614
615
|
},
|
|
615
616
|
nodeSetPos: (id, position) => {
|
|
@@ -644,7 +645,7 @@ export function createWompSceneApi(context) {
|
|
|
644
645
|
return "operation" in node ? OPERATIONS.indexOf(node.operation) : OperationType.Union;
|
|
645
646
|
},
|
|
646
647
|
nodeSetOp: (id, operation) => {
|
|
647
|
-
const value = OPERATIONS[
|
|
648
|
+
const value = OPERATIONS[finite(operation, "operation")];
|
|
648
649
|
if (!value)
|
|
649
650
|
throw new Error("Operation must be from 0 to 3");
|
|
650
651
|
const node = requireNode(id);
|
|
@@ -702,51 +703,113 @@ export function createWompSceneApi(context) {
|
|
|
702
703
|
},
|
|
703
704
|
nodeGetLightType: (id) => LIGHT_TYPES.indexOf(requireLight(id).lightType),
|
|
704
705
|
nodeSetLightType: (id, lightType) => {
|
|
705
|
-
|
|
706
|
+
requireLight(id);
|
|
707
|
+
const value = LIGHT_TYPES[finite(lightType, "lightType")];
|
|
706
708
|
if (!value)
|
|
707
|
-
throw new Error("LightType must be from 0 to 2");
|
|
709
|
+
throw new Error("LightType must be an integer from 0 to 2");
|
|
708
710
|
update(id, { lightType: value });
|
|
709
711
|
},
|
|
710
712
|
nodeGetPower: (id) => requireLight(id).power,
|
|
713
|
+
/** Linear emitted intensity before collimation; not a percentage or physical unit. */
|
|
711
714
|
nodeSetPower: (id, power) => {
|
|
712
|
-
requireLight(id);
|
|
713
|
-
|
|
714
|
-
|
|
715
|
+
const light = requireLight(id);
|
|
716
|
+
const max = maxLightIntensity(light.lightType);
|
|
717
|
+
if (!Number.isFinite(power) || power < 0 || power > max)
|
|
718
|
+
throw new Error(`Light ${id} (${light.lightType}): linear intensity must be a finite number from 0 through ${max}`);
|
|
715
719
|
update(id, { power });
|
|
716
720
|
},
|
|
717
721
|
nodeGetText: (id) => requireText(id).text,
|
|
718
|
-
|
|
722
|
+
/** Aim light emission or the readable text/decal face using target minus node position in parent-local coordinates. Use instead of generic lookAt for these faces. Y-up, Z-up when vertical. */
|
|
723
|
+
nodeSetFacing: (id, direction) => {
|
|
724
|
+
requireNode(id);
|
|
725
|
+
const value = vector(direction, "direction");
|
|
726
|
+
const nativeDirection = { x: -value.z, y: value.y, z: -value.x };
|
|
727
|
+
const up = Math.abs(value.y) / Math.hypot(value.x, value.y, value.z) > 1 - 1e-8
|
|
728
|
+
? { x: -1, y: 0, z: 0 } : { x: 0, y: 1, z: 0 };
|
|
729
|
+
context.call("setNodeFacing", [id, nativeDirection, up], () => scene.setNodeFacing(id, nativeDirection, up));
|
|
730
|
+
},
|
|
731
|
+
/** Font em size and extrusion depth in project units, not text bounding-box dimensions. */
|
|
732
|
+
nodeSetTextSize: (id, size) => {
|
|
733
|
+
requireText(id);
|
|
734
|
+
const fontSize = finite(size?.fontSize, "fontSize");
|
|
735
|
+
const depth = finite(size?.depth, "depth");
|
|
736
|
+
if (fontSize <= 0 || depth <= 0)
|
|
737
|
+
throw new Error("Text fontSize and depth must be positive");
|
|
738
|
+
const factor = INTERNAL_UNITS_PER_MM / ancestorScale(id);
|
|
739
|
+
const nativeSize = {
|
|
740
|
+
fontSize: clamp(fontSize / unitMultiplier, 0.01, 1000) * factor,
|
|
741
|
+
depth: clamp(depth / unitMultiplier, 0.01, 1000) * factor,
|
|
742
|
+
};
|
|
743
|
+
context.call("setTextSize", [id, nativeSize], () => scene.setTextSize(id, nativeSize));
|
|
744
|
+
},
|
|
745
|
+
nodeGetTextSize: (id) => {
|
|
746
|
+
const node = requireText(id);
|
|
747
|
+
const factor = ancestorScale(id) * unitMultiplier / INTERNAL_UNITS_PER_MM;
|
|
748
|
+
return { fontSize: node.transform.scale.x * factor, depth: node.transform.scale.z * factor };
|
|
749
|
+
},
|
|
750
|
+
nodeSetText: (id, text) => {
|
|
751
|
+
requireText(id);
|
|
752
|
+
if (typeof text !== "string")
|
|
753
|
+
throw new Error("text must be a string; use an empty string to clear it");
|
|
754
|
+
update(id, { text });
|
|
755
|
+
},
|
|
719
756
|
nodeGetFont: (id) => requireText(id).fontFamily,
|
|
720
757
|
nodeSetFont: (id, font) => {
|
|
758
|
+
requireText(id);
|
|
759
|
+
if (typeof font !== "string" || !font.trim())
|
|
760
|
+
throw new Error("font must be a non-empty font family name");
|
|
761
|
+
if (!context.fonts.length)
|
|
762
|
+
throw new Error("Font catalog is unavailable; this host cannot validate a new font selection");
|
|
721
763
|
const match = context.fonts.find((family) => family.name.toLowerCase() === font.toLowerCase());
|
|
722
|
-
if (!match
|
|
723
|
-
throw new Error(`Unknown font "${font}"`);
|
|
764
|
+
if (!match)
|
|
765
|
+
throw new Error(`Unknown font "${font}"; choose a family from the font catalog`);
|
|
724
766
|
update(id, { fontFamily: match?.name ?? font });
|
|
725
767
|
},
|
|
726
768
|
nodeGetWeight: (id) => requireText(id).weight,
|
|
727
|
-
nodeSetWeight: (id, weight) =>
|
|
769
|
+
nodeSetWeight: (id, weight) => {
|
|
770
|
+
requireText(id);
|
|
771
|
+
update(id, { weight: clamp(finite(weight, "weight"), 100, 900) });
|
|
772
|
+
},
|
|
728
773
|
nodeGetItalic: (id) => requireText(id).italic,
|
|
729
|
-
nodeSetItalic: (id, italic) =>
|
|
774
|
+
nodeSetItalic: (id, italic) => {
|
|
775
|
+
requireText(id);
|
|
776
|
+
if (typeof italic !== "boolean")
|
|
777
|
+
throw new Error("italic must be a boolean");
|
|
778
|
+
update(id, { italic });
|
|
779
|
+
},
|
|
730
780
|
nodeGetAlign: (id) => ALIGNS.indexOf(requireText(id).align),
|
|
731
781
|
nodeSetAlign: (id, align) => {
|
|
732
|
-
|
|
782
|
+
requireText(id);
|
|
783
|
+
const value = ALIGNS[finite(align, "align")];
|
|
733
784
|
if (!value)
|
|
734
|
-
throw new Error("Align must be from 0 to 2");
|
|
785
|
+
throw new Error("Align must be an integer from 0 to 2");
|
|
735
786
|
update(id, { align: value });
|
|
736
787
|
},
|
|
737
788
|
nodeGetWrap: (id) => WRAPS.indexOf(requireText(id).wrap),
|
|
738
789
|
nodeSetWrap: (id, wrap) => {
|
|
739
|
-
|
|
790
|
+
requireText(id);
|
|
791
|
+
const value = WRAPS[finite(wrap, "wrap")];
|
|
740
792
|
if (!value)
|
|
741
|
-
throw new Error("Wrap must be from 0 to 2");
|
|
793
|
+
throw new Error("Wrap must be an integer from 0 to 2");
|
|
742
794
|
update(id, { wrap: value });
|
|
743
795
|
},
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
796
|
+
/** Text layout width in project units, including owning Area scale. */
|
|
797
|
+
nodeGetWidth: (id) => requireText(id).width * ancestorScale(id) * unitMultiplier / INTERNAL_UNITS_PER_MM,
|
|
798
|
+
nodeSetWidth: (id, width) => {
|
|
799
|
+
requireText(id);
|
|
800
|
+
update(id, { width: finite(width, "width") * INTERNAL_UNITS_PER_MM / unitMultiplier / ancestorScale(id) });
|
|
801
|
+
},
|
|
802
|
+
/** Additional letter spacing in project units, including owning Area scale. */
|
|
803
|
+
nodeGetSpacing: (id) => requireText(id).spacing * ancestorScale(id) * unitMultiplier / INTERNAL_UNITS_PER_MM,
|
|
804
|
+
nodeSetSpacing: (id, spacing) => {
|
|
805
|
+
requireText(id);
|
|
806
|
+
update(id, { spacing: clamp(finite(spacing, "spacing") / unitMultiplier, -25, 25) * INTERNAL_UNITS_PER_MM / ancestorScale(id) });
|
|
807
|
+
},
|
|
748
808
|
nodeGetLineHeight: (id) => requireText(id).lineHeight,
|
|
749
|
-
nodeSetLineHeight: (id, lineHeight) =>
|
|
809
|
+
nodeSetLineHeight: (id, lineHeight) => {
|
|
810
|
+
requireText(id);
|
|
811
|
+
update(id, { lineHeight: clamp(finite(lineHeight, "lineHeight"), 0.5, 3) });
|
|
812
|
+
},
|
|
750
813
|
nodeGetDensity: (id) => requireCurve(id).density,
|
|
751
814
|
nodeSetDensity: (id, density) => update(id, { density: clamp(Math.round(finite(density, "density")), 0, 250) }),
|
|
752
815
|
nodeGetRoundness: (id) => requireCurve(id).roundness,
|
|
@@ -763,7 +826,7 @@ export function createWompSceneApi(context) {
|
|
|
763
826
|
return value;
|
|
764
827
|
},
|
|
765
828
|
nodeSetPrimType: (id, primitive) => {
|
|
766
|
-
const value = PUBLIC_PRIMITIVES.get(
|
|
829
|
+
const value = PUBLIC_PRIMITIVES.get(finite(primitive, "primitive"));
|
|
767
830
|
if (!value)
|
|
768
831
|
throw new Error("PrimitiveType must be Sphere, Cylinder, Cube, Cone, Torus, or Pyramid");
|
|
769
832
|
const node = requireNode(id);
|
|
@@ -849,7 +912,7 @@ export function createWompSceneApi(context) {
|
|
|
849
912
|
},
|
|
850
913
|
curvePointGetName: (curveId, pointIndex) => {
|
|
851
914
|
const index = requirePoint(curveId, pointIndex);
|
|
852
|
-
const points = metadataObject(metadataObject(scene.getSceneExt()[String(curveId)]).pointsExt);
|
|
915
|
+
const points = metadataObject(metadataObject(scene.getSceneExt([String(curveId)])[String(curveId)]).pointsExt);
|
|
853
916
|
const name = metadataObject(points[String(index)]).name;
|
|
854
917
|
return typeof name === "string" ? name : `Point ${index + 1}`;
|
|
855
918
|
},
|
|
@@ -992,6 +1055,7 @@ export function createWompSceneApi(context) {
|
|
|
992
1055
|
z: (box.min.z + box.max.z) / 2,
|
|
993
1056
|
}),
|
|
994
1057
|
aabbRadius: (box) => Math.hypot(box.max.x - box.min.x, box.max.y - box.min.y, box.max.z - box.min.z) / 2,
|
|
1058
|
+
/** Align local +Z from origin toward target, not a light's emission or a text/decal face; use nodeSetFacing for those. */
|
|
995
1059
|
lookAt,
|
|
996
1060
|
alignAxis,
|
|
997
1061
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@womp/spark-agent",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.4.1",
|
|
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.
|
|
113
|
+
"@womp/kakapo-sdk": "0.6.0",
|
|
114
114
|
"ai": "7.0.95",
|
|
115
115
|
"eventsource-parser": "^3.0.6",
|
|
116
116
|
"express": "^5.2.1",
|