@womp/spark-agent 6.0.0 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +239 -0
- package/README.md +119 -250
- package/dist/agent-tools.js +3 -1
- package/dist/bounded-output.d.ts +11 -2
- package/dist/bounded-output.js +21 -3
- package/dist/capabilities/scene.js +1 -1
- package/dist/generated/scene-declarations.d.ts +1 -1
- package/dist/generated/scene-declarations.js +1 -1
- package/dist/model-history.js +24 -5
- package/dist/sdk-scene-host.d.ts +0 -1
- package/dist/womp-scene-api.d.ts +0 -1
- package/dist/womp-scene-api.js +0 -6
- package/package.json +4 -3
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Notable changes to `@womp/spark-agent`, newest first. Versions follow
|
|
4
|
+
[Semantic Versioning](https://semver.org/). Add an entry with each version bump; describe what
|
|
5
|
+
changed for hosts and users, and how to migrate across breaking changes.
|
|
6
|
+
|
|
7
|
+
## 6.1.0 — 2026-10-08
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- A Geometry Nodes Area that the agent copies gets its own graph and script instance. The agent's
|
|
12
|
+
`nodeClone` copied the Area's `scriptInstanceId`, so editing either Area's graph or parameters
|
|
13
|
+
changed both. Areas linked this way before the upgrade stay linked.
|
|
14
|
+
|
|
15
|
+
### Removed
|
|
16
|
+
|
|
17
|
+
- `nodeClone` from the agent's scene API. `cloneSubtree` is the only copy operation and also copies
|
|
18
|
+
single nodes. Hosts need no code change.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Depends on `@womp/kakapo-sdk` 0.8.0, which removes `cloneNode`. Hosts that pin the SDK move it to
|
|
23
|
+
0.8.0 together with this release, because the host's `KakapoAPI` and Spark must share one SDK copy.
|
|
24
|
+
|
|
25
|
+
## 6.0.1 — 2026-10-07
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- Tool results reach the model with sorted keys, and `convertSparkMessages` replays stored tool
|
|
30
|
+
inputs as their schema validates them. History that a host reads back from storage that reorders
|
|
31
|
+
keys (Swan's Postgres JSONB thread rows) now matches what the live run sent, so turn starts in
|
|
32
|
+
Swan and Crow keep the provider prompt cache. Hosts need no change beyond the upgrade.
|
|
33
|
+
|
|
34
|
+
## 6.0.0 — 2026-10-07
|
|
35
|
+
|
|
36
|
+
### Breaking
|
|
37
|
+
|
|
38
|
+
- Removed `SparkAgentOptions.context`, the `createHost` `context` result, and `wompifyContext`.
|
|
39
|
+
Hosts send `sparkSystemPrompt(skills)`, which stays identical across a conversation so provider
|
|
40
|
+
prompt caches hit.
|
|
41
|
+
- `wompifyPrompt` takes a single request object including `referenceNamePrefix`.
|
|
42
|
+
|
|
43
|
+
### Added
|
|
44
|
+
|
|
45
|
+
- `data-selection` user message part (`{ nodeIds }`) for the editor selection sent with a message.
|
|
46
|
+
|
|
47
|
+
### Migrating to 6.0
|
|
48
|
+
|
|
49
|
+
- Stop passing per-run state in `context`. Attach the editor selection to the user message as a
|
|
50
|
+
`data-selection` part; send other changing state in messages.
|
|
51
|
+
- Replace `wompifyContext(...)` and positional `wompifyPrompt(...)` calls with
|
|
52
|
+
`wompifyPrompt({ referenceName, referenceNamePrefix, preset, note })`.
|
|
53
|
+
|
|
54
|
+
## 5.12.1 — 2026-10-07
|
|
55
|
+
|
|
56
|
+
### Fixed
|
|
57
|
+
|
|
58
|
+
- Goal state, rules and evaluator feedback are sent as appended messages instead of changing the
|
|
59
|
+
system prompt, so goal turns keep the prompt cache.
|
|
60
|
+
|
|
61
|
+
## 5.12.0 — 2026-10-07
|
|
62
|
+
|
|
63
|
+
### Added
|
|
64
|
+
|
|
65
|
+
- Goal endpoint `update_budget` command edits a goal's credit cap without restarting the run.
|
|
66
|
+
- Wompify detail levels Simple, High res and Ultra res.
|
|
67
|
+
|
|
68
|
+
### Changed
|
|
69
|
+
|
|
70
|
+
- A Wompify pass completes when it reaches its credit cap instead of failing the run, and can keep
|
|
71
|
+
refining in the same conversation with a new budget.
|
|
72
|
+
- Goal credit budgets are no longer included in continuation prompts.
|
|
73
|
+
|
|
74
|
+
## 5.11.1 — 2026-10-06
|
|
75
|
+
|
|
76
|
+
### Fixed
|
|
77
|
+
|
|
78
|
+
- Removed goal token budgets that were reintroduced in 5.11.0.
|
|
79
|
+
|
|
80
|
+
## 5.11.0 — 2026-10-06
|
|
81
|
+
|
|
82
|
+
### Added
|
|
83
|
+
|
|
84
|
+
- Scene API support for patterned lights, light collimation, texture imports and physical depth
|
|
85
|
+
of field.
|
|
86
|
+
|
|
87
|
+
## 5.10.0 — 2026-10-05
|
|
88
|
+
|
|
89
|
+
### Changed
|
|
90
|
+
|
|
91
|
+
- Ambiguous creative requests get an image preview before building again; turning an image into
|
|
92
|
+
3D uses mesh generation.
|
|
93
|
+
|
|
94
|
+
## 5.9.1 — 2026-10-05
|
|
95
|
+
|
|
96
|
+
### Fixed
|
|
97
|
+
|
|
98
|
+
- Goal turns report the credits they actually used and no longer estimate costs.
|
|
99
|
+
|
|
100
|
+
## 5.9.0 — 2026-10-05
|
|
101
|
+
|
|
102
|
+
### Changed
|
|
103
|
+
|
|
104
|
+
- Context trimming can also shorten the earlier steps of a long current turn.
|
|
105
|
+
|
|
106
|
+
## 5.8.0 — 2026-10-04
|
|
107
|
+
|
|
108
|
+
### Changed
|
|
109
|
+
|
|
110
|
+
- Goal budgets are enforced with host-reported charged credits; goal token budgets were removed.
|
|
111
|
+
|
|
112
|
+
### Fixed
|
|
113
|
+
|
|
114
|
+
- Scene access results omit undefined properties.
|
|
115
|
+
|
|
116
|
+
## 5.7.1 — 2026-10-03
|
|
117
|
+
|
|
118
|
+
### Fixed
|
|
119
|
+
|
|
120
|
+
- `read_skill` takes names-only requests and accepts combined skill name inputs.
|
|
121
|
+
|
|
122
|
+
## 5.7.0 — 2026-10-02
|
|
123
|
+
|
|
124
|
+
### Added
|
|
125
|
+
|
|
126
|
+
- Persistent server goals with `set`, `pause`, `resume` and `clear` controls.
|
|
127
|
+
|
|
128
|
+
## 5.6.1 — 2026-10-03
|
|
129
|
+
|
|
130
|
+
Published from a maintenance branch before 5.7.1.
|
|
131
|
+
|
|
132
|
+
### Fixed
|
|
133
|
+
|
|
134
|
+
- `read_skill` uses names-only requests.
|
|
135
|
+
|
|
136
|
+
## 5.6.0 — 2026-10-02
|
|
137
|
+
|
|
138
|
+
### Fixed
|
|
139
|
+
|
|
140
|
+
- Skill tool input uses an object-root schema for provider compatibility.
|
|
141
|
+
|
|
142
|
+
## 5.5.0 — 2026-10-01
|
|
143
|
+
|
|
144
|
+
### Added
|
|
145
|
+
|
|
146
|
+
- Mesh Wompify: the shared `mesh-wompify` skill and Wompify request helpers in
|
|
147
|
+
`@womp/spark-agent/ui`.
|
|
148
|
+
|
|
149
|
+
## 5.4.0 — 2026-09-30
|
|
150
|
+
|
|
151
|
+
### Changed
|
|
152
|
+
|
|
153
|
+
- Requires Kakapo SDK 0.7.3.
|
|
154
|
+
|
|
155
|
+
### Fixed
|
|
156
|
+
|
|
157
|
+
- Missing procedural material node locations.
|
|
158
|
+
|
|
159
|
+
## 5.3.0 — 2026-09-29
|
|
160
|
+
|
|
161
|
+
### Added
|
|
162
|
+
|
|
163
|
+
- Procedural material authoring capability.
|
|
164
|
+
- GPT-6.1 Sol model.
|
|
165
|
+
|
|
166
|
+
### Changed
|
|
167
|
+
|
|
168
|
+
- Required skills load in one `read_skill` call.
|
|
169
|
+
|
|
170
|
+
## 5.2.3 — 2026-09-29
|
|
171
|
+
|
|
172
|
+
### Added
|
|
173
|
+
|
|
174
|
+
- Shared SDK scene adapters can omit `operations` to edit and save directly, without a recovery
|
|
175
|
+
journal.
|
|
176
|
+
|
|
177
|
+
## 5.2.2 — 2026-09-28
|
|
178
|
+
|
|
179
|
+
### Fixed
|
|
180
|
+
|
|
181
|
+
- Requires Kakapo SDK 0.7.2; curve density 0 is allowed again.
|
|
182
|
+
|
|
183
|
+
## 5.2.1 — 2026-09-28
|
|
184
|
+
|
|
185
|
+
### Fixed
|
|
186
|
+
|
|
187
|
+
- Requires Kakapo SDK 0.7.1, so stored out-of-range values no longer block unrelated reads and edits.
|
|
188
|
+
|
|
189
|
+
## 5.2.0 — 2026-09-28
|
|
190
|
+
|
|
191
|
+
### Changed
|
|
192
|
+
|
|
193
|
+
- A generation that ends on `length`, `content-filter`, `error` or `other` fails the run with the
|
|
194
|
+
unified and provider finish reasons in its error and diagnostics.
|
|
195
|
+
|
|
196
|
+
## 5.1.0 — 2026-09-26
|
|
197
|
+
|
|
198
|
+
### Added
|
|
199
|
+
|
|
200
|
+
- Each model step is trimmed to fit the model's context window.
|
|
201
|
+
|
|
202
|
+
## 5.0.2 — 2026-09-25
|
|
203
|
+
|
|
204
|
+
### Fixed
|
|
205
|
+
|
|
206
|
+
- Restored screenshot framing guidance.
|
|
207
|
+
|
|
208
|
+
## 5.0.1 — 2026-09-25
|
|
209
|
+
|
|
210
|
+
### Fixed
|
|
211
|
+
|
|
212
|
+
- Restored screenshot camera controls.
|
|
213
|
+
|
|
214
|
+
## 5.0.0 — 2026-09-25
|
|
215
|
+
|
|
216
|
+
### Breaking
|
|
217
|
+
|
|
218
|
+
- Scene capability `read`/`edit` replaced by `access(callback)`; custom scene hosts implement
|
|
219
|
+
`SceneHost.access` and SDK adapters `acquireAccess`.
|
|
220
|
+
- Requires Kakapo SDK 0.7.0.
|
|
221
|
+
|
|
222
|
+
### Migrating to 5.0
|
|
223
|
+
|
|
224
|
+
- Replace scene capability `read`/`edit` with `access(callback)`. Inspect the current draft
|
|
225
|
+
through `scene.nodes({ ids, name, type, parentId, offset, limit })`, not a `nodes` array.
|
|
226
|
+
Results default to 100, with a maximum page size of 1,000.
|
|
227
|
+
- Update custom scene hosts to `SceneHost.access` and SDK adapters to `acquireAccess`.
|
|
228
|
+
`onCommitted` receives the acknowledged scene; keep host access suspended until synchronization
|
|
229
|
+
succeeds.
|
|
230
|
+
- Remove scene revision arguments from Geometry/OpenSCAD writes.
|
|
231
|
+
- Screenshot calls without options capture the current native viewport. Explicit `camera`
|
|
232
|
+
position/target, projection, `horizontalFovDegrees` and `orthographicWidth` are supported;
|
|
233
|
+
remove `targetId` and `view` presets. Camera distances use current project units.
|
|
234
|
+
- Request scene health explicitly through `scene.health()`; it no longer runs after each edit.
|
|
235
|
+
- Native and QuickJS executors allow 100,000 host calls per execution.
|
|
236
|
+
|
|
237
|
+
## Earlier versions
|
|
238
|
+
|
|
239
|
+
Changes before 5.0.0 are recorded in the Git history.
|
package/README.md
CHANGED
|
@@ -6,25 +6,9 @@ Spark Agent uses AI SDK 7 `UIMessage` and `UIMessageChunk` as its public chat pr
|
|
|
6
6
|
JavaScript uses the host's executor and capabilities. Native browser execution and isolated QuickJS
|
|
7
7
|
execution use the same model loop. The host owns conversations, artifacts, authorization, and connections.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
### Migrating to 5.0
|
|
9
|
+
Release notes and migration guides are in [CHANGELOG.md](CHANGELOG.md).
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
through `scene.nodes({ ids, name, type, parentId, offset, limit })`, not a `nodes` array.
|
|
15
|
-
Results default to 100, with a maximum page size of 1,000.
|
|
16
|
-
- Update custom scene hosts to `SceneHost.access` and SDK adapters to `acquireAccess`.
|
|
17
|
-
`onCommitted` receives the acknowledged scene; keep host access suspended until synchronization succeeds.
|
|
18
|
-
- Remove scene revision arguments from Geometry/OpenSCAD writes. Current parameters and overrides
|
|
19
|
-
are prepared inside protected access. Hosts must still enforce connection/project ownership.
|
|
20
|
-
- Screenshot calls without options capture the current native viewport. Explicit `camera`
|
|
21
|
-
position/target, projection, `horizontalFovDegrees` and `orthographicWidth` are supported;
|
|
22
|
-
remove `targetId` and `view` presets. Camera distances use current project units.
|
|
23
|
-
- Scene health is explicitly requested through `scene.health()`, not automatically after each edit.
|
|
24
|
-
- This release requires Kakapo SDK 0.7.0. Native and QuickJS executors now allow 100,000 host calls
|
|
25
|
-
per execution. Receipts, cancellation, timeout limits and uncertain-outcome handling remain enforced.
|
|
26
|
-
|
|
27
|
-
### Runtime
|
|
11
|
+
## Requirements
|
|
28
12
|
|
|
29
13
|
- Node.js 22.13 or newer
|
|
30
14
|
- AI SDK 7
|
|
@@ -34,77 +18,6 @@ execution use the same model loop. The host owns conversations, artifacts, autho
|
|
|
34
18
|
npm install @womp/spark-agent
|
|
35
19
|
```
|
|
36
20
|
|
|
37
|
-
## Run a prompt from the command line
|
|
38
|
-
|
|
39
|
-
With the Spark server already running:
|
|
40
|
-
|
|
41
|
-
```sh
|
|
42
|
-
yarn agent-run --prompt "Make a cube" --model gpt-5.6-luna --reasoning max
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
Use `--conversation <id>` to continue a thread and `--output <new-directory>` to save
|
|
46
|
-
`result.json`, `transcript.json` and original run artifacts under `artifacts/`.
|
|
47
|
-
For local runs, use the git-ignored `.spark/` directory, with a fresh subdirectory per run:
|
|
48
|
-
|
|
49
|
-
```sh
|
|
50
|
-
yarn agent-run --prompt "Make rainbow-colored boxes" --output .spark/agent-runs/rainbow-boxes
|
|
51
|
-
yarn agent-run --prompt "Model this object using both views" --image front.png --image side.jpg --output .spark/agent-runs/reference-model
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
Repeat `--image <path>` for local PNG, JPEG, WebP or GIF references, in argument order.
|
|
55
|
-
The required prompt and all images are sent in one user message. Files, format signatures,
|
|
56
|
-
and the full JSON request size (including base64 overhead) are checked before contacting the server.
|
|
57
|
-
The CLI uses the server's default 25 MiB request limit; a custom server or provider may impose
|
|
58
|
-
stricter limits. Images are never resized, and remote URLs are not accepted.
|
|
59
|
-
With `--output`, original bytes are saved under `inputs/`; `input.json` and the result's `input`
|
|
60
|
-
field list ordered original filenames, MIME types and relative paths. The submitted message in
|
|
61
|
-
`transcript.json` uses those paths instead of inline data. Generated artifacts stay in `artifacts/`.
|
|
62
|
-
|
|
63
|
-
Without output, artifacts remain server references. The CLI never clears the scene or
|
|
64
|
-
takes extra screenshots. Defaults are `gpt-6-astra`, `high`, and
|
|
65
|
-
`--api http://127.0.0.1:8787/agent`; unsupported settings are rejected.
|
|
66
|
-
|
|
67
|
-
Progress goes to stderr; one JSON result goes to stdout. Use `yarn --silent agent-run`
|
|
68
|
-
or the installed `agent-run` executable when parsing stdout (Yarn otherwise adds banners).
|
|
69
|
-
Usage comes from the provider, with per-step USD estimates; missing usage is not estimated.
|
|
70
|
-
Exit codes: 0 completed, 1 run/transport/export failure, 2 invalid arguments,
|
|
71
|
-
3 requires user action (continue in the UI), 130 interrupted. Interrupts attempt to cancel
|
|
72
|
-
only this invocation's run; a failed cancellation is reported and the run may still be active.
|
|
73
|
-
Output directories must not already exist. Artifact manifests include IDs, media types,
|
|
74
|
-
server URLs and relative paths; failed downloads retain their references and report errors.
|
|
75
|
-
Legacy inline base64 uploads in transcripts are replaced with `[inline data omitted]`.
|
|
76
|
-
|
|
77
|
-
## Mesh Wompify
|
|
78
|
-
|
|
79
|
-
Swan imports the reference mesh with Disjoint off, then requests reconstruction
|
|
80
|
-
through the shared `mesh-wompify` and `scene-editing` skills. Tier and request
|
|
81
|
-
helpers are exported from `@womp/spark-agent/ui`. Server mode requires Crow to
|
|
82
|
-
install the updated package and be redeployed; a local Swan package link is insufficient.
|
|
83
|
-
The Mesh Wompify function panel accepts a file and a detail level (Simple, High res,
|
|
84
|
-
or Ultra res). Reconstruction matches the reference's shape and colors; textures
|
|
85
|
-
are not carried over. Crow sets the initial cap for each level and bills actual
|
|
86
|
-
usage. Wompify keeps refining across turns until the cap, even if the evaluator
|
|
87
|
-
judges the reconstruction sufficient; insufficient credits or a blocker stop it.
|
|
88
|
-
Reaching the cap completes the pass without a run error. Keep refining
|
|
89
|
-
asks for a new pass budget, then continues in the same conversation with the
|
|
90
|
-
same reference and detail level. The budget travels as structured goal data.
|
|
91
|
-
`wompifyPrompt` writes the reference name prefix into the request message, which is
|
|
92
|
-
also the goal objective, so every pass names the same reference.
|
|
93
|
-
|
|
94
|
-
Ordinary goals support `{ action: "update_budget", goalId, creditBudget }` on
|
|
95
|
-
the goal endpoint. This edits the total credit cap without resetting usage,
|
|
96
|
-
restarting the run, or adding a model message. Crow reads the current cap before
|
|
97
|
-
worker and evaluator calls; an in-flight call may finish. Raising an exhausted
|
|
98
|
-
cap leaves the goal paused until Resume. Wompify's tier caps cannot be edited.
|
|
99
|
-
|
|
100
|
-
## System prompt and editor selection
|
|
101
|
-
|
|
102
|
-
Every host sends `sparkSystemPrompt(skills)`: the shared agent prompt and the skills
|
|
103
|
-
directory, with nothing host-specific, so it stays identical across a conversation.
|
|
104
|
-
Hosts attach the editor selection to the user message it was sent with as a
|
|
105
|
-
`data-selection` part (`{ nodeIds }`). It is not rendered as chat text; the model reads
|
|
106
|
-
it as a short note on that message.
|
|
107
|
-
|
|
108
21
|
## Package entry points
|
|
109
22
|
|
|
110
23
|
- `@womp/spark-agent` — browser-safe model loop, two tools, persistence hooks, and shared contracts
|
|
@@ -124,8 +37,17 @@ Kakapo, Express, or React at runtime.
|
|
|
124
37
|
|
|
125
38
|
`runSparkAgent` accepts a configured model, model messages, an executor, a capability composition,
|
|
126
39
|
and an artifact resolver. It exposes exactly `read_skill` and `execute_javascript` to the model.
|
|
127
|
-
Skills carry instructions, declarations, and JavaScript examples.
|
|
128
|
-
|
|
40
|
+
Skills carry instructions, declarations, and JavaScript examples. Kakapo skill declarations are
|
|
41
|
+
generated from its typed API at build time and packaged as JavaScript strings.
|
|
42
|
+
|
|
43
|
+
### System prompt and editor selection
|
|
44
|
+
|
|
45
|
+
Every host sends `sparkSystemPrompt(skills)`: the shared agent prompt and the skills directory,
|
|
46
|
+
with nothing host-specific, so it stays identical across a conversation. Hosts attach the editor
|
|
47
|
+
selection to the user message it was sent with as a `data-selection` part (`{ nodeIds }`). It is
|
|
48
|
+
not rendered as chat text; the model reads it as a short note on that message.
|
|
49
|
+
|
|
50
|
+
### Capabilities
|
|
129
51
|
|
|
130
52
|
Compose only supported capabilities with `composeCapabilities({ scene, account, ... })`. Each
|
|
131
53
|
capability supplies its skills and `createApi(context)`; the returned API is bound under `womp`.
|
|
@@ -134,34 +56,35 @@ own their transactions and must check cancellation at their commit boundary.
|
|
|
134
56
|
|
|
135
57
|
For a real user interaction, call `context.waitForUser(label, async signal => ...)` outside mutation
|
|
136
58
|
locks. The run stays active with `requires_action` progress and resumes the same invocation after
|
|
137
|
-
input
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
59
|
+
input; the wait is excluded from the execution budget. Abort settles the wait and late answers
|
|
60
|
+
cannot revive it. Custom executors must honor the optional host-owned `userWait` argument to `execute`.
|
|
61
|
+
|
|
62
|
+
Shared SDK scene adapters may omit `operations` to edit and save directly. Supplying `operations`
|
|
63
|
+
adds a durable operation journal and recovery of uncertain edits.
|
|
64
|
+
|
|
65
|
+
### Persistence and run lifecycle
|
|
142
66
|
|
|
143
67
|
Persist the user message before starting a run. Supply `persistence.beforeToolCall`,
|
|
144
68
|
`persistence.recordReceipt`, and `persistence.afterToolCall` for awaited storage barriers.
|
|
145
69
|
Supply `persistence.saveMessage` to save the canonical UI message at each model-step boundary and
|
|
146
|
-
at termination
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
`status: "incomplete"
|
|
151
|
-
A generation that ends on any other non-`stop` reason
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
70
|
+
at termination. Spark awaits each checkpoint before the next model request; a failed barrier aborts
|
|
71
|
+
the loop. Consume the run's stream while awaiting its result; a host run owner must keep consuming
|
|
72
|
+
when a view detaches.
|
|
73
|
+
|
|
74
|
+
The default model-step limit is 100; reaching it returns `status: "incomplete"`, and hosts must not
|
|
75
|
+
restart automatically to bypass it. A generation that ends on any other non-`stop` reason fails the
|
|
76
|
+
run with the unified and provider finish reasons in its error and diagnostics.
|
|
77
|
+
|
|
78
|
+
Before each model step, Spark trims older images, large tool results, and whole earlier turns to
|
|
79
|
+
keep the request inside the model's context window. The latest user message and the most recent
|
|
80
|
+
steps are never trimmed.
|
|
81
|
+
|
|
82
|
+
### Artifacts
|
|
157
83
|
|
|
158
84
|
Screenshot and file APIs return serializable artifact references. `emitImage` and `emitFile` resolve
|
|
159
85
|
them through the host's artifact resolver. Keep references resolvable when reloading history, and
|
|
160
86
|
pass `createSparkTools(...)` to AI SDK's `convertToModelMessages` to reconstruct multimodal results.
|
|
161
|
-
`emitImage(artifact, { inspect: false })` displays an image without adding its bytes to model input
|
|
162
|
-
including restored history. Inspection is enabled by default.
|
|
163
|
-
Kakapo skill declarations are generated from its actual typed API during the build and packaged as
|
|
164
|
-
JavaScript strings; they do not need filesystem or Markdown loading in the browser.
|
|
87
|
+
`emitImage(artifact, { inspect: false })` displays an image without adding its bytes to model input.
|
|
165
88
|
|
|
166
89
|
## Local frontend
|
|
167
90
|
|
|
@@ -196,10 +119,7 @@ const chat = useChat<SparkUIMessage>({
|
|
|
196
119
|
|
|
197
120
|
Render `message.parts`. Standard AI SDK parts represent text, reasoning, files, tool inputs, tool
|
|
198
121
|
outputs, approvals, and step boundaries. Spark adds typed `data-console`, `data-artifact`,
|
|
199
|
-
`data-run-status`, `data-step-metrics`,
|
|
200
|
-
their storage barrier, keeping known effects visible even when saving the tool result fails.
|
|
201
|
-
Hosts can consume `data-tool-input-label` once the tool's label field is complete, while the
|
|
202
|
-
remaining input is still streaming.
|
|
122
|
+
`data-run-status`, `data-step-metrics`, `data-execution-receipt`, and `data-tool-input-label` parts.
|
|
203
123
|
|
|
204
124
|
An explicit Stop action must cancel the durable run before stopping local observation:
|
|
205
125
|
|
|
@@ -215,21 +135,16 @@ Closing or reloading the page only detaches the SSE subscriber. It does not canc
|
|
|
215
135
|
`SparkChatTransport` hides the durable run lifecycle from `useChat`:
|
|
216
136
|
|
|
217
137
|
```text
|
|
218
|
-
POST
|
|
138
|
+
POST /agent/conversations/:conversationId/messages
|
|
219
139
|
PATCH /agent/conversations/:conversationId/settings
|
|
220
|
-
|
|
221
|
-
|
|
140
|
+
POST /agent/conversations/:conversationId/goal
|
|
141
|
+
GET /agent/runs/:runId/stream?after=0
|
|
142
|
+
POST /agent/runs/:runId/cancel
|
|
222
143
|
```
|
|
223
144
|
|
|
224
|
-
Conversation settings contain `modelId` and `reasoningEffort
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
unsupported choices fall back to supported settings. Assistant footers show the model recorded on
|
|
228
|
-
that turn, independently of the selector.
|
|
229
|
-
|
|
230
|
-
Custom stores must implement `saveConversationSettings` as a settings-only update, and preserve
|
|
231
|
-
stored settings during `saveConversation` so streaming history saves cannot overwrite preferences.
|
|
232
|
-
The built-in memory and SQLite stores implement this contract.
|
|
145
|
+
Conversation settings contain `modelId` and `reasoningEffort`; save them with
|
|
146
|
+
`transport.saveConversationSettings(id, settings)`. The goal endpoint accepts `set`, `pause`,
|
|
147
|
+
`resume`, `clear`, and `update_budget` commands.
|
|
233
148
|
|
|
234
149
|
The SSE response contains ordered persistence envelopes around standard AI SDK chunks:
|
|
235
150
|
|
|
@@ -244,8 +159,7 @@ type StoredSparkChunk = {
|
|
|
244
159
|
```
|
|
245
160
|
|
|
246
161
|
The transport unwraps each envelope and returns the contained `UIMessageChunk` to `useChat`.
|
|
247
|
-
Active assistant messages are replayed from sequence zero when reconnecting
|
|
248
|
-
reconstructs the in-progress message from the resumed stream.
|
|
162
|
+
Active assistant messages are replayed from sequence zero when reconnecting.
|
|
249
163
|
|
|
250
164
|
## Embedding in an Express backend
|
|
251
165
|
|
|
@@ -276,15 +190,25 @@ app.use(
|
|
|
276
190
|
|
|
277
191
|
`MemorySparkAgentStore` and `MemorySparkArtifactStore` are development implementations. Production
|
|
278
192
|
hosts must supply durable implementations backed by their database/object storage and must preserve
|
|
279
|
-
the ordering contract of `appendRunChunk()`.
|
|
193
|
+
the ordering contract of `appendRunChunk()`. Custom stores must also:
|
|
194
|
+
|
|
195
|
+
- implement `saveConversationSettings` as a settings-only update, and preserve stored settings
|
|
196
|
+
during `saveConversation`;
|
|
197
|
+
- implement `saveConversationGoal` to support goals;
|
|
198
|
+
- optionally implement `releaseActiveRun(conversationId, runId, updatedAt)` to clear the active run
|
|
199
|
+
only if its ID still matches.
|
|
200
|
+
|
|
201
|
+
The built-in memory and SQLite stores implement all of these.
|
|
280
202
|
|
|
281
203
|
`SparkAgentServiceOptions.endOrphanedRuns` defaults to `false`. Enable it only when one process
|
|
282
|
-
owns the store: a message or Stop then ends unfinished runs not held by that process.
|
|
283
|
-
store, enabling it could end another process's live run.
|
|
204
|
+
owns the store: a message or Stop then ends unfinished runs not held by that process.
|
|
284
205
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
206
|
+
## Mesh Wompify
|
|
207
|
+
|
|
208
|
+
Mesh Wompify reconstructs an imported reference mesh as editable primitives through the shared
|
|
209
|
+
`mesh-wompify` and `scene-editing` skills. `WOMPIFY_PRESETS`, `wompifyPrompt`, and
|
|
210
|
+
`parseWompifyCommand` are exported from `@womp/spark-agent/ui`. A Wompify run is a goal: it refines
|
|
211
|
+
across turns until its credit cap, and can continue in the same conversation with a new budget.
|
|
288
212
|
|
|
289
213
|
## Standalone development server
|
|
290
214
|
|
|
@@ -302,107 +226,63 @@ Configure the process with:
|
|
|
302
226
|
- `KAKAPO_URL` (defaults to `ws://127.0.0.1:5502`)
|
|
303
227
|
- `PORT` (defaults to `8787`)
|
|
304
228
|
- `SPARK_STORAGE_PATH` (defaults to `.spark/spark.sqlite`)
|
|
305
|
-
- `SPARK_SCENE_IDENTITY` (optional
|
|
229
|
+
- `SPARK_SCENE_IDENTITY` (optional; set only when the value names the same durable scene across
|
|
230
|
+
renderer reconnects)
|
|
306
231
|
|
|
307
|
-
The CLI
|
|
308
|
-
|
|
309
|
-
variables take precedence over values loaded from the file.
|
|
232
|
+
The CLI loads `.env` from its working directory when present; copy `.env.example` to `.env` and add
|
|
233
|
+
the provider key you intend to use. Process environment variables take precedence.
|
|
310
234
|
|
|
311
235
|
For repository development, `yarn dev` starts the Express server and Vite demo together. Open
|
|
312
|
-
`http://127.0.0.1:5173`.
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
When using a sibling `kakapo-sdk` dependency, run `yarn build` in `../kakapo-sdk` before installing
|
|
341
|
-
Spark dependencies. Replace local dependencies with registry versions before publishing.
|
|
342
|
-
|
|
343
|
-
For the explicit fictional account profile, use `yarn dev:demo-account` or
|
|
344
|
-
`spark-agent --profile demo-account`. It adds the `account` skill and `womp.account.read`
|
|
345
|
-
beside the real local Kakapo scene API. Profile reads identify themselves as fictional fixtures;
|
|
346
|
-
credits, billing, orders, and other account services report unavailable. The default composition
|
|
347
|
-
omits account entirely. Neither profile supplies fake generation jobs, imports, or billing permission.
|
|
348
|
-
Embedded development servers can select `developmentProfile: "demo-account"` explicitly.
|
|
349
|
-
|
|
350
|
-
The same profile supplies two actual local material resources: `Development: Matte Blue` and
|
|
351
|
-
`Development: Polished Copper`. They are bundled JSON files under `src/server/fixtures/materials`
|
|
352
|
-
and imported through the normal SDK draft, not simulated scene effects. In `scene.edit`, await
|
|
353
|
-
`api.materialImport(name)`, then assign its numeric ID. The default profile has no library service.
|
|
236
|
+
`http://127.0.0.1:5173`. When using a sibling `kakapo-sdk` dependency, run `yarn build` in
|
|
237
|
+
`../kakapo-sdk` before installing Spark dependencies.
|
|
238
|
+
|
|
239
|
+
The standalone server persists conversations, run streams, and screenshots in SQLite; only one
|
|
240
|
+
local process can execute against a database. `createStandaloneSparkAgentApp(options)` is
|
|
241
|
+
asynchronous: await it before listening, and call `await app.dispose()` on shutdown.
|
|
242
|
+
|
|
243
|
+
`yarn dev:demo-account` (or `spark-agent --profile demo-account`) adds a fictional `account` skill
|
|
244
|
+
and two development material resources beside the real local Kakapo scene API. Its account reads
|
|
245
|
+
identify themselves as fixtures; other account services report unavailable.
|
|
246
|
+
|
|
247
|
+
## Run a prompt from the command line
|
|
248
|
+
|
|
249
|
+
With the Spark server already running:
|
|
250
|
+
|
|
251
|
+
```sh
|
|
252
|
+
yarn agent-run --prompt "Make a cube" --model gpt-5.6-luna --reasoning max
|
|
253
|
+
yarn agent-run --prompt "Model this object using both views" --image front.png --image side.jpg --output .spark/agent-runs/reference-model
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
- `--conversation <id>` continues a thread.
|
|
257
|
+
- `--image <path>` attaches a local PNG, JPEG, WebP or GIF reference; repeat it for more images.
|
|
258
|
+
- `--output <new-directory>` saves `result.json`, `transcript.json`, inputs, and run artifacts.
|
|
259
|
+
For local runs, use a fresh subdirectory of the git-ignored `.spark/` directory.
|
|
260
|
+
|
|
261
|
+
Progress goes to stderr; one JSON result goes to stdout. Use `yarn --silent agent-run` when parsing
|
|
262
|
+
stdout. Exit codes: 0 completed, 1 run/transport/export failure, 2 invalid arguments, 3 requires
|
|
263
|
+
user action, 130 interrupted.
|
|
354
264
|
|
|
355
265
|
## Run cost estimates
|
|
356
266
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
and [OpenAI caching](https://developers.openai.com/api/docs/guides/prompt-caching).
|
|
366
|
-
Restart the server after changing these settings; existing runs keep their original configuration.
|
|
367
|
-
|
|
368
|
-
The chat displays estimated API token cost in USD, updated after every completed model step.
|
|
369
|
-
Hover or focus the amount to inspect uncached input, cache reads/writes, and output costs. Output usage
|
|
370
|
-
already includes reasoning tokens. Image input is included in the provider's input token count.
|
|
371
|
-
|
|
372
|
-
`src/pricing.ts` contains standard direct API rates verified on September 9, 2026:
|
|
373
|
-
|
|
374
|
-
| Model | Input / 1M | Cache read / 1M | Cache write / 1M | Output / 1M |
|
|
375
|
-
| -------------- | ---------- | --------------- | --------------------- | ----------- |
|
|
376
|
-
| GPT-6 Astra | $10 | $1 | $12.50 | $50 |
|
|
377
|
-
| Claude Opus 5 | $5 | $0.50 | $6.25 (5m), $10 (1h) | $25 |
|
|
378
|
-
| Claude Fable 5 | $10 | $1 | $12.50 (5m), $20 (1h) | $50 |
|
|
379
|
-
|
|
380
|
-
Astra requests above 272,000 input tokens use 2x input/cache rates and 1.5x output rates.
|
|
381
|
-
This threshold is applied to each request before summing run costs. Claude's full context uses
|
|
382
|
-
standard rates. Sources: [Astra pricing](https://developers.openai.com/api/docs/models/gpt-6-astra),
|
|
383
|
-
[Claude pricing](https://platform.claude.com/docs/en/about-claude/pricing).
|
|
384
|
-
|
|
385
|
-
Each `data-step-metrics` part stores a `cost` snapshot with the model, rate date, source, token
|
|
386
|
-
categories, rates, and amounts. The UI sums those stored amounts, so reconnection does not double
|
|
387
|
-
count steps and future price changes do not reprice recorded runs. Update the rate table and its
|
|
388
|
-
verification date when provider pricing changes.
|
|
389
|
-
|
|
390
|
-
The unfinished step is excluded until its usage arrives. Cancelled/failed runs show a partial
|
|
391
|
-
estimate. Missing usage, unknown models, missing cache TTLs, or provider sub-inferences without
|
|
392
|
-
separate attribution are marked unavailable, never silently priced as zero. Historical runs
|
|
393
|
-
without step pricing remain unavailable. Estimates exclude taxes, negotiated discounts, and scene
|
|
394
|
-
hosting; the provider bill is authoritative. Spark requests OpenAI's standard service tier.
|
|
267
|
+
The chat displays estimated API token cost in USD after every completed model step, from the
|
|
268
|
+
provider-reported usage and the rates in `src/pricing.ts`. Each `data-step-metrics` part stores
|
|
269
|
+
its `cost` snapshot, so recorded runs are not repriced when rates change. Missing usage or unknown
|
|
270
|
+
models are shown as unavailable, never priced as zero. Estimates exclude taxes, discounts, and
|
|
271
|
+
scene hosting; the provider bill is authoritative.
|
|
272
|
+
|
|
273
|
+
Prompt caching is enabled for every listed model. It depends on an identical request prefix, which
|
|
274
|
+
is why per-turn state travels in messages rather than the system prompt.
|
|
395
275
|
|
|
396
276
|
## Execution security
|
|
397
277
|
|
|
398
278
|
The standalone host uses a fresh QuickJS runtime for each JavaScript execution. It has no Node.js
|
|
399
279
|
or browser globals and receives only the composed capability APIs. Imports, filesystem access,
|
|
400
280
|
network APIs, and host environment variables are not exposed. QuickJS limits memory, stack size,
|
|
401
|
-
execution time, source size, host calls, and data crossing the host bridge.
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
execution.
|
|
405
|
-
and
|
|
281
|
+
execution time, source size, host calls, and data crossing the host bridge. Both executors allow
|
|
282
|
+
100,000 host calls per execution by default (`maxHostCalls` overrides this in QuickJS).
|
|
283
|
+
|
|
284
|
+
Browser hosts can instead use native page execution. It runs in the page realm: it is not a sandbox
|
|
285
|
+
and cannot interrupt a synchronous infinite loop.
|
|
406
286
|
|
|
407
287
|
QuickJS isolates generated code from the JavaScript host API; it is not an operating-system security
|
|
408
288
|
boundary. Multi-tenant deployments must additionally isolate workers, authorize every Kakapo
|
|
@@ -420,41 +300,30 @@ yarn web:build
|
|
|
420
300
|
|
|
421
301
|
## Release procedure
|
|
422
302
|
|
|
423
|
-
Pushes to `main` run `.github/workflows/publish.yml`. Publication is driven by
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
Versions follow **MAJOR.MINOR.PATCH** (for example, `4.4.0`):
|
|
428
|
-
|
|
429
|
-
- **Major:** breaking changes.
|
|
430
|
-
- **Minor:** backward-compatible new features.
|
|
431
|
-
- **Patch:** backward-compatible bug fixes.
|
|
303
|
+
Pushes to `main` run `.github/workflows/publish.yml`. Publication is driven by `package.json`, not
|
|
304
|
+
Git tags: already-published versions are skipped; an unpublished stable version newer than npm's
|
|
305
|
+
`latest` runs the release checks and is published automatically.
|
|
432
306
|
|
|
433
|
-
|
|
307
|
+
Versions follow **MAJOR.MINOR.PATCH**: major for breaking changes, minor for backward-compatible
|
|
308
|
+
features, patch for backward-compatible fixes.
|
|
434
309
|
|
|
435
310
|
1. Configure npm's trusted publisher once for `@womp/spark-agent`: organization `wompxyz`,
|
|
436
311
|
repository `spark-agent`, workflow filename `publish.yml`, no environment, and allow direct
|
|
437
312
|
`npm publish`. GitHub-hosted runners use OIDC; no publishing token is required.
|
|
438
|
-
2.
|
|
439
|
-
|
|
440
|
-
3. CI installs the frozen
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
Releases are serialized; newer pending pushes may supersede older pending runs.
|
|
447
|
-
Registry failures stop publication rather than being treated as missing versions.
|
|
448
|
-
4. If publication reports an uncertain result, inspect npm before rerunning the failed workflow.
|
|
449
|
-
Published versions cannot be replaced; corrections need a new version. No tags are required.
|
|
450
|
-
5. In the consuming application, use `yarn add @womp/spark-agent@<version> --exact`. Commit its
|
|
451
|
-
manifest and lockfile together, and verify a clean frozen-lockfile installation and production
|
|
452
|
-
build. Remove the temporary archive dependency. Application deployment and merge requirements
|
|
453
|
-
remain separate from package publication.
|
|
313
|
+
2. Bump `package.json` to an unused stable version, add its entry to `CHANGELOG.md`, and push the
|
|
314
|
+
release commit to `main`. Prereleases are not published by this workflow.
|
|
315
|
+
3. CI installs the frozen lockfile, runs typechecks, tests and the UI build, verifies the packed
|
|
316
|
+
tarball's entry points and imports, then publishes and verifies registry integrity and `latest`.
|
|
317
|
+
4. If publication reports an uncertain result, inspect npm before rerunning the workflow. Published
|
|
318
|
+
versions cannot be replaced; corrections need a new version.
|
|
319
|
+
5. In the consuming application, run `yarn add @womp/spark-agent@<version> --exact` and commit its
|
|
320
|
+
manifest and lockfile together.
|
|
454
321
|
|
|
455
322
|
## Layout
|
|
456
323
|
|
|
457
324
|
- `src/agent.ts` — AI SDK stream and Spark tool orchestration
|
|
325
|
+
- `src/prompt.ts` — shared system prompt
|
|
326
|
+
- `src/context-budget.ts` — per-step context-window trimming
|
|
458
327
|
- `src/ui.ts` — browser-safe protocol types and validation schemas
|
|
459
328
|
- `src/client.ts` — durable `ChatTransport` implementation
|
|
460
329
|
- `src/server/` — service, storage contracts, Express adapter, artifacts, and standalone composition
|
package/dist/agent-tools.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { tool } from "ai";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { boundedResultText } from "./bounded-output.js";
|
|
3
|
+
import { boundedResultText, canonicalJsonValue } from "./bounded-output.js";
|
|
4
4
|
import { completedInputString } from "./tool-input-label.js";
|
|
5
5
|
import { UserWait } from "./execution-lifetime.js";
|
|
6
6
|
function errorMessage(error) {
|
|
@@ -98,6 +98,8 @@ export function createSparkTools(options) {
|
|
|
98
98
|
const skills = [...new Set(input.names)].map(read);
|
|
99
99
|
return { ok: skills.every(skill => skill.ok), skills };
|
|
100
100
|
}),
|
|
101
|
+
// Replayed from storage that may reorder keys; see canonicalJsonValue.
|
|
102
|
+
toModelOutput: ({ output }) => ({ type: "json", value: canonicalJsonValue(output) }),
|
|
101
103
|
}),
|
|
102
104
|
execute_javascript: tool({
|
|
103
105
|
...inputLabels("purpose"),
|
package/dist/bounded-output.d.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
export declare const MODEL_RESULT_BYTE_LIMIT: number;
|
|
2
2
|
export declare const MODEL_ERROR_BYTE_LIMIT: number;
|
|
3
|
+
/**
|
|
4
|
+
* `value` with every object's keys sorted, recursively. Hosts store tool
|
|
5
|
+
* results in databases that reorder keys (Postgres JSONB puts shorter keys
|
|
6
|
+
* first), so a replayed result must not depend on the order it was read back
|
|
7
|
+
* in: the bytes the model reads have to match what the live run sent, or every
|
|
8
|
+
* later turn misses the provider's prompt cache from that result onward.
|
|
9
|
+
*/
|
|
10
|
+
export declare function canonicalJsonValue(value: unknown): unknown;
|
|
3
11
|
export declare function byteLength(text: string): number;
|
|
4
12
|
/**
|
|
5
13
|
* `text` cut to at most `limit` bytes on a character boundary. A cut that lands
|
|
@@ -15,8 +23,9 @@ export declare function truncateUtf8(text: string, limit: number): string;
|
|
|
15
23
|
export declare function boundedText(text: string, limit: number, label: string): string;
|
|
16
24
|
/**
|
|
17
25
|
* The serialized tool result the model reads, bounded to
|
|
18
|
-
* `MODEL_RESULT_BYTE_LIMIT
|
|
19
|
-
* receipts keep the full output; only model input is
|
|
26
|
+
* `MODEL_RESULT_BYTE_LIMIT`, with keys in canonical order. Persistence, the UI
|
|
27
|
+
* stream and the host's own receipts keep the full output; only model input is
|
|
28
|
+
* bounded here.
|
|
20
29
|
*
|
|
21
30
|
* Stages, in order, so the most useful part survives: bound `error`, then bound
|
|
22
31
|
* each receipt's `details`, then keep only as many receipts as the budget
|
package/dist/bounded-output.js
CHANGED
|
@@ -4,6 +4,23 @@ const encoder = new TextEncoder();
|
|
|
4
4
|
const decoder = new TextDecoder();
|
|
5
5
|
export const MODEL_RESULT_BYTE_LIMIT = 1024 * 1024;
|
|
6
6
|
export const MODEL_ERROR_BYTE_LIMIT = 8 * 1024;
|
|
7
|
+
/**
|
|
8
|
+
* `value` with every object's keys sorted, recursively. Hosts store tool
|
|
9
|
+
* results in databases that reorder keys (Postgres JSONB puts shorter keys
|
|
10
|
+
* first), so a replayed result must not depend on the order it was read back
|
|
11
|
+
* in: the bytes the model reads have to match what the live run sent, or every
|
|
12
|
+
* later turn misses the provider's prompt cache from that result onward.
|
|
13
|
+
*/
|
|
14
|
+
export function canonicalJsonValue(value) {
|
|
15
|
+
if (Array.isArray(value))
|
|
16
|
+
return value.map(canonicalJsonValue);
|
|
17
|
+
if (value === null || typeof value !== "object")
|
|
18
|
+
return value;
|
|
19
|
+
const record = value;
|
|
20
|
+
return Object.fromEntries(Object.keys(record)
|
|
21
|
+
.sort()
|
|
22
|
+
.map((key) => [key, canonicalJsonValue(record[key])]));
|
|
23
|
+
}
|
|
7
24
|
export function byteLength(text) {
|
|
8
25
|
return encoder.encode(text).byteLength;
|
|
9
26
|
}
|
|
@@ -33,8 +50,9 @@ export function boundedText(text, limit, label) {
|
|
|
33
50
|
}
|
|
34
51
|
/**
|
|
35
52
|
* The serialized tool result the model reads, bounded to
|
|
36
|
-
* `MODEL_RESULT_BYTE_LIMIT
|
|
37
|
-
* receipts keep the full output; only model input is
|
|
53
|
+
* `MODEL_RESULT_BYTE_LIMIT`, with keys in canonical order. Persistence, the UI
|
|
54
|
+
* stream and the host's own receipts keep the full output; only model input is
|
|
55
|
+
* bounded here.
|
|
38
56
|
*
|
|
39
57
|
* Stages, in order, so the most useful part survives: bound `error`, then bound
|
|
40
58
|
* each receipt's `details`, then keep only as many receipts as the budget
|
|
@@ -46,7 +64,7 @@ export function boundedResultText(output, limit = MODEL_RESULT_BYTE_LIMIT) {
|
|
|
46
64
|
const errorBounded = typeof output.error === "string"
|
|
47
65
|
? { ...output, error: boundedText(output.error, MODEL_ERROR_BYTE_LIMIT, "Error") }
|
|
48
66
|
: output;
|
|
49
|
-
const asText = (value) => JSON.stringify(value) ?? "null";
|
|
67
|
+
const asText = (value) => JSON.stringify(canonicalJsonValue(value)) ?? "null";
|
|
50
68
|
let text = asText(errorBounded);
|
|
51
69
|
if (byteLength(text) <= limit)
|
|
52
70
|
return text;
|
|
@@ -102,7 +102,7 @@ Establish a comparison view matching the reference's angle, projection, and subj
|
|
|
102
102
|
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.
|
|
103
103
|
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.
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
await cloneSubtree(id, { parentId?, name?, index? }) copies a node and its complete hierarchy with fresh IDs,
|
|
106
106
|
preserving local transforms, order and metadata, remapping internal references and sharing external materials/assets.
|
|
107
107
|
Cloning stages changes in the draft and commits them with the rest of the access.
|
|
108
108
|
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.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const WOMP_SCENE_DECLARATIONS = "declare const womp: { scene: {\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\"access\": (<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\"nodeGetCollimation\": ((id: number) => number);\n\"nodeSetCollimation\": ((id: number, collimation: number) => void);\n\"nodeGetLightTextureFile\": ((id: number) => string);\n\"nodeSetLightTextureFile\": ((id: number, textureFile: string) => void);\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\"cameraReadDepthOfField\": (() => {\n\"enabled\": false | true;\n\"mode\": \"physical\" | \"post-process\";\n\"focusDistance\": number;\n\"aperturePercent\": number;\n\"projection\": \"perspective\" | \"orthographic\";\n});\n\"cameraSetDepthOfField\": ((input: {\n\"enabled\"?: undefined | false | true;\n\"mode\"?: undefined | \"physical\" | \"post-process\";\n\"focusDistance\"?: undefined | number;\n\"aperturePercent\"?: undefined | number;\n}) => void);\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\"unitMultiplier\": number;\n\"nodes\": ((options?: {\n\"ids\"?: undefined | Array<number>;\n\"type\"?: undefined | number;\n\"parentId\"?: undefined | number;\n\"name\"?: undefined | string;\n\"offset\"?: undefined | number;\n\"limit\"?: undefined | number;\n}) => Array<{\n\"id\": number;\n\"name\": string;\n\"type\": number;\n\"parentId\": number;\n}>);\n}) => T | Promise<T>)) => 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\"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\"access\": (<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\"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\"nodeGetCollimation\": ((id: number) => number);\n\"nodeSetCollimation\": ((id: number, collimation: number) => void);\n\"nodeGetLightTextureFile\": ((id: number) => string);\n\"nodeSetLightTextureFile\": ((id: number, textureFile: string) => void);\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\"cameraReadDepthOfField\": (() => {\n\"enabled\": false | true;\n\"mode\": \"physical\" | \"post-process\";\n\"focusDistance\": number;\n\"aperturePercent\": number;\n\"projection\": \"perspective\" | \"orthographic\";\n});\n\"cameraSetDepthOfField\": ((input: {\n\"enabled\"?: undefined | false | true;\n\"mode\"?: undefined | \"physical\" | \"post-process\";\n\"focusDistance\"?: undefined | number;\n\"aperturePercent\"?: undefined | number;\n}) => void);\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\"unitMultiplier\": number;\n\"nodes\": ((options?: {\n\"ids\"?: undefined | Array<number>;\n\"type\"?: undefined | number;\n\"parentId\"?: undefined | number;\n\"name\"?: undefined | string;\n\"offset\"?: undefined | number;\n\"limit\"?: undefined | number;\n}) => Array<{\n\"id\": number;\n\"name\": string;\n\"type\": number;\n\"parentId\": number;\n}>);\n}) => T | Promise<T>)) => 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\"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\"access\": (<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\"nodeGetCollimation\": ((id: number) => number);\n\"nodeSetCollimation\": ((id: number, collimation: number) => void);\n\"nodeGetLightTextureFile\": ((id: number) => string);\n\"nodeSetLightTextureFile\": ((id: number, textureFile: string) => void);\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\"cameraReadDepthOfField\": (() => {\n\"enabled\": false | true;\n\"mode\": \"physical\" | \"post-process\";\n\"focusDistance\": number;\n\"aperturePercent\": number;\n\"projection\": \"perspective\" | \"orthographic\";\n});\n\"cameraSetDepthOfField\": ((input: {\n\"enabled\"?: undefined | false | true;\n\"mode\"?: undefined | \"physical\" | \"post-process\";\n\"focusDistance\"?: undefined | number;\n\"aperturePercent\"?: undefined | number;\n}) => void);\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\"unitMultiplier\": number;\n\"nodes\": ((options?: {\n\"ids\"?: undefined | Array<number>;\n\"type\"?: undefined | number;\n\"parentId\"?: undefined | number;\n\"name\"?: undefined | string;\n\"offset\"?: undefined | number;\n\"limit\"?: undefined | number;\n}) => Array<{\n\"id\": number;\n\"name\": string;\n\"type\": number;\n\"parentId\": number;\n}>);\n}) => T | Promise<T>)) => 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\"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\"access\": (<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\"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\"nodeGetCollimation\": ((id: number) => number);\n\"nodeSetCollimation\": ((id: number, collimation: number) => void);\n\"nodeGetLightTextureFile\": ((id: number) => string);\n\"nodeSetLightTextureFile\": ((id: number, textureFile: string) => void);\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\"cameraReadDepthOfField\": (() => {\n\"enabled\": false | true;\n\"mode\": \"physical\" | \"post-process\";\n\"focusDistance\": number;\n\"aperturePercent\": number;\n\"projection\": \"perspective\" | \"orthographic\";\n});\n\"cameraSetDepthOfField\": ((input: {\n\"enabled\"?: undefined | false | true;\n\"mode\"?: undefined | \"physical\" | \"post-process\";\n\"focusDistance\"?: undefined | number;\n\"aperturePercent\"?: undefined | number;\n}) => void);\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\"unitMultiplier\": number;\n\"nodes\": ((options?: {\n\"ids\"?: undefined | Array<number>;\n\"type\"?: undefined | number;\n\"parentId\"?: undefined | number;\n\"name\"?: undefined | string;\n\"offset\"?: undefined | number;\n\"limit\"?: undefined | number;\n}) => Array<{\n\"id\": number;\n\"name\": string;\n\"type\": number;\n\"parentId\": number;\n}>);\n}) => T | Promise<T>)) => 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/model-history.js
CHANGED
|
@@ -1,13 +1,30 @@
|
|
|
1
|
-
import { convertToModelMessages } from "ai";
|
|
1
|
+
import { asSchema, convertToModelMessages } from "ai";
|
|
2
2
|
import { sparkDataPartSchemas } from "./ui.js";
|
|
3
3
|
function record(value) {
|
|
4
4
|
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
5
5
|
? value
|
|
6
6
|
: {};
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* A stored call's input as the live run handed it to the model: the AI SDK
|
|
10
|
+
* passes on the input its schema validated, in the schema's key order, while
|
|
11
|
+
* storage may return the keys in another order (Postgres JSONB sorts them).
|
|
12
|
+
* An input the schema refuses is replayed as stored.
|
|
13
|
+
*/
|
|
14
|
+
async function liveInput(tools, part) {
|
|
15
|
+
if (part.type !== "dynamic-tool" && !part.type.startsWith("tool-"))
|
|
16
|
+
return part;
|
|
17
|
+
const name = part.type === "dynamic-tool" ? part.toolName : part.type.slice(5);
|
|
18
|
+
const tool = tools[name];
|
|
19
|
+
const input = part.input;
|
|
20
|
+
if (tool === undefined || input === null || typeof input !== "object" || Array.isArray(input))
|
|
21
|
+
return part;
|
|
22
|
+
const validated = await asSchema(tool.inputSchema).validate?.(input);
|
|
23
|
+
return validated?.success ? { ...part, input: validated.value } : part;
|
|
24
|
+
}
|
|
8
25
|
/** UI artifact previews already represented by a tool result are not model output. */
|
|
9
|
-
export function convertSparkMessages(messages, tools) {
|
|
10
|
-
const history = messages.map((message) => {
|
|
26
|
+
export async function convertSparkMessages(messages, tools) {
|
|
27
|
+
const history = await Promise.all(messages.map(async (message) => {
|
|
11
28
|
if (message.role !== "assistant")
|
|
12
29
|
return message;
|
|
13
30
|
const previews = new Set();
|
|
@@ -28,9 +45,11 @@ export function convertSparkMessages(messages, tools) {
|
|
|
28
45
|
}
|
|
29
46
|
return {
|
|
30
47
|
...message,
|
|
31
|
-
parts:
|
|
48
|
+
parts: await Promise.all(message.parts
|
|
49
|
+
.filter((part) => part.type !== "file" || (!previews.has(part.url) && part.providerMetadata?.spark?.inspect !== false))
|
|
50
|
+
.map((part) => liveInput(tools, part))),
|
|
32
51
|
};
|
|
33
|
-
});
|
|
52
|
+
}));
|
|
34
53
|
return convertToModelMessages(history, {
|
|
35
54
|
tools,
|
|
36
55
|
convertDataPart: (part) => {
|
package/dist/sdk-scene-host.d.ts
CHANGED
|
@@ -88,7 +88,6 @@ export declare function createSdkSceneDraft(api: KakapoAPI, scene: SceneEdit, se
|
|
|
88
88
|
} & Record<number, string>;
|
|
89
89
|
nodeCreate: (type: number, parentId?: number) => number;
|
|
90
90
|
nodeDelete: (id: number) => void;
|
|
91
|
-
nodeClone: (id: number) => number;
|
|
92
91
|
cloneSubtree: (id: number, options?: {
|
|
93
92
|
parentId?: number;
|
|
94
93
|
name?: string;
|
package/dist/womp-scene-api.d.ts
CHANGED
|
@@ -124,7 +124,6 @@ export declare function createWompSceneApi(context: WompSceneApiContext): {
|
|
|
124
124
|
} & Record<number, string>;
|
|
125
125
|
nodeCreate: (type: number, parentId?: number) => number;
|
|
126
126
|
nodeDelete: (id: number) => void;
|
|
127
|
-
nodeClone: (id: number) => number;
|
|
128
127
|
/** Deep clone; preserves sibling order and remaps internal references. Await before other edits. */
|
|
129
128
|
cloneSubtree: (id: number, options?: {
|
|
130
129
|
parentId?: number;
|
package/dist/womp-scene-api.js
CHANGED
|
@@ -545,12 +545,6 @@ export function createWompSceneApi(context) {
|
|
|
545
545
|
requireNode(id);
|
|
546
546
|
context.call("deleteNode", [id], () => scene.deleteNode(id));
|
|
547
547
|
},
|
|
548
|
-
nodeClone: (id) => {
|
|
549
|
-
requireNode(id);
|
|
550
|
-
const clone = context.call("cloneNode", [id], () => scene.cloneNode(id));
|
|
551
|
-
context.trackNode(clone.id);
|
|
552
|
-
return clone.id;
|
|
553
|
-
},
|
|
554
548
|
/** Deep clone; preserves sibling order and remaps internal references. Await before other edits. */
|
|
555
549
|
cloneSubtree: async (id, options = {}) => {
|
|
556
550
|
if (id === context.rootId)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@womp/spark-agent",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.1.0",
|
|
4
4
|
"description": "Portable skills-based AI agent with local and durable chat transports for Womp",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -73,7 +73,8 @@
|
|
|
73
73
|
"dist/**/*.d.ts",
|
|
74
74
|
"dist/server/fixtures/**/*.json",
|
|
75
75
|
"dist/geometry/schemas/**/*.json",
|
|
76
|
-
"README.md"
|
|
76
|
+
"README.md",
|
|
77
|
+
"CHANGELOG.md"
|
|
77
78
|
],
|
|
78
79
|
"sideEffects": false,
|
|
79
80
|
"engines": {
|
|
@@ -111,7 +112,7 @@
|
|
|
111
112
|
"@ai-sdk/openai": "4.0.63",
|
|
112
113
|
"@jitl/quickjs-wasmfile-release-sync": "0.32.0",
|
|
113
114
|
"@womp/flowir": "0.3.0",
|
|
114
|
-
"@womp/kakapo-sdk": "0.
|
|
115
|
+
"@womp/kakapo-sdk": "0.8.0",
|
|
115
116
|
"ai": "7.0.95",
|
|
116
117
|
"eventsource-parser": "^3.0.6",
|
|
117
118
|
"express": "^5.2.1",
|