@things-factory/board-ai 10.1.24 → 10.1.25
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/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-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/package.json +6 -5
- 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-client/tsconfig.tsbuildinfo +0 -1
- 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/dist-server/tsconfig.tsbuildinfo +0 -1
- package/logs/connections-2026-09-12-15.log +0 -0
- 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
|
@@ -9,9 +9,9 @@ exports.listLayoutTemplateNames = listLayoutTemplateNames;
|
|
|
9
9
|
exports.isWriteTool = isWriteTool;
|
|
10
10
|
exports.isActionTool = isActionTool;
|
|
11
11
|
exports.buildToolGate = buildToolGate;
|
|
12
|
-
exports.
|
|
12
|
+
exports.toolCallToSceneActionOp = toolCallToSceneActionOp;
|
|
13
13
|
exports.toolResultToChatResponse = toolResultToChatResponse;
|
|
14
|
-
exports.
|
|
14
|
+
exports.toolCallToSceneEditOp = toolCallToSceneEditOp;
|
|
15
15
|
exports.summarizeBoard = summarizeBoard;
|
|
16
16
|
const board_import_1 = require("@things-factory/board-import");
|
|
17
17
|
const prefab_registry_1 = require("./prefab-registry");
|
|
@@ -183,7 +183,7 @@ class DefaultBoardAIAssistant {
|
|
|
183
183
|
executeReadTool: (tc, ctx) => wrappedExecuteReadTool(tc, ctx.board, ctx.selectedRefids),
|
|
184
184
|
/* 문서에서 부품을 꺼내는 일은 **여기서** 한다 — 루프는 board 의 모양을 모른다. */
|
|
185
185
|
validateWriteToolCall: (tc, ctx) => (0, tool_validation_1.validateWriteToolCall)(tc, (ctx.board?.components ?? [])),
|
|
186
|
-
toolCallToOp:
|
|
186
|
+
toolCallToOp: toolCallToSceneActionOp,
|
|
187
187
|
summarizeToolResult: ai_client_base_1.summarizeToolResult
|
|
188
188
|
},
|
|
189
189
|
context: { board: currentBoard, selectedRefids }
|
|
@@ -193,11 +193,11 @@ class DefaultBoardAIAssistant {
|
|
|
193
193
|
const toolUsages = loopResult.toolUsages;
|
|
194
194
|
const lastText = loopResult.lastText;
|
|
195
195
|
const stopReason = loopResult.stopReason;
|
|
196
|
-
// accumulated write calls →
|
|
196
|
+
// accumulated write calls → SceneEditPatch (tool 이 array 반환 가능 — flat)
|
|
197
197
|
const components = (currentBoard?.components ?? []);
|
|
198
198
|
const ops = accumulatedWriteCalls
|
|
199
199
|
.flatMap(call => {
|
|
200
|
-
const r =
|
|
200
|
+
const r = toolCallToSceneEditOp(call, components, gate);
|
|
201
201
|
if (r === null)
|
|
202
202
|
return [];
|
|
203
203
|
return Array.isArray(r) ? r : [r];
|
|
@@ -287,7 +287,7 @@ class DefaultBoardAIAssistant {
|
|
|
287
287
|
아무것도 안 바뀌었기 때문.
|
|
288
288
|
|
|
289
289
|
룰:
|
|
290
|
-
1. 변경 요청 → write tool 호출 필수 (
|
|
290
|
+
1. 변경 요청 → write tool 호출 필수 (modifyScene / setFill / setStroke / setMaterial /
|
|
291
291
|
setShadow / setOpacity / setVisible / setFont / setText / setMaterial / addComponent /
|
|
292
292
|
removeComponentByRefid / modifyComponentByRefid / align/distribute/group/zorder 등)
|
|
293
293
|
2. 호출 + 짧은 reply 텍스트 동시 작성 OK — reply 는 *결과* 를 한국어로 한두 문장 요약
|
|
@@ -311,22 +311,22 @@ root-level properties separate from any child:
|
|
|
311
311
|
- 3D 환경: \`sky\` / \`skyColor\` / \`exposure\` / \`hemi*\` / \`dirLight*\` / \`dirShadow*\` / \`camera*\` / \`autoRotate\`
|
|
312
312
|
- 식별: \`id\`, \`refid\`, \`type\` ("model-layer")
|
|
313
313
|
⚠ 보드 \*\*name\*\* 은 root attribute 가 아님 — Board 엔티티의 DB 컬럼이지 scene
|
|
314
|
-
MODEL 의 필드가 아님 (model-layer 가 무시). 보드 라벨 변경은
|
|
314
|
+
MODEL 의 필드가 아님 (model-layer 가 무시). 보드 라벨 변경은 modifyScene 영역 X.
|
|
315
315
|
• Children: an array of components inside the board (rect / circle / text /
|
|
316
316
|
gauge / etc.). 컴포넌트들은 \`name\` (user label) 를 가질 수 있음 — 이는 child
|
|
317
317
|
component 의 속성이지 board root 의 속성이 아님.
|
|
318
318
|
|
|
319
319
|
Rules:
|
|
320
320
|
- To change a board-level attribute (background, board size, 3D atmosphere)
|
|
321
|
-
→ call \`
|
|
321
|
+
→ call \`modifyScene({ patch: { fillStyle: ..., width: ..., sky: ..., exposure: ..., dirLight*: ..., hemi*: ... } })\`.
|
|
322
322
|
NOTE: 보드 라벨/제목 ("보드 이름") 은 scene model 이 아니라 Board *엔티티* 의 컬럼.
|
|
323
|
-
things-scene 의 model-layer 는 \`name\` 을 인식하지 않음.
|
|
323
|
+
things-scene 의 model-layer 는 \`name\` 을 인식하지 않음. modifyScene 의 patch 에
|
|
324
324
|
\`name\` 을 넣지 말 것 — 죽은 필드로 박힐 뿐 효과 없음.
|
|
325
325
|
- To change a CHILD COMPONENT's attribute → call \`modifyComponentByRefid\`.
|
|
326
|
-
- DO NOT use
|
|
326
|
+
- DO NOT use modifyScene to change a child. DO NOT use modifyComponentByRefid
|
|
327
327
|
to change board background.
|
|
328
328
|
- "보드 배경색", "board background", "테두리/캔버스 크기" 같은 요청은 root
|
|
329
|
-
attribute 변경 → \`
|
|
329
|
+
attribute 변경 → \`modifyScene\`.
|
|
330
330
|
|
|
331
331
|
==== COMPONENT TREE (NESTING) ====
|
|
332
332
|
컴포넌트는 *재귀 구조*. group / container 같은 부모 컴포넌트는 자기 \`components\`
|
|
@@ -392,8 +392,8 @@ to that wording in your reply. Do not echo refid back to the user.
|
|
|
392
392
|
|
|
393
393
|
==== AVAILABLE TOOLS ====
|
|
394
394
|
Board-level (root attributes):
|
|
395
|
-
-
|
|
396
|
-
- replaceBoard: wholesale board reset (heavy — prefer
|
|
395
|
+
- 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 엔티티 컬럼.
|
|
396
|
+
- replaceBoard: wholesale board reset (heavy — prefer modifyScene for most changes)
|
|
397
397
|
Child components — data:
|
|
398
398
|
- addComponent: add a new component (parallel calls for multiple adds)
|
|
399
399
|
- removeComponentByRefid: remove a child by refid
|
|
@@ -450,10 +450,10 @@ Modeller actions (ephemeral — does NOT modify the board model, no undo, no sav
|
|
|
450
450
|
- fitToView: reset view so the board fits the canvas (mode: fit/ratio/width/height)
|
|
451
451
|
- setSceneMode: switch modeller between 'edit' and 'view' modes
|
|
452
452
|
Knowledge:
|
|
453
|
-
- getAtmosphereGuide: 3D atmosphere synthesis primer — parameter physics, ranges, color theory, archetype recipes (time-of-day / indoor / surreal). Call BEFORE applying atmospheric/styling
|
|
453
|
+
- 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.
|
|
454
454
|
|
|
455
455
|
==== 3D ATMOSPHERE SYNTHESIS ====
|
|
456
|
-
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
|
|
456
|
+
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.
|
|
457
457
|
|
|
458
458
|
For ANY natural-language atmospheric request — "공장 분위기로", "심해 컬러", "황혼", "사이버펑크", "안개 자욱한 새벽", "1980 우주정거장", "따뜻하게", "차갑고 극적으로" — follow this workflow:
|
|
459
459
|
|
|
@@ -461,11 +461,11 @@ For ANY natural-language atmospheric request — "공장 분위기로", "심해
|
|
|
461
461
|
2. From the guide's "archetypes" section, pick the closest base recipe (time-of-day / indoor / surreal). Interpolate if user combines multiple cues.
|
|
462
462
|
3. Apply user's nuance via the guide's "modifiers" (warm/cool, drama, saturation, contrast).
|
|
463
463
|
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.
|
|
464
|
-
5. Apply ALL keys in ONE
|
|
464
|
+
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.
|
|
465
465
|
6. In the reply, briefly state which archetype + modifier you composed.
|
|
466
466
|
|
|
467
467
|
Avoid:
|
|
468
|
-
- Calling
|
|
468
|
+
- Calling modifyScene with only "fillStyle" for atmospheric requests — that only changes 2D background and floor tint, NOT the 3D scene mood.
|
|
469
469
|
- Mixing a sky preset with explicit skyColor (preset wins, skyColor ignored).
|
|
470
470
|
- Setting dirLightAzimuth/Elevation while leaving dirLightFollowCamera=true (no effect — set follow=false first).
|
|
471
471
|
- Using only canned presets when the user describes a custom mood — the guide enables synthesis beyond presets.
|
|
@@ -651,7 +651,7 @@ function buildBoardEditTools(knownTypes, exposure = {}) {
|
|
|
651
651
|
}
|
|
652
652
|
},
|
|
653
653
|
{
|
|
654
|
-
name: '
|
|
654
|
+
name: 'modifyScene',
|
|
655
655
|
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.",
|
|
656
656
|
parameters: {
|
|
657
657
|
type: 'object',
|
|
@@ -667,7 +667,7 @@ function buildBoardEditTools(knownTypes, exposure = {}) {
|
|
|
667
667
|
},
|
|
668
668
|
{
|
|
669
669
|
name: 'replaceBoard',
|
|
670
|
-
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
|
|
670
|
+
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.',
|
|
671
671
|
parameters: {
|
|
672
672
|
type: 'object',
|
|
673
673
|
properties: {
|
|
@@ -736,7 +736,7 @@ function buildBoardEditTools(knownTypes, exposure = {}) {
|
|
|
736
736
|
},
|
|
737
737
|
{
|
|
738
738
|
name: 'getAtmosphereGuide',
|
|
739
|
-
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
|
|
739
|
+
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.",
|
|
740
740
|
parameters: { type: 'object', properties: {} }
|
|
741
741
|
},
|
|
742
742
|
{
|
|
@@ -1068,7 +1068,7 @@ const WRITE_TOOL_NAMES = new Set([
|
|
|
1068
1068
|
'setShadowProperties',
|
|
1069
1069
|
'clearStyle',
|
|
1070
1070
|
'copyStyle',
|
|
1071
|
-
'
|
|
1071
|
+
'modifyScene',
|
|
1072
1072
|
'replaceBoard',
|
|
1073
1073
|
// Phase 2 — model 차원 scene 조작 (좌표/구조/zorder)
|
|
1074
1074
|
'alignComponents',
|
|
@@ -1085,7 +1085,7 @@ const WRITE_TOOL_NAMES = new Set([
|
|
|
1085
1085
|
]);
|
|
1086
1086
|
/**
|
|
1087
1087
|
* C-1 — ephemeral scene 조작 (selection / view / mode). model 변경 X, undo 영향 X.
|
|
1088
|
-
* 별도 ChatResponse.actions 채널로 전달 → 호스트가
|
|
1088
|
+
* 별도 ChatResponse.actions 채널로 전달 → 호스트가 scene-action-execute 로 적용.
|
|
1089
1089
|
*/
|
|
1090
1090
|
const ACTION_TOOL_NAMES = new Set([
|
|
1091
1091
|
'selectComponents',
|
|
@@ -1222,13 +1222,13 @@ function executeReadTool(call, currentBoard, selectedRefids) {
|
|
|
1222
1222
|
*
|
|
1223
1223
|
* 의도 — preset 한 단어로 끝나지 않는 사용자 요청 ("심해", "황혼", "1980 우주정거장",
|
|
1224
1224
|
* "안개 새벽") 에 AI 가 구체적 파라미터 값을 직접 합성하도록 물리/색채/미학 지식
|
|
1225
|
-
* 동시 제공. AI 는 이 가이드를 받은 뒤
|
|
1225
|
+
* 동시 제공. AI 는 이 가이드를 받은 뒤 modifyScene 로 한 번에 적용.
|
|
1226
1226
|
*
|
|
1227
|
-
* things-scene 의 board model 에 들어가는 root level 키만 다룸 (
|
|
1227
|
+
* things-scene 의 board model 에 들어가는 root level 키만 다룸 (modifyScene 로
|
|
1228
1228
|
* 적용 가능한 것). camera position 같은 ephemeral 한 것은 별도 영역.
|
|
1229
1229
|
*/
|
|
1230
1230
|
const ATMOSPHERE_GUIDE = {
|
|
1231
|
-
overview: '3D 보드 분위기는 (1) sky preset 또는 단색 (2) tone mapping exposure (3) hemisphere ambient (4) directional sun/key (5) floor 의 조합. 모두 board root model 의 속성이라
|
|
1231
|
+
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.',
|
|
1232
1232
|
parameters: {
|
|
1233
1233
|
sky: {
|
|
1234
1234
|
description: '3D 배경 + IBL (image-based lighting) 의 source. preset / "color" / "" 셋 중 하나.',
|
|
@@ -1553,7 +1553,7 @@ const ATMOSPHERE_GUIDE = {
|
|
|
1553
1553
|
'2. archetypes 에서 가장 가까운 base 레시피 선택.',
|
|
1554
1554
|
'3. modifiers 로 사용자 요청 뉘앙스 fine-tune (warm/cool/drama/...).',
|
|
1555
1555
|
'4. sanity check — exposure × hemi × dir 어느 한쪽 극단 아닌지, hemi sky/ground 색 모순 없는지.',
|
|
1556
|
-
"5.
|
|
1556
|
+
"5. modifyScene({ patch: { ...combined keys... } }) 한 번에 적용. 사용자에게 어떤 archetype + modifier 조합으로 갔는지 한 줄로 설명."
|
|
1557
1557
|
],
|
|
1558
1558
|
pitfalls: [
|
|
1559
1559
|
'sky preset 위에 skyColor 같이 지정하면 preset 이 우선 (skyColor 무시).',
|
|
@@ -1573,7 +1573,7 @@ const ATMOSPHERE_GUIDE = {
|
|
|
1573
1573
|
* 사용 흐름:
|
|
1574
1574
|
* 1. 사용자 의도 (산업 / 금융 / 의료 / SF / ...) 식별
|
|
1575
1575
|
* 2. recommendations 에서 매칭 후보 1~2개 추림
|
|
1576
|
-
* 3.
|
|
1576
|
+
* 3. modifyScene 로 board.fillStyle 을 palette.base 로 설정
|
|
1577
1577
|
* 4. addPrefab / addComponent 시 palette 의 surface/accent/text 사용
|
|
1578
1578
|
* 5. 일관된 룩 → 한 번 정한 팔레트 안에서만 색 선택
|
|
1579
1579
|
*
|
|
@@ -1700,7 +1700,7 @@ const COLOR_PALETTES = {
|
|
|
1700
1700
|
workflow: [
|
|
1701
1701
|
'1. 사용자 도메인 / 분위기 키워드 식별 — 산업/금융/관제/의료/SF/프레젠테이션',
|
|
1702
1702
|
'2. recommendations 에서 매칭 후보 추림. 사용자 모호하면 가장 흔한 industrial-steel 디폴트.',
|
|
1703
|
-
"3.
|
|
1703
|
+
"3. modifyScene({ patch: { fillStyle: palette.base } }) 으로 보드 배경 set.",
|
|
1704
1704
|
'4. 이후 모든 add / addPrefab 호출 시 palette.surface / accent / text / border 사용. 자유 색 X.',
|
|
1705
1705
|
'5. status 표시는 success / warning / danger / info 4종에서만 — 자체 hex 만들지 마라.'
|
|
1706
1706
|
],
|
|
@@ -1872,10 +1872,10 @@ function buildExternalCategoryDefinitions(filter) {
|
|
|
1872
1872
|
}));
|
|
1873
1873
|
}
|
|
1874
1874
|
/**
|
|
1875
|
-
* Tool call →
|
|
1875
|
+
* Tool call → SceneActionOp 변환 (C-1 ephemeral scene 조작).
|
|
1876
1876
|
* 잘못된 인자는 null — agentic loop 가 Unknown tool 비슷하게 처리.
|
|
1877
1877
|
*/
|
|
1878
|
-
function
|
|
1878
|
+
function toolCallToSceneActionOp(tc, gate = buildToolGate()) {
|
|
1879
1879
|
const args = tc.arguments ?? {};
|
|
1880
1880
|
/* 씬 조작 액션은 전부 코어(보드) 능력 — 노출 안 된 대화에서는 만들지 않는다.
|
|
1881
1881
|
* loop 는 gate.isAction 으로 이미 걸러내지만, 다른 호출부의 오용도 막는다. */
|
|
@@ -1912,7 +1912,7 @@ function toolCallToBoardActionOp(tc, gate = buildToolGate()) {
|
|
|
1912
1912
|
return null;
|
|
1913
1913
|
}
|
|
1914
1914
|
}
|
|
1915
|
-
// ── Tool call →
|
|
1915
|
+
// ── Tool call → SceneEditOp 변환 ───────────────────────────────────
|
|
1916
1916
|
/**
|
|
1917
1917
|
* AIToolChatResult → ChatResponse.
|
|
1918
1918
|
*
|
|
@@ -1924,7 +1924,7 @@ function toolCallToBoardActionOp(tc, gate = buildToolGate()) {
|
|
|
1924
1924
|
function toolResultToChatResponse(result) {
|
|
1925
1925
|
const ops = result.toolCalls
|
|
1926
1926
|
.flatMap(call => {
|
|
1927
|
-
const r =
|
|
1927
|
+
const r = toolCallToSceneEditOp(call);
|
|
1928
1928
|
if (r === null)
|
|
1929
1929
|
return [];
|
|
1930
1930
|
return Array.isArray(r) ? r : [r];
|
|
@@ -1940,7 +1940,7 @@ function toolResultToChatResponse(result) {
|
|
|
1940
1940
|
}
|
|
1941
1941
|
return { reply, patch, followUp: undefined };
|
|
1942
1942
|
}
|
|
1943
|
-
function
|
|
1943
|
+
function toolCallToSceneEditOp(tc, components = [], gate = buildToolGate()) {
|
|
1944
1944
|
const args = tc.arguments ?? {};
|
|
1945
1945
|
/* 노출되지 않은 코어(보드 편집) 도구는 op 를 만들지 않는다 — 정의를 숨겼어도 호출은 올 수 있다. */
|
|
1946
1946
|
if (!gate.coreOn && !gate.spec(tc.name))
|
|
@@ -1953,7 +1953,7 @@ function toolCallToBoardEditOp(tc, components = [], gate = buildToolGate()) {
|
|
|
1953
1953
|
return (0, registry_js_1.dispatchStylingTool)(tc.name, args, components);
|
|
1954
1954
|
}
|
|
1955
1955
|
// tool-registry plugin point — 외부 등록 'write' 카테고리 dispatch.
|
|
1956
|
-
// builder 결과는
|
|
1956
|
+
// builder 결과는 SceneEditOp[] | { ops, errors? } | null 셋 중 하나.
|
|
1957
1957
|
// (read/external 카테고리는 별도 dispatch path — agentic loop 의 executeReadTool 이 직접 처리.)
|
|
1958
1958
|
const registrySpec = gate.spec(tc.name);
|
|
1959
1959
|
if (registrySpec && registrySpec.kind === 'write') {
|
|
@@ -1985,17 +1985,17 @@ function toolCallToBoardEditOp(tc, components = [], gate = buildToolGate()) {
|
|
|
1985
1985
|
// 모든 styling tool (setFill/setStroke/setText/setFont/setShadow/setOpacity/
|
|
1986
1986
|
// setVisible/setMaterial/setShadowProperties/clearStyle/copyStyle) 은 registry
|
|
1987
1987
|
// 가 처리 — 상단 isStylingTool 분기 참조
|
|
1988
|
-
case '
|
|
1988
|
+
case 'modifyScene': {
|
|
1989
1989
|
if (!args.patch || typeof args.patch !== 'object' || Array.isArray(args.patch))
|
|
1990
1990
|
return null;
|
|
1991
|
-
return { op: '
|
|
1991
|
+
return { op: 'modifyScene', patch: args.patch };
|
|
1992
1992
|
}
|
|
1993
1993
|
case 'replaceBoard': {
|
|
1994
1994
|
if (!Array.isArray(args.components))
|
|
1995
1995
|
return null;
|
|
1996
1996
|
return {
|
|
1997
1997
|
op: 'replace',
|
|
1998
|
-
|
|
1998
|
+
model: {
|
|
1999
1999
|
width: typeof args.width === 'number' ? args.width : undefined,
|
|
2000
2000
|
height: typeof args.height === 'number' ? args.height : undefined,
|
|
2001
2001
|
fillStyle: typeof args.fillStyle === 'string' ? args.fillStyle : undefined,
|