@things-factory/board-ai 10.1.24 β 10.1.26
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/PLAN-styling-tools.md +1 -1
- package/dist-client/server/service/assistant.d.ts +5 -4
- package/dist-client/server/service/assistant.js +35 -35
- package/dist-client/server/service/assistant.js.map +1 -1
- package/dist-client/server/service/styling/clear-tools.d.ts +2 -2
- package/dist-client/server/service/styling/clear-tools.js.map +1 -1
- package/dist-client/server/service/styling/copy-tools.d.ts +3 -3
- package/dist-client/server/service/styling/copy-tools.js +1 -1
- package/dist-client/server/service/styling/copy-tools.js.map +1 -1
- package/dist-client/server/service/styling/effect-tools.d.ts +2 -2
- package/dist-client/server/service/styling/effect-tools.js.map +1 -1
- package/dist-client/server/service/styling/fill-tools.d.ts +3 -3
- package/dist-client/server/service/styling/fill-tools.js +1 -1
- package/dist-client/server/service/styling/fill-tools.js.map +1 -1
- package/dist-client/server/service/styling/material-tools.d.ts +2 -2
- package/dist-client/server/service/styling/material-tools.js.map +1 -1
- package/dist-client/server/service/styling/registry.d.ts +6 -6
- package/dist-client/server/service/styling/registry.js +2 -2
- package/dist-client/server/service/styling/registry.js.map +1 -1
- package/dist-client/server/service/styling/stroke-tools.d.ts +2 -2
- package/dist-client/server/service/styling/stroke-tools.js.map +1 -1
- package/dist-client/server/service/styling/text-tools.d.ts +2 -2
- package/dist-client/server/service/styling/text-tools.js.map +1 -1
- package/dist-client/server/service/types.d.ts +6 -148
- package/dist-client/server/service/types.js.map +1 -1
- package/dist-client/server/service/validation/board-model-schema.d.ts +262 -262
- package/dist-client/server/service/validation/board-model-schema.js +4 -4
- package/dist-client/server/service/validation/board-model-schema.js.map +1 -1
- package/dist-client/server/service/validation/tool-validation.js +5 -5
- package/dist-client/server/service/validation/tool-validation.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/index.d.ts +2 -2
- package/dist-server/index.js +2 -2
- package/dist-server/index.js.map +1 -1
- package/dist-server/service/assistant.d.ts +5 -4
- package/dist-server/service/assistant.js +37 -37
- package/dist-server/service/assistant.js.map +1 -1
- package/dist-server/service/board-ai-resolver.js +2 -2
- package/dist-server/service/board-ai-resolver.js.map +1 -1
- package/dist-server/service/index.d.ts +0 -1
- package/dist-server/service/index.js +0 -1
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/service/patch-entry/board-patch-subscription.js +1 -1
- package/dist-server/service/patch-entry/board-patch-subscription.js.map +1 -1
- package/dist-server/service/patch-entry/patch-entry.d.ts +1 -1
- package/dist-server/service/patch-entry/patch-entry.js +1 -1
- package/dist-server/service/patch-entry/patch-entry.js.map +1 -1
- package/dist-server/service/styling/clear-tools.d.ts +2 -2
- package/dist-server/service/styling/clear-tools.js.map +1 -1
- package/dist-server/service/styling/copy-tools.d.ts +3 -3
- package/dist-server/service/styling/copy-tools.js +1 -1
- package/dist-server/service/styling/copy-tools.js.map +1 -1
- package/dist-server/service/styling/effect-tools.d.ts +2 -2
- package/dist-server/service/styling/effect-tools.js.map +1 -1
- package/dist-server/service/styling/fill-tools.d.ts +3 -3
- package/dist-server/service/styling/fill-tools.js +1 -1
- package/dist-server/service/styling/fill-tools.js.map +1 -1
- package/dist-server/service/styling/material-tools.d.ts +2 -2
- package/dist-server/service/styling/material-tools.js.map +1 -1
- package/dist-server/service/styling/registry.d.ts +6 -6
- package/dist-server/service/styling/registry.js +2 -2
- package/dist-server/service/styling/registry.js.map +1 -1
- package/dist-server/service/styling/stroke-tools.d.ts +2 -2
- package/dist-server/service/styling/stroke-tools.js.map +1 -1
- package/dist-server/service/styling/text-tools.d.ts +2 -2
- package/dist-server/service/styling/text-tools.js.map +1 -1
- package/dist-server/service/types.d.ts +6 -148
- package/dist-server/service/types.js.map +1 -1
- package/dist-server/service/validation/board-model-schema.d.ts +262 -262
- package/dist-server/service/validation/board-model-schema.js +4 -4
- package/dist-server/service/validation/board-model-schema.js.map +1 -1
- package/dist-server/service/validation/tool-validation.js +5 -5
- package/dist-server/service/validation/tool-validation.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/logs/.5e5d741d8b7784a2fbad65eedc0fd46946aaf6f2-audit.json +5 -0
- package/logs/connections-2026-09-17-16.log +0 -0
- package/package.json +8 -7
- package/server/index.ts +2 -2
- package/server/service/assistant-integration.test.ts +44 -44
- package/server/service/assistant-llm-smoke.test.ts +5 -5
- package/server/service/assistant.test.ts +86 -86
- package/server/service/assistant.ts +41 -43
- package/server/service/board-ai-resolver.ts +2 -2
- package/server/service/index.ts +0 -1
- package/server/service/patch-entry/board-patch-subscription.ts +1 -1
- package/server/service/patch-entry/patch-entry.ts +2 -2
- package/server/service/styling/clear-tools.ts +2 -2
- package/server/service/styling/copy-tools.ts +3 -3
- package/server/service/styling/effect-tools.ts +2 -2
- package/server/service/styling/fill-tools.test.ts +1 -1
- package/server/service/styling/fill-tools.ts +4 -4
- package/server/service/styling/material-tools.ts +2 -2
- package/server/service/styling/registry.ts +6 -6
- package/server/service/styling/stroke-tools.test.ts +1 -1
- package/server/service/styling/stroke-tools.ts +3 -3
- package/server/service/styling/text-tools.ts +2 -2
- package/server/service/tool-exposure.test.ts +7 -7
- package/server/service/types.ts +9 -110
- package/server/service/validation/board-model-schema.test.ts +3 -3
- package/server/service/validation/board-model-schema.ts +4 -4
- package/server/service/validation/tool-validation.ts +5 -5
- package/dist-server/service/apply-patch.d.ts +0 -47
- package/dist-server/service/apply-patch.js +0 -369
- package/dist-server/service/apply-patch.js.map +0 -1
- package/server/service/apply-patch-drift.test.ts +0 -831
- package/server/service/apply-patch.test.ts +0 -757
- package/server/service/apply-patch.ts +0 -411
package/PLAN-styling-tools.md
CHANGED
|
@@ -572,7 +572,7 @@ packages/board-ai/server/service/
|
|
|
572
572
|
|
|
573
573
|
```ts
|
|
574
574
|
// μ: setFill(refids=[35], mode='solid', color='red')
|
|
575
|
-
// β
|
|
575
|
+
// β SceneEditPatch:
|
|
576
576
|
{
|
|
577
577
|
ops: [
|
|
578
578
|
{ op: 'modify', refid: 35, patch: { fillStyle: { type: 'solid', color: '#ff0000' } } }
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import type { AIClient, AITool, AIToolCall, AIToolChatResult } from '@things-factory/ai-client-base';
|
|
5
5
|
import { type BoardModel, type ComponentCategory } from '@things-factory/board-import';
|
|
6
|
-
import type { BoardAIAssistant,
|
|
6
|
+
import type { BoardAIAssistant, ChatOptions, ChatResponse, LLMMessage } from './types.js';
|
|
7
7
|
import { formatAbortNotice, summarizeToolResult, type ToolGate as NeutralToolGate } from '@things-factory/ai-client-base';
|
|
8
|
+
import type { SceneEditOp } from '@operato/scene-ops';
|
|
8
9
|
import { type ToolCategoryFilter } from '@things-factory/ai-client-base';
|
|
9
10
|
export interface BoardAIAssistantOptions {
|
|
10
11
|
/** κΈ°λ³Έ scope (chat νΈμΆ μ μ΅μ
μ΄ μμΌλ©΄ μ¬μ©) */
|
|
@@ -96,10 +97,10 @@ export interface ToolGate extends NeutralToolGate {
|
|
|
96
97
|
*/
|
|
97
98
|
export declare function buildToolGate(exposure?: ToolExposure): ToolGate;
|
|
98
99
|
/**
|
|
99
|
-
* Tool call β
|
|
100
|
+
* Tool call β SceneActionOp λ³ν (C-1 ephemeral scene μ‘°μ).
|
|
100
101
|
* μλͺ»λ μΈμλ null β agentic loop κ° Unknown tool λΉμ·νκ² μ²λ¦¬.
|
|
101
102
|
*/
|
|
102
|
-
export declare function
|
|
103
|
+
export declare function toolCallToSceneActionOp(tc: AIToolCall, gate?: ToolGate): import('@operato/scene-ops').SceneActionOp | null;
|
|
103
104
|
/**
|
|
104
105
|
* AIToolChatResult β ChatResponse.
|
|
105
106
|
*
|
|
@@ -109,5 +110,5 @@ export declare function toolCallToBoardActionOp(tc: AIToolCall, gate?: ToolGate)
|
|
|
109
110
|
* μ€κ³.
|
|
110
111
|
*/
|
|
111
112
|
export declare function toolResultToChatResponse(result: AIToolChatResult): ChatResponse;
|
|
112
|
-
export declare function
|
|
113
|
+
export declare function toolCallToSceneEditOp(tc: AIToolCall, components?: ReadonlyArray<any>, gate?: ToolGate): SceneEditOp | SceneEditOp[] | null;
|
|
113
114
|
export declare function summarizeBoard(board: BoardModel | null | undefined): any;
|
|
@@ -166,7 +166,7 @@ export class DefaultBoardAIAssistant {
|
|
|
166
166
|
executeReadTool: (tc, ctx) => wrappedExecuteReadTool(tc, ctx.board, ctx.selectedRefids),
|
|
167
167
|
/* λ¬Έμμμ λΆνμ κΊΌλ΄λ μΌμ **μ¬κΈ°μ** νλ€ β 루νλ board μ λͺ¨μμ λͺ¨λ₯Έλ€. */
|
|
168
168
|
validateWriteToolCall: (tc, ctx) => validateWriteToolCall(tc, (ctx.board?.components ?? [])),
|
|
169
|
-
toolCallToOp:
|
|
169
|
+
toolCallToOp: toolCallToSceneActionOp,
|
|
170
170
|
summarizeToolResult
|
|
171
171
|
},
|
|
172
172
|
context: { board: currentBoard, selectedRefids }
|
|
@@ -176,11 +176,11 @@ export class DefaultBoardAIAssistant {
|
|
|
176
176
|
const toolUsages = loopResult.toolUsages;
|
|
177
177
|
const lastText = loopResult.lastText;
|
|
178
178
|
const stopReason = loopResult.stopReason;
|
|
179
|
-
// accumulated write calls β
|
|
179
|
+
// accumulated write calls β SceneEditPatch (tool μ΄ array λ°ν κ°λ₯ β flat)
|
|
180
180
|
const components = (currentBoard?.components ?? []);
|
|
181
181
|
const ops = accumulatedWriteCalls
|
|
182
182
|
.flatMap(call => {
|
|
183
|
-
const r =
|
|
183
|
+
const r = toolCallToSceneEditOp(call, components, gate);
|
|
184
184
|
if (r === null)
|
|
185
185
|
return [];
|
|
186
186
|
return Array.isArray(r) ? r : [r];
|
|
@@ -270,7 +270,7 @@ export class DefaultBoardAIAssistant {
|
|
|
270
270
|
μ무κ²λ μ λ°λμκΈ° λλ¬Έ.
|
|
271
271
|
|
|
272
272
|
λ£°:
|
|
273
|
-
1. λ³κ²½ μμ² β write tool νΈμΆ νμ (
|
|
273
|
+
1. λ³κ²½ μμ² β write tool νΈμΆ νμ (modifyScene / setFill / setStroke / setMaterial /
|
|
274
274
|
setShadow / setOpacity / setVisible / setFont / setText / setMaterial / addComponent /
|
|
275
275
|
removeComponentByRefid / modifyComponentByRefid / align/distribute/group/zorder λ±)
|
|
276
276
|
2. νΈμΆ + μ§§μ reply ν
μ€νΈ λμ μμ± OK β reply λ *κ²°κ³Ό* λ₯Ό νκ΅μ΄λ‘ νλ λ¬Έμ₯ μμ½
|
|
@@ -294,22 +294,22 @@ root-level properties separate from any child:
|
|
|
294
294
|
- 3D νκ²½: \`sky\` / \`skyColor\` / \`exposure\` / \`hemi*\` / \`dirLight*\` / \`dirShadow*\` / \`camera*\` / \`autoRotate\`
|
|
295
295
|
- μλ³: \`id\`, \`refid\`, \`type\` ("model-layer")
|
|
296
296
|
β 보λ \*\*name\*\* μ root attribute κ° μλ β Board μν°ν°μ DB 컬λΌμ΄μ§ scene
|
|
297
|
-
MODEL μ νλκ° μλ (model-layer κ° λ¬΄μ). 보λ λΌλ²¨ λ³κ²½μ
|
|
297
|
+
MODEL μ νλκ° μλ (model-layer κ° λ¬΄μ). 보λ λΌλ²¨ λ³κ²½μ modifyScene μμ X.
|
|
298
298
|
β’ Children: an array of components inside the board (rect / circle / text /
|
|
299
299
|
gauge / etc.). μ»΄ν¬λνΈλ€μ \`name\` (user label) λ₯Ό κ°μ§ μ μμ β μ΄λ child
|
|
300
300
|
component μ μμ±μ΄μ§ board root μ μμ±μ΄ μλ.
|
|
301
301
|
|
|
302
302
|
Rules:
|
|
303
303
|
- To change a board-level attribute (background, board size, 3D atmosphere)
|
|
304
|
-
β call \`
|
|
304
|
+
β call \`modifyScene({ patch: { fillStyle: ..., width: ..., sky: ..., exposure: ..., dirLight*: ..., hemi*: ... } })\`.
|
|
305
305
|
NOTE: 보λ λΌλ²¨/μ λͺ© ("보λ μ΄λ¦") μ scene model μ΄ μλλΌ Board *μν°ν°* μ 컬λΌ.
|
|
306
|
-
things-scene μ model-layer λ \`name\` μ μΈμνμ§ μμ.
|
|
306
|
+
things-scene μ model-layer λ \`name\` μ μΈμνμ§ μμ. modifyScene μ patch μ
|
|
307
307
|
\`name\` μ λ£μ§ λ§ κ² β μ£½μ νλλ‘ λ°ν λΏ ν¨κ³Ό μμ.
|
|
308
308
|
- To change a CHILD COMPONENT's attribute β call \`modifyComponentByRefid\`.
|
|
309
|
-
- DO NOT use
|
|
309
|
+
- DO NOT use modifyScene to change a child. DO NOT use modifyComponentByRefid
|
|
310
310
|
to change board background.
|
|
311
311
|
- "보λ λ°°κ²½μ", "board background", "ν
λ리/μΊλ²μ€ ν¬κΈ°" κ°μ μμ²μ root
|
|
312
|
-
attribute λ³κ²½ β \`
|
|
312
|
+
attribute λ³κ²½ β \`modifyScene\`.
|
|
313
313
|
|
|
314
314
|
==== COMPONENT TREE (NESTING) ====
|
|
315
315
|
μ»΄ν¬λνΈλ *μ¬κ· ꡬ쑰*. group / container κ°μ λΆλͺ¨ μ»΄ν¬λνΈλ μκΈ° \`components\`
|
|
@@ -375,8 +375,8 @@ to that wording in your reply. Do not echo refid back to the user.
|
|
|
375
375
|
|
|
376
376
|
==== AVAILABLE TOOLS ====
|
|
377
377
|
Board-level (root attributes):
|
|
378
|
-
-
|
|
379
|
-
- replaceBoard: wholesale board reset (heavy β prefer
|
|
378
|
+
- modifyScene: change board's own fillStyle / width / height / fitMode / translate / scale AND 3D atmosphere (sky / skyColor / exposure / hemiSkyColor / hemiGroundColor / hemiIntensity / dirLightEnabled / dirLightColor / dirLightIntensity / dirLightFollowCamera / dirLightAzimuth / dirLightElevation / dirShadow* / camera* / autoRotate / initialCameraView). β "name" κΈμ§ β scene MODEL μ΄ μλλΌ Board μν°ν° 컬λΌ.
|
|
379
|
+
- replaceBoard: wholesale board reset (heavy β prefer modifyScene for most changes)
|
|
380
380
|
Child components β data:
|
|
381
381
|
- addComponent: add a new component (parallel calls for multiple adds)
|
|
382
382
|
- removeComponentByRefid: remove a child by refid
|
|
@@ -433,10 +433,10 @@ Modeller actions (ephemeral β does NOT modify the board model, no undo, no sav
|
|
|
433
433
|
- fitToView: reset view so the board fits the canvas (mode: fit/ratio/width/height)
|
|
434
434
|
- setSceneMode: switch modeller between 'edit' and 'view' modes
|
|
435
435
|
Knowledge:
|
|
436
|
-
- getAtmosphereGuide: 3D atmosphere synthesis primer β parameter physics, ranges, color theory, archetype recipes (time-of-day / indoor / surreal). Call BEFORE applying atmospheric/styling
|
|
436
|
+
- getAtmosphereGuide: 3D atmosphere synthesis primer β parameter physics, ranges, color theory, archetype recipes (time-of-day / indoor / surreal). Call BEFORE applying atmospheric/styling modifyScene for any natural-language mood request.
|
|
437
437
|
|
|
438
438
|
==== 3D ATMOSPHERE SYNTHESIS ====
|
|
439
|
-
3D scene atmosphere = combination of (1) sky preset / color (2) exposure (3) hemisphere ambient (4) directional sun/key (5) floor material. ALL of these are root-level board attributes β applied via a SINGLE
|
|
439
|
+
3D scene atmosphere = combination of (1) sky preset / color (2) exposure (3) hemisphere ambient (4) directional sun/key (5) floor material. ALL of these are root-level board attributes β applied via a SINGLE modifyScene call.
|
|
440
440
|
|
|
441
441
|
For ANY natural-language atmospheric request β "곡μ₯ λΆμκΈ°λ‘", "μ¬ν΄ 컬λ¬", "ν©νΌ", "μ¬μ΄λ²νν¬", "μκ° μμ±ν μλ²½", "1980 μ°μ£Όμ κ±°μ₯", "λ°λ»νκ²", "μ°¨κ°κ³ κ·Ήμ μΌλ‘" β follow this workflow:
|
|
442
442
|
|
|
@@ -444,11 +444,11 @@ For ANY natural-language atmospheric request β "곡μ₯ λΆμκΈ°λ‘", "μ¬ν΄
|
|
|
444
444
|
2. From the guide's "archetypes" section, pick the closest base recipe (time-of-day / indoor / surreal). Interpolate if user combines multiple cues.
|
|
445
445
|
3. Apply user's nuance via the guide's "modifiers" (warm/cool, drama, saturation, contrast).
|
|
446
446
|
4. Sanity-check: avoid washout (all params maxed) or mud (all minned). Confirm hemi sky/ground colors and dir color are consistent with the mood.
|
|
447
|
-
5. Apply ALL keys in ONE
|
|
447
|
+
5. Apply ALL keys in ONE modifyScene({patch}) call (sky, skyColor?, exposure, hemiIntensity, hemiSkyColor, hemiGroundColor, dirLightEnabled, dirLightColor, dirLightIntensity, dirLightFollowCamera=false, dirLightAzimuth, dirLightElevation, fillStyle?). ONE patch β not multiple modifyScene calls.
|
|
448
448
|
6. In the reply, briefly state which archetype + modifier you composed.
|
|
449
449
|
|
|
450
450
|
Avoid:
|
|
451
|
-
- Calling
|
|
451
|
+
- Calling modifyScene with only "fillStyle" for atmospheric requests β that only changes 2D background and floor tint, NOT the 3D scene mood.
|
|
452
452
|
- Mixing a sky preset with explicit skyColor (preset wins, skyColor ignored).
|
|
453
453
|
- Setting dirLightAzimuth/Elevation while leaving dirLightFollowCamera=true (no effect β set follow=false first).
|
|
454
454
|
- Using only canned presets when the user describes a custom mood β the guide enables synthesis beyond presets.
|
|
@@ -633,7 +633,7 @@ export function buildBoardEditTools(knownTypes, exposure = {}) {
|
|
|
633
633
|
}
|
|
634
634
|
},
|
|
635
635
|
{
|
|
636
|
-
name: '
|
|
636
|
+
name: 'modifyScene',
|
|
637
637
|
description: "Modify the BOARD's OWN root-level properties β the board itself is the topmost parent (model-layer) and has its own attributes (NOT child components). Valid root keys (things-scene μ model-layer κ° μ€μ μΈμνλ κ²λ§):\n β’ Layout/Geometry: `width`, `height`, `fitMode` ('ratio'|'both'|'width'|'height'|'center'|'none'), `translate` ({x,y}), `scale` ({x,y})\n β’ 2D λ°°κ²½: `fillStyle` (string color or object)\n β’ 3D Sky: `sky` (preset μ΄λ¦), `skyColor` (preset λ―Έμ§μ μ λ¨μ)\n β’ 3D Tone: `exposure` (toneMappingExposure, κΈ°λ³Έ 1.0~1.2)\n β’ 3D Hemisphere light: `hemiSkyColor`, `hemiGroundColor`, `hemiIntensity` (κΈ°λ³Έ 4.0)\n β’ 3D Directional light: `dirLightEnabled` (bool), `dirLightColor`, `dirLightIntensity` (κΈ°λ³Έ 2.0), `dirLightFollowCamera` (bool, κΈ°λ³Έ true), `dirLightAzimuth` (deg, follow=false μΌ λλ§), `dirLightElevation` (deg, follow=false μΌ λλ§)\n β’ 3D Shadow: `dirShadowEnabled`, `dirShadowMapSize` (κΈ°λ³Έ 2048), `dirShadowBias`\n β’ 3D Camera: `cameraX`, `cameraY`, `cameraZ`, `cameraAutoPlay` ('orbit' λ±), `autoRotate` (bool), `initialCameraView`\n\nβ μ λ μ¬μ© κΈμ§: `name` β Board *μν°ν°* μ 컬λΌμ΄μ§ scene MODEL μ νλκ° μλ. things-scene μ΄ μΈμ μ ν¨. 보λ λΌλ²¨ λ³κ²½μ GraphQL boardPatch μ μμ.\n\nDo NOT use for child component edits (use modifyComponentByRefid for those). Do NOT pass a `components` array here β children are managed by add/remove/modify ops separately.",
|
|
638
638
|
parameters: {
|
|
639
639
|
type: 'object',
|
|
@@ -649,7 +649,7 @@ export function buildBoardEditTools(knownTypes, exposure = {}) {
|
|
|
649
649
|
},
|
|
650
650
|
{
|
|
651
651
|
name: 'replaceBoard',
|
|
652
|
-
description: 'Replace the entire board (use ONLY for fresh start or wholesale redesign β heavy operation that resets undo history). For just changing background or size, prefer
|
|
652
|
+
description: 'Replace the entire board (use ONLY for fresh start or wholesale redesign β heavy operation that resets undo history). For just changing background or size, prefer modifyScene. Provide width/height and the full components array.',
|
|
653
653
|
parameters: {
|
|
654
654
|
type: 'object',
|
|
655
655
|
properties: {
|
|
@@ -718,7 +718,7 @@ export function buildBoardEditTools(knownTypes, exposure = {}) {
|
|
|
718
718
|
},
|
|
719
719
|
{
|
|
720
720
|
name: 'getAtmosphereGuide',
|
|
721
|
-
description: "Get a comprehensive 3D atmosphere synthesis guide β parameter physics (sky / exposure / hemisphere / directional / shadow / floor / camera), sane ranges, color theory, time-of-day archetypes, and indoor/surreal mood recipes. Call this BEFORE applying atmospheric/styling changes via
|
|
721
|
+
description: "Get a comprehensive 3D atmosphere synthesis guide β parameter physics (sky / exposure / hemisphere / directional / shadow / floor / camera), sane ranges, color theory, time-of-day archetypes, and indoor/surreal mood recipes. Call this BEFORE applying atmospheric/styling changes via modifyScene whenever the user describes a mood / scene / time-of-day in natural language (e.g. 'μ¬ν΄ 컬λ¬', 'ν©νΌ', '곡μ₯ λΆμκΈ°', 'μ¬μ΄λ²νν¬', 'μκ° μμ±ν μλ²½'). The guide enables you to synthesize concrete parameter values yourself, beyond canned presets.",
|
|
722
722
|
parameters: { type: 'object', properties: {} }
|
|
723
723
|
},
|
|
724
724
|
{
|
|
@@ -1050,7 +1050,7 @@ const WRITE_TOOL_NAMES = new Set([
|
|
|
1050
1050
|
'setShadowProperties',
|
|
1051
1051
|
'clearStyle',
|
|
1052
1052
|
'copyStyle',
|
|
1053
|
-
'
|
|
1053
|
+
'modifyScene',
|
|
1054
1054
|
'replaceBoard',
|
|
1055
1055
|
// Phase 2 β model μ°¨μ scene μ‘°μ (μ’ν/ꡬ쑰/zorder)
|
|
1056
1056
|
'alignComponents',
|
|
@@ -1067,7 +1067,7 @@ const WRITE_TOOL_NAMES = new Set([
|
|
|
1067
1067
|
]);
|
|
1068
1068
|
/**
|
|
1069
1069
|
* C-1 β ephemeral scene μ‘°μ (selection / view / mode). model λ³κ²½ X, undo μν₯ X.
|
|
1070
|
-
* λ³λ ChatResponse.actions μ±λλ‘ μ λ¬ β νΈμ€νΈκ°
|
|
1070
|
+
* λ³λ ChatResponse.actions μ±λλ‘ μ λ¬ β νΈμ€νΈκ° scene-action-execute λ‘ μ μ©.
|
|
1071
1071
|
*/
|
|
1072
1072
|
const ACTION_TOOL_NAMES = new Set([
|
|
1073
1073
|
'selectComponents',
|
|
@@ -1204,13 +1204,13 @@ export function executeReadTool(call, currentBoard, selectedRefids) {
|
|
|
1204
1204
|
*
|
|
1205
1205
|
* μλ β preset ν λ¨μ΄λ‘ λλμ§ μλ μ¬μ©μ μμ² ("μ¬ν΄", "ν©νΌ", "1980 μ°μ£Όμ κ±°μ₯",
|
|
1206
1206
|
* "μκ° μλ²½") μ AI κ° κ΅¬μ²΄μ νλΌλ―Έν° κ°μ μ§μ ν©μ±νλλ‘ λ¬Όλ¦¬/μμ±/λ―Έν μ§μ
|
|
1207
|
-
* λμ μ 곡. AI λ μ΄ κ°μ΄λλ₯Ό λ°μ λ€
|
|
1207
|
+
* λμ μ 곡. AI λ μ΄ κ°μ΄λλ₯Ό λ°μ λ€ modifyScene λ‘ ν λ²μ μ μ©.
|
|
1208
1208
|
*
|
|
1209
|
-
* things-scene μ board model μ λ€μ΄κ°λ root level ν€λ§ λ€λ£Έ (
|
|
1209
|
+
* things-scene μ board model μ λ€μ΄κ°λ root level ν€λ§ λ€λ£Έ (modifyScene λ‘
|
|
1210
1210
|
* μ μ© κ°λ₯ν κ²). camera position κ°μ ephemeral ν κ²μ λ³λ μμ.
|
|
1211
1211
|
*/
|
|
1212
1212
|
const ATMOSPHERE_GUIDE = {
|
|
1213
|
-
overview: '3D 보λ λΆμκΈ°λ (1) sky preset λλ λ¨μ (2) tone mapping exposure (3) hemisphere ambient (4) directional sun/key (5) floor μ μ‘°ν©. λͺ¨λ board root model μ μμ±μ΄λΌ
|
|
1213
|
+
overview: '3D 보λ λΆμκΈ°λ (1) sky preset λλ λ¨μ (2) tone mapping exposure (3) hemisphere ambient (4) directional sun/key (5) floor μ μ‘°ν©. λͺ¨λ board root model μ μμ±μ΄λΌ modifyScene λ¨μΌ op λ‘ ν λ²μ μ μ©. μμ°μ΄ μμ²μ archetype λ μνΌλ₯Ό base λ‘ μ‘κ³ modifier λ‘ fine-tune.',
|
|
1214
1214
|
parameters: {
|
|
1215
1215
|
sky: {
|
|
1216
1216
|
description: '3D λ°°κ²½ + IBL (image-based lighting) μ source. preset / "color" / "" μ
μ€ νλ.',
|
|
@@ -1535,7 +1535,7 @@ const ATMOSPHERE_GUIDE = {
|
|
|
1535
1535
|
'2. archetypes μμ κ°μ₯ κ°κΉμ΄ base λ μνΌ μ ν.',
|
|
1536
1536
|
'3. modifiers λ‘ μ¬μ©μ μμ² λμμ€ fine-tune (warm/cool/drama/...).',
|
|
1537
1537
|
'4. sanity check β exposure Γ hemi Γ dir μ΄λ νμͺ½ κ·Ήλ¨ μλμ§, hemi sky/ground μ λͺ¨μ μλμ§.',
|
|
1538
|
-
"5.
|
|
1538
|
+
"5. modifyScene({ patch: { ...combined keys... } }) ν λ²μ μ μ©. μ¬μ©μμκ² μ΄λ€ archetype + modifier μ‘°ν©μΌλ‘ κ°λμ§ ν μ€λ‘ μ€λͺ
."
|
|
1539
1539
|
],
|
|
1540
1540
|
pitfalls: [
|
|
1541
1541
|
'sky preset μμ skyColor κ°μ΄ μ§μ νλ©΄ preset μ΄ μ°μ (skyColor 무μ).',
|
|
@@ -1555,7 +1555,7 @@ const ATMOSPHERE_GUIDE = {
|
|
|
1555
1555
|
* μ¬μ© νλ¦:
|
|
1556
1556
|
* 1. μ¬μ©μ μλ (μ°μ
/ κΈμ΅ / μλ£ / SF / ...) μλ³
|
|
1557
1557
|
* 2. recommendations μμ λ§€μΉ ν보 1~2κ° μΆλ¦Ό
|
|
1558
|
-
* 3.
|
|
1558
|
+
* 3. modifyScene λ‘ board.fillStyle μ palette.base λ‘ μ€μ
|
|
1559
1559
|
* 4. addPrefab / addComponent μ palette μ surface/accent/text μ¬μ©
|
|
1560
1560
|
* 5. μΌκ΄λ 룩 β ν λ² μ ν νλ νΈ μμμλ§ μ μ ν
|
|
1561
1561
|
*
|
|
@@ -1682,7 +1682,7 @@ const COLOR_PALETTES = {
|
|
|
1682
1682
|
workflow: [
|
|
1683
1683
|
'1. μ¬μ©μ λλ©μΈ / λΆμκΈ° ν€μλ μλ³ β μ°μ
/κΈμ΅/κ΄μ /μλ£/SF/νλ μ ν
μ΄μ
',
|
|
1684
1684
|
'2. recommendations μμ λ§€μΉ ν보 μΆλ¦Ό. μ¬μ©μ λͺ¨νΈνλ©΄ κ°μ₯ νν industrial-steel λν΄νΈ.',
|
|
1685
|
-
"3.
|
|
1685
|
+
"3. modifyScene({ patch: { fillStyle: palette.base } }) μΌλ‘ 보λ λ°°κ²½ set.",
|
|
1686
1686
|
'4. μ΄ν λͺ¨λ add / addPrefab νΈμΆ μ palette.surface / accent / text / border μ¬μ©. μμ μ X.',
|
|
1687
1687
|
'5. status νμλ success / warning / danger / info 4μ’
μμλ§ β μ체 hex λ§λ€μ§ λ§λΌ.'
|
|
1688
1688
|
],
|
|
@@ -1867,10 +1867,10 @@ function buildExternalCategoryDefinitions(filter) {
|
|
|
1867
1867
|
}));
|
|
1868
1868
|
}
|
|
1869
1869
|
/**
|
|
1870
|
-
* Tool call β
|
|
1870
|
+
* Tool call β SceneActionOp λ³ν (C-1 ephemeral scene μ‘°μ).
|
|
1871
1871
|
* μλͺ»λ μΈμλ null β agentic loop κ° Unknown tool λΉμ·νκ² μ²λ¦¬.
|
|
1872
1872
|
*/
|
|
1873
|
-
export function
|
|
1873
|
+
export function toolCallToSceneActionOp(tc, gate = buildToolGate()) {
|
|
1874
1874
|
const args = tc.arguments ?? {};
|
|
1875
1875
|
/* μ¬ μ‘°μ μ‘μ
μ μ λΆ μ½μ΄(보λ) λ₯λ ₯ β λ
ΈμΆ μ λ λνμμλ λ§λ€μ§ μλλ€.
|
|
1876
1876
|
* loop λ gate.isAction μΌλ‘ μ΄λ―Έ κ±Έλ¬λ΄μ§λ§, λ€λ₯Έ νΈμΆλΆμ μ€μ©λ λ§λλ€. */
|
|
@@ -1907,7 +1907,7 @@ export function toolCallToBoardActionOp(tc, gate = buildToolGate()) {
|
|
|
1907
1907
|
return null;
|
|
1908
1908
|
}
|
|
1909
1909
|
}
|
|
1910
|
-
// ββ Tool call β
|
|
1910
|
+
// ββ Tool call β SceneEditOp λ³ν βββββββββββββββββββββββββββββββββββ
|
|
1911
1911
|
/**
|
|
1912
1912
|
* AIToolChatResult β ChatResponse.
|
|
1913
1913
|
*
|
|
@@ -1919,7 +1919,7 @@ export function toolCallToBoardActionOp(tc, gate = buildToolGate()) {
|
|
|
1919
1919
|
export function toolResultToChatResponse(result) {
|
|
1920
1920
|
const ops = result.toolCalls
|
|
1921
1921
|
.flatMap(call => {
|
|
1922
|
-
const r =
|
|
1922
|
+
const r = toolCallToSceneEditOp(call);
|
|
1923
1923
|
if (r === null)
|
|
1924
1924
|
return [];
|
|
1925
1925
|
return Array.isArray(r) ? r : [r];
|
|
@@ -1935,7 +1935,7 @@ export function toolResultToChatResponse(result) {
|
|
|
1935
1935
|
}
|
|
1936
1936
|
return { reply, patch, followUp: undefined };
|
|
1937
1937
|
}
|
|
1938
|
-
export function
|
|
1938
|
+
export function toolCallToSceneEditOp(tc, components = [], gate = buildToolGate()) {
|
|
1939
1939
|
const args = tc.arguments ?? {};
|
|
1940
1940
|
/* λ
ΈμΆλμ§ μμ μ½μ΄(보λ νΈμ§) λꡬλ op λ₯Ό λ§λ€μ§ μλλ€ β μ μλ₯Ό μ¨κ²Όμ΄λ νΈμΆμ μ¬ μ μλ€. */
|
|
1941
1941
|
if (!gate.coreOn && !gate.spec(tc.name))
|
|
@@ -1948,7 +1948,7 @@ export function toolCallToBoardEditOp(tc, components = [], gate = buildToolGate(
|
|
|
1948
1948
|
return dispatchStylingTool(tc.name, args, components);
|
|
1949
1949
|
}
|
|
1950
1950
|
// tool-registry plugin point β μΈλΆ λ±λ‘ 'write' μΉ΄ν
κ³ λ¦¬ dispatch.
|
|
1951
|
-
// builder κ²°κ³Όλ
|
|
1951
|
+
// builder κ²°κ³Όλ SceneEditOp[] | { ops, errors? } | null μ
μ€ νλ.
|
|
1952
1952
|
// (read/external μΉ΄ν
κ³ λ¦¬λ λ³λ dispatch path β agentic loop μ executeReadTool μ΄ μ§μ μ²λ¦¬.)
|
|
1953
1953
|
const registrySpec = gate.spec(tc.name);
|
|
1954
1954
|
if (registrySpec && registrySpec.kind === 'write') {
|
|
@@ -1980,17 +1980,17 @@ export function toolCallToBoardEditOp(tc, components = [], gate = buildToolGate(
|
|
|
1980
1980
|
// λͺ¨λ styling tool (setFill/setStroke/setText/setFont/setShadow/setOpacity/
|
|
1981
1981
|
// setVisible/setMaterial/setShadowProperties/clearStyle/copyStyle) μ registry
|
|
1982
1982
|
// κ° μ²λ¦¬ β μλ¨ isStylingTool λΆκΈ° μ°Έμ‘°
|
|
1983
|
-
case '
|
|
1983
|
+
case 'modifyScene': {
|
|
1984
1984
|
if (!args.patch || typeof args.patch !== 'object' || Array.isArray(args.patch))
|
|
1985
1985
|
return null;
|
|
1986
|
-
return { op: '
|
|
1986
|
+
return { op: 'modifyScene', patch: args.patch };
|
|
1987
1987
|
}
|
|
1988
1988
|
case 'replaceBoard': {
|
|
1989
1989
|
if (!Array.isArray(args.components))
|
|
1990
1990
|
return null;
|
|
1991
1991
|
return {
|
|
1992
1992
|
op: 'replace',
|
|
1993
|
-
|
|
1993
|
+
model: {
|
|
1994
1994
|
width: typeof args.width === 'number' ? args.width : undefined,
|
|
1995
1995
|
height: typeof args.height === 'number' ? args.height : undefined,
|
|
1996
1996
|
fillStyle: typeof args.fillStyle === 'string' ? args.fillStyle : undefined,
|