@compilr-dev/sdk 0.40.0 → 0.41.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.
|
@@ -25,7 +25,7 @@ export type SceneOp =
|
|
|
25
25
|
objects: SceneObjectInput[];
|
|
26
26
|
index?: number;
|
|
27
27
|
}
|
|
28
|
-
/** Shallow merge; arrays replaced whole; `null` clears
|
|
28
|
+
/** Shallow merge; arrays replaced whole; `material` MERGES; `null` clears; id/type rejected. */
|
|
29
29
|
| {
|
|
30
30
|
op: 'update';
|
|
31
31
|
id: string;
|
package/dist/canvas/scene-ops.js
CHANGED
|
@@ -171,6 +171,30 @@ function showVal(v) {
|
|
|
171
171
|
return fmtVec(v);
|
|
172
172
|
return JSON.stringify(v);
|
|
173
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* `material` MERGES, where every other object-valued field is replaced whole.
|
|
176
|
+
*
|
|
177
|
+
* ⚠️ IT USED TO REPLACE, AND THAT COST SOMEONE A SURFACE. A material is a bag of independent
|
|
178
|
+
* knobs — roughness, metalness, opacity, emissive, wireframe — so "make this glow" is naturally
|
|
179
|
+
* `{ material: { emissive: "#f59e0b" } }`, and under replace that ALSO reset the metalness and
|
|
180
|
+
* roughness that were there. Reported from real use: a ring patched to glow quietly lost its
|
|
181
|
+
* metal finish, and the agent only caught it because it re-read the scene. Nothing errored, and
|
|
182
|
+
* the patch did exactly what it said.
|
|
183
|
+
*
|
|
184
|
+
* Arrays still replace whole (a position is one value, not three independent ones). To clear a
|
|
185
|
+
* single knob, pass it as `null`; to clear the whole material, pass `material: null`, which is
|
|
186
|
+
* the same rule one level up.
|
|
187
|
+
*/
|
|
188
|
+
function mergeMaterial(before, patch) {
|
|
189
|
+
const base = isRecord(before) ? { ...before } : {};
|
|
190
|
+
for (const [k, v] of Object.entries(patch)) {
|
|
191
|
+
if (v === null)
|
|
192
|
+
Reflect.deleteProperty(base, k);
|
|
193
|
+
else
|
|
194
|
+
base[k] = clone(v);
|
|
195
|
+
}
|
|
196
|
+
return base;
|
|
197
|
+
}
|
|
174
198
|
function updateObject(scene, id, patch, opts) {
|
|
175
199
|
const idx = scene.objects.findIndex((o) => o.id === id);
|
|
176
200
|
if (idx < 0)
|
|
@@ -205,8 +229,10 @@ function updateObject(scene, id, patch, opts) {
|
|
|
205
229
|
const from = before[k];
|
|
206
230
|
if (v === null)
|
|
207
231
|
Reflect.deleteProperty(next, k);
|
|
232
|
+
else if (k === 'material' && isRecord(v))
|
|
233
|
+
next[k] = mergeMaterial(before[k], v);
|
|
208
234
|
else
|
|
209
|
-
next[k] = clone(v); // shallow merge: arrays
|
|
235
|
+
next[k] = clone(v); // shallow merge: arrays replaced whole
|
|
210
236
|
const to = next[k];
|
|
211
237
|
if (JSON.stringify(from) === JSON.stringify(to))
|
|
212
238
|
continue;
|
|
@@ -233,7 +233,10 @@ const OBJECT_PROPERTIES = {
|
|
|
233
233
|
type: 'string',
|
|
234
234
|
description: 'label only: the words to show (≤ 120, ONE line — no newline; use two labels). The scene is ' +
|
|
235
235
|
'otherwise unlabelled solids, so name the rooms and the parts: a screenshot with no text in ' +
|
|
236
|
-
'it cannot be read back by you or by anyone else.'
|
|
236
|
+
'it cannot be read back by you or by anyone else. ⚠️ SIZE IT AGAINST WHAT IT NAMES: the text ' +
|
|
237
|
+
'is in METRES like everything else, so the 0.25 default is right for a desk and unreadable ' +
|
|
238
|
+
'across a building. Roughly a tenth of the thing it labels — a 4 m wall wants ~0.4, a whole ' +
|
|
239
|
+
'floor plan wants more. A label you have to zoom in to read is one nobody reads.',
|
|
237
240
|
},
|
|
238
241
|
background: {
|
|
239
242
|
type: 'string',
|
|
@@ -538,7 +541,10 @@ export function createSceneTools(config, options) {
|
|
|
538
541
|
const sceneUpdateObjectTool = defineTool({
|
|
539
542
|
name: 'scene_update_object',
|
|
540
543
|
description: 'Change fields of one object in a 3D scene. patch is a SHALLOW merge — arrays (position, size, ' +
|
|
541
|
-
'points, rotation)
|
|
544
|
+
'points, rotation) are replaced whole, since a position is one value and not three independent ' +
|
|
545
|
+
'ones. MATERIAL IS THE EXCEPTION: it merges, so { material: { emissive: "#f59e0b" } } adds a glow ' +
|
|
546
|
+
'and leaves the roughness, metalness and opacity that were already there. null clears an optional ' +
|
|
547
|
+
'field (group, or material itself); a null INSIDE material clears that one knob. ' +
|
|
542
548
|
'id and type cannot change: remove the object and add it again. Read ids with scene_get first.',
|
|
543
549
|
inputSchema: {
|
|
544
550
|
type: 'object',
|