@things-factory/board-ai 10.0.2 → 10.0.3
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/client/components/board-ai-chat.ts +458 -19
- package/client/components/chat-echo-dedup.test.ts +59 -3
- package/client/components/chat-echo-dedup.ts +29 -0
- package/dist-client/client/components/board-ai-chat.d.ts +63 -0
- package/dist-client/client/components/board-ai-chat.js +438 -16
- package/dist-client/client/components/board-ai-chat.js.map +1 -1
- package/dist-client/client/components/chat-echo-dedup.js +28 -0
- package/dist-client/client/components/chat-echo-dedup.js.map +1 -1
- package/dist-client/client/components/chat-echo-dedup.test.js +53 -3
- package/dist-client/client/components/chat-echo-dedup.test.js.map +1 -1
- package/dist-client/server/service/agentic-loop.d.ts +15 -0
- package/dist-client/server/service/agentic-loop.js +70 -9
- package/dist-client/server/service/agentic-loop.js.map +1 -1
- package/dist-client/server/service/assistant.js +18 -3
- package/dist-client/server/service/assistant.js.map +1 -1
- package/dist-client/server/service/types.d.ts +23 -0
- package/dist-client/server/service/types.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/service/agentic-loop.d.ts +15 -0
- package/dist-server/service/agentic-loop.js +71 -9
- package/dist-server/service/agentic-loop.js.map +1 -1
- package/dist-server/service/assistant.js +17 -2
- package/dist-server/service/assistant.js.map +1 -1
- package/dist-server/service/board-ai-resolver.d.ts +13 -0
- package/dist-server/service/board-ai-resolver.js +99 -1
- package/dist-server/service/board-ai-resolver.js.map +1 -1
- package/dist-server/service/chat-message/fold-history.d.ts +30 -0
- package/dist-server/service/chat-message/fold-history.js +29 -0
- package/dist-server/service/chat-message/fold-history.js.map +1 -0
- package/dist-server/service/chat-message/history-summary.d.ts +43 -0
- package/dist-server/service/chat-message/history-summary.js +77 -0
- package/dist-server/service/chat-message/history-summary.js.map +1 -0
- package/dist-server/service/chat-message/llm-history.d.ts +19 -0
- package/dist-server/service/chat-message/llm-history.js +31 -1
- package/dist-server/service/chat-message/llm-history.js.map +1 -1
- package/dist-server/service/chat-session/chat-session.d.ts +8 -0
- package/dist-server/service/chat-session/chat-session.js +5 -0
- package/dist-server/service/chat-session/chat-session.js.map +1 -1
- package/dist-server/service/types.d.ts +23 -0
- package/dist-server/service/types.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -6
- package/server/service/agentic-loop.test.ts +91 -0
- package/server/service/agentic-loop.ts +80 -9
- package/server/service/assistant.ts +21 -3
- package/server/service/board-ai-resolver.ts +108 -1
- package/server/service/chat-message/fold-history.test.ts +98 -0
- package/server/service/chat-message/fold-history.ts +60 -0
- package/server/service/chat-message/history-summary.test.ts +127 -0
- package/server/service/chat-message/history-summary.ts +100 -0
- package/server/service/chat-message/llm-history.test.ts +65 -0
- package/server/service/chat-message/llm-history.ts +48 -1
- package/server/service/chat-session/chat-session.ts +11 -0
- package/server/service/dock-contract.test.ts +305 -0
- package/server/service/types.ts +23 -0
- package/translations/en.json +14 -1
- package/translations/ja.json +14 -1
- package/translations/ko.json +13 -0
- package/translations/ms.json +14 -1
- package/translations/zh.json +14 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assistant.js","sourceRoot":"","sources":["../../../server/service/assistant.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * DefaultBoardAIAssistant — base AIClient 위에 LLM 프롬프트로 chat() 구현.\n */\nimport type {\n AIClient,\n AIMessage,\n AITool,\n AIToolCall,\n AIToolChatResult\n} from '@things-factory/ai-client-base'\nimport {\n getImportRules,\n type BoardComponent,\n type BoardModel,\n type ComponentCategory\n} from '@things-factory/board-import'\nimport type {\n BoardAIAssistant,\n BoardEditOp,\n BoardEditPatch,\n ChatOptions,\n ChatResponse,\n ComponentSchema,\n LLMMessage,\n ToolUsage\n} from './types.js'\nimport {\n findBoardPrefab,\n listBoardPrefabs\n} from './prefab-registry'\nimport { resolveMentions } from './mention-resolver'\nimport { resolveCatalogMentions } from './catalog-resolver'\n// styling write tool builder 들은 registry (./styling/registry.ts) 에서 등록 + dispatch.\n// 직접 import 안 함 — 신규 styling tool 추가 시 registry 에만 spec 추가하면 됨.\nimport { buildComponentStyleSummary } from './styling/read-tools'\nimport { runAgenticLoop, type AgenticLoopResult } from './agentic-loop'\nimport { checkReplyGrounding } from './grounding'\nimport { collectAllComponents, findComponentByRefid } from './component-tree'\nimport {\n isStylingTool,\n dispatchStylingTool,\n buildStylingToolDefinitions\n} from './styling/registry.js'\nimport {\n getAllToolSpecs,\n getToolSpecsFor,\n getToolKind,\n findToolSpec,\n type ToolSpec,\n type ToolCategoryFilter\n} from '@things-factory/ai-client-base'\nimport { validateWriteToolCall } from './validation/tool-validation'\n\nconst ALL_CATEGORIES: ComponentCategory[] = [\n 'container',\n 'vehicle',\n 'path',\n 'region',\n 'equipment',\n 'io',\n 'marker',\n 'structure',\n 'unknown'\n]\n\nconst MAX_BOARD_SUMMARY_COMPONENTS = 80\n\n/**\n * 마지막 user 메시지에 한해 #token (컴포넌트 selector) + @token (카탈로그\n * 식별자) 멘션을 LLM 친화 형태로 변환. 다른 메시지 / assistant 메시지는 그대로.\n * 원본 messages 도 mutate 하지 않음.\n *\n * - # 는 본문 LITERAL 보존 + 끝에 mention map 블록 첨부 (refid 본문 노출 0)\n * - @ 는 inline disambiguation ('monitor-card (prefab)')\n *\n * 두 resolver 의 변환 결과 / token regex 가 서로 안 겹쳐 순서 무관.\n */\nfunction enrichLastUserWithMentions(\n messages: LLMMessage[],\n currentBoard: BoardModel | undefined,\n picks?: Array<{ token: string; refid: number }>\n): LLMMessage[] {\n if (messages.length === 0) return messages\n const lastIdx = messages.length - 1\n const last = messages[lastIdx]\n if (last.role !== 'user' || typeof last.content !== 'string') return messages\n const step1 = resolveMentions(last.content, currentBoard ?? null, { picks })\n const step2 = resolveCatalogMentions(step1)\n if (step2 === last.content) return messages\n const out = messages.slice()\n out[lastIdx] = { ...last, content: step2 }\n return out\n}\n\nexport interface BoardAIAssistantOptions {\n /** 기본 scope (chat 호출 시 옵션이 없으면 사용) */\n scopes?: string[]\n knownTypes?: string[]\n categories?: ComponentCategory[]\n}\n\nexport class DefaultBoardAIAssistant implements BoardAIAssistant {\n readonly id: string\n constructor(private base: AIClient, private options: BoardAIAssistantOptions = {}) {\n this.id = base.id\n }\n\n async chat(\n messages: LLMMessage[],\n currentBoard: BoardModel | undefined,\n options: ChatOptions = {}\n ): Promise<ChatResponse> {\n if (messages.length === 0) {\n throw new Error('chat() requires at least one message')\n }\n\n const { knownTypes, categories } = this.resolveTypesAndCategories(options)\n const schemas = options.componentSchemas ?? []\n\n // chatWithTools 필수 — multi-turn agentic loop / read tool / atmosphere guide /\n // tool trace 모두 chatWithTools 위에서 동작. legacy chatViaJSON fallback 은 v10\n // 에서 제거됨 (모던 provider — Anthropic / Gemini / OpenAI — 모두 tool calling 지원).\n if (typeof this.base.chatWithTools !== 'function') {\n throw new Error(\n `AI client \"${this.base.id}\" does not support chatWithTools. ` +\n 'board-ai requires a tool-calling-capable provider (Anthropic / Gemini / OpenAI).'\n )\n }\n\n // 마지막 user 메시지의 #name 멘션을 refid 로 보강 — 영속(ChatMessage) 은 호출자가\n // 받은 원본을 저장하므로 chat 내부에서만 변환된 사본을 사용. AI 가 findComponents\n // 호출 1턴 절약 + 환각 방지.\n const enriched = enrichLastUserWithMentions(\n messages,\n currentBoard,\n options.mentionPicks\n )\n\n return await this.chatViaTools(enriched, currentBoard, options, knownTypes, categories, schemas)\n }\n\n // ── Tool calling 경로 (agentic multi-turn) ─────────────────────────\n\n private async chatViaTools(\n messages: LLMMessage[],\n currentBoard: BoardModel | undefined,\n options: ChatOptions,\n knownTypes: string[],\n categories: ComponentCategory[],\n schemas: ComponentSchema[]\n ): Promise<ChatResponse> {\n /* 대화별 도구 노출 — 정의 조립과 dispatch 판정에 **같은 게이트**를 쓴다.\n * 정의만 숨기면 모델이 이름을 추측하거나 옛 대화가 재생될 때 숨긴 도구가 실행된다. */\n const gate = buildToolGate({ boardTools: options.boardTools, toolCategories: options.toolCategories })\n const tools = buildBoardEditTools(knownTypes, { boardTools: options.boardTools, toolCategories: options.toolCategories })\n const systemPrompt = this.buildSystemPromptForTools(knownTypes, categories, schemas)\n\n const selectedRefids = (options.selectedRefids ?? []).filter(\n (n): n is number => typeof n === 'number' && Number.isFinite(n)\n )\n // selection 정보는 항상 포함 (비어 있어도) — LLM 이 \"선택된 게 뭐냐\" 류 질문에\n // getSelection 을 호출할지 판단하는 데 필요.\n const selectionContext = selectedRefids.length > 0\n ? `\\n\\nUser-selected component refids: ${JSON.stringify(selectedRefids)}\\n` +\n `When the user says \"selected\" / \"선택한\" / \"this\" / \"그것\" / \"these\" etc. ` +\n `WITHOUT specifying targets, operate ONLY on these refids. ` +\n `Do not modify other components unless explicitly asked. ` +\n `For inspecting selected components, prefer calling \\`getSelection\\` over guessing.`\n : `\\n\\nNo component is currently selected. If the user asks about \"selected\" / \"this\", ` +\n `clarify or call \\`getSelection\\` to confirm.`\n\n const boardContext = currentBoard\n ? `Current board state (JSON, summarized; full details via \\`getComponent\\` / \\`findComponents\\`):\\n` +\n `${JSON.stringify(summarizeBoard(currentBoard), null, 2)}` + selectionContext\n : 'No current board (empty start).' + selectionContext\n\n let conversation: AIMessage[] = [\n { role: 'user', content: boardContext },\n ...messages.map<AIMessage>(m => ({\n role: m.role === 'assistant' ? 'assistant' : 'user',\n content: m.content\n }))\n ]\n\n // multi-turn agentic loop — LLM 이 read 호출 → 서버 실행 → 결과 회신 → LLM 추론 반복.\n // write tool 은 누적해 client 에 patch 로 전달. 본체는 ./agentic-loop 에 분리.\n //\n // executeReadTool 은 closure wrapper — board-ai 자체 read tool (READ_TOOL_NAMES) 은\n // 기존 hardcoded executeReadTool 로 dispatch, registry 에 등록된 read/external tool\n // 은 spec.builder 에 ctx (board, selectedRefids, state=options.toolCallContext) 주입.\n /* 도구 문맥 = 서버가 준 state(도메인·사용자 — 권한 정본) + 호스트가 보낸 문맥(무엇을 보고 있는지).\n * host 는 클라이언트 값이므로 권한 판정에 쓰지 않는다(도구가 소속을 검증). */\n const toolCallContext = options.hostContext\n ? { ...(options.toolCallContext ?? {}), host: options.hostContext }\n : options.toolCallContext\n const wrappedExecuteReadTool = (\n call: any,\n board: any,\n selectedRefids: number[]\n ): any => {\n // 1) board-ai 코어 read tool — 기존 hardcoded 경로. 코어를 끈 대화에서는 실행하지 않는다.\n if (gate.coreOn && READ_TOOL_NAMES.has(call.name)) {\n return executeReadTool(call, board, selectedRefids)\n }\n // 2) registry — read 와 external 둘 다 동일 dispatch path (LLM 회신 측면 동일).\n // external builder 가 server-side mutation 호출하는 케이스라 ctx.state 주입 필수.\n const spec = gate.spec(call.name)\n if (spec && (spec.kind === 'read' || spec.kind === 'external')) {\n return (spec.builder as any)(call.arguments ?? {}, {\n board,\n selectedRefids,\n state: toolCallContext\n })\n }\n // 3) 미등록 / 잘못된 분기 — 빈 응답. agentic-loop 가 LLM 에 회신 후 다음 turn.\n return undefined\n }\n\n const loopResult = await runAgenticLoop({\n initialConversation: conversation,\n tools,\n options: {\n systemPrompt,\n model: options.model,\n temperature: options.temperature,\n maxTokens: options.maxTokens,\n /* 라이브 상태를 다루는 대화면은 첫 턴에 조회를 강제한다 — 근거 없이 상태를 단언할 길을 막는다. */\n requireToolOnFirstTurn: options.requireGroundingTools\n },\n chat: (msgs, tools, opts) => this.base.chatWithTools!(msgs, tools, opts),\n dispatch: {\n /* 노출 게이트를 통과하지 못한 이름은 미등록으로 분류 → loop 가 LLM 에 회신(조용한 무동작 아님). */\n isReadTool: gate.isRead,\n isWriteTool: gate.isWrite,\n isActionTool: gate.isAction,\n executeReadTool: wrappedExecuteReadTool,\n validateWriteToolCall,\n toolCallToBoardActionOp,\n summarizeToolResult\n },\n currentBoard,\n selectedRefids\n })\n const accumulatedWriteCalls = loopResult.accumulatedWriteCalls\n const accumulatedActions = loopResult.accumulatedActions\n const toolUsages = loopResult.toolUsages\n const lastText = loopResult.lastText\n const stopReason = loopResult.stopReason\n\n // accumulated write calls → BoardEditPatch (tool 이 array 반환 가능 — flat)\n const components = (currentBoard?.components ?? []) as any[]\n const ops = accumulatedWriteCalls\n .flatMap(call => {\n const r = toolCallToBoardEditOp(call, components, gate)\n if (r === null) return []\n return Array.isArray(r) ? r : [r]\n })\n\n // abortReason 이 있으면 사용자 메시지에 한 줄 부기 — 침묵 종료 방지.\n // (정상 종료 시 abortReason undefined 로 부기 없음.)\n const baseReply = lastText || (ops.length > 0 ? '변경했습니다.' : '')\n const reply = baseReply + formatAbortNotice(loopResult.abortReason)\n\n let patch: BoardEditPatch | undefined\n if (ops.length > 0) {\n patch = {\n ops,\n summary: lastText ?? `${ops.length} edit op(s) applied`,\n confidence: 0.9\n }\n }\n\n /* 접지 검사 — 답이 **모델이 받은 것** 밖의 식별자를 지목했는지. 답은 고치지 않고 경고만 낸다.\n * 근거집합의 정의와 사정거리는 ./grounding 머리말 참조(식별자 없는 창작 서술은 잡지 못한다). */\n const warnings = checkReplyGrounding(baseReply, {\n systemPrompt,\n boardContext,\n messages: messages.map(m => (typeof m.content === 'string' ? m.content : '')),\n toolResults: loopResult.groundedTexts\n })\n\n return {\n reply,\n patch,\n followUp: undefined,\n toolUsages: toolUsages.length > 0 ? toolUsages : undefined,\n actions: accumulatedActions.length > 0 ? accumulatedActions : undefined,\n groundingWarnings: warnings.length > 0 ? warnings : undefined\n }\n }\n\n private resolveTypesAndCategories(options: ChatOptions): {\n knownTypes: string[]\n categories: ComponentCategory[]\n } {\n const explicitTypes = options.knownTypes ?? this.options.knownTypes\n const explicitCats = (options.categories ?? this.options.categories) as ComponentCategory[] | undefined\n if (explicitTypes && explicitCats) {\n return { knownTypes: explicitTypes, categories: explicitCats }\n }\n\n const scopes = options.scopes ?? this.options.scopes\n if (scopes && scopes.length > 0) {\n const rules = getImportRules(scopes)\n const types = explicitTypes ?? Array.from(new Set(rules.map(r => r.componentType))).filter(Boolean)\n const cats =\n explicitCats ??\n (Array.from(new Set(rules.map(r => r.category).filter(Boolean))) as ComponentCategory[])\n return {\n knownTypes: types,\n categories: cats.length > 0 ? cats : ALL_CATEGORIES\n }\n }\n\n return {\n knownTypes: explicitTypes ?? [],\n categories: explicitCats ?? ALL_CATEGORIES\n }\n }\n\n\n // ── Tool calling 용 system prompt ──────────────────────────────────\n\n private buildSystemPromptForTools(\n knownTypes: string[],\n categories: ComponentCategory[],\n schemas: ComponentSchema[]\n ): string {\n const typeLine = knownTypes.length > 0 ? knownTypes.join(', ') : '(none registered)'\n const catLine = categories.join(', ')\n const schemaSection = formatSchemas(schemas, knownTypes)\n\n return `You are a board modeling assistant. Edit the board by calling the provided tools.\n\n==== ⚠⚠⚠ ACTION POLICY — TEXT-ONLY 응답 절대 금지 ⚠⚠⚠ ====\n사용자의 메시지가 보드 변경을 *암시하거나 요청* 하면 (색을 바꿔, 정렬해, 추가해,\n스타일을 바꿔, \"분위기 바꿔\", \"북유럽스타일로\", \"어울리게\", \"정리해\" 등) **반드시\n적절한 write tool 을 호출** 해야 한다. tool 을 부르지 않고 \"이렇게 바꾸겠습니다\"\n또는 \"X 를 Y 로 변경했습니다\" 라고 설명만 하는 것은 **거짓말** 이다 — 실제로는\n아무것도 안 바뀌었기 때문.\n\n룰:\n 1. 변경 요청 → write tool 호출 필수 (modifyBoard / setFill / setStroke / setMaterial /\n setShadow / setOpacity / setVisible / setFont / setText / setMaterial / addComponent /\n removeComponentByRefid / modifyComponentByRefid / align/distribute/group/zorder 등)\n 2. 호출 + 짧은 reply 텍스트 동시 작성 OK — reply 는 *결과* 를 한국어로 한두 문장 요약\n 3. read tool (getSelection, findComponents, getComponentByRefid, getAtmosphereGuide 등)\n 만으로 응답 끝나는 것도 금지 — 정보 조회 후엔 *그 정보를 바탕으로 write tool 까지*\n 불러야 사용자 의도 충족\n 4. 진짜로 변경할 게 없는 단순 질문 (\"이거 뭐예요?\", \"몇 개 있어요?\") 만 텍스트로 답\n 5. tool 호출이 schema 검증 실패해서 retry 받으면 — 포기하지 말고 args 정정해 다시 호출\n 6. 사용자에게 \"X 했습니다\" 라고 쓰려면 그 *X 가 실제 tool 호출로 이뤄진 다음* 에만\n\n응답에 reply 텍스트만 있고 write tool 호출이 없다면 — 그건 사용자에게 \"변경 약속\" 만\n한 채 *아무 일도 안 한* 상태다. 사용자가 가장 싫어하는 패턴이며, 신뢰를 즉시 잃는다.\n\n==== BOARD HIERARCHY (CRITICAL) ====\nThe BOARD itself is the TOPMOST PARENT. It is NOT a component — it has its own\nroot-level properties separate from any child:\n\n • Root attributes (things-scene model-layer 가 인식하는 키만):\n - Layout: \\`width\\`, \\`height\\`, \\`fitMode\\`, \\`translate\\`, \\`scale\\`\n - 2D 배경: \\`fillStyle\\`\n - 3D 환경: \\`sky\\` / \\`skyColor\\` / \\`exposure\\` / \\`hemi*\\` / \\`dirLight*\\` / \\`dirShadow*\\` / \\`camera*\\` / \\`autoRotate\\`\n - 식별: \\`id\\`, \\`refid\\`, \\`type\\` (\"model-layer\")\n ⚠ 보드 \\*\\*name\\*\\* 은 root attribute 가 아님 — Board 엔티티의 DB 컬럼이지 scene\n MODEL 의 필드가 아님 (model-layer 가 무시). 보드 라벨 변경은 modifyBoard 영역 X.\n • Children: an array of components inside the board (rect / circle / text /\n gauge / etc.). 컴포넌트들은 \\`name\\` (user label) 를 가질 수 있음 — 이는 child\n component 의 속성이지 board root 의 속성이 아님.\n\nRules:\n - To change a board-level attribute (background, board size, 3D atmosphere)\n → call \\`modifyBoard({ patch: { fillStyle: ..., width: ..., sky: ..., exposure: ..., dirLight*: ..., hemi*: ... } })\\`.\n NOTE: 보드 라벨/제목 (\"보드 이름\") 은 scene model 이 아니라 Board *엔티티* 의 컬럼.\n things-scene 의 model-layer 는 \\`name\\` 을 인식하지 않음. modifyBoard 의 patch 에\n \\`name\\` 을 넣지 말 것 — 죽은 필드로 박힐 뿐 효과 없음.\n - To change a CHILD COMPONENT's attribute → call \\`modifyComponentByRefid\\`.\n - DO NOT use modifyBoard to change a child. DO NOT use modifyComponentByRefid\n to change board background.\n - \"보드 배경색\", \"board background\", \"테두리/캔버스 크기\" 같은 요청은 root\n attribute 변경 → \\`modifyBoard\\`.\n\n==== COMPONENT TREE (NESTING) ====\n컴포넌트는 *재귀 구조*. group / container 같은 부모 컴포넌트는 자기 \\`components\\`\n배열에 자식을 가질 수 있다. 자식이 또 group 일 수 있어 임의 깊이로 중첩 가능.\n\n가시성:\n - \\`summarizeBoard\\` (대화 시작 시 보여지는 보드 상태) 는 *평면 list* 로 모든\n 컴포넌트를 노출한다 — top-level 뿐 아니라 group/container 안 자식도 모두 포함.\n - 자식은 \\`_parentRefid\\` (부모 group refid) 와 \\`_depth\\` (중첩 깊이, 0=root) 메타\n 가 첨부되어 어느 group 안에 있는지 식별 가능.\n - \\`findComponents\\` 는 전체 트리를 search — group 안 자식까지 매칭. 특정 group\n 안만 좁히려면 \\`parentRefid\\` 필터 사용.\n - \\`getComponentByRefid\\` / \\`getComponentStyle\\` / \\`setFill\\` 등 모든 styling tool 의\n refid 매개변수는 *어느 깊이의* 컴포넌트든 받음. modify / remove op 도 deep search.\n\n테마 / 스타일 적용 시 룰:\n - \"북유럽스타일\", \"사이버펑크\" 등 테마 요청 → 보드의 *모든* 컴포넌트에 적용 — group\n 안 자식도 포함. 평면 list 그대로 색상 통일.\n - 사용자가 \"이 group 만\" / \"왼쪽 영역만\" 처럼 *범위 명시* 한 경우만 \\`findComponents\\`\n 의 \\`parentRefid\\` / \\`region\\` 으로 좁혀 그 자식들만 styling.\n - group 자체에 fillStyle 적용해도 자식에게 자동 전파 안 됨 — 자식 각각의 refid 로\n setFill 호출 필요.\n\n==== IDENTIFIER POLICY (CRITICAL) ====\nEach CHILD component has THREE identifier-like fields. Their roles differ:\n\n • \\`refid\\` (number) — INTERNAL SYSTEM HANDLE (things-scene auto-assigned).\n Always present, unique within a board. Use as tool\n argument ONLY. NEVER mention \"refid\" in user-facing\n reply text — users don't see it and it's confusing.\n\n • \\`id\\` (string) — DATA BINDING NAME. Optional. Multiple components MAY share\n the same id. Human-readable. OK to mention in replies\n (\"'motor-1' 컴포넌트\", \"id가 'motor-1' 인 것\").\n\n • \\`name\\` (string) — USER LABEL. Optional. Human-readable. Most user-friendly\n way to refer to a component in replies.\n\nRules:\n - In tool calls (modifyComponentByRefid, etc.) → pass refid as the argument.\n - In your TEXT REPLY to the user → refer to components by name (preferred)\n or id, NEVER by refid. Saying \"refid 35 를 변경했습니다\" is forbidden;\n say \"'경광등1' 을 변경했습니다\" or \"id 'motor-1' 컴포넌트를 변경했습니다\".\n - findComponents may return many matches by id (data binding group); that is correct.\n - User selection arrives as refids — that's an internal handle, treat it as opaque.\n - The BOARD itself does NOT have refid (only children do).\n\n==== USER MENTIONS (#token) ====\nThe user can write \\`#token\\` to reference a component (a SELECTOR, not a key).\nThe server pre-resolves these by matching name OR id OR type, and APPENDS a\n\"mention map\" block at the end of the user's message. Format:\n\n --- mention map (자동 첨부 — 사용자가 # 로 지칭한 컴포넌트) ---\n #경광등1 →\n { name='경광등1', id='motor-1', type='rect', refid=35 }\n #rect →\n { name='경광등1', id='motor-1', type='rect', refid=35 }\n { name='펌프', id='pump-1', type='rect', refid=42 }\n\nUse this map to resolve which refid(s) to pass to tool calls. The user's\nORIGINAL #token (e.g., \"#경광등1\") is preserved in the message body — refer\nto that wording in your reply. Do not echo refid back to the user.\n\n==== AVAILABLE TOOLS ====\nBoard-level (root attributes):\n - modifyBoard: 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 엔티티 컬럼.\n - replaceBoard: wholesale board reset (heavy — prefer modifyBoard for most changes)\nChild components — data:\n - addComponent: add a new component (parallel calls for multiple adds)\n - removeComponentByRefid: remove a child by refid\n - modifyComponentByRefid: edit a child's properties by refid (raw fallback — prefer specific styling tools below for any styling change)\n - getComponentByRefid: inspect full data of one child by refid\n - getSelection: return full data of components currently selected by the user\n - findComponents: search children by type/id/name/region — returns matches with refid\n\nComponent styling — PREFER these over modifyComponentByRefid:\n\n ⚠⚠⚠ ABSOLUTE RULE — 테마 요청 처리 ⚠⚠⚠\n 사용자 요청에 \"테마 / 스타일 / 분위기\" 류 단어가 포함된 경우 (\"북유럽스타일\",\n \"사이버펑크\", \"미니멀하게\", \"따뜻하게\", \"빈티지\", \"고급스럽게\", \"어울리게\" 등):\n ✅ 변경 OK — fillStyle / strokeStyle.color / shadow.color / fontColor /\n opacity / 3D material / sky / 광원 (= 색·재질·빛만)\n ❌ 변경 절대 금지 — text 내용 / fontSize / fontFamily / lineWidth / lineDash /\n lineCap / lineJoin / left / top / width / height / cx / cy / rx / ry /\n points / path / data / mappings / accessor / id / name (= 콘텐츠·디멘션·정보)\n 이 룰은 setText / setFont(size,family) / setStroke(width,dash) /\n modifyComponentByRefid 모두에 적용. 사용자가 \"텍스트도 바꿔\", \"두께도\",\n \"폰트 굵게\" 같이 *명시적으로 요청한 경우에만* 해당 도구 사용.\n 의심스러우면 색·재질·빛만 적용. 자세한 매트릭스는 THEMATIC STYLING SCOPE 섹션 참조.\n\n 도구 목록:\n - setFill: 컴포넌트 배경. mode (solid / gradient / pattern / image / none) + color / opacity / colorStops. mode 명시 시 fillStyle 통째 교체, 미지정 시 부분 update.\n - setStroke: 테두리. color / width / dash ('solid'|'dashed'|'dotted'|'dashdot' or number[]) / lineCap / lineJoin / opacity. enabled=false 로 제거.\n - setText: 텍스트 *내용* 변경 (state.text). 폰트는 setFont 별개. **테마 요청 시 호출 금지.**\n - setFont: 폰트 스타일. fontFamily / fontSize / fontWeight / fontStyle / fontColor / textAlign / textBaseline / lineHeight. **테마 요청 시 fontColor 만 OK.**\n - setShadow: 그림자. color / blur / offsetX / offsetY. enabled=false 로 제거.\n - setOpacity: 컴포넌트 전체 alpha (0..1).\n - setVisible: 표시/숨김 토글.\n - setMaterial: 3D PBR 재질. preset (default/metal/glass/plastic/wood/ceramic/rubber/custom) + metalness / roughness / emissive / emissiveIntensity / opacity / envMapIntensity / side. preset 만 = reset, preset + 속성 = override.\n - setShadowProperties: 3D castShadow / receiveShadow.\n - clearStyle: 특정 styling aspect 들 reset (preset / 데이터 바인딩 적용 전).\n\n Tool 선택 룰:\n 1. **테마 요청 → 위 ABSOLUTE RULE 먼저 확인. 텍스트·폰트크기·두께·치수·데이터 손대지 말 것.**\n 2. Fill 변경 → setFill (modifyComponentByRefid 사용 금지)\n 3. Stroke 변경 → setStroke\n 4. Text 내용 vs 스타일 명확히 구분 — setText / setFont 분리\n 5. 3D 재질 → setMaterial (preset 위주)\n 6. 여러 컴포넌트 동일 변경 → 한 tool 호출의 refids 배열로 (반복 호출 X)\n 7. 색상은 hex / rgb / CSS named ('red') / semantic ('warm-red', 'success', 'warning') 모두 가능\n 8. 위 tool 로 표현 안 되는 raw 속성 변경에만 modifyComponentByRefid 사용\nChild components — scene operations (Phase 2):\n - alignComponents: align multiple by edge/center (left/right/center/top/middle/bottom)\n - distributeComponents: even spacing along horizontal / vertical axis\n - groupComponents: combine multiple into a Group container (parent-child)\n - ungroupComponent: disband a Group (children move up to grandparent)\n - changeZorder: front / back / forward / backward for a single component\nModeller actions (ephemeral — does NOT modify the board model, no undo, no save):\n - selectComponents: change the user's current selection (pass [] to deselect all)\n - centerToComponent: move modeller view to center on a component\n - fitToView: reset view so the board fits the canvas (mode: fit/ratio/width/height)\n - setSceneMode: switch modeller between 'edit' and 'view' modes\nKnowledge:\n - getAtmosphereGuide: 3D atmosphere synthesis primer — parameter physics, ranges, color theory, archetype recipes (time-of-day / indoor / surreal). Call BEFORE applying atmospheric/styling modifyBoard for any natural-language mood request.\n\n==== 3D ATMOSPHERE SYNTHESIS ====\n3D 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 modifyBoard call.\n\nFor ANY natural-language atmospheric request — \"공장 분위기로\", \"심해 컬러\", \"황혼\", \"사이버펑크\", \"안개 자욱한 새벽\", \"1980 우주정거장\", \"따뜻하게\", \"차갑고 극적으로\" — follow this workflow:\n\n 1. Call getAtmosphereGuide first.\n 2. From the guide's \"archetypes\" section, pick the closest base recipe (time-of-day / indoor / surreal). Interpolate if user combines multiple cues.\n 3. Apply user's nuance via the guide's \"modifiers\" (warm/cool, drama, saturation, contrast).\n 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.\n 5. Apply ALL keys in ONE modifyBoard({patch}) call (sky, skyColor?, exposure, hemiIntensity, hemiSkyColor, hemiGroundColor, dirLightEnabled, dirLightColor, dirLightIntensity, dirLightFollowCamera=false, dirLightAzimuth, dirLightElevation, fillStyle?). ONE patch — not multiple modifyBoard calls.\n 6. In the reply, briefly state which archetype + modifier you composed.\n\nAvoid:\n - Calling modifyBoard with only \"fillStyle\" for atmospheric requests — that only changes 2D background and floor tint, NOT the 3D scene mood.\n - Mixing a sky preset with explicit skyColor (preset wins, skyColor ignored).\n - Setting dirLightAzimuth/Elevation while leaving dirLightFollowCamera=true (no effect — set follow=false first).\n - Using only canned presets when the user describes a custom mood — the guide enables synthesis beyond presets.\n\n==== THEMATIC STYLING — SCOPE DISCIPLINE ====\n\"테마\" 성격의 자연어 요청 (\"북유럽스타일로\", \"사이버펑크\", \"미니멀하게\", \"따뜻하게\",\n\"빈티지\", \"미래지향적으로\", \"고급스럽게\" 등) 은 **시각적 분위기**에만 적용한다.\n컴포넌트의 **치수·구조·레이아웃·정보 위계**는 건드리지 않는다.\n\n테마 요청 시 변경 OK — *visual aesthetics only*:\n - 색상 — fillStyle (solid/gradient/pattern), strokeStyle.color, shadow.color, fontColor\n - 투명/표시 — opacity, alpha\n - 3D — material preset/속성 (metalness/roughness/emissive), 보드 root 의 sky/exposure/광원\n - 보드 배경 fillStyle\n\n테마 요청 시 변경 금지 — *dimensions / structure / layout / information*:\n - 선 형태 — lineWidth / lineDash / lineCap / lineJoin (테두리 색상은 OK, 두께·점선\n 패턴은 디자인 의도를 가진 *구조*. 사용자가 \"두께도 바꿔\" 라고 명시 안 하면 손대지 말 것)\n - 모든 geometry — left/top/width/height/cx/cy/rx/ry/points/path/vertices\n - 폰트 크기·패밀리 — fontSize / fontFamily (정보 위계 영향. fontColor 만 OK)\n - **텍스트 / 데이터 / 정보** — state.text, gauge value/min/max, chart data, 라벨 문구,\n 데이터 바인딩 (mappings / accessor / dataSource / refresh), id / name / class / tag.\n 이것들은 *콘텐츠* 이지 *스타일* 이 아니다.\n - 정렬·z-order·group — alignComponents/distributeComponents/changeZorder/groupComponents\n\n이유: \"북유럽스타일\" 은 색·재질·빛의 일관성을 뜻하지, 선을 굵게 하거나 텍스트를\n바꾸는 게 아니다. 테마는 *형식 (form)* 의 영역이고 콘텐츠와 디멘션은 별개의 영역.\n사용자가 명시적으로 요청한 게 아니면 콘텐츠/디멘션에 손대지 말 것. 의심스러우면\n묻거나 색·재질 위주로만 적용.\n\n==== AVAILABLE COMPONENT TYPES (enum-enforced by tool schema) ====\n${typeLine}\n\n==== AVAILABLE GROUPS / CATEGORIES ====\n${catLine}\n\n==== COMPONENT SCHEMAS (type-specific geometry + properties) ====\n${schemaSection}\n\nCRITICAL — geometry discipline:\n- Each type has its OWN geometry keys, listed under \"geometry:\" above.\n- Use EXACTLY those keys for that type. Do NOT default to {left, top, width, height} for every type.\n Examples:\n rect/image/text: left, top, width, height\n circle/ellipse: cx, cy, rx (or radius), ry\n line/polyline: points or path or vertices array\n gauge-* may use left, top, width, height OR cx, cy depending on the variant.\n- Include ALL the geometry keys for the type with sensible numeric values (no undefined).\n- Include type-specific REQUIRED properties (gauge needs value/min/max, chart needs data, text needs text).\n\nCRITICAL — type discipline:\n- The \"type\" parameter is enum-restricted by the tool schema. Use ONLY values from the registered list.\n- If a domain concept (e.g., \"AGV\", \"Stocker\") is NOT in the list, pick the closest registered type or use a generic shape ('rect', 'ellipse', 'text') with descriptive fillStyle and a \"name\" field.\n\nBehavioral rules:\n- If the user is asking a question rather than commanding, REPLY in TEXT WITHOUT calling any tool.\n- If the user's request is ambiguous, REPLY in TEXT (asking for clarification) WITHOUT calling any tool.\n- For multiple components, call addComponent multiple times in parallel.\n- The current board JSON is provided as the first user message in the conversation.\n\nReply formatting rules (chat surface):\n- Reply ONCE with ONE form only. NEVER restate the same answer in a second form (e.g. do NOT add a prose summary after a bullet list, or vice versa).\n- Keep replies concise — chat-style, not document-style. Prefer 1–4 sentences or a short bullet list.\n- Use markdown for emphasis (**bold**, *italic*) and short lists. Avoid headings (#) and long structured documents.\n- Use the same language as the user's last message.`\n }\n}\n\n// ── Tool 정의 ──────────────────────────────────────────────────────\n\n/**\n * 4 op 직교 set 을 4 개의 도구로 정의.\n *\n * 핵심: addComponent 의 `type` 파라미터가 knownTypes 의 enum 으로 강제 →\n * LLM 이 등록 안 된 type 을 만들 수 없음 (provider 단계에서 차단).\n *\n * 좌표/크기 키들은 모두 optional 로 허용 (type 별로 사용 키 다름).\n * type-specific 추가 속성은 additionalProperties 로 허용.\n */\nexport function buildBoardEditTools(knownTypes: string[], exposure: ToolExposure = {}): AITool[] {\n const gate = buildToolGate(exposure)\n const typeProp: Record<string, any> = {\n type: 'string',\n description: 'Registered component type (must be from the enum).'\n }\n if (knownTypes.length > 0) {\n typeProp.enum = knownTypes\n }\n\n const componentSchema: Record<string, any> = {\n type: 'object',\n description: 'Component fields (geometry + style + type-specific properties).',\n properties: {\n type: typeProp,\n id: { type: 'string', description: 'Unique id within the board.' },\n // 좌상단 기반 박스 좌표\n left: { type: 'number' },\n top: { type: 'number' },\n width: { type: 'number' },\n height: { type: 'number' },\n rotation: { type: 'number' },\n // 중심 기반 좌표 (circle/ellipse 등)\n cx: { type: 'number' },\n cy: { type: 'number' },\n radius: { type: 'number' },\n rx: { type: 'number' },\n ry: { type: 'number' },\n // 경로 (line/polyline 등)\n points: { type: 'array', items: { type: 'object' } },\n // 일반 스타일\n fillStyle: { type: 'string', description: 'CSS color or pattern.' },\n strokeStyle: { type: 'string' },\n strokeWidth: { type: 'number' },\n strokeDashArray: { type: 'string' },\n opacity: { type: 'number' },\n name: { type: 'string', description: 'Optional human label.' }\n },\n required: ['type'],\n additionalProperties: true\n }\n\n const tools: AITool[] = [\n {\n name: 'addComponent',\n description:\n 'Add a new component to the board. Call this multiple times in parallel for multiple adds. Use the type-specific geometry keys (left/top vs cx/cy etc.) and include any required type-specific properties.',\n parameters: componentSchema\n },\n {\n name: 'removeComponentByRefid',\n description:\n 'Remove an existing component by its `refid` — the universal numeric handle that things-scene auto-assigns to every component (visible in board summary as the `refid` field of each component).',\n parameters: {\n type: 'object',\n properties: {\n refid: {\n type: 'number',\n description: 'things-scene auto-assigned numeric handle. Always present.'\n }\n },\n required: ['refid']\n }\n },\n {\n name: 'modifyComponentByRefid',\n description:\n 'Modify properties of an existing component by its `refid`. The patch is deep-merged with the existing component (style/position/size/3D material all in one). ⚠ 테마 요청 (북유럽/사이버펑크/미니멀 등) 시 patch 에 text / fontSize / fontFamily / lineWidth / lineDash / left / top / width / height / cx / cy / rx / ry / points / data / mappings / id / name 등 *콘텐츠·디멘션* 키 포함 금지 — fillStyle / strokeStyle.color / fontColor / shadow.color / opacity / 3D material 만 OK. setFill / setStroke / setMaterial / setShadow 등 전용 tool 사용을 우선 검토.',\n parameters: {\n type: 'object',\n properties: {\n refid: {\n type: 'number',\n description: 'things-scene auto-assigned numeric handle.'\n },\n patch: {\n type: 'object',\n description: 'Partial fields to merge.',\n additionalProperties: true\n }\n },\n required: ['refid', 'patch']\n }\n },\n // styling registry 에서 자동 도출 — setFill 부터 점진 이전 중.\n // 다음 tool 들은 registry 로 옮겨질 때마다 본 spread 가 자동 흡수.\n /* 스타일링도 보드 편집 능력 — 코어를 끈 대화(운영 도크)에는 노출하지 않는다. */\n ...(gate.coreOn ? buildStylingToolDefinitions() : []),\n // tool-registry plugin point — 외부 도메인 패키지 (board-import 등) 가\n // registerToolCategory() 로 등록한 모든 tool 의 LLM 정의를 spread.\n // styling 처럼 board-ai 코어 안에 정의되지 않고 외부에서 들어오는 카테고리들.\n ...buildExternalCategoryDefinitions(gate.filter),\n {\n name: 'getComponentStyle',\n description:\n \"Get the current STYLING state of a component (read-only). Useful before modifying styles to understand what's already applied (avoid blind overwrites). Returns fill / stroke / shadow / material3d / font / opacity / visibility / text. Use `aspects` to limit response size.\",\n parameters: {\n type: 'object',\n properties: {\n refid: { type: 'number' },\n aspects: {\n type: 'array',\n items: {\n type: 'string',\n enum: ['fill', 'stroke', 'shadow', 'material', 'font', 'opacity', 'visibility', 'text']\n },\n description: 'Limit response to specific aspects. Omit for all.'\n }\n },\n required: ['refid']\n }\n },\n {\n name: 'modifyBoard',\n description:\n \"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.\",\n parameters: {\n type: 'object',\n properties: {\n patch: {\n type: 'object',\n description:\n 'Root-level fields to merge into the board. Examples: { fillStyle: \"#0a1929\" } for dark navy background; { width: 1920, height: 1080 } for resize; { sky: \"studio\", exposure: 1.2 } for 3D atmosphere. Do NOT include `name` — that is the Board entity column, not a scene model field.',\n additionalProperties: true\n }\n },\n required: ['patch']\n }\n },\n {\n name: 'replaceBoard',\n description:\n '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 modifyBoard. Provide width/height and the full components array.',\n parameters: {\n type: 'object',\n properties: {\n width: { type: 'number' },\n height: { type: 'number' },\n fillStyle: { type: 'string' },\n components: {\n type: 'array',\n items: { type: 'object', additionalProperties: true }\n }\n },\n required: ['components']\n }\n },\n // ── Read tools (서버측 즉시 실행, 결과를 LLM 에 회신) ─────────\n {\n name: 'getSelection',\n description:\n 'Get full details of components currently selected by the user in the modeller. Call this when the user asks \"what is selected?\" / \"선택된 게 뭐냐?\" / refers to \"the selected component\" without specifying ids. Returns array of full component objects (no truncation).',\n parameters: { type: 'object', properties: {} }\n },\n {\n name: 'getComponentByRefid',\n description:\n 'Get full details of a single component by its `refid` (the things-scene-assigned universal numeric handle). Use this to inspect properties not visible in the board summary.',\n parameters: {\n type: 'object',\n properties: {\n refid: {\n type: 'number',\n description: 'things-scene auto-assigned numeric handle. Universal.'\n }\n },\n required: ['refid']\n }\n },\n {\n name: 'findComponents',\n description:\n 'Search components by criteria. Searches the entire board tree including children of group/container components. Returned components include `_parentRefid` and `_depth` meta when nested (depth > 0). All filters are optional and AND-combined. Returns matching components (capped at 50).',\n parameters: {\n type: 'object',\n properties: {\n type: { type: 'string', description: 'Match by exact type.' },\n id: {\n type: 'string',\n description:\n 'Match by exact data-binding id. Note: id is NOT unique — multiple components may share an id. Returns all matches.'\n },\n namePattern: {\n type: 'string',\n description: 'Case-insensitive substring match on the `name` field.'\n },\n parentRefid: {\n type: 'number',\n description:\n \"Limit search to children of this group/container refid only (one level — direct children). Use to scope a theme to a specific group's contents.\"\n },\n region: {\n type: 'object',\n description:\n 'Bounding box. Components whose left/top fall within are returned. Provide all 4 fields when used.',\n properties: {\n left: { type: 'number' },\n top: { type: 'number' },\n width: { type: 'number' },\n height: { type: 'number' }\n }\n }\n }\n }\n },\n {\n name: 'getAtmosphereGuide',\n description:\n \"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 modifyBoard 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.\",\n parameters: { type: 'object', properties: {} }\n },\n {\n name: 'getColorPalettes',\n description:\n \"Get the curated color palette catalog — 7 verified palettes (industrial-steel / financial-trader / control-room-dark / medical-clean / logistics-warm / neon-cyberpunk / paper-light), each with base/surface/border/text/muted/accent/success/warning/danger/info color tokens. Call this BEFORE applying colors to a dashboard whenever the user describes a domain or mood ('산업 분위기', '금융 대시보드', '관제실 느낌', '의료 차트', 'SF 사이버펑크'). Use the palette tokens consistently — do not invent free-form colors.\",\n parameters: { type: 'object', properties: {} }\n },\n {\n name: 'getLayoutTemplates',\n description:\n \"Get the curated dashboard layout templates — verified composition recipes (kpi-row / 3x3-grid / t-shape-command / side-rail / split-half / header-content-footer) with slot regions for component placement. Call this BEFORE arranging components on an empty/sparse board whenever the user describes a structural intent ('KPI 4개 상단에', '관제실 구도', '비교 화면', '3x3 그리드'). Use slot region coordinates directly with addPrefab/addComponent — no pixel guesswork.\",\n parameters: { type: 'object', properties: {} }\n },\n // ── Phase 2: Scene 조작 (model 차원 좌표/구조 변경) ─────────────\n {\n name: 'alignComponents',\n description:\n \"Align multiple components by their refids. Use for natural-language requests like '왼쪽 정렬', '가운데 정렬', '위쪽으로 맞춰', 'align left'. Operates on the things-scene level — the resulting coordinate adjustments are committed as a single undo step.\",\n parameters: {\n type: 'object',\n properties: {\n refids: {\n type: 'array',\n items: { type: 'number' },\n description:\n 'Component refids to align (2 or more). For \"selected\" intent, pass the user-selected refids.'\n },\n direction: {\n type: 'string',\n enum: ['left', 'right', 'center', 'top', 'middle', 'bottom'],\n description:\n 'Alignment edge/center: left/right/center for horizontal, top/middle/bottom for vertical.'\n }\n },\n required: ['refids', 'direction']\n }\n },\n {\n name: 'distributeComponents',\n description:\n \"Distribute multiple components evenly along an axis. Use for '간격 일정하게', 'evenly distribute'. Requires 3 or more components.\",\n parameters: {\n type: 'object',\n properties: {\n refids: {\n type: 'array',\n items: { type: 'number' },\n description: 'Component refids to distribute (3 or more recommended).'\n },\n axis: {\n type: 'string',\n enum: ['horizontal', 'vertical'],\n description: 'horizontal = even spacing along x; vertical = along y.'\n }\n },\n required: ['refids', 'axis']\n }\n },\n {\n name: 'groupComponents',\n description:\n \"Group multiple components into a single Group container. Use for '그룹화', '하나로 묶어'. The new Group becomes a parent; child components keep their relative positions.\",\n parameters: {\n type: 'object',\n properties: {\n refids: {\n type: 'array',\n items: { type: 'number' },\n description: 'Component refids to group (2 or more).'\n }\n },\n required: ['refids']\n }\n },\n {\n name: 'ungroupComponent',\n description:\n \"Disband a Group component — children are moved up to the Group's parent. Use for '그룹 해제', 'ungroup'.\",\n parameters: {\n type: 'object',\n properties: {\n refid: {\n type: 'number',\n description: 'refid of the Group component to ungroup.'\n }\n },\n required: ['refid']\n }\n },\n {\n name: 'changeZorder',\n description:\n \"Change a single component's z-order (front/back/forward/backward). Use for '맨 앞으로', '맨 뒤로', '한 단계 앞으로'.\",\n parameters: {\n type: 'object',\n properties: {\n refid: { type: 'number', description: 'Target component refid.' },\n direction: {\n type: 'string',\n enum: ['front', 'back', 'forward', 'backward'],\n description:\n 'front = bring to front, back = send to back, forward = step toward front, backward = step toward back.'\n }\n },\n required: ['refid', 'direction']\n }\n },\n // ── Sugar layout — high-level 배치 의도 (refids 의 left/top 만 변경) ─\n {\n name: 'arrangeInGrid',\n description:\n \"Arrange components into a grid layout. Use for '3x2 그리드로', '4열로 배치', 'arrange in grid'. Computes positions on the host based on each component's current width/height. Only left/top change — sizes preserved. Single undo step. The cell size = max(width)/max(height) across the refids; gap defaults to 10. anchor (top-left of the grid) defaults to the first component's current (left, top). Order in `refids` determines fill order (row-major).\",\n parameters: {\n type: 'object',\n properties: {\n refids: {\n type: 'array',\n items: { type: 'number' },\n description: 'Component refids in fill order (row-major).'\n },\n cols: {\n type: 'number',\n description: 'Number of columns. Rows are inferred from refids.length / cols.'\n },\n gap: {\n type: 'number',\n description: 'Spacing between cells in pixels (default 10).'\n },\n anchor: {\n type: 'object',\n description: 'Top-left of the grid. Default: first component current (left, top).',\n properties: {\n left: { type: 'number' },\n top: { type: 'number' }\n }\n }\n },\n required: ['refids', 'cols']\n }\n },\n {\n name: 'arrangeInRow',\n description:\n \"Arrange components into a single horizontal row, left-to-right in `refids` order. Use for '한 줄로', 'arrange in row'. Each next component is placed at (prev.left + prev.width + gap). align controls cross-axis (top): start = same top as anchor (default), center = vertically centered to tallest, end = bottom-aligned to tallest.\",\n parameters: {\n type: 'object',\n properties: {\n refids: {\n type: 'array',\n items: { type: 'number' },\n description: 'Component refids in left-to-right order.'\n },\n gap: { type: 'number', description: 'Horizontal spacing in pixels (default 10).' },\n anchor: {\n type: 'object',\n description: 'Start position. Default: first component current (left, top).',\n properties: {\n left: { type: 'number' },\n top: { type: 'number' }\n }\n },\n align: {\n type: 'string',\n enum: ['start', 'center', 'end'],\n description:\n 'Cross-axis (vertical) alignment within row. start = top-aligned (default), center = mid, end = bottom.'\n }\n },\n required: ['refids']\n }\n },\n {\n name: 'arrangeInColumn',\n description:\n \"Arrange components into a single vertical column, top-to-bottom in `refids` order. Use for '세로로 일렬', '위에서 아래로', 'arrange in column'. align controls cross-axis (left): start = same left as anchor (default), center = horizontally centered to widest, end = right-aligned to widest.\",\n parameters: {\n type: 'object',\n properties: {\n refids: {\n type: 'array',\n items: { type: 'number' },\n description: 'Component refids in top-to-bottom order.'\n },\n gap: { type: 'number', description: 'Vertical spacing in pixels (default 10).' },\n anchor: {\n type: 'object',\n description: 'Start position. Default: first component current (left, top).',\n properties: {\n left: { type: 'number' },\n top: { type: 'number' }\n }\n },\n align: {\n type: 'string',\n enum: ['start', 'center', 'end'],\n description:\n 'Cross-axis (horizontal) alignment within column. start = left-aligned (default), center = mid, end = right.'\n }\n },\n required: ['refids']\n }\n },\n // ── C-1: Scene 조작 (ephemeral — selection / view / mode) ───────\n {\n name: 'selectComponents',\n description:\n \"Change the user's selection in the modeller. Use for '이거 선택해' / '선택 풀어' / '이 컴포넌트들 선택' style requests. Pass empty array [] to deselect everything. This does NOT modify the board model — it only changes the modeller's current selection.\",\n parameters: {\n type: 'object',\n properties: {\n refids: {\n type: 'array',\n items: { type: 'number' },\n description: 'Refids to select. Empty array deselects all.'\n }\n },\n required: ['refids']\n }\n },\n {\n name: 'centerToComponent',\n description:\n \"Move the modeller's view to center on a specific component. Use for '이 컴포넌트로 이동' / '저거 화면 가운데로' / '여기 보여줘'. Ephemeral — does not modify model.\",\n parameters: {\n type: 'object',\n properties: {\n refid: { type: 'number', description: 'Target component refid to center.' },\n animated: {\n type: 'boolean',\n description: 'Animate the camera move (default true).'\n }\n },\n required: ['refid']\n }\n },\n {\n name: 'fitToView',\n description:\n \"Reset the modeller's view so the board fits the canvas. Use for '전체 보기' / '맞춰서 보여줘' / 'fit to screen'. Ephemeral.\",\n parameters: {\n type: 'object',\n properties: {\n mode: {\n type: 'string',\n enum: ['fit', 'ratio', 'width', 'height'],\n description:\n \"fit = best-fit (default), ratio = preserve aspect, width = fit width, height = fit height.\"\n }\n }\n }\n },\n {\n name: 'setSceneMode',\n description:\n \"Switch the modeller between edit and view modes. Use for '편집 모드' / '뷰어 모드' / '읽기전용으로 전환'. Ephemeral.\",\n parameters: {\n type: 'object',\n properties: {\n mode: {\n type: 'string',\n enum: ['edit', 'view'],\n description: 'edit = full editing, view = read-only viewer.'\n }\n },\n required: ['mode']\n }\n },\n // ── Prefab — 검증된 복합 컴포넌트 카탈로그 ────────────────────\n {\n name: 'getAvailablePrefabs',\n description:\n \"List curated high-quality prefab modules — composed multi-component widgets like 'monitor-card', 'gauge-panel', 'stat-tile'. Call this BEFORE adding individual primitives whenever the user asks for a domain-meaningful unit ('온도 모니터링 카드', 'AGV 상태판', 'KPI 타일', 'sensor card', 'dashboard tile'). Each prefab has name/description/keywords/defaultSize. Then use addPrefab(name, ...) to instantiate.\",\n parameters: {\n type: 'object',\n properties: {\n category: {\n type: 'string',\n description: 'Optional category filter (e.g. \"monitoring\", \"kpi\", \"control\").'\n },\n keywordPattern: {\n type: 'string',\n description:\n 'Optional case-insensitive substring match against name/description/keywords.'\n }\n }\n }\n },\n {\n name: 'addPrefab',\n description:\n \"Instantiate a registered prefab at a position. Prefer this over addComponent when the user describes a domain-meaningful unit ('모니터링 카드 하나 추가', 'KPI 타일'). The prefab is added as a single group component (one undo step). Supports per-prefab options (title/value/fillStyle etc.) — see the prefab description from getAvailablePrefabs.\",\n parameters: {\n type: 'object',\n properties: {\n name: {\n type: 'string',\n description: 'Prefab name from getAvailablePrefabs (e.g. \"monitor-card\").'\n },\n left: { type: 'number', description: 'X anchor (top-left origin).' },\n top: { type: 'number', description: 'Y anchor.' },\n width: {\n type: 'number',\n description: 'Optional override of prefab defaultSize.width.'\n },\n height: {\n type: 'number',\n description: 'Optional override of prefab defaultSize.height.'\n },\n options: {\n type: 'object',\n description:\n 'Prefab-specific customization (title, value, fillStyle, accent, etc.). See each prefab description for accepted keys.',\n additionalProperties: true\n }\n },\n required: ['name', 'left', 'top']\n }\n }\n ]\n\n /* 코어(보드 편집) 도구를 끈 대화는 **외부 카테고리 도구만** 남긴다.\n * 배열 리터럴 안 어디에 있든 이름 기준으로 걸러 누락이 없게 한다. */\n if (!gate.coreOn) {\n const externalNames = new Set(getToolSpecsFor(gate.filter).map(spec => spec.name))\n return tools.filter(tool => externalNames.has(tool.name))\n }\n return tools\n}\n\n// ── Read tool 분류 + 실행기 ────────────────────────────────────────\n\nconst READ_TOOL_NAMES = new Set([\n 'getSelection',\n 'getComponentByRefid',\n 'getComponentStyle',\n 'findComponents',\n 'getAtmosphereGuide',\n 'getAvailablePrefabs',\n 'getColorPalettes',\n 'getLayoutTemplates'\n])\nconst WRITE_TOOL_NAMES = new Set([\n 'addComponent',\n 'removeComponentByRefid',\n 'modifyComponentByRefid',\n // Styling Tier 1 — 컴포넌트 보편 스타일링\n 'setFill',\n 'setStroke',\n 'setText',\n 'setFont',\n 'setShadow',\n 'setOpacity',\n 'setVisible',\n 'setMaterial',\n 'setShadowProperties',\n 'clearStyle',\n 'copyStyle',\n 'modifyBoard',\n 'replaceBoard',\n // Phase 2 — model 차원 scene 조작 (좌표/구조/zorder)\n 'alignComponents',\n 'distributeComponents',\n 'groupComponents',\n 'ungroupComponent',\n 'changeZorder',\n // Prefab — 검증된 복합 컴포넌트 한 번에 추가\n 'addPrefab',\n // Sugar layout — high-level 의도 표현 (grid/row/column)\n 'arrangeInGrid',\n 'arrangeInRow',\n 'arrangeInColumn'\n])\n/**\n * C-1 — ephemeral scene 조작 (selection / view / mode). model 변경 X, undo 영향 X.\n * 별도 ChatResponse.actions 채널로 전달 → 호스트가 board-action-execute 로 적용.\n */\nconst ACTION_TOOL_NAMES = new Set([\n 'selectComponents',\n 'centerToComponent',\n 'fitToView',\n 'setSceneMode'\n])\n\nconst FIND_COMPONENTS_CAP = 50\n\n/**\n * Read tool 의 서버측 실행기 — currentBoard / selectedRefids 에 대해 즉시 실행해 결과 반환.\n * LLM 의 다음 turn 에 tool_result 로 회신된다.\n *\n * 식별자 정책:\n * - 컴포넌트 targeting 은 항상 refid (universal numeric handle).\n * - id 는 데이터 바인딩 이름이며 unique 가 아니다 — filter 용도로만 사용 (findComponents).\n */\nexport function executeReadTool(\n call: AIToolCall,\n currentBoard: BoardModel | null | undefined,\n selectedRefids: number[]\n): any {\n const board = currentBoard\n // 평면 view — group / container 자식 포함. AI 가 hierarchy 무관하게 모든\n // 컴포넌트 인지 가능. (top-level 만 보던 옛 동작 → 자식 누락 사고 방지)\n const flatComponents = collectAllComponents(board).map(f => f.component)\n\n switch (call.name) {\n case 'getSelection': {\n if (selectedRefids.length === 0) {\n return { selected: [], message: 'No component is currently selected.' }\n }\n const matched = flatComponents.filter(\n c => c && typeof (c as any).refid === 'number' && selectedRefids.includes((c as any).refid)\n )\n return { selected: matched, count: matched.length, selectedRefids }\n }\n case 'getComponentByRefid': {\n const refid = call.arguments?.refid\n if (typeof refid !== 'number') return { error: 'refid (number) is required' }\n const f = findComponentByRefid(board, refid)\n if (!f) return { error: `Component with refid ${refid} not found.` }\n return { component: f.component }\n }\n case 'getComponentStyle': {\n const refid = call.arguments?.refid\n const aspects = call.arguments?.aspects\n if (typeof refid !== 'number') return { error: 'refid (number) is required' }\n const f = findComponentByRefid(board, refid)\n if (!f) return { error: `Component with refid ${refid} not found.` }\n return { style: buildComponentStyleSummary(f.component, aspects) }\n }\n case 'findComponents': {\n const args = call.arguments ?? {}\n const type = typeof args.type === 'string' ? args.type : undefined\n const namePattern =\n typeof args.namePattern === 'string' && args.namePattern.length > 0\n ? args.namePattern.toLowerCase()\n : undefined\n const idFilter = typeof args.id === 'string' && args.id.length > 0 ? args.id : undefined\n const parentRefidFilter =\n typeof args.parentRefid === 'number' ? args.parentRefid : undefined\n const region =\n args.region &&\n typeof args.region === 'object' &&\n typeof args.region.left === 'number' &&\n typeof args.region.top === 'number' &&\n typeof args.region.width === 'number' &&\n typeof args.region.height === 'number'\n ? args.region\n : undefined\n\n // 평면 view 로 search — group/container 자식까지 매칭. parentRefid 메타도 함께.\n const flat = collectAllComponents(board)\n const matched = flat.filter(({ component: c, parentRefid }) => {\n if (!c) return false\n if (type && (c as any).type !== type) return false\n if (idFilter && (c as any).id !== idFilter) return false\n if (parentRefidFilter !== undefined && parentRefid !== parentRefidFilter) return false\n if (namePattern) {\n const name = typeof (c as any).name === 'string' ? (c as any).name.toLowerCase() : ''\n if (!name.includes(namePattern)) return false\n }\n if (region) {\n const left = typeof (c as any).left === 'number' ? (c as any).left : (c as any).cx\n const top = typeof (c as any).top === 'number' ? (c as any).top : (c as any).cy\n if (typeof left !== 'number' || typeof top !== 'number') return false\n if (\n left < region.left ||\n left > region.left + region.width ||\n top < region.top ||\n top > region.top + region.height\n ) {\n return false\n }\n }\n return true\n })\n\n // 결과에 parentRefid / depth 메타 포함 — AI 가 어느 그룹 안인지 인지\n const results = matched.slice(0, FIND_COMPONENTS_CAP).map(f => {\n const c: any = { ...f.component }\n if (f.depth > 0) {\n c._parentRefid = f.parentRefid\n c._depth = f.depth\n }\n return c\n })\n\n return {\n components: results,\n totalMatched: matched.length,\n truncated: matched.length > FIND_COMPONENTS_CAP\n }\n }\n case 'getAtmosphereGuide':\n return ATMOSPHERE_GUIDE\n case 'getAvailablePrefabs': {\n const args = call.arguments ?? {}\n const filter: { category?: string; keywordPattern?: string } = {}\n if (typeof args.category === 'string' && args.category.length > 0) {\n filter.category = args.category\n }\n if (typeof args.keywordPattern === 'string' && args.keywordPattern.length > 0) {\n filter.keywordPattern = args.keywordPattern\n }\n const prefabs = listBoardPrefabs(filter)\n return { prefabs, count: prefabs.length }\n }\n case 'getColorPalettes':\n return COLOR_PALETTES\n case 'getLayoutTemplates':\n return LAYOUT_TEMPLATES\n default:\n return { error: `Unknown read tool: ${call.name}` }\n }\n}\n\n/**\n * 3D 분위기 합성 지식 primer.\n *\n * 의도 — preset 한 단어로 끝나지 않는 사용자 요청 (\"심해\", \"황혼\", \"1980 우주정거장\",\n * \"안개 새벽\") 에 AI 가 구체적 파라미터 값을 직접 합성하도록 물리/색채/미학 지식\n * 동시 제공. AI 는 이 가이드를 받은 뒤 modifyBoard 로 한 번에 적용.\n *\n * things-scene 의 board model 에 들어가는 root level 키만 다룸 (modifyBoard 로\n * 적용 가능한 것). camera position 같은 ephemeral 한 것은 별도 영역.\n */\nconst ATMOSPHERE_GUIDE = {\n overview:\n '3D 보드 분위기는 (1) sky preset 또는 단색 (2) tone mapping exposure (3) hemisphere ambient (4) directional sun/key (5) floor 의 조합. 모두 board root model 의 속성이라 modifyBoard 단일 op 로 한 번에 적용. 자연어 요청은 archetype 레시피를 base 로 잡고 modifier 로 fine-tune.',\n\n parameters: {\n sky: {\n description:\n '3D 배경 + IBL (image-based lighting) 의 source. preset / \"color\" / \"\" 셋 중 하나.',\n presets: {\n studio: 'Neutral white studio with soft IBL — product-photo / showroom 분위기',\n warehouse: 'Indoor industrial space — moderate ambient, warm-tinted',\n factory: 'Bright factory floor — high ceiling lights, ~6000K cool',\n office: 'Clean office interior — neutral fluorescent feel',\n home: 'Warm domestic interior',\n sunny: 'Outdoor clear day — Three.js Sky shader, strong directional sun',\n cloudy: 'Outdoor overcast — soft diffuse, low contrast',\n rainy: 'Outdoor rainy — dim, cool, very diffuse'\n },\n special: {\n color: '단색 배경 (skyColor 같이 지정). IBL 없음 — hemi/dir 만 유효.',\n '\"\"': 'no background, no IBL. 거의 안 씀.'\n },\n tip: '커스텀 분위기는 sky=\"color\" + skyColor + hemi/dir 수동 튜닝 조합. preset 위에 hemi 등을 덮어쓰면 IBL 과 ambient 가 섞여 의도 흐려질 수 있다.'\n },\n skyColor: {\n description: 'sky=\"color\" 일 때 단색 배경. hex string.',\n examples: {\n '#0a1929': 'deep navy — 심해, 우주, 어두운 SF',\n '#1a2540': 'midnight blue — 밤, 차가운 미래',\n '#2c1b3d': 'deep violet — magical, mystical',\n '#3a4a3a': 'forest moss — 자연, 안개숲',\n '#f5e6d0': 'cream warm — 빈티지, 70년대',\n '#0a0a0a': 'pure dark — 드라마, 미니멀'\n }\n },\n exposure: {\n description: 'tone mapping exposure (ACESFilmic). 카메라 노출과 동일 개념.',\n range: '0.4 ~ 2.5 (sane), default ~1.2',\n bands: {\n '< 0.7': 'dim — 동굴, 심해, 음울, 야간',\n '0.7 ~ 1.0': 'subdued — 황혼, 안개, 침착',\n '1.0 ~ 1.4': 'balanced — 일반 실내/실외',\n '1.4 ~ 2.0': 'bright — 쇼룸, 한낮, 클린룸',\n '> 2.0': 'over — 매우 주의 (washout)'\n },\n pitfall: 'exposure 만 올리고 hemi/dir 도 동시에 올리면 wash 되어 평면화. 한쪽만 손대는 게 깔끔.'\n },\n hemisphere: {\n description:\n 'Hemisphere light = 위(sky)/아래(ground) 두 색을 보간한 ambient. 환경의 base 색조 결정.',\n keys: {\n hemiIntensity: '0 ~ 10, default 4. 높을수록 wash, 낮을수록 contrast.',\n hemiSkyColor: 'hex. 위에서 내려오는 빛 색조 (sky 의 색).',\n hemiGroundColor: 'hex. 아래에서 올라오는 반사 색 (floor / ground 의 bounce).'\n },\n tip: 'sky/ground 색 차이가 크면 environmental tint 강조 (예: sky=warm orange, ground=cool blue → 일출 분위기). 비슷하면 평탄한 ambient.'\n },\n directional: {\n description: 'Directional light = 태양/key light. 하나만 존재. 그림자 source.',\n keys: {\n dirLightEnabled: 'boolean. 태양 on/off. 야간 / 동굴 / 우주 등은 false.',\n dirLightColor:\n 'hex. 색온도 — 0xfff0d0 따뜻 (~3000K), 0xffffff 중성, 0xd0e0ff 차가움 (~7000K).',\n dirLightIntensity: '0 ~ 5, default 2. dramatic 은 높이고 hemi 낮춤.',\n dirLightAzimuth:\n '도. 0=북, 90=동, 180=남, 270=서. dirLightFollowCamera=false 일 때만 유효.',\n dirLightElevation: '도. 0=수평선, 90=정수리. 일출/석양 5–15, 한낮 70–90.',\n dirLightFollowCamera: 'true 면 카메라에 묶임 (편집 편의), false 면 world-fixed (sim 자연).'\n },\n sunPhysics: {\n dawn: 'elevation 10–20, color #ffb070 (warm orange), intensity 1.0–1.5',\n goldenHour: 'elevation 15–25, color #ffaf60 (saturated warm), intensity 2.0–2.5',\n noon: 'elevation 80–90, color #ffffff (neutral), intensity 2.8–3.5',\n sunset: 'elevation 5–15, color #ff7050 (red-orange), intensity 1.5–2.0',\n moonlight: 'elevation 60–80, color #a0b0d0 (cool blue), intensity 0.4–0.7'\n }\n },\n shadow: {\n keys: {\n dirShadowEnabled: 'boolean. drama 위해 on, exposure < 0.7 이면 의미 약함.',\n dirShadowBias: 'small negative (-0.0005 default). artifact 시 -0.001 정도 시도.'\n }\n },\n floor: {\n keys: {\n floorMaterial3d: '바닥 재질 preset (rubber/concrete/wood/metal/... — 도메인 별 등록).',\n fillStyle:\n '보드 배경 색 + preset 없을 때 floor tint. 3D 에서는 ground color 와 시각적으로 묶임.'\n }\n },\n camera: {\n keys: {\n fov: '30 ~ 75, default ~45. 낮으면 telephoto/compressed (드라마틱), 높으면 wide-angle.',\n near: '클리핑 near plane.',\n far: '클리핑 far plane (큰 보드면 5000+).'\n }\n }\n },\n\n archetypes: {\n timeOfDay: {\n dawn: {\n description: '해 뜨기 직전 — 차분, 기대감, 청량 + 약한 따뜻함',\n patch: {\n sky: 'color',\n skyColor: '#a0b8d0',\n exposure: 0.85,\n hemiIntensity: 3,\n hemiSkyColor: '#ffd0a0',\n hemiGroundColor: '#3a3040',\n dirLightEnabled: true,\n dirLightColor: '#ffb070',\n dirLightIntensity: 1.2,\n dirLightFollowCamera: false,\n dirLightElevation: 12,\n dirLightAzimuth: 80\n }\n },\n goldenHour: {\n description: '황금시간 — 따뜻, 풍부, 영화적',\n patch: {\n sky: 'sunny',\n exposure: 1.3,\n hemiIntensity: 4,\n hemiSkyColor: '#ffd5a0',\n hemiGroundColor: '#5a4030',\n dirLightEnabled: true,\n dirLightColor: '#ffaf60',\n dirLightIntensity: 2.2,\n dirLightFollowCamera: false,\n dirLightElevation: 20,\n dirLightAzimuth: 250\n }\n },\n noon: {\n description: '한낮 — 밝고 또렷, 사실적',\n patch: {\n sky: 'sunny',\n exposure: 1.4,\n hemiIntensity: 5,\n hemiSkyColor: '#cfe7ff',\n hemiGroundColor: '#5a5550',\n dirLightEnabled: true,\n dirLightColor: '#ffffff',\n dirLightIntensity: 3.0,\n dirLightFollowCamera: false,\n dirLightElevation: 85,\n dirLightAzimuth: 180\n }\n },\n dusk: {\n description: '황혼 — melancholy, 따뜻한 노을',\n patch: {\n sky: 'color',\n skyColor: '#3a4a6a',\n exposure: 0.95,\n hemiIntensity: 2.5,\n hemiSkyColor: '#a070a0',\n hemiGroundColor: '#2a2030',\n dirLightEnabled: true,\n dirLightColor: '#ff7050',\n dirLightIntensity: 1.6,\n dirLightFollowCamera: false,\n dirLightElevation: 8,\n dirLightAzimuth: 270\n }\n },\n night: {\n description: '밤 — 정적, 차가움, 달빛',\n patch: {\n sky: 'color',\n skyColor: '#0a0e1a',\n exposure: 0.7,\n hemiIntensity: 1.5,\n hemiSkyColor: '#3a4060',\n hemiGroundColor: '#0a0a14',\n dirLightEnabled: true,\n dirLightColor: '#a0b0d0',\n dirLightIntensity: 0.5,\n dirLightFollowCamera: false,\n dirLightElevation: 70,\n dirLightAzimuth: 200\n }\n }\n },\n\n indoor: {\n studioShowroom: {\n description: '스튜디오 / 매장 — 깨끗, 균일, 제품-photo',\n patch: {\n sky: 'studio',\n exposure: 1.3,\n hemiIntensity: 4.5,\n hemiSkyColor: '#ffffff',\n hemiGroundColor: '#a0a0a0',\n dirLightEnabled: true,\n dirLightColor: '#ffffff',\n dirLightIntensity: 2.0,\n dirLightFollowCamera: false,\n dirLightElevation: 70,\n dirLightAzimuth: 135\n }\n },\n industrialFactory: {\n description: '공장 — 기능적, 밝음, 약간 차가움',\n patch: {\n sky: 'factory',\n exposure: 1.2,\n hemiIntensity: 4.5,\n hemiSkyColor: '#e8eef5',\n hemiGroundColor: '#404040',\n dirLightEnabled: true,\n dirLightColor: '#f0f5ff',\n dirLightIntensity: 2.5,\n dirLightFollowCamera: false,\n dirLightElevation: 80,\n dirLightAzimuth: 90\n }\n },\n hospitalCleanroom: {\n description: '병원/클린룸 — 매우 밝음, 차갑고 균일',\n patch: {\n sky: 'studio',\n exposure: 1.5,\n hemiIntensity: 6,\n hemiSkyColor: '#ffffff',\n hemiGroundColor: '#d8e0e8',\n dirLightEnabled: true,\n dirLightColor: '#ffffff',\n dirLightIntensity: 1.5,\n dirLightFollowCamera: false,\n dirLightElevation: 90,\n dirLightAzimuth: 0\n }\n },\n cyberpunkLab: {\n description: '사이버펑크 실험실 — 네온, 마젠타+시안, 어두움',\n patch: {\n sky: 'color',\n skyColor: '#0a0a1a',\n exposure: 1.0,\n hemiIntensity: 3,\n hemiSkyColor: '#5040a0',\n hemiGroundColor: '#003a4a',\n dirLightEnabled: true,\n dirLightColor: '#a040c0',\n dirLightIntensity: 1.8,\n dirLightFollowCamera: false,\n dirLightElevation: 50,\n dirLightAzimuth: 135\n }\n }\n },\n\n surreal: {\n deepOcean: {\n description: '심해 — 차가운 청록, 위에서 약하게 비치는 빛',\n patch: {\n sky: 'color',\n skyColor: '#0a1929',\n exposure: 0.7,\n hemiIntensity: 2,\n hemiSkyColor: '#1a4060',\n hemiGroundColor: '#050a14',\n dirLightEnabled: true,\n dirLightColor: '#5080a0',\n dirLightIntensity: 0.8,\n dirLightFollowCamera: false,\n dirLightElevation: 75,\n dirLightAzimuth: 90,\n fillStyle: '#0a1929'\n }\n },\n mistyForest: {\n description: '안개 자욱한 숲 — 매우 diffuse, 채도 낮음',\n patch: {\n sky: 'cloudy',\n exposure: 0.95,\n hemiIntensity: 4,\n hemiSkyColor: '#c0d0c8',\n hemiGroundColor: '#3a4a3a',\n dirLightEnabled: true,\n dirLightColor: '#e0e0d0',\n dirLightIntensity: 0.8,\n dirLightFollowCamera: false,\n dirLightElevation: 35,\n dirLightAzimuth: 100\n }\n },\n deepSpace: {\n description: '우주 / SF — 검은 배경, 차갑고 강한 key',\n patch: {\n sky: 'color',\n skyColor: '#020205',\n exposure: 0.95,\n hemiIntensity: 0.5,\n hemiSkyColor: '#1a2040',\n hemiGroundColor: '#000005',\n dirLightEnabled: true,\n dirLightColor: '#ffffff',\n dirLightIntensity: 3,\n dirLightFollowCamera: false,\n dirLightElevation: 30,\n dirLightAzimuth: 70\n }\n },\n vintage70s: {\n description: '70년대 빈티지 — 따뜻한 베이지, 부드러운 그림자',\n patch: {\n sky: 'color',\n skyColor: '#d8b890',\n exposure: 1.15,\n hemiIntensity: 3.5,\n hemiSkyColor: '#f5d8a8',\n hemiGroundColor: '#705038',\n dirLightEnabled: true,\n dirLightColor: '#ffd098',\n dirLightIntensity: 1.8,\n dirLightFollowCamera: false,\n dirLightElevation: 45,\n dirLightAzimuth: 135\n }\n }\n }\n },\n\n modifiers: {\n warmCool:\n 'warm 으로 가려면 hemiSkyColor / dirLightColor 를 +30° hue red 방향. cool 은 반대.',\n drama:\n 'drama 강조 — hemiIntensity 낮추고 dirLightIntensity 올림. 그림자 강해짐.',\n saturation:\n 'vivid — 색채 그대로 유지하고 hemi 약간 낮춰 dir 가 punch 하게. muted — hemi 올리고 채도 낮은 색.',\n contrast:\n 'high — exposure 1.0 이하 + dir 강하게. low — exposure 1.3 이상 + hemi 강하게.'\n },\n\n workflow: [\n '1. 사용자 요청에서 archetype 키워드 식별 (시간대 / 실내 / 초현실 카테고리).',\n '2. archetypes 에서 가장 가까운 base 레시피 선택.',\n '3. modifiers 로 사용자 요청 뉘앙스 fine-tune (warm/cool/drama/...).',\n '4. sanity check — exposure × hemi × dir 어느 한쪽 극단 아닌지, hemi sky/ground 색 모순 없는지.',\n \"5. modifyBoard({ patch: { ...combined keys... } }) 한 번에 적용. 사용자에게 어떤 archetype + modifier 조합으로 갔는지 한 줄로 설명.\"\n ],\n\n pitfalls: [\n 'sky preset 위에 skyColor 같이 지정하면 preset 이 우선 (skyColor 무시).',\n 'exposure 와 hemi/dir 모두 max 면 washout. 한 쪽만 강하게.',\n 'dirLightEnabled=false 인데 dirLight 색/강도 설정해도 효과 없음.',\n 'dirLightFollowCamera=true 일 땐 azimuth/elevation 무의미 — false 로 바꿔야 적용.',\n \"fillStyle 만 바꾸면 floor tint 도 같이 바뀜 (floor preset 없을 때). 의도 없으면 floorMaterial3d 같이 점검.\"\n ]\n}\n\n/**\n * 색 팔레트 카탈로그 — 검증된 디자인 시스템 (industrial / financial /\n * control-room / medical / logistics / cyberpunk / paper).\n *\n * 의도: LLM 이 자유 색 작곡 (#3b82f6 + 보색?) 하지 않고 도메인에 맞는 검증된\n * 팔레트에서 고름. 결과 일관성 ↑, 비용 0, atmosphere primer 와 시너지.\n *\n * 사용 흐름:\n * 1. 사용자 의도 (산업 / 금융 / 의료 / SF / ...) 식별\n * 2. recommendations 에서 매칭 후보 1~2개 추림\n * 3. modifyBoard 로 board.fillStyle 을 palette.base 로 설정\n * 4. addPrefab / addComponent 시 palette 의 surface/accent/text 사용\n * 5. 일관된 룩 → 한 번 정한 팔레트 안에서만 색 선택\n *\n * 키 정의:\n * - base: 보드 / 큰 영역 background\n * - surface: 카드 / 패널 background (base 보다 1tier 밝음/어두움)\n * - border: subtle 경계선\n * - text: primary 본문\n * - muted: secondary 라벨 / 보조 텍스트\n * - accent: primary 강조 (값 / action / link)\n * - success/warning/danger/info: status 4종 (KPI 색상)\n */\nconst COLOR_PALETTES = {\n overview:\n '대시보드 색은 도메인에 따라 검증된 팔레트 7종 중 하나를 선택. 한 보드 안에서 같은 팔레트만 사용 → 일관성. 자유 색 조합은 보통 inconsistent — 카탈로그에서 골라 써라.',\n\n palettes: {\n 'industrial-steel': {\n description: '제조 / 공장 / 산업현장 — 차분한 강철색 + 강조용 cyan',\n moods: ['신뢰감', '엔지니어링', '차분', '기능적'],\n base: '#0f1722',\n surface: '#1a2332',\n border: '#2a3a52',\n text: '#e2e8f0',\n muted: '#94a3b8',\n accent: '#4fc3f7',\n success: '#10b981',\n warning: '#f59e0b',\n danger: '#ef4444',\n info: '#3b82f6'\n },\n 'financial-trader': {\n description: '금융 / 트레이딩 — 짙은 navy 위에 gold 강조, 상승 green / 하락 red',\n moods: ['프리미엄', '집중', '데이터 밀도'],\n base: '#0a0e1a',\n surface: '#131a2e',\n border: '#1f2a44',\n text: '#f1f5f9',\n muted: '#64748b',\n accent: '#fbbf24',\n success: '#22c55e',\n warning: '#eab308',\n danger: '#dc2626',\n info: '#60a5fa'\n },\n 'control-room-dark': {\n description: 'NOC / 관제실 — pure black + 네온 cyan/magenta 강조',\n moods: ['drama', 'mission-critical', 'high-contrast'],\n base: '#000000',\n surface: '#0a0a0a',\n border: '#1f1f1f',\n text: '#ffffff',\n muted: '#a3a3a3',\n accent: '#06b6d4',\n success: '#10b981',\n warning: '#f97316',\n danger: '#dc2626',\n info: '#a855f7'\n },\n 'medical-clean': {\n description: '의료 / 헬스케어 — soft white 위에 신뢰감 있는 blue / teal',\n moods: ['청결', '신뢰', '평온', '따뜻함'],\n base: '#f8fafc',\n surface: '#ffffff',\n border: '#e2e8f0',\n text: '#1e293b',\n muted: '#64748b',\n accent: '#0ea5e9',\n success: '#14b8a6',\n warning: '#f59e0b',\n danger: '#e11d48',\n info: '#3b82f6'\n },\n 'logistics-warm': {\n description: '물류 / 운송 — 따뜻한 baseline + amber 강조',\n moods: ['활동적', '에너지', '포근'],\n base: '#1c1410',\n surface: '#2a1f17',\n border: '#3d2e22',\n text: '#fef3c7',\n muted: '#a8916b',\n accent: '#f59e0b',\n success: '#84cc16',\n warning: '#fb923c',\n danger: '#dc2626',\n info: '#06b6d4'\n },\n 'neon-cyberpunk': {\n description: 'SF / 사이버펑크 — 새까만 배경 + magenta + cyan 네온',\n moods: ['미래적', 'edgy', 'attention-grabbing'],\n base: '#050008',\n surface: '#0d0118',\n border: '#1f0a35',\n text: '#f0e6ff',\n muted: '#7e6b96',\n accent: '#ec4899',\n success: '#22d3ee',\n warning: '#fde047',\n danger: '#ef4444',\n info: '#a78bfa'\n },\n 'paper-light': {\n description: '프레젠테이션 / 보고서 — 종이 느낌 light + 부드러운 ink',\n moods: ['클래식', '읽기 편함', '인쇄 친화'],\n base: '#fafaf9',\n surface: '#ffffff',\n border: '#e7e5e4',\n text: '#1c1917',\n muted: '#78716c',\n accent: '#1e40af',\n success: '#15803d',\n warning: '#a16207',\n danger: '#991b1b',\n info: '#0369a1'\n }\n },\n\n recommendations: {\n monitoring: ['industrial-steel', 'control-room-dark'],\n kpi: ['financial-trader', 'logistics-warm'],\n control: ['industrial-steel', 'neon-cyberpunk'],\n medical: ['medical-clean'],\n presentation: ['paper-light'],\n futuristic: ['neon-cyberpunk', 'control-room-dark'],\n classic: ['paper-light', 'industrial-steel']\n },\n\n workflow: [\n '1. 사용자 도메인 / 분위기 키워드 식별 — 산업/금융/관제/의료/SF/프레젠테이션',\n '2. recommendations 에서 매칭 후보 추림. 사용자 모호하면 가장 흔한 industrial-steel 디폴트.',\n \"3. modifyBoard({ patch: { fillStyle: palette.base } }) 으로 보드 배경 set.\",\n '4. 이후 모든 add / addPrefab 호출 시 palette.surface / accent / text / border 사용. 자유 색 X.',\n '5. status 표시는 success / warning / danger / info 4종에서만 — 자체 hex 만들지 마라.'\n ],\n\n pitfalls: [\n '한 보드 안에서 두 팔레트 섞으면 정신없음 — 한 번 정했으면 끝까지 그것만.',\n 'light palette (medical-clean, paper-light) 위에 dark prefab 옵션 넣으면 가독성 무너짐. fillStyle 같이 갱신.',\n 'accent 는 강조용 — 모든 텍스트에 쓰지 마라. 1~2개 핵심 값에만.',\n 'control-room-dark 에서 success(#10b981) 만 강조하면 화면 단조로움. accent(cyan) + status 색 섞어 써라.'\n ]\n}\n\n/**\n * Layout 템플릿 카탈로그 — 검증된 구도 레시피.\n *\n * 의도: 빈 보드에 컴포넌트를 어디에 배치할지 LLM 이 픽셀 노가다 하지 않고\n * 검증된 layout 에서 슬롯 좌표를 받아 사용. 1280x720 기준 — 다른 size 시\n * 비율 조정.\n */\nconst LAYOUT_TEMPLATES = {\n overview:\n '대시보드 구도는 보통 4~6 종 패턴 안에서 결정됨. 빈 보드 + 사용자 의도 명확하면 템플릿의 슬롯 좌표 그대로 addPrefab 호출. 1280×720 기준 — 다른 size 면 비율 조정.',\n\n templates: {\n 'kpi-row': {\n description: '상단 wide KPI 4-tile + 하단 메인 영역. 가장 흔한 dashboard 헤더.',\n bestFor: ['종합 모니터링', '경영 대시보드', '운영 status'],\n boardSize: { width: 1280, height: 720 },\n slots: [\n { name: 'kpi-1', region: { left: 20, top: 20, width: 290, height: 130 } },\n { name: 'kpi-2', region: { left: 330, top: 20, width: 290, height: 130 } },\n { name: 'kpi-3', region: { left: 640, top: 20, width: 290, height: 130 } },\n { name: 'kpi-4', region: { left: 950, top: 20, width: 290, height: 130 } },\n { name: 'main-area', region: { left: 20, top: 170, width: 1240, height: 530 } }\n ],\n recommendation:\n 'kpi-1~4 슬롯에 stat-tile 4개. main-area 슬롯에 큰 차트 / 맵 / 테이블. 같은 팔레트 사용.'\n },\n '3x3-grid': {\n description: '균등한 3×3 그리드 — 9개 동등 단위. 모니터링 매트릭스.',\n bestFor: ['센서 어레이', '여러 라인 동시 모니터링', '대조 표시'],\n boardSize: { width: 1280, height: 720 },\n slots: Array.from({ length: 9 }, (_, i) => {\n const col = i % 3\n const row = Math.floor(i / 3)\n return {\n name: `cell-${row}-${col}`,\n region: {\n left: 20 + col * 420,\n top: 20 + row * 240,\n width: 400,\n height: 220\n }\n }\n })\n },\n 't-shape-command': {\n description: '상단 wide alarm bar + 하단 좌측 큰 메인 + 우측 narrow side panel',\n bestFor: ['관제실', 'mission-critical', '알람 + 상세 분석 동시 보기'],\n boardSize: { width: 1280, height: 720 },\n slots: [\n { name: 'alarm-bar', region: { left: 20, top: 20, width: 1240, height: 80 } },\n { name: 'main-canvas', region: { left: 20, top: 120, width: 870, height: 580 } },\n { name: 'side-panel', region: { left: 910, top: 120, width: 350, height: 580 } }\n ],\n recommendation:\n 'alarm-bar 에 status 인디케이터들 가로 배치. main-canvas 에 layout map / chart. side-panel 에 detail / history.'\n },\n 'side-rail': {\n description: '좌측 narrow 네비/필터 + 메인 wide content',\n bestFor: ['exploration UI', '필터 + 결과', '카테고리 navigation'],\n boardSize: { width: 1280, height: 720 },\n slots: [\n { name: 'rail', region: { left: 20, top: 20, width: 240, height: 680 } },\n { name: 'main', region: { left: 280, top: 20, width: 980, height: 680 } }\n ]\n },\n 'split-half': {\n description: '50/50 가로 분할 — 비교 / 대조',\n bestFor: ['before/after', 'A/B 비교', '듀얼 라인 모니터링'],\n boardSize: { width: 1280, height: 720 },\n slots: [\n { name: 'left', region: { left: 20, top: 20, width: 610, height: 680 } },\n { name: 'right', region: { left: 650, top: 20, width: 610, height: 680 } }\n ]\n },\n 'header-content-footer': {\n description: '상단 헤더 (제목/메타) + 메인 콘텐츠 + 하단 푸터 (요약/시간)',\n bestFor: ['보고서 형식', '인쇄 친화적 layout', '프레젠테이션'],\n boardSize: { width: 1280, height: 720 },\n slots: [\n { name: 'header', region: { left: 20, top: 20, width: 1240, height: 80 } },\n { name: 'content', region: { left: 20, top: 120, width: 1240, height: 520 } },\n { name: 'footer', region: { left: 20, top: 660, width: 1240, height: 40 } }\n ]\n }\n },\n\n workflow: [\n '1. 사용자 의도 식별 — 종합 monitoring? 비교? 관제?',\n '2. bestFor 매칭으로 템플릿 후보 1~2개 추림.',\n '3. 보드 size 가 1280×720 다르면 슬롯 좌표/크기를 비율로 조정.',\n '4. 각 슬롯의 region 으로 addPrefab / addComponent 호출. 슬롯 1개에 1 prefab 권장 (단일 group 으로 wrap).',\n '5. 빈 슬롯 남겨두는 것도 OK — 사용자 후속 작업 여지.'\n ],\n\n pitfalls: [\n '슬롯끼리 겹치게 배치하지 마라 — 의도 없으면 시각 혼란.',\n 'kpi-row 의 main-area 에 너무 많은 위젯 욱여 넣지 마라 — 여백이 정보다.',\n \"보드 size 가 정사각이면 't-shape-command' 같은 wide-bias 템플릿은 비율 조정해도 어색. 'split-half' 또는 '3x3-grid' 가 더 적합.\",\n '템플릿은 시작점 — 사용자가 추가 요청 시 슬롯 안에서 자유 배치 가능. 슬롯에 갇혀 있을 필요 없다.'\n ]\n}\n\nexport function isReadTool(name: string): boolean {\n if (READ_TOOL_NAMES.has(name)) return true\n // tool-registry plugin point — 'read' 와 'external' 는 LLM 측에서 동일하게 다뤄짐\n // (server 즉시 실행 + 결과 회신). external 은 board model 외부 entity 변경이\n // 가능한 점에서 의미 차이가 있지만, dispatch path 는 read 와 같다.\n const kind = getToolKind(name)\n return kind === 'read' || kind === 'external'\n}\n\n/**\n * 등록된 색 팔레트 이름 목록 — catalog-resolver / 클라이언트 popup 데이터 source.\n * 호스트 패키지가 추가 팔레트 등록은 현재 미지원 (향후 별도 registry 패턴 필요).\n */\nexport function listColorPaletteNames(): string[] {\n return Object.keys(COLOR_PALETTES.palettes)\n}\n\n/**\n * 등록된 레이아웃 템플릿 이름 목록 — 위와 동일.\n */\nexport function listLayoutTemplateNames(): string[] {\n return Object.keys(LAYOUT_TEMPLATES.templates)\n}\n\n/**\n * agentic loop 의 비정상 종료 사유 → 사용자 메시지에 부기할 한국어 한 줄.\n *\n * 정상 종료 (abortReason undefined) 면 빈 문자열 — concat 해도 무해.\n * 사용자에게 \"왜 중간에 멈췄는지\" 단서 제공이 목적 — 침묵 종료 금지.\n */\nexport function formatAbortNotice(\n abortReason: AgenticLoopResult['abortReason']\n): string {\n if (!abortReason) return ''\n switch (abortReason.type) {\n case 'aborted':\n return '\\n\\n_(요청이 중단되어 일부만 처리됐어요.)_'\n case 'provider_error':\n return `\\n\\n_(처리 중 오류가 발생했어요: ${abortReason.message})_`\n case 'max_iterations':\n return `\\n\\n_(작업이 너무 길어 ${abortReason.iter}회에서 중단했어요. 더 작게 나눠 요청해보세요.)_`\n case 'repeated_validation_failure':\n return `\\n\\n_(\\`${abortReason.toolName}\\` 호출이 ${abortReason.consecutive}회 연속 실패해 중단했어요. 요청을 다시 표현해보세요.)_`\n }\n}\n\n/**\n * tool 결과를 UI fold-able 박스에 보여줄 만한 크기로 요약.\n *\n * 원본 그대로면 findComponents 50개 / getAtmosphereGuide 같은 큰 객체가 ChatMessage\n * 영속까지 부담 — 핵심 모양만 유지하고 나머지는 marker.\n */\nexport function summarizeToolResult(value: any, depth = 0): any {\n if (value === null || value === undefined) return value\n if (typeof value === 'string') {\n return value.length > 200 ? `${value.slice(0, 200)}…[+${value.length - 200} chars]` : value\n }\n if (typeof value === 'number' || typeof value === 'boolean') return value\n if (Array.isArray(value)) {\n if (depth >= 2) return `[Array(${value.length})]`\n const out = value.slice(0, 5).map(v => summarizeToolResult(v, depth + 1))\n if (value.length > 5) out.push(`…[+${value.length - 5} items]`)\n return out\n }\n if (typeof value === 'object') {\n if (depth >= 3) {\n const keys = Object.keys(value).slice(0, 6).join(',')\n return `{${keys}${Object.keys(value).length > 6 ? ',…' : ''}}`\n }\n const out: any = {}\n for (const key of Object.keys(value)) {\n out[key] = summarizeToolResult(value[key], depth + 1)\n }\n return out\n }\n return undefined\n}\n\nexport function isWriteTool(name: string): boolean {\n if (WRITE_TOOL_NAMES.has(name)) return true\n return getToolKind(name) === 'write'\n}\n\nexport function isActionTool(name: string): boolean {\n if (ACTION_TOOL_NAMES.has(name)) return true\n return getToolKind(name) === 'action'\n}\n\n/**\n * 대화별 **도구 노출 게이트**.\n *\n * 왜 필요한가: 한 제품에 성격이 다른 대화면이 여럿 생긴다(보드 저작 도크 · 운영 도크 …).\n * 보드 편집은 patch/revert 로 되돌아가지만 운영 명령은 실 시스템에 영향을 준다 — 두 능력이\n * 한 대화에 모두 들려 있으면 경계가 UI 문패에 불과하다.\n *\n * **정의를 숨기는 것만으로는 부족하다**: 모델이 이름을 추측하거나 옛 대화가 재생되면 숨긴 도구도\n * 호출된다. 그래서 정의 조립과 **dispatch 판정(isRead/isWrite/isAction·spec 조회)** 에 같은 게이트를\n * 통과시킨다. 게이트를 통과하지 못한 이름은 loop 가 미등록 도구로 처리해 LLM 에 회신한다(조용한 무동작 아님).\n *\n * 기본값은 **현행 동작 그대로** — exposure 를 주지 않으면 코어 도구 on + 전 카테고리 허용.\n */\nexport interface ToolExposure {\n /** 코어 보드 편집 도구(addComponent·스타일링·씬 조작) 노출 여부. 기본 true. */\n boardTools?: boolean\n /** 외부 카테고리 화이트리스트(registerToolCategory 이름). 미지정 = 전부. */\n toolCategories?: ToolCategoryFilter\n}\n\nexport interface ToolGate {\n coreOn: boolean\n filter: ToolCategoryFilter\n isRead(name: string): boolean\n isWrite(name: string): boolean\n isAction(name: string): boolean\n spec(name: string): ToolSpec | undefined\n}\n\nexport function buildToolGate(exposure: ToolExposure = {}): ToolGate {\n const coreOn = exposure.boardTools !== false\n const filter = exposure.toolCategories\n const kind = (name: string) => getToolKind(name, filter)\n return {\n coreOn,\n filter,\n isRead: name => (coreOn && READ_TOOL_NAMES.has(name)) || kind(name) === 'read' || kind(name) === 'external',\n isWrite: name => (coreOn && WRITE_TOOL_NAMES.has(name)) || kind(name) === 'write',\n isAction: name => (coreOn && ACTION_TOOL_NAMES.has(name)) || kind(name) === 'action',\n spec: name => findToolSpec(name, filter)\n }\n}\n\n/**\n * tool-registry plugin point — 등록된 모든 외부 카테고리의 LLM tool 정의를 도출.\n * styling-tools 가 buildStylingToolDefinitions 로 자기 정의를 내보내듯, 외부 카테고리\n * (board-import 등) 도 본 함수로 합집합. buildBoardEditTools 의 spread 부분에서 호출.\n */\nfunction buildExternalCategoryDefinitions(\n filter?: ToolCategoryFilter\n): Array<{ name: string; description: string; parameters: any }> {\n return getToolSpecsFor(filter).map(spec => ({\n name: spec.name,\n description: spec.themeNote ? `${spec.description} ${spec.themeNote}` : spec.description,\n parameters: spec.schema\n }))\n}\n\n/**\n * Tool call → BoardActionOp 변환 (C-1 ephemeral scene 조작).\n * 잘못된 인자는 null — agentic loop 가 Unknown tool 비슷하게 처리.\n */\nexport function toolCallToBoardActionOp(\n tc: AIToolCall,\n gate: ToolGate = buildToolGate()\n): import('./types.js').BoardActionOp | null {\n const args = tc.arguments ?? {}\n /* 씬 조작 액션은 전부 코어(보드) 능력 — 노출 안 된 대화에서는 만들지 않는다.\n * loop 는 gate.isAction 으로 이미 걸러내지만, 다른 호출부의 오용도 막는다. */\n if (!gate.coreOn) return null\n switch (tc.name) {\n case 'selectComponents': {\n if (!Array.isArray(args.refids)) return null\n const refids = args.refids.filter((n: any) => typeof n === 'number') as number[]\n return { action: 'selectComponents', refids }\n }\n case 'centerToComponent': {\n if (typeof args.refid !== 'number') return null\n const out: any = { action: 'centerToComponent', refid: args.refid }\n if (typeof args.animated === 'boolean') out.animated = args.animated\n return out\n }\n case 'fitToView': {\n const allowed = new Set(['fit', 'ratio', 'width', 'height'])\n const out: any = { action: 'fitToView' }\n if (typeof args.mode === 'string' && allowed.has(args.mode)) out.mode = args.mode\n return out\n }\n case 'setSceneMode': {\n if (args.mode !== 'edit' && args.mode !== 'view') return null\n return { action: 'setSceneMode', mode: args.mode }\n }\n default:\n return null\n }\n}\n\n// ── Tool call → BoardEditOp 변환 ───────────────────────────────────\n\n/**\n * AIToolChatResult → ChatResponse.\n *\n * 정책 — followUp 항상 undefined: reply 와 동일 텍스트를 followUp 에 복제하면 클라이언트\n * 에서 .md-body 와 .followup 두 박스에 같은 내용이 표시되어 사용자에게 \"동일 응답이\n * 두 번 반복\" 으로 보인다. 명확화 질문이 필요한 경우 LLM 이 reply 자체에 포함시키도록\n * 설계.\n */\nexport function toolResultToChatResponse(result: AIToolChatResult): ChatResponse {\n const ops = result.toolCalls\n .flatMap(call => {\n const r = toolCallToBoardEditOp(call)\n if (r === null) return []\n return Array.isArray(r) ? r : [r]\n })\n\n const reply = result.text || (ops.length > 0 ? '변경했습니다.' : '')\n\n let patch: BoardEditPatch | undefined\n if (ops.length > 0) {\n patch = {\n ops,\n summary: result.text ?? `${ops.length} edit op(s) applied`,\n confidence: 0.9\n }\n }\n\n return { reply, patch, followUp: undefined }\n}\n\nexport function toolCallToBoardEditOp(\n tc: AIToolCall,\n components: ReadonlyArray<any> = [],\n gate: ToolGate = buildToolGate()\n): BoardEditOp | BoardEditOp[] | null {\n const args = tc.arguments ?? {}\n /* 노출되지 않은 코어(보드 편집) 도구는 op 를 만들지 않는다 — 정의를 숨겼어도 호출은 올 수 있다. */\n if (!gate.coreOn && !gate.spec(tc.name)) return null\n // styling registry 에 등록된 tool 은 위임 — 한 tool 씩 점진 이전 중.\n // registry 에 없는 styling tool 은 아래 switch 의 기존 case 가 처리.\n if (isStylingTool(tc.name)) {\n if (!gate.coreOn) return null\n return dispatchStylingTool(tc.name, args, components)\n }\n // tool-registry plugin point — 외부 등록 'write' 카테고리 dispatch.\n // builder 결과는 BoardEditOp[] | { ops, errors? } | null 셋 중 하나.\n // (read/external 카테고리는 별도 dispatch path — agentic loop 의 executeReadTool 이 직접 처리.)\n const registrySpec = gate.spec(tc.name)\n if (registrySpec && registrySpec.kind === 'write') {\n const r = registrySpec.builder(args, { components })\n if (!r) return null\n if (Array.isArray(r)) return r.length > 0 ? r : null\n return r.ops.length > 0 ? r.ops : null\n }\n if (!gate.coreOn) return null // 코어 도구 switch 는 보드 편집 — 노출 안 된 대화에서는 진입 금지\n switch (tc.name) {\n case 'addComponent': {\n if (typeof args.type !== 'string') return null\n return { op: 'add', component: args as BoardComponent }\n }\n case 'removeComponentByRefid': {\n if (typeof args.refid !== 'number') return null\n return { op: 'remove', refid: args.refid }\n }\n case 'modifyComponentByRefid': {\n if (typeof args.refid !== 'number' || !args.patch || typeof args.patch !== 'object') return null\n return { op: 'modify', refid: args.refid, patch: args.patch as Partial<BoardComponent> }\n }\n // 모든 styling tool (setFill/setStroke/setText/setFont/setShadow/setOpacity/\n // setVisible/setMaterial/setShadowProperties/clearStyle/copyStyle) 은 registry\n // 가 처리 — 상단 isStylingTool 분기 참조\n case 'modifyBoard': {\n if (!args.patch || typeof args.patch !== 'object' || Array.isArray(args.patch)) return null\n return { op: 'modifyBoard', patch: args.patch as Partial<BoardModel> }\n }\n case 'replaceBoard': {\n if (!Array.isArray(args.components)) return null\n return {\n op: 'replace',\n board: {\n width: typeof args.width === 'number' ? args.width : undefined,\n height: typeof args.height === 'number' ? args.height : undefined,\n fillStyle: typeof args.fillStyle === 'string' ? args.fillStyle : undefined,\n components: args.components as BoardComponent[]\n } as BoardModel\n }\n }\n // Phase 2 — Scene 조작\n case 'alignComponents': {\n if (!Array.isArray(args.refids) || args.refids.length === 0) return null\n const refids = args.refids.filter((n: any) => typeof n === 'number') as number[]\n if (refids.length === 0) return null\n const allowed = new Set(['left', 'right', 'center', 'top', 'middle', 'bottom'])\n if (typeof args.direction !== 'string' || !allowed.has(args.direction)) return null\n return { op: 'align', refids, direction: args.direction as any }\n }\n case 'distributeComponents': {\n if (!Array.isArray(args.refids)) return null\n const refids = args.refids.filter((n: any) => typeof n === 'number') as number[]\n if (refids.length === 0) return null\n if (args.axis !== 'horizontal' && args.axis !== 'vertical') return null\n return { op: 'distribute', refids, axis: args.axis }\n }\n case 'groupComponents': {\n if (!Array.isArray(args.refids)) return null\n const refids = args.refids.filter((n: any) => typeof n === 'number') as number[]\n if (refids.length < 2) return null\n return { op: 'group', refids }\n }\n case 'ungroupComponent': {\n if (typeof args.refid !== 'number') return null\n return { op: 'ungroup', refid: args.refid }\n }\n case 'changeZorder': {\n if (typeof args.refid !== 'number') return null\n const allowed = new Set(['front', 'back', 'forward', 'backward'])\n if (typeof args.direction !== 'string' || !allowed.has(args.direction)) return null\n return { op: 'zorder', refid: args.refid, direction: args.direction as any }\n }\n case 'arrangeInGrid': {\n if (!Array.isArray(args.refids)) return null\n const refids = args.refids.filter((n: any) => typeof n === 'number') as number[]\n if (refids.length < 2) return null\n const cols = typeof args.cols === 'number' && args.cols >= 1 ? Math.floor(args.cols) : null\n if (cols === null) return null\n const layout: any = { type: 'grid', cols }\n if (typeof args.gap === 'number') layout.gap = args.gap\n if (\n args.anchor &&\n typeof args.anchor === 'object' &&\n typeof args.anchor.left === 'number' &&\n typeof args.anchor.top === 'number'\n ) {\n layout.anchor = { left: args.anchor.left, top: args.anchor.top }\n }\n return { op: 'arrange', refids, layout }\n }\n case 'arrangeInRow':\n case 'arrangeInColumn': {\n if (!Array.isArray(args.refids)) return null\n const refids = args.refids.filter((n: any) => typeof n === 'number') as number[]\n if (refids.length < 2) return null\n const layout: any = {\n type: tc.name === 'arrangeInRow' ? 'row' : 'column'\n }\n if (typeof args.gap === 'number') layout.gap = args.gap\n if (\n args.anchor &&\n typeof args.anchor === 'object' &&\n typeof args.anchor.left === 'number' &&\n typeof args.anchor.top === 'number'\n ) {\n layout.anchor = { left: args.anchor.left, top: args.anchor.top }\n }\n if (args.align === 'start' || args.align === 'center' || args.align === 'end') {\n layout.align = args.align\n }\n return { op: 'arrange', refids, layout }\n }\n case 'addPrefab': {\n if (typeof args.name !== 'string' || args.name.length === 0) return null\n if (typeof args.left !== 'number' || typeof args.top !== 'number') return null\n const prefab = findBoardPrefab(args.name)\n if (!prefab) return null\n const options: any = {\n left: args.left,\n top: args.top,\n ...(typeof args.width === 'number' && { width: args.width }),\n ...(typeof args.height === 'number' && { height: args.height }),\n ...(args.options && typeof args.options === 'object' ? args.options : {})\n }\n let component: BoardComponent\n try {\n component = prefab.build(options)\n } catch {\n // 잘못된 옵션 (예: 잘못된 타입) — 무시. agentic loop 가 fallback 가능.\n return null\n }\n if (!component || typeof component !== 'object') return null\n return { op: 'add', component }\n }\n default:\n return null\n }\n}\n\n// ── 스킴 포맷 ──────────────────────────────────────────────────────\n\n/**\n * ComponentSchema[] 를 LLM 친화적 형태로 압축. 토큰 절감을 위해:\n * - knownTypes 에 포함된 schema 만\n * - properties 의 nested object 는 키 목록만\n */\nfunction formatSchemas(schemas: ComponentSchema[], knownTypes: string[]): string {\n if (!schemas || schemas.length === 0) return '(none provided)'\n const allowed = new Set(knownTypes)\n const filtered = schemas.filter(s => s && allowed.has(s.type))\n if (filtered.length === 0) return '(none provided)'\n\n const lines: string[] = []\n for (const s of filtered) {\n const desc = s.description ? ` — ${s.description}` : ''\n const grp = s.group ? ` [${s.group}]` : ''\n const geom =\n s.geometryKeys && s.geometryKeys.length > 0\n ? `\\n geometry: ${s.geometryKeys.join(', ')}`\n : ''\n const propKeys = s.properties ? formatProperties(s.properties) : ''\n const propLine = propKeys ? `\\n properties: ${propKeys}` : ''\n lines.push(`- ${s.type}${grp}${desc}${geom}${propLine}`)\n }\n return lines.join('\\n')\n}\n\nfunction formatProperties(props: Record<string, any>): string {\n const items: string[] = []\n for (const [k, v] of Object.entries(props)) {\n if (v === null || v === undefined) {\n items.push(k)\n } else if (typeof v === 'object' && !Array.isArray(v)) {\n const subKeys = Object.keys(v).slice(0, 6).join(',')\n items.push(`${k}:{${subKeys}}`)\n } else if (Array.isArray(v)) {\n items.push(`${k}:[]`)\n } else if (typeof v === 'string' && v.length > 24) {\n items.push(`${k}:string`)\n } else {\n items.push(`${k}=${JSON.stringify(v)}`)\n }\n }\n return items.join(', ')\n}\n\n// ── 보드 요약 (LLM 토큰 절감) ──────────────────────────────────────\n\nexport function summarizeBoard(board: BoardModel | null | undefined): any {\n if (!board || typeof board !== 'object') return null\n const components = board.components ?? []\n\n // 루트(보드 자체) 의 모든 비-internal 속성을 그대로 노출.\n // 단순 whitelist (width/height/fillStyle) 로 좁히면 AI 가 보드 자체의 다른 속성\n // (name 등) 을 모르고 또한 \"보드는 단순 컨테이너\" 로 오해할 수 있다. 보드도\n // 자체 속성을 가진 부모 노드임을 분명히 보이도록.\n const root: any = {}\n for (const key of Object.keys(board)) {\n if (key === 'components') continue // children 은 별도 처리\n if (key.startsWith('_')) continue\n root[key] = summarizeValue((board as any)[key], 0)\n }\n\n // group/container 자식까지 포함한 평면 list — AI 가 hierarchy 무관하게 모든\n // 컴포넌트를 인지할 수 있도록. 메타 (parentRefid, depth) 첨부.\n const flat = collectAllComponents(board)\n const flatSummary = flat\n .slice(0, MAX_BOARD_SUMMARY_COMPONENTS)\n .map(f => {\n const summary = summarizeComponent(f.component)\n // depth 0 은 메타 생략 (top-level — parentRefid undefined)\n if (f.depth > 0) {\n summary._parentRefid = f.parentRefid\n summary._depth = f.depth\n }\n return summary\n })\n\n return {\n // 'model' 은 things-scene 보드 root 의 type — 보드가 컴포넌트 같은 대상임을 명시.\n boardRoot: { type: 'model', ...root },\n componentCount: flat.length, // 평면 — group 자식 포함\n topLevelCount: components.length,\n components: flatSummary,\n truncated: flat.length > MAX_BOARD_SUMMARY_COMPONENTS\n }\n}\n\n// 요약에서 제외할 키 — things-scene 의 내부/transient 상태 (사용자가 편집 대상으로 삼지 않음)\nconst COMPONENT_OMIT_KEYS = new Set<string>([\n 'components', // group/container 의 children — 별도 처리\n '_state',\n '_cache',\n '_layout',\n '_dirty',\n '_internal'\n])\n\nconst MAX_STRING_LEN = 200\nconst MAX_ARRAY_LEN = 50\n\n/**\n * 컴포넌트 요약 — type-specific 속성 (text, value, cx/cy/radius, points, ...) 까지\n * 포함해 LLM 이 정확한 modify 대상을 판단할 수 있도록.\n *\n * 토큰 절감을 위해:\n * - 긴 문자열/배열은 길이 제한 (말미 truncated 마커)\n * - things-scene 내부 키 (_state 등) 는 제외\n * - nested object 는 1단계까지 그대로, 그 이상은 키 목록만\n */\nfunction summarizeComponent(c: BoardComponent): any {\n if (!c || typeof c !== 'object') return c\n const out: any = {}\n for (const key of Object.keys(c)) {\n if (COMPONENT_OMIT_KEYS.has(key)) continue\n if (key.startsWith('_')) continue\n out[key] = summarizeValue((c as any)[key], 0)\n }\n return out\n}\n\nfunction summarizeValue(v: any, depth: number): any {\n if (v === null || v === undefined) return v\n const t = typeof v\n if (t === 'string') {\n return v.length > MAX_STRING_LEN ? `${v.slice(0, MAX_STRING_LEN)}…[+${v.length - MAX_STRING_LEN} chars]` : v\n }\n if (t === 'number' || t === 'boolean') return v\n if (Array.isArray(v)) {\n if (v.length === 0) return []\n if (depth >= 2) return `[Array(${v.length})]`\n const out = v.slice(0, MAX_ARRAY_LEN).map(x => summarizeValue(x, depth + 1))\n if (v.length > MAX_ARRAY_LEN) out.push(`…[+${v.length - MAX_ARRAY_LEN} items]`)\n return out\n }\n if (t === 'object') {\n if (depth >= 2) {\n const keys = Object.keys(v).slice(0, 8)\n return `{${keys.join(',')}${Object.keys(v).length > 8 ? ',…' : ''}}`\n }\n const out: any = {}\n for (const key of Object.keys(v)) {\n if (key.startsWith('_')) continue\n out[key] = summarizeValue(v[key], depth + 1)\n }\n return out\n }\n return undefined\n}\n"]}
|
|
1
|
+
{"version":3,"file":"assistant.js","sourceRoot":"","sources":["../../../server/service/assistant.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * DefaultBoardAIAssistant — base AIClient 위에 LLM 프롬프트로 chat() 구현.\n */\nimport type {\n AIClient,\n AIMessage,\n AITool,\n AIToolCall,\n AIToolChatResult\n} from '@things-factory/ai-client-base'\nimport {\n getImportRules,\n type BoardComponent,\n type BoardModel,\n type ComponentCategory\n} from '@things-factory/board-import'\nimport type {\n BoardAIAssistant,\n BoardEditOp,\n BoardEditPatch,\n ChatOptions,\n ChatResponse,\n ComponentSchema,\n LLMMessage,\n ToolUsage\n} from './types.js'\nimport {\n findBoardPrefab,\n listBoardPrefabs\n} from './prefab-registry'\nimport { resolveMentions } from './mention-resolver'\nimport { resolveCatalogMentions } from './catalog-resolver'\n// styling write tool builder 들은 registry (./styling/registry.ts) 에서 등록 + dispatch.\n// 직접 import 안 함 — 신규 styling tool 추가 시 registry 에만 spec 추가하면 됨.\nimport { buildComponentStyleSummary } from './styling/read-tools'\nimport { runAgenticLoop, type AgenticLoopResult } from './agentic-loop'\nimport { checkReplyGrounding } from './grounding'\nimport { collectAllComponents, findComponentByRefid } from './component-tree'\nimport {\n isStylingTool,\n dispatchStylingTool,\n buildStylingToolDefinitions\n} from './styling/registry.js'\nimport {\n getAllToolSpecs,\n getToolSpecsFor,\n getToolKind,\n findToolSpec,\n type ToolSpec,\n type ToolCategoryFilter,\n getCategoryGuidance,\n isTransientAIError\n} from '@things-factory/ai-client-base'\nimport { validateWriteToolCall } from './validation/tool-validation'\n\nconst ALL_CATEGORIES: ComponentCategory[] = [\n 'container',\n 'vehicle',\n 'path',\n 'region',\n 'equipment',\n 'io',\n 'marker',\n 'structure',\n 'unknown'\n]\n\nconst MAX_BOARD_SUMMARY_COMPONENTS = 80\n\n/**\n * 마지막 user 메시지에 한해 #token (컴포넌트 selector) + @token (카탈로그\n * 식별자) 멘션을 LLM 친화 형태로 변환. 다른 메시지 / assistant 메시지는 그대로.\n * 원본 messages 도 mutate 하지 않음.\n *\n * - # 는 본문 LITERAL 보존 + 끝에 mention map 블록 첨부 (refid 본문 노출 0)\n * - @ 는 inline disambiguation ('monitor-card (prefab)')\n *\n * 두 resolver 의 변환 결과 / token regex 가 서로 안 겹쳐 순서 무관.\n */\nfunction enrichLastUserWithMentions(\n messages: LLMMessage[],\n currentBoard: BoardModel | undefined,\n picks?: Array<{ token: string; refid: number }>\n): LLMMessage[] {\n if (messages.length === 0) return messages\n const lastIdx = messages.length - 1\n const last = messages[lastIdx]\n if (last.role !== 'user' || typeof last.content !== 'string') return messages\n const step1 = resolveMentions(last.content, currentBoard ?? null, { picks })\n const step2 = resolveCatalogMentions(step1)\n if (step2 === last.content) return messages\n const out = messages.slice()\n out[lastIdx] = { ...last, content: step2 }\n return out\n}\n\nexport interface BoardAIAssistantOptions {\n /** 기본 scope (chat 호출 시 옵션이 없으면 사용) */\n scopes?: string[]\n knownTypes?: string[]\n categories?: ComponentCategory[]\n}\n\nexport class DefaultBoardAIAssistant implements BoardAIAssistant {\n readonly id: string\n constructor(private base: AIClient, private options: BoardAIAssistantOptions = {}) {\n this.id = base.id\n }\n\n async chat(\n messages: LLMMessage[],\n currentBoard: BoardModel | undefined,\n options: ChatOptions = {}\n ): Promise<ChatResponse> {\n if (messages.length === 0) {\n throw new Error('chat() requires at least one message')\n }\n\n const { knownTypes, categories } = this.resolveTypesAndCategories(options)\n const schemas = options.componentSchemas ?? []\n\n // chatWithTools 필수 — multi-turn agentic loop / read tool / atmosphere guide /\n // tool trace 모두 chatWithTools 위에서 동작. legacy chatViaJSON fallback 은 v10\n // 에서 제거됨 (모던 provider — Anthropic / Gemini / OpenAI — 모두 tool calling 지원).\n if (typeof this.base.chatWithTools !== 'function') {\n throw new Error(\n `AI client \"${this.base.id}\" does not support chatWithTools. ` +\n 'board-ai requires a tool-calling-capable provider (Anthropic / Gemini / OpenAI).'\n )\n }\n\n // 마지막 user 메시지의 #name 멘션을 refid 로 보강 — 영속(ChatMessage) 은 호출자가\n // 받은 원본을 저장하므로 chat 내부에서만 변환된 사본을 사용. AI 가 findComponents\n // 호출 1턴 절약 + 환각 방지.\n const enriched = enrichLastUserWithMentions(\n messages,\n currentBoard,\n options.mentionPicks\n )\n\n return await this.chatViaTools(enriched, currentBoard, options, knownTypes, categories, schemas)\n }\n\n // ── Tool calling 경로 (agentic multi-turn) ─────────────────────────\n\n private async chatViaTools(\n messages: LLMMessage[],\n currentBoard: BoardModel | undefined,\n options: ChatOptions,\n knownTypes: string[],\n categories: ComponentCategory[],\n schemas: ComponentSchema[]\n ): Promise<ChatResponse> {\n /* 대화별 도구 노출 — 정의 조립과 dispatch 판정에 **같은 게이트**를 쓴다.\n * 정의만 숨기면 모델이 이름을 추측하거나 옛 대화가 재생될 때 숨긴 도구가 실행된다. */\n const gate = buildToolGate({ boardTools: options.boardTools, toolCategories: options.toolCategories })\n const tools = buildBoardEditTools(knownTypes, { boardTools: options.boardTools, toolCategories: options.toolCategories })\n /* 노출된 도구 카테고리의 **사용 규율**을 프롬프트에 함께 싣는다.\n *\n * 도구 목록만 보내면 모델은 \"무엇이 있는지\" 는 알지만 \"언제 반드시 불러야 하는지\" 는 모른다.\n * 실제로 그 공백에서 사고가 났다 — 조치 요청에 제안 도구를 부르지 않고 \"제안해 두었습니다\" 라고만\n * 답해, 사용자에게 없는 버튼을 누르라고 안내했다. 규율은 도구를 등록한 쪽이 소유하고 여기서는\n * 모아 붙이기만 한다(도메인 지식이 board-ai 프롬프트로 새지 않는다). */\n const guidance = getCategoryGuidance(options.toolCategories)\n const systemPrompt =\n this.buildSystemPromptForTools(knownTypes, categories, schemas) +\n (guidance.length ? `\\n\\n==== TOOL USE RULES (from the tools exposed to this conversation) ====\\n${guidance.join('\\n')}` : '')\n\n const selectedRefids = (options.selectedRefids ?? []).filter(\n (n): n is number => typeof n === 'number' && Number.isFinite(n)\n )\n // selection 정보는 항상 포함 (비어 있어도) — LLM 이 \"선택된 게 뭐냐\" 류 질문에\n // getSelection 을 호출할지 판단하는 데 필요.\n const selectionContext = selectedRefids.length > 0\n ? `\\n\\nUser-selected component refids: ${JSON.stringify(selectedRefids)}\\n` +\n `When the user says \"selected\" / \"선택한\" / \"this\" / \"그것\" / \"these\" etc. ` +\n `WITHOUT specifying targets, operate ONLY on these refids. ` +\n `Do not modify other components unless explicitly asked. ` +\n `For inspecting selected components, prefer calling \\`getSelection\\` over guessing.`\n : `\\n\\nNo component is currently selected. If the user asks about \"selected\" / \"this\", ` +\n `clarify or call \\`getSelection\\` to confirm.`\n\n const boardContext = currentBoard\n ? `Current board state (JSON, summarized; full details via \\`getComponent\\` / \\`findComponents\\`):\\n` +\n `${JSON.stringify(summarizeBoard(currentBoard), null, 2)}` + selectionContext\n : 'No current board (empty start).' + selectionContext\n\n let conversation: AIMessage[] = [\n { role: 'user', content: boardContext },\n ...messages.map<AIMessage>(m => ({\n role: m.role === 'assistant' ? 'assistant' : 'user',\n content: m.content\n }))\n ]\n\n // multi-turn agentic loop — LLM 이 read 호출 → 서버 실행 → 결과 회신 → LLM 추론 반복.\n // write tool 은 누적해 client 에 patch 로 전달. 본체는 ./agentic-loop 에 분리.\n //\n // executeReadTool 은 closure wrapper — board-ai 자체 read tool (READ_TOOL_NAMES) 은\n // 기존 hardcoded executeReadTool 로 dispatch, registry 에 등록된 read/external tool\n // 은 spec.builder 에 ctx (board, selectedRefids, state=options.toolCallContext) 주입.\n /* 도구 문맥 = 서버가 준 state(도메인·사용자 — 권한 정본) + 호스트가 보낸 문맥(무엇을 보고 있는지).\n * host 는 클라이언트 값이므로 권한 판정에 쓰지 않는다(도구가 소속을 검증). */\n const toolCallContext = options.hostContext\n ? { ...(options.toolCallContext ?? {}), host: options.hostContext }\n : options.toolCallContext\n const wrappedExecuteReadTool = (\n call: any,\n board: any,\n selectedRefids: number[]\n ): any => {\n // 1) board-ai 코어 read tool — 기존 hardcoded 경로. 코어를 끈 대화에서는 실행하지 않는다.\n if (gate.coreOn && READ_TOOL_NAMES.has(call.name)) {\n return executeReadTool(call, board, selectedRefids)\n }\n // 2) registry — read 와 external 둘 다 동일 dispatch path (LLM 회신 측면 동일).\n // external builder 가 server-side mutation 호출하는 케이스라 ctx.state 주입 필수.\n const spec = gate.spec(call.name)\n if (spec && (spec.kind === 'read' || spec.kind === 'external')) {\n return (spec.builder as any)(call.arguments ?? {}, {\n board,\n selectedRefids,\n state: toolCallContext\n })\n }\n // 3) 미등록 / 잘못된 분기 — 빈 응답. agentic-loop 가 LLM 에 회신 후 다음 turn.\n return undefined\n }\n\n const loopResult = await runAgenticLoop({\n initialConversation: conversation,\n tools,\n options: {\n systemPrompt,\n model: options.model,\n temperature: options.temperature,\n maxTokens: options.maxTokens,\n /* 라이브 상태를 다루는 대화면은 첫 턴에 조회를 강제한다 — 근거 없이 상태를 단언할 길을 막는다. */\n requireToolOnFirstTurn: options.requireGroundingTools\n },\n chat: (msgs, tools, opts) => this.base.chatWithTools!(msgs, tools, opts),\n dispatch: {\n /* 노출 게이트를 통과하지 못한 이름은 미등록으로 분류 → loop 가 LLM 에 회신(조용한 무동작 아님). */\n isReadTool: gate.isRead,\n isWriteTool: gate.isWrite,\n isActionTool: gate.isAction,\n executeReadTool: wrappedExecuteReadTool,\n validateWriteToolCall,\n toolCallToBoardActionOp,\n summarizeToolResult\n },\n currentBoard,\n selectedRefids\n })\n const accumulatedWriteCalls = loopResult.accumulatedWriteCalls\n const accumulatedActions = loopResult.accumulatedActions\n const toolUsages = loopResult.toolUsages\n const lastText = loopResult.lastText\n const stopReason = loopResult.stopReason\n\n // accumulated write calls → BoardEditPatch (tool 이 array 반환 가능 — flat)\n const components = (currentBoard?.components ?? []) as any[]\n const ops = accumulatedWriteCalls\n .flatMap(call => {\n const r = toolCallToBoardEditOp(call, components, gate)\n if (r === null) return []\n return Array.isArray(r) ? r : [r]\n })\n\n // abortReason 이 있으면 사용자 메시지에 한 줄 부기 — 침묵 종료 방지.\n // (정상 종료 시 abortReason undefined 로 부기 없음.)\n const baseReply = lastText || (ops.length > 0 ? '변경했습니다.' : '')\n const reply = baseReply + formatAbortNotice(loopResult.abortReason)\n\n let patch: BoardEditPatch | undefined\n if (ops.length > 0) {\n patch = {\n ops,\n summary: lastText ?? `${ops.length} edit op(s) applied`,\n confidence: 0.9\n }\n }\n\n /* 접지 검사 — 답이 **모델이 받은 것** 밖의 식별자를 지목했는지. 답은 고치지 않고 경고만 낸다.\n * 근거집합의 정의와 사정거리는 ./grounding 머리말 참조(식별자 없는 창작 서술은 잡지 못한다). */\n const warnings = checkReplyGrounding(baseReply, {\n systemPrompt,\n boardContext,\n messages: messages.map(m => (typeof m.content === 'string' ? m.content : '')),\n toolResults: loopResult.groundedTexts\n })\n\n return {\n reply,\n patch,\n followUp: undefined,\n toolUsages: toolUsages.length > 0 ? toolUsages : undefined,\n actions: accumulatedActions.length > 0 ? accumulatedActions : undefined,\n /* 제안은 실행 전 상태다 — 대화면이 확인 버튼을 그린다. 서버는 실행하지 않는다. */\n proposals: loopResult.proposals.length > 0 ? loopResult.proposals : undefined,\n groundingWarnings: warnings.length > 0 ? warnings : undefined\n }\n }\n\n private resolveTypesAndCategories(options: ChatOptions): {\n knownTypes: string[]\n categories: ComponentCategory[]\n } {\n const explicitTypes = options.knownTypes ?? this.options.knownTypes\n const explicitCats = (options.categories ?? this.options.categories) as ComponentCategory[] | undefined\n if (explicitTypes && explicitCats) {\n return { knownTypes: explicitTypes, categories: explicitCats }\n }\n\n const scopes = options.scopes ?? this.options.scopes\n if (scopes && scopes.length > 0) {\n const rules = getImportRules(scopes)\n const types = explicitTypes ?? Array.from(new Set(rules.map(r => r.componentType))).filter(Boolean)\n const cats =\n explicitCats ??\n (Array.from(new Set(rules.map(r => r.category).filter(Boolean))) as ComponentCategory[])\n return {\n knownTypes: types,\n categories: cats.length > 0 ? cats : ALL_CATEGORIES\n }\n }\n\n return {\n knownTypes: explicitTypes ?? [],\n categories: explicitCats ?? ALL_CATEGORIES\n }\n }\n\n\n // ── Tool calling 용 system prompt ──────────────────────────────────\n\n private buildSystemPromptForTools(\n knownTypes: string[],\n categories: ComponentCategory[],\n schemas: ComponentSchema[]\n ): string {\n const typeLine = knownTypes.length > 0 ? knownTypes.join(', ') : '(none registered)'\n const catLine = categories.join(', ')\n const schemaSection = formatSchemas(schemas, knownTypes)\n\n return `You are a board modeling assistant. Edit the board by calling the provided tools.\n\n==== ⚠⚠⚠ ACTION POLICY — TEXT-ONLY 응답 절대 금지 ⚠⚠⚠ ====\n사용자의 메시지가 보드 변경을 *암시하거나 요청* 하면 (색을 바꿔, 정렬해, 추가해,\n스타일을 바꿔, \"분위기 바꿔\", \"북유럽스타일로\", \"어울리게\", \"정리해\" 등) **반드시\n적절한 write tool 을 호출** 해야 한다. tool 을 부르지 않고 \"이렇게 바꾸겠습니다\"\n또는 \"X 를 Y 로 변경했습니다\" 라고 설명만 하는 것은 **거짓말** 이다 — 실제로는\n아무것도 안 바뀌었기 때문.\n\n룰:\n 1. 변경 요청 → write tool 호출 필수 (modifyBoard / setFill / setStroke / setMaterial /\n setShadow / setOpacity / setVisible / setFont / setText / setMaterial / addComponent /\n removeComponentByRefid / modifyComponentByRefid / align/distribute/group/zorder 등)\n 2. 호출 + 짧은 reply 텍스트 동시 작성 OK — reply 는 *결과* 를 한국어로 한두 문장 요약\n 3. read tool (getSelection, findComponents, getComponentByRefid, getAtmosphereGuide 등)\n 만으로 응답 끝나는 것도 금지 — 정보 조회 후엔 *그 정보를 바탕으로 write tool 까지*\n 불러야 사용자 의도 충족\n 4. 진짜로 변경할 게 없는 단순 질문 (\"이거 뭐예요?\", \"몇 개 있어요?\") 만 텍스트로 답\n 5. tool 호출이 schema 검증 실패해서 retry 받으면 — 포기하지 말고 args 정정해 다시 호출\n 6. 사용자에게 \"X 했습니다\" 라고 쓰려면 그 *X 가 실제 tool 호출로 이뤄진 다음* 에만\n\n응답에 reply 텍스트만 있고 write tool 호출이 없다면 — 그건 사용자에게 \"변경 약속\" 만\n한 채 *아무 일도 안 한* 상태다. 사용자가 가장 싫어하는 패턴이며, 신뢰를 즉시 잃는다.\n\n==== BOARD HIERARCHY (CRITICAL) ====\nThe BOARD itself is the TOPMOST PARENT. It is NOT a component — it has its own\nroot-level properties separate from any child:\n\n • Root attributes (things-scene model-layer 가 인식하는 키만):\n - Layout: \\`width\\`, \\`height\\`, \\`fitMode\\`, \\`translate\\`, \\`scale\\`\n - 2D 배경: \\`fillStyle\\`\n - 3D 환경: \\`sky\\` / \\`skyColor\\` / \\`exposure\\` / \\`hemi*\\` / \\`dirLight*\\` / \\`dirShadow*\\` / \\`camera*\\` / \\`autoRotate\\`\n - 식별: \\`id\\`, \\`refid\\`, \\`type\\` (\"model-layer\")\n ⚠ 보드 \\*\\*name\\*\\* 은 root attribute 가 아님 — Board 엔티티의 DB 컬럼이지 scene\n MODEL 의 필드가 아님 (model-layer 가 무시). 보드 라벨 변경은 modifyBoard 영역 X.\n • Children: an array of components inside the board (rect / circle / text /\n gauge / etc.). 컴포넌트들은 \\`name\\` (user label) 를 가질 수 있음 — 이는 child\n component 의 속성이지 board root 의 속성이 아님.\n\nRules:\n - To change a board-level attribute (background, board size, 3D atmosphere)\n → call \\`modifyBoard({ patch: { fillStyle: ..., width: ..., sky: ..., exposure: ..., dirLight*: ..., hemi*: ... } })\\`.\n NOTE: 보드 라벨/제목 (\"보드 이름\") 은 scene model 이 아니라 Board *엔티티* 의 컬럼.\n things-scene 의 model-layer 는 \\`name\\` 을 인식하지 않음. modifyBoard 의 patch 에\n \\`name\\` 을 넣지 말 것 — 죽은 필드로 박힐 뿐 효과 없음.\n - To change a CHILD COMPONENT's attribute → call \\`modifyComponentByRefid\\`.\n - DO NOT use modifyBoard to change a child. DO NOT use modifyComponentByRefid\n to change board background.\n - \"보드 배경색\", \"board background\", \"테두리/캔버스 크기\" 같은 요청은 root\n attribute 변경 → \\`modifyBoard\\`.\n\n==== COMPONENT TREE (NESTING) ====\n컴포넌트는 *재귀 구조*. group / container 같은 부모 컴포넌트는 자기 \\`components\\`\n배열에 자식을 가질 수 있다. 자식이 또 group 일 수 있어 임의 깊이로 중첩 가능.\n\n가시성:\n - \\`summarizeBoard\\` (대화 시작 시 보여지는 보드 상태) 는 *평면 list* 로 모든\n 컴포넌트를 노출한다 — top-level 뿐 아니라 group/container 안 자식도 모두 포함.\n - 자식은 \\`_parentRefid\\` (부모 group refid) 와 \\`_depth\\` (중첩 깊이, 0=root) 메타\n 가 첨부되어 어느 group 안에 있는지 식별 가능.\n - \\`findComponents\\` 는 전체 트리를 search — group 안 자식까지 매칭. 특정 group\n 안만 좁히려면 \\`parentRefid\\` 필터 사용.\n - \\`getComponentByRefid\\` / \\`getComponentStyle\\` / \\`setFill\\` 등 모든 styling tool 의\n refid 매개변수는 *어느 깊이의* 컴포넌트든 받음. modify / remove op 도 deep search.\n\n테마 / 스타일 적용 시 룰:\n - \"북유럽스타일\", \"사이버펑크\" 등 테마 요청 → 보드의 *모든* 컴포넌트에 적용 — group\n 안 자식도 포함. 평면 list 그대로 색상 통일.\n - 사용자가 \"이 group 만\" / \"왼쪽 영역만\" 처럼 *범위 명시* 한 경우만 \\`findComponents\\`\n 의 \\`parentRefid\\` / \\`region\\` 으로 좁혀 그 자식들만 styling.\n - group 자체에 fillStyle 적용해도 자식에게 자동 전파 안 됨 — 자식 각각의 refid 로\n setFill 호출 필요.\n\n==== IDENTIFIER POLICY (CRITICAL) ====\nEach CHILD component has THREE identifier-like fields. Their roles differ:\n\n • \\`refid\\` (number) — INTERNAL SYSTEM HANDLE (things-scene auto-assigned).\n Always present, unique within a board. Use as tool\n argument ONLY. NEVER mention \"refid\" in user-facing\n reply text — users don't see it and it's confusing.\n\n • \\`id\\` (string) — DATA BINDING NAME. Optional. Multiple components MAY share\n the same id. Human-readable. OK to mention in replies\n (\"'motor-1' 컴포넌트\", \"id가 'motor-1' 인 것\").\n\n • \\`name\\` (string) — USER LABEL. Optional. Human-readable. Most user-friendly\n way to refer to a component in replies.\n\nRules:\n - In tool calls (modifyComponentByRefid, etc.) → pass refid as the argument.\n - In your TEXT REPLY to the user → refer to components by name (preferred)\n or id, NEVER by refid. Saying \"refid 35 를 변경했습니다\" is forbidden;\n say \"'경광등1' 을 변경했습니다\" or \"id 'motor-1' 컴포넌트를 변경했습니다\".\n - findComponents may return many matches by id (data binding group); that is correct.\n - User selection arrives as refids — that's an internal handle, treat it as opaque.\n - The BOARD itself does NOT have refid (only children do).\n\n==== USER MENTIONS (#token) ====\nThe user can write \\`#token\\` to reference a component (a SELECTOR, not a key).\nThe server pre-resolves these by matching name OR id OR type, and APPENDS a\n\"mention map\" block at the end of the user's message. Format:\n\n --- mention map (자동 첨부 — 사용자가 # 로 지칭한 컴포넌트) ---\n #경광등1 →\n { name='경광등1', id='motor-1', type='rect', refid=35 }\n #rect →\n { name='경광등1', id='motor-1', type='rect', refid=35 }\n { name='펌프', id='pump-1', type='rect', refid=42 }\n\nUse this map to resolve which refid(s) to pass to tool calls. The user's\nORIGINAL #token (e.g., \"#경광등1\") is preserved in the message body — refer\nto that wording in your reply. Do not echo refid back to the user.\n\n==== AVAILABLE TOOLS ====\nBoard-level (root attributes):\n - modifyBoard: 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 엔티티 컬럼.\n - replaceBoard: wholesale board reset (heavy — prefer modifyBoard for most changes)\nChild components — data:\n - addComponent: add a new component (parallel calls for multiple adds)\n - removeComponentByRefid: remove a child by refid\n - modifyComponentByRefid: edit a child's properties by refid (raw fallback — prefer specific styling tools below for any styling change)\n - getComponentByRefid: inspect full data of one child by refid\n - getSelection: return full data of components currently selected by the user\n - findComponents: search children by type/id/name/region — returns matches with refid\n\nComponent styling — PREFER these over modifyComponentByRefid:\n\n ⚠⚠⚠ ABSOLUTE RULE — 테마 요청 처리 ⚠⚠⚠\n 사용자 요청에 \"테마 / 스타일 / 분위기\" 류 단어가 포함된 경우 (\"북유럽스타일\",\n \"사이버펑크\", \"미니멀하게\", \"따뜻하게\", \"빈티지\", \"고급스럽게\", \"어울리게\" 등):\n ✅ 변경 OK — fillStyle / strokeStyle.color / shadow.color / fontColor /\n opacity / 3D material / sky / 광원 (= 색·재질·빛만)\n ❌ 변경 절대 금지 — text 내용 / fontSize / fontFamily / lineWidth / lineDash /\n lineCap / lineJoin / left / top / width / height / cx / cy / rx / ry /\n points / path / data / mappings / accessor / id / name (= 콘텐츠·디멘션·정보)\n 이 룰은 setText / setFont(size,family) / setStroke(width,dash) /\n modifyComponentByRefid 모두에 적용. 사용자가 \"텍스트도 바꿔\", \"두께도\",\n \"폰트 굵게\" 같이 *명시적으로 요청한 경우에만* 해당 도구 사용.\n 의심스러우면 색·재질·빛만 적용. 자세한 매트릭스는 THEMATIC STYLING SCOPE 섹션 참조.\n\n 도구 목록:\n - setFill: 컴포넌트 배경. mode (solid / gradient / pattern / image / none) + color / opacity / colorStops. mode 명시 시 fillStyle 통째 교체, 미지정 시 부분 update.\n - setStroke: 테두리. color / width / dash ('solid'|'dashed'|'dotted'|'dashdot' or number[]) / lineCap / lineJoin / opacity. enabled=false 로 제거.\n - setText: 텍스트 *내용* 변경 (state.text). 폰트는 setFont 별개. **테마 요청 시 호출 금지.**\n - setFont: 폰트 스타일. fontFamily / fontSize / fontWeight / fontStyle / fontColor / textAlign / textBaseline / lineHeight. **테마 요청 시 fontColor 만 OK.**\n - setShadow: 그림자. color / blur / offsetX / offsetY. enabled=false 로 제거.\n - setOpacity: 컴포넌트 전체 alpha (0..1).\n - setVisible: 표시/숨김 토글.\n - setMaterial: 3D PBR 재질. preset (default/metal/glass/plastic/wood/ceramic/rubber/custom) + metalness / roughness / emissive / emissiveIntensity / opacity / envMapIntensity / side. preset 만 = reset, preset + 속성 = override.\n - setShadowProperties: 3D castShadow / receiveShadow.\n - clearStyle: 특정 styling aspect 들 reset (preset / 데이터 바인딩 적용 전).\n\n Tool 선택 룰:\n 1. **테마 요청 → 위 ABSOLUTE RULE 먼저 확인. 텍스트·폰트크기·두께·치수·데이터 손대지 말 것.**\n 2. Fill 변경 → setFill (modifyComponentByRefid 사용 금지)\n 3. Stroke 변경 → setStroke\n 4. Text 내용 vs 스타일 명확히 구분 — setText / setFont 분리\n 5. 3D 재질 → setMaterial (preset 위주)\n 6. 여러 컴포넌트 동일 변경 → 한 tool 호출의 refids 배열로 (반복 호출 X)\n 7. 색상은 hex / rgb / CSS named ('red') / semantic ('warm-red', 'success', 'warning') 모두 가능\n 8. 위 tool 로 표현 안 되는 raw 속성 변경에만 modifyComponentByRefid 사용\nChild components — scene operations (Phase 2):\n - alignComponents: align multiple by edge/center (left/right/center/top/middle/bottom)\n - distributeComponents: even spacing along horizontal / vertical axis\n - groupComponents: combine multiple into a Group container (parent-child)\n - ungroupComponent: disband a Group (children move up to grandparent)\n - changeZorder: front / back / forward / backward for a single component\nModeller actions (ephemeral — does NOT modify the board model, no undo, no save):\n - selectComponents: change the user's current selection (pass [] to deselect all)\n - centerToComponent: move modeller view to center on a component\n - fitToView: reset view so the board fits the canvas (mode: fit/ratio/width/height)\n - setSceneMode: switch modeller between 'edit' and 'view' modes\nKnowledge:\n - getAtmosphereGuide: 3D atmosphere synthesis primer — parameter physics, ranges, color theory, archetype recipes (time-of-day / indoor / surreal). Call BEFORE applying atmospheric/styling modifyBoard for any natural-language mood request.\n\n==== 3D ATMOSPHERE SYNTHESIS ====\n3D 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 modifyBoard call.\n\nFor ANY natural-language atmospheric request — \"공장 분위기로\", \"심해 컬러\", \"황혼\", \"사이버펑크\", \"안개 자욱한 새벽\", \"1980 우주정거장\", \"따뜻하게\", \"차갑고 극적으로\" — follow this workflow:\n\n 1. Call getAtmosphereGuide first.\n 2. From the guide's \"archetypes\" section, pick the closest base recipe (time-of-day / indoor / surreal). Interpolate if user combines multiple cues.\n 3. Apply user's nuance via the guide's \"modifiers\" (warm/cool, drama, saturation, contrast).\n 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.\n 5. Apply ALL keys in ONE modifyBoard({patch}) call (sky, skyColor?, exposure, hemiIntensity, hemiSkyColor, hemiGroundColor, dirLightEnabled, dirLightColor, dirLightIntensity, dirLightFollowCamera=false, dirLightAzimuth, dirLightElevation, fillStyle?). ONE patch — not multiple modifyBoard calls.\n 6. In the reply, briefly state which archetype + modifier you composed.\n\nAvoid:\n - Calling modifyBoard with only \"fillStyle\" for atmospheric requests — that only changes 2D background and floor tint, NOT the 3D scene mood.\n - Mixing a sky preset with explicit skyColor (preset wins, skyColor ignored).\n - Setting dirLightAzimuth/Elevation while leaving dirLightFollowCamera=true (no effect — set follow=false first).\n - Using only canned presets when the user describes a custom mood — the guide enables synthesis beyond presets.\n\n==== THEMATIC STYLING — SCOPE DISCIPLINE ====\n\"테마\" 성격의 자연어 요청 (\"북유럽스타일로\", \"사이버펑크\", \"미니멀하게\", \"따뜻하게\",\n\"빈티지\", \"미래지향적으로\", \"고급스럽게\" 등) 은 **시각적 분위기**에만 적용한다.\n컴포넌트의 **치수·구조·레이아웃·정보 위계**는 건드리지 않는다.\n\n테마 요청 시 변경 OK — *visual aesthetics only*:\n - 색상 — fillStyle (solid/gradient/pattern), strokeStyle.color, shadow.color, fontColor\n - 투명/표시 — opacity, alpha\n - 3D — material preset/속성 (metalness/roughness/emissive), 보드 root 의 sky/exposure/광원\n - 보드 배경 fillStyle\n\n테마 요청 시 변경 금지 — *dimensions / structure / layout / information*:\n - 선 형태 — lineWidth / lineDash / lineCap / lineJoin (테두리 색상은 OK, 두께·점선\n 패턴은 디자인 의도를 가진 *구조*. 사용자가 \"두께도 바꿔\" 라고 명시 안 하면 손대지 말 것)\n - 모든 geometry — left/top/width/height/cx/cy/rx/ry/points/path/vertices\n - 폰트 크기·패밀리 — fontSize / fontFamily (정보 위계 영향. fontColor 만 OK)\n - **텍스트 / 데이터 / 정보** — state.text, gauge value/min/max, chart data, 라벨 문구,\n 데이터 바인딩 (mappings / accessor / dataSource / refresh), id / name / class / tag.\n 이것들은 *콘텐츠* 이지 *스타일* 이 아니다.\n - 정렬·z-order·group — alignComponents/distributeComponents/changeZorder/groupComponents\n\n이유: \"북유럽스타일\" 은 색·재질·빛의 일관성을 뜻하지, 선을 굵게 하거나 텍스트를\n바꾸는 게 아니다. 테마는 *형식 (form)* 의 영역이고 콘텐츠와 디멘션은 별개의 영역.\n사용자가 명시적으로 요청한 게 아니면 콘텐츠/디멘션에 손대지 말 것. 의심스러우면\n묻거나 색·재질 위주로만 적용.\n\n==== AVAILABLE COMPONENT TYPES (enum-enforced by tool schema) ====\n${typeLine}\n\n==== AVAILABLE GROUPS / CATEGORIES ====\n${catLine}\n\n==== COMPONENT SCHEMAS (type-specific geometry + properties) ====\n${schemaSection}\n\nCRITICAL — geometry discipline:\n- Each type has its OWN geometry keys, listed under \"geometry:\" above.\n- Use EXACTLY those keys for that type. Do NOT default to {left, top, width, height} for every type.\n Examples:\n rect/image/text: left, top, width, height\n circle/ellipse: cx, cy, rx (or radius), ry\n line/polyline: points or path or vertices array\n gauge-* may use left, top, width, height OR cx, cy depending on the variant.\n- Include ALL the geometry keys for the type with sensible numeric values (no undefined).\n- Include type-specific REQUIRED properties (gauge needs value/min/max, chart needs data, text needs text).\n\nCRITICAL — type discipline:\n- The \"type\" parameter is enum-restricted by the tool schema. Use ONLY values from the registered list.\n- If a domain concept (e.g., \"AGV\", \"Stocker\") is NOT in the list, pick the closest registered type or use a generic shape ('rect', 'ellipse', 'text') with descriptive fillStyle and a \"name\" field.\n\nBehavioral rules:\n- If the user is asking a question rather than commanding, REPLY in TEXT WITHOUT calling any tool.\n- If the user's request is ambiguous, REPLY in TEXT (asking for clarification) WITHOUT calling any tool.\n- For multiple components, call addComponent multiple times in parallel.\n- The current board JSON is provided as the first user message in the conversation.\n\nReply formatting rules (chat surface):\n- Reply ONCE with ONE form only. NEVER restate the same answer in a second form (e.g. do NOT add a prose summary after a bullet list, or vice versa).\n- Keep replies concise — chat-style, not document-style. Prefer 1–4 sentences or a short bullet list.\n- Use markdown for emphasis (**bold**, *italic*) and short lists. Avoid headings (#) and long structured documents.\n- Use the same language as the user's last message.`\n }\n}\n\n// ── Tool 정의 ──────────────────────────────────────────────────────\n\n/**\n * 4 op 직교 set 을 4 개의 도구로 정의.\n *\n * 핵심: addComponent 의 `type` 파라미터가 knownTypes 의 enum 으로 강제 →\n * LLM 이 등록 안 된 type 을 만들 수 없음 (provider 단계에서 차단).\n *\n * 좌표/크기 키들은 모두 optional 로 허용 (type 별로 사용 키 다름).\n * type-specific 추가 속성은 additionalProperties 로 허용.\n */\nexport function buildBoardEditTools(knownTypes: string[], exposure: ToolExposure = {}): AITool[] {\n const gate = buildToolGate(exposure)\n const typeProp: Record<string, any> = {\n type: 'string',\n description: 'Registered component type (must be from the enum).'\n }\n if (knownTypes.length > 0) {\n typeProp.enum = knownTypes\n }\n\n const componentSchema: Record<string, any> = {\n type: 'object',\n description: 'Component fields (geometry + style + type-specific properties).',\n properties: {\n type: typeProp,\n id: { type: 'string', description: 'Unique id within the board.' },\n // 좌상단 기반 박스 좌표\n left: { type: 'number' },\n top: { type: 'number' },\n width: { type: 'number' },\n height: { type: 'number' },\n rotation: { type: 'number' },\n // 중심 기반 좌표 (circle/ellipse 등)\n cx: { type: 'number' },\n cy: { type: 'number' },\n radius: { type: 'number' },\n rx: { type: 'number' },\n ry: { type: 'number' },\n // 경로 (line/polyline 등)\n points: { type: 'array', items: { type: 'object' } },\n // 일반 스타일\n fillStyle: { type: 'string', description: 'CSS color or pattern.' },\n strokeStyle: { type: 'string' },\n strokeWidth: { type: 'number' },\n strokeDashArray: { type: 'string' },\n opacity: { type: 'number' },\n name: { type: 'string', description: 'Optional human label.' }\n },\n required: ['type'],\n additionalProperties: true\n }\n\n const tools: AITool[] = [\n {\n name: 'addComponent',\n description:\n 'Add a new component to the board. Call this multiple times in parallel for multiple adds. Use the type-specific geometry keys (left/top vs cx/cy etc.) and include any required type-specific properties.',\n parameters: componentSchema\n },\n {\n name: 'removeComponentByRefid',\n description:\n 'Remove an existing component by its `refid` — the universal numeric handle that things-scene auto-assigns to every component (visible in board summary as the `refid` field of each component).',\n parameters: {\n type: 'object',\n properties: {\n refid: {\n type: 'number',\n description: 'things-scene auto-assigned numeric handle. Always present.'\n }\n },\n required: ['refid']\n }\n },\n {\n name: 'modifyComponentByRefid',\n description:\n 'Modify properties of an existing component by its `refid`. The patch is deep-merged with the existing component (style/position/size/3D material all in one). ⚠ 테마 요청 (북유럽/사이버펑크/미니멀 등) 시 patch 에 text / fontSize / fontFamily / lineWidth / lineDash / left / top / width / height / cx / cy / rx / ry / points / data / mappings / id / name 등 *콘텐츠·디멘션* 키 포함 금지 — fillStyle / strokeStyle.color / fontColor / shadow.color / opacity / 3D material 만 OK. setFill / setStroke / setMaterial / setShadow 등 전용 tool 사용을 우선 검토.',\n parameters: {\n type: 'object',\n properties: {\n refid: {\n type: 'number',\n description: 'things-scene auto-assigned numeric handle.'\n },\n patch: {\n type: 'object',\n description: 'Partial fields to merge.',\n additionalProperties: true\n }\n },\n required: ['refid', 'patch']\n }\n },\n // styling registry 에서 자동 도출 — setFill 부터 점진 이전 중.\n // 다음 tool 들은 registry 로 옮겨질 때마다 본 spread 가 자동 흡수.\n /* 스타일링도 보드 편집 능력 — 코어를 끈 대화(운영 도크)에는 노출하지 않는다. */\n ...(gate.coreOn ? buildStylingToolDefinitions() : []),\n // tool-registry plugin point — 외부 도메인 패키지 (board-import 등) 가\n // registerToolCategory() 로 등록한 모든 tool 의 LLM 정의를 spread.\n // styling 처럼 board-ai 코어 안에 정의되지 않고 외부에서 들어오는 카테고리들.\n ...buildExternalCategoryDefinitions(gate.filter),\n {\n name: 'getComponentStyle',\n description:\n \"Get the current STYLING state of a component (read-only). Useful before modifying styles to understand what's already applied (avoid blind overwrites). Returns fill / stroke / shadow / material3d / font / opacity / visibility / text. Use `aspects` to limit response size.\",\n parameters: {\n type: 'object',\n properties: {\n refid: { type: 'number' },\n aspects: {\n type: 'array',\n items: {\n type: 'string',\n enum: ['fill', 'stroke', 'shadow', 'material', 'font', 'opacity', 'visibility', 'text']\n },\n description: 'Limit response to specific aspects. Omit for all.'\n }\n },\n required: ['refid']\n }\n },\n {\n name: 'modifyBoard',\n description:\n \"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.\",\n parameters: {\n type: 'object',\n properties: {\n patch: {\n type: 'object',\n description:\n 'Root-level fields to merge into the board. Examples: { fillStyle: \"#0a1929\" } for dark navy background; { width: 1920, height: 1080 } for resize; { sky: \"studio\", exposure: 1.2 } for 3D atmosphere. Do NOT include `name` — that is the Board entity column, not a scene model field.',\n additionalProperties: true\n }\n },\n required: ['patch']\n }\n },\n {\n name: 'replaceBoard',\n description:\n '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 modifyBoard. Provide width/height and the full components array.',\n parameters: {\n type: 'object',\n properties: {\n width: { type: 'number' },\n height: { type: 'number' },\n fillStyle: { type: 'string' },\n components: {\n type: 'array',\n items: { type: 'object', additionalProperties: true }\n }\n },\n required: ['components']\n }\n },\n // ── Read tools (서버측 즉시 실행, 결과를 LLM 에 회신) ─────────\n {\n name: 'getSelection',\n description:\n 'Get full details of components currently selected by the user in the modeller. Call this when the user asks \"what is selected?\" / \"선택된 게 뭐냐?\" / refers to \"the selected component\" without specifying ids. Returns array of full component objects (no truncation).',\n parameters: { type: 'object', properties: {} }\n },\n {\n name: 'getComponentByRefid',\n description:\n 'Get full details of a single component by its `refid` (the things-scene-assigned universal numeric handle). Use this to inspect properties not visible in the board summary.',\n parameters: {\n type: 'object',\n properties: {\n refid: {\n type: 'number',\n description: 'things-scene auto-assigned numeric handle. Universal.'\n }\n },\n required: ['refid']\n }\n },\n {\n name: 'findComponents',\n description:\n 'Search components by criteria. Searches the entire board tree including children of group/container components. Returned components include `_parentRefid` and `_depth` meta when nested (depth > 0). All filters are optional and AND-combined. Returns matching components (capped at 50).',\n parameters: {\n type: 'object',\n properties: {\n type: { type: 'string', description: 'Match by exact type.' },\n id: {\n type: 'string',\n description:\n 'Match by exact data-binding id. Note: id is NOT unique — multiple components may share an id. Returns all matches.'\n },\n namePattern: {\n type: 'string',\n description: 'Case-insensitive substring match on the `name` field.'\n },\n parentRefid: {\n type: 'number',\n description:\n \"Limit search to children of this group/container refid only (one level — direct children). Use to scope a theme to a specific group's contents.\"\n },\n region: {\n type: 'object',\n description:\n 'Bounding box. Components whose left/top fall within are returned. Provide all 4 fields when used.',\n properties: {\n left: { type: 'number' },\n top: { type: 'number' },\n width: { type: 'number' },\n height: { type: 'number' }\n }\n }\n }\n }\n },\n {\n name: 'getAtmosphereGuide',\n description:\n \"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 modifyBoard 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.\",\n parameters: { type: 'object', properties: {} }\n },\n {\n name: 'getColorPalettes',\n description:\n \"Get the curated color palette catalog — 7 verified palettes (industrial-steel / financial-trader / control-room-dark / medical-clean / logistics-warm / neon-cyberpunk / paper-light), each with base/surface/border/text/muted/accent/success/warning/danger/info color tokens. Call this BEFORE applying colors to a dashboard whenever the user describes a domain or mood ('산업 분위기', '금융 대시보드', '관제실 느낌', '의료 차트', 'SF 사이버펑크'). Use the palette tokens consistently — do not invent free-form colors.\",\n parameters: { type: 'object', properties: {} }\n },\n {\n name: 'getLayoutTemplates',\n description:\n \"Get the curated dashboard layout templates — verified composition recipes (kpi-row / 3x3-grid / t-shape-command / side-rail / split-half / header-content-footer) with slot regions for component placement. Call this BEFORE arranging components on an empty/sparse board whenever the user describes a structural intent ('KPI 4개 상단에', '관제실 구도', '비교 화면', '3x3 그리드'). Use slot region coordinates directly with addPrefab/addComponent — no pixel guesswork.\",\n parameters: { type: 'object', properties: {} }\n },\n // ── Phase 2: Scene 조작 (model 차원 좌표/구조 변경) ─────────────\n {\n name: 'alignComponents',\n description:\n \"Align multiple components by their refids. Use for natural-language requests like '왼쪽 정렬', '가운데 정렬', '위쪽으로 맞춰', 'align left'. Operates on the things-scene level — the resulting coordinate adjustments are committed as a single undo step.\",\n parameters: {\n type: 'object',\n properties: {\n refids: {\n type: 'array',\n items: { type: 'number' },\n description:\n 'Component refids to align (2 or more). For \"selected\" intent, pass the user-selected refids.'\n },\n direction: {\n type: 'string',\n enum: ['left', 'right', 'center', 'top', 'middle', 'bottom'],\n description:\n 'Alignment edge/center: left/right/center for horizontal, top/middle/bottom for vertical.'\n }\n },\n required: ['refids', 'direction']\n }\n },\n {\n name: 'distributeComponents',\n description:\n \"Distribute multiple components evenly along an axis. Use for '간격 일정하게', 'evenly distribute'. Requires 3 or more components.\",\n parameters: {\n type: 'object',\n properties: {\n refids: {\n type: 'array',\n items: { type: 'number' },\n description: 'Component refids to distribute (3 or more recommended).'\n },\n axis: {\n type: 'string',\n enum: ['horizontal', 'vertical'],\n description: 'horizontal = even spacing along x; vertical = along y.'\n }\n },\n required: ['refids', 'axis']\n }\n },\n {\n name: 'groupComponents',\n description:\n \"Group multiple components into a single Group container. Use for '그룹화', '하나로 묶어'. The new Group becomes a parent; child components keep their relative positions.\",\n parameters: {\n type: 'object',\n properties: {\n refids: {\n type: 'array',\n items: { type: 'number' },\n description: 'Component refids to group (2 or more).'\n }\n },\n required: ['refids']\n }\n },\n {\n name: 'ungroupComponent',\n description:\n \"Disband a Group component — children are moved up to the Group's parent. Use for '그룹 해제', 'ungroup'.\",\n parameters: {\n type: 'object',\n properties: {\n refid: {\n type: 'number',\n description: 'refid of the Group component to ungroup.'\n }\n },\n required: ['refid']\n }\n },\n {\n name: 'changeZorder',\n description:\n \"Change a single component's z-order (front/back/forward/backward). Use for '맨 앞으로', '맨 뒤로', '한 단계 앞으로'.\",\n parameters: {\n type: 'object',\n properties: {\n refid: { type: 'number', description: 'Target component refid.' },\n direction: {\n type: 'string',\n enum: ['front', 'back', 'forward', 'backward'],\n description:\n 'front = bring to front, back = send to back, forward = step toward front, backward = step toward back.'\n }\n },\n required: ['refid', 'direction']\n }\n },\n // ── Sugar layout — high-level 배치 의도 (refids 의 left/top 만 변경) ─\n {\n name: 'arrangeInGrid',\n description:\n \"Arrange components into a grid layout. Use for '3x2 그리드로', '4열로 배치', 'arrange in grid'. Computes positions on the host based on each component's current width/height. Only left/top change — sizes preserved. Single undo step. The cell size = max(width)/max(height) across the refids; gap defaults to 10. anchor (top-left of the grid) defaults to the first component's current (left, top). Order in `refids` determines fill order (row-major).\",\n parameters: {\n type: 'object',\n properties: {\n refids: {\n type: 'array',\n items: { type: 'number' },\n description: 'Component refids in fill order (row-major).'\n },\n cols: {\n type: 'number',\n description: 'Number of columns. Rows are inferred from refids.length / cols.'\n },\n gap: {\n type: 'number',\n description: 'Spacing between cells in pixels (default 10).'\n },\n anchor: {\n type: 'object',\n description: 'Top-left of the grid. Default: first component current (left, top).',\n properties: {\n left: { type: 'number' },\n top: { type: 'number' }\n }\n }\n },\n required: ['refids', 'cols']\n }\n },\n {\n name: 'arrangeInRow',\n description:\n \"Arrange components into a single horizontal row, left-to-right in `refids` order. Use for '한 줄로', 'arrange in row'. Each next component is placed at (prev.left + prev.width + gap). align controls cross-axis (top): start = same top as anchor (default), center = vertically centered to tallest, end = bottom-aligned to tallest.\",\n parameters: {\n type: 'object',\n properties: {\n refids: {\n type: 'array',\n items: { type: 'number' },\n description: 'Component refids in left-to-right order.'\n },\n gap: { type: 'number', description: 'Horizontal spacing in pixels (default 10).' },\n anchor: {\n type: 'object',\n description: 'Start position. Default: first component current (left, top).',\n properties: {\n left: { type: 'number' },\n top: { type: 'number' }\n }\n },\n align: {\n type: 'string',\n enum: ['start', 'center', 'end'],\n description:\n 'Cross-axis (vertical) alignment within row. start = top-aligned (default), center = mid, end = bottom.'\n }\n },\n required: ['refids']\n }\n },\n {\n name: 'arrangeInColumn',\n description:\n \"Arrange components into a single vertical column, top-to-bottom in `refids` order. Use for '세로로 일렬', '위에서 아래로', 'arrange in column'. align controls cross-axis (left): start = same left as anchor (default), center = horizontally centered to widest, end = right-aligned to widest.\",\n parameters: {\n type: 'object',\n properties: {\n refids: {\n type: 'array',\n items: { type: 'number' },\n description: 'Component refids in top-to-bottom order.'\n },\n gap: { type: 'number', description: 'Vertical spacing in pixels (default 10).' },\n anchor: {\n type: 'object',\n description: 'Start position. Default: first component current (left, top).',\n properties: {\n left: { type: 'number' },\n top: { type: 'number' }\n }\n },\n align: {\n type: 'string',\n enum: ['start', 'center', 'end'],\n description:\n 'Cross-axis (horizontal) alignment within column. start = left-aligned (default), center = mid, end = right.'\n }\n },\n required: ['refids']\n }\n },\n // ── C-1: Scene 조작 (ephemeral — selection / view / mode) ───────\n {\n name: 'selectComponents',\n description:\n \"Change the user's selection in the modeller. Use for '이거 선택해' / '선택 풀어' / '이 컴포넌트들 선택' style requests. Pass empty array [] to deselect everything. This does NOT modify the board model — it only changes the modeller's current selection.\",\n parameters: {\n type: 'object',\n properties: {\n refids: {\n type: 'array',\n items: { type: 'number' },\n description: 'Refids to select. Empty array deselects all.'\n }\n },\n required: ['refids']\n }\n },\n {\n name: 'centerToComponent',\n description:\n \"Move the modeller's view to center on a specific component. Use for '이 컴포넌트로 이동' / '저거 화면 가운데로' / '여기 보여줘'. Ephemeral — does not modify model.\",\n parameters: {\n type: 'object',\n properties: {\n refid: { type: 'number', description: 'Target component refid to center.' },\n animated: {\n type: 'boolean',\n description: 'Animate the camera move (default true).'\n }\n },\n required: ['refid']\n }\n },\n {\n name: 'fitToView',\n description:\n \"Reset the modeller's view so the board fits the canvas. Use for '전체 보기' / '맞춰서 보여줘' / 'fit to screen'. Ephemeral.\",\n parameters: {\n type: 'object',\n properties: {\n mode: {\n type: 'string',\n enum: ['fit', 'ratio', 'width', 'height'],\n description:\n \"fit = best-fit (default), ratio = preserve aspect, width = fit width, height = fit height.\"\n }\n }\n }\n },\n {\n name: 'setSceneMode',\n description:\n \"Switch the modeller between edit and view modes. Use for '편집 모드' / '뷰어 모드' / '읽기전용으로 전환'. Ephemeral.\",\n parameters: {\n type: 'object',\n properties: {\n mode: {\n type: 'string',\n enum: ['edit', 'view'],\n description: 'edit = full editing, view = read-only viewer.'\n }\n },\n required: ['mode']\n }\n },\n // ── Prefab — 검증된 복합 컴포넌트 카탈로그 ────────────────────\n {\n name: 'getAvailablePrefabs',\n description:\n \"List curated high-quality prefab modules — composed multi-component widgets like 'monitor-card', 'gauge-panel', 'stat-tile'. Call this BEFORE adding individual primitives whenever the user asks for a domain-meaningful unit ('온도 모니터링 카드', 'AGV 상태판', 'KPI 타일', 'sensor card', 'dashboard tile'). Each prefab has name/description/keywords/defaultSize. Then use addPrefab(name, ...) to instantiate.\",\n parameters: {\n type: 'object',\n properties: {\n category: {\n type: 'string',\n description: 'Optional category filter (e.g. \"monitoring\", \"kpi\", \"control\").'\n },\n keywordPattern: {\n type: 'string',\n description:\n 'Optional case-insensitive substring match against name/description/keywords.'\n }\n }\n }\n },\n {\n name: 'addPrefab',\n description:\n \"Instantiate a registered prefab at a position. Prefer this over addComponent when the user describes a domain-meaningful unit ('모니터링 카드 하나 추가', 'KPI 타일'). The prefab is added as a single group component (one undo step). Supports per-prefab options (title/value/fillStyle etc.) — see the prefab description from getAvailablePrefabs.\",\n parameters: {\n type: 'object',\n properties: {\n name: {\n type: 'string',\n description: 'Prefab name from getAvailablePrefabs (e.g. \"monitor-card\").'\n },\n left: { type: 'number', description: 'X anchor (top-left origin).' },\n top: { type: 'number', description: 'Y anchor.' },\n width: {\n type: 'number',\n description: 'Optional override of prefab defaultSize.width.'\n },\n height: {\n type: 'number',\n description: 'Optional override of prefab defaultSize.height.'\n },\n options: {\n type: 'object',\n description:\n 'Prefab-specific customization (title, value, fillStyle, accent, etc.). See each prefab description for accepted keys.',\n additionalProperties: true\n }\n },\n required: ['name', 'left', 'top']\n }\n }\n ]\n\n /* 코어(보드 편집) 도구를 끈 대화는 **외부 카테고리 도구만** 남긴다.\n * 배열 리터럴 안 어디에 있든 이름 기준으로 걸러 누락이 없게 한다. */\n if (!gate.coreOn) {\n const externalNames = new Set(getToolSpecsFor(gate.filter).map(spec => spec.name))\n return tools.filter(tool => externalNames.has(tool.name))\n }\n return tools\n}\n\n// ── Read tool 분류 + 실행기 ────────────────────────────────────────\n\nconst READ_TOOL_NAMES = new Set([\n 'getSelection',\n 'getComponentByRefid',\n 'getComponentStyle',\n 'findComponents',\n 'getAtmosphereGuide',\n 'getAvailablePrefabs',\n 'getColorPalettes',\n 'getLayoutTemplates'\n])\nconst WRITE_TOOL_NAMES = new Set([\n 'addComponent',\n 'removeComponentByRefid',\n 'modifyComponentByRefid',\n // Styling Tier 1 — 컴포넌트 보편 스타일링\n 'setFill',\n 'setStroke',\n 'setText',\n 'setFont',\n 'setShadow',\n 'setOpacity',\n 'setVisible',\n 'setMaterial',\n 'setShadowProperties',\n 'clearStyle',\n 'copyStyle',\n 'modifyBoard',\n 'replaceBoard',\n // Phase 2 — model 차원 scene 조작 (좌표/구조/zorder)\n 'alignComponents',\n 'distributeComponents',\n 'groupComponents',\n 'ungroupComponent',\n 'changeZorder',\n // Prefab — 검증된 복합 컴포넌트 한 번에 추가\n 'addPrefab',\n // Sugar layout — high-level 의도 표현 (grid/row/column)\n 'arrangeInGrid',\n 'arrangeInRow',\n 'arrangeInColumn'\n])\n/**\n * C-1 — ephemeral scene 조작 (selection / view / mode). model 변경 X, undo 영향 X.\n * 별도 ChatResponse.actions 채널로 전달 → 호스트가 board-action-execute 로 적용.\n */\nconst ACTION_TOOL_NAMES = new Set([\n 'selectComponents',\n 'centerToComponent',\n 'fitToView',\n 'setSceneMode'\n])\n\nconst FIND_COMPONENTS_CAP = 50\n\n/**\n * Read tool 의 서버측 실행기 — currentBoard / selectedRefids 에 대해 즉시 실행해 결과 반환.\n * LLM 의 다음 turn 에 tool_result 로 회신된다.\n *\n * 식별자 정책:\n * - 컴포넌트 targeting 은 항상 refid (universal numeric handle).\n * - id 는 데이터 바인딩 이름이며 unique 가 아니다 — filter 용도로만 사용 (findComponents).\n */\nexport function executeReadTool(\n call: AIToolCall,\n currentBoard: BoardModel | null | undefined,\n selectedRefids: number[]\n): any {\n const board = currentBoard\n // 평면 view — group / container 자식 포함. AI 가 hierarchy 무관하게 모든\n // 컴포넌트 인지 가능. (top-level 만 보던 옛 동작 → 자식 누락 사고 방지)\n const flatComponents = collectAllComponents(board).map(f => f.component)\n\n switch (call.name) {\n case 'getSelection': {\n if (selectedRefids.length === 0) {\n return { selected: [], message: 'No component is currently selected.' }\n }\n const matched = flatComponents.filter(\n c => c && typeof (c as any).refid === 'number' && selectedRefids.includes((c as any).refid)\n )\n return { selected: matched, count: matched.length, selectedRefids }\n }\n case 'getComponentByRefid': {\n const refid = call.arguments?.refid\n if (typeof refid !== 'number') return { error: 'refid (number) is required' }\n const f = findComponentByRefid(board, refid)\n if (!f) return { error: `Component with refid ${refid} not found.` }\n return { component: f.component }\n }\n case 'getComponentStyle': {\n const refid = call.arguments?.refid\n const aspects = call.arguments?.aspects\n if (typeof refid !== 'number') return { error: 'refid (number) is required' }\n const f = findComponentByRefid(board, refid)\n if (!f) return { error: `Component with refid ${refid} not found.` }\n return { style: buildComponentStyleSummary(f.component, aspects) }\n }\n case 'findComponents': {\n const args = call.arguments ?? {}\n const type = typeof args.type === 'string' ? args.type : undefined\n const namePattern =\n typeof args.namePattern === 'string' && args.namePattern.length > 0\n ? args.namePattern.toLowerCase()\n : undefined\n const idFilter = typeof args.id === 'string' && args.id.length > 0 ? args.id : undefined\n const parentRefidFilter =\n typeof args.parentRefid === 'number' ? args.parentRefid : undefined\n const region =\n args.region &&\n typeof args.region === 'object' &&\n typeof args.region.left === 'number' &&\n typeof args.region.top === 'number' &&\n typeof args.region.width === 'number' &&\n typeof args.region.height === 'number'\n ? args.region\n : undefined\n\n // 평면 view 로 search — group/container 자식까지 매칭. parentRefid 메타도 함께.\n const flat = collectAllComponents(board)\n const matched = flat.filter(({ component: c, parentRefid }) => {\n if (!c) return false\n if (type && (c as any).type !== type) return false\n if (idFilter && (c as any).id !== idFilter) return false\n if (parentRefidFilter !== undefined && parentRefid !== parentRefidFilter) return false\n if (namePattern) {\n const name = typeof (c as any).name === 'string' ? (c as any).name.toLowerCase() : ''\n if (!name.includes(namePattern)) return false\n }\n if (region) {\n const left = typeof (c as any).left === 'number' ? (c as any).left : (c as any).cx\n const top = typeof (c as any).top === 'number' ? (c as any).top : (c as any).cy\n if (typeof left !== 'number' || typeof top !== 'number') return false\n if (\n left < region.left ||\n left > region.left + region.width ||\n top < region.top ||\n top > region.top + region.height\n ) {\n return false\n }\n }\n return true\n })\n\n // 결과에 parentRefid / depth 메타 포함 — AI 가 어느 그룹 안인지 인지\n const results = matched.slice(0, FIND_COMPONENTS_CAP).map(f => {\n const c: any = { ...f.component }\n if (f.depth > 0) {\n c._parentRefid = f.parentRefid\n c._depth = f.depth\n }\n return c\n })\n\n return {\n components: results,\n totalMatched: matched.length,\n truncated: matched.length > FIND_COMPONENTS_CAP\n }\n }\n case 'getAtmosphereGuide':\n return ATMOSPHERE_GUIDE\n case 'getAvailablePrefabs': {\n const args = call.arguments ?? {}\n const filter: { category?: string; keywordPattern?: string } = {}\n if (typeof args.category === 'string' && args.category.length > 0) {\n filter.category = args.category\n }\n if (typeof args.keywordPattern === 'string' && args.keywordPattern.length > 0) {\n filter.keywordPattern = args.keywordPattern\n }\n const prefabs = listBoardPrefabs(filter)\n return { prefabs, count: prefabs.length }\n }\n case 'getColorPalettes':\n return COLOR_PALETTES\n case 'getLayoutTemplates':\n return LAYOUT_TEMPLATES\n default:\n return { error: `Unknown read tool: ${call.name}` }\n }\n}\n\n/**\n * 3D 분위기 합성 지식 primer.\n *\n * 의도 — preset 한 단어로 끝나지 않는 사용자 요청 (\"심해\", \"황혼\", \"1980 우주정거장\",\n * \"안개 새벽\") 에 AI 가 구체적 파라미터 값을 직접 합성하도록 물리/색채/미학 지식\n * 동시 제공. AI 는 이 가이드를 받은 뒤 modifyBoard 로 한 번에 적용.\n *\n * things-scene 의 board model 에 들어가는 root level 키만 다룸 (modifyBoard 로\n * 적용 가능한 것). camera position 같은 ephemeral 한 것은 별도 영역.\n */\nconst ATMOSPHERE_GUIDE = {\n overview:\n '3D 보드 분위기는 (1) sky preset 또는 단색 (2) tone mapping exposure (3) hemisphere ambient (4) directional sun/key (5) floor 의 조합. 모두 board root model 의 속성이라 modifyBoard 단일 op 로 한 번에 적용. 자연어 요청은 archetype 레시피를 base 로 잡고 modifier 로 fine-tune.',\n\n parameters: {\n sky: {\n description:\n '3D 배경 + IBL (image-based lighting) 의 source. preset / \"color\" / \"\" 셋 중 하나.',\n presets: {\n studio: 'Neutral white studio with soft IBL — product-photo / showroom 분위기',\n warehouse: 'Indoor industrial space — moderate ambient, warm-tinted',\n factory: 'Bright factory floor — high ceiling lights, ~6000K cool',\n office: 'Clean office interior — neutral fluorescent feel',\n home: 'Warm domestic interior',\n sunny: 'Outdoor clear day — Three.js Sky shader, strong directional sun',\n cloudy: 'Outdoor overcast — soft diffuse, low contrast',\n rainy: 'Outdoor rainy — dim, cool, very diffuse'\n },\n special: {\n color: '단색 배경 (skyColor 같이 지정). IBL 없음 — hemi/dir 만 유효.',\n '\"\"': 'no background, no IBL. 거의 안 씀.'\n },\n tip: '커스텀 분위기는 sky=\"color\" + skyColor + hemi/dir 수동 튜닝 조합. preset 위에 hemi 등을 덮어쓰면 IBL 과 ambient 가 섞여 의도 흐려질 수 있다.'\n },\n skyColor: {\n description: 'sky=\"color\" 일 때 단색 배경. hex string.',\n examples: {\n '#0a1929': 'deep navy — 심해, 우주, 어두운 SF',\n '#1a2540': 'midnight blue — 밤, 차가운 미래',\n '#2c1b3d': 'deep violet — magical, mystical',\n '#3a4a3a': 'forest moss — 자연, 안개숲',\n '#f5e6d0': 'cream warm — 빈티지, 70년대',\n '#0a0a0a': 'pure dark — 드라마, 미니멀'\n }\n },\n exposure: {\n description: 'tone mapping exposure (ACESFilmic). 카메라 노출과 동일 개념.',\n range: '0.4 ~ 2.5 (sane), default ~1.2',\n bands: {\n '< 0.7': 'dim — 동굴, 심해, 음울, 야간',\n '0.7 ~ 1.0': 'subdued — 황혼, 안개, 침착',\n '1.0 ~ 1.4': 'balanced — 일반 실내/실외',\n '1.4 ~ 2.0': 'bright — 쇼룸, 한낮, 클린룸',\n '> 2.0': 'over — 매우 주의 (washout)'\n },\n pitfall: 'exposure 만 올리고 hemi/dir 도 동시에 올리면 wash 되어 평면화. 한쪽만 손대는 게 깔끔.'\n },\n hemisphere: {\n description:\n 'Hemisphere light = 위(sky)/아래(ground) 두 색을 보간한 ambient. 환경의 base 색조 결정.',\n keys: {\n hemiIntensity: '0 ~ 10, default 4. 높을수록 wash, 낮을수록 contrast.',\n hemiSkyColor: 'hex. 위에서 내려오는 빛 색조 (sky 의 색).',\n hemiGroundColor: 'hex. 아래에서 올라오는 반사 색 (floor / ground 의 bounce).'\n },\n tip: 'sky/ground 색 차이가 크면 environmental tint 강조 (예: sky=warm orange, ground=cool blue → 일출 분위기). 비슷하면 평탄한 ambient.'\n },\n directional: {\n description: 'Directional light = 태양/key light. 하나만 존재. 그림자 source.',\n keys: {\n dirLightEnabled: 'boolean. 태양 on/off. 야간 / 동굴 / 우주 등은 false.',\n dirLightColor:\n 'hex. 색온도 — 0xfff0d0 따뜻 (~3000K), 0xffffff 중성, 0xd0e0ff 차가움 (~7000K).',\n dirLightIntensity: '0 ~ 5, default 2. dramatic 은 높이고 hemi 낮춤.',\n dirLightAzimuth:\n '도. 0=북, 90=동, 180=남, 270=서. dirLightFollowCamera=false 일 때만 유효.',\n dirLightElevation: '도. 0=수평선, 90=정수리. 일출/석양 5–15, 한낮 70–90.',\n dirLightFollowCamera: 'true 면 카메라에 묶임 (편집 편의), false 면 world-fixed (sim 자연).'\n },\n sunPhysics: {\n dawn: 'elevation 10–20, color #ffb070 (warm orange), intensity 1.0–1.5',\n goldenHour: 'elevation 15–25, color #ffaf60 (saturated warm), intensity 2.0–2.5',\n noon: 'elevation 80–90, color #ffffff (neutral), intensity 2.8–3.5',\n sunset: 'elevation 5–15, color #ff7050 (red-orange), intensity 1.5–2.0',\n moonlight: 'elevation 60–80, color #a0b0d0 (cool blue), intensity 0.4–0.7'\n }\n },\n shadow: {\n keys: {\n dirShadowEnabled: 'boolean. drama 위해 on, exposure < 0.7 이면 의미 약함.',\n dirShadowBias: 'small negative (-0.0005 default). artifact 시 -0.001 정도 시도.'\n }\n },\n floor: {\n keys: {\n floorMaterial3d: '바닥 재질 preset (rubber/concrete/wood/metal/... — 도메인 별 등록).',\n fillStyle:\n '보드 배경 색 + preset 없을 때 floor tint. 3D 에서는 ground color 와 시각적으로 묶임.'\n }\n },\n camera: {\n keys: {\n fov: '30 ~ 75, default ~45. 낮으면 telephoto/compressed (드라마틱), 높으면 wide-angle.',\n near: '클리핑 near plane.',\n far: '클리핑 far plane (큰 보드면 5000+).'\n }\n }\n },\n\n archetypes: {\n timeOfDay: {\n dawn: {\n description: '해 뜨기 직전 — 차분, 기대감, 청량 + 약한 따뜻함',\n patch: {\n sky: 'color',\n skyColor: '#a0b8d0',\n exposure: 0.85,\n hemiIntensity: 3,\n hemiSkyColor: '#ffd0a0',\n hemiGroundColor: '#3a3040',\n dirLightEnabled: true,\n dirLightColor: '#ffb070',\n dirLightIntensity: 1.2,\n dirLightFollowCamera: false,\n dirLightElevation: 12,\n dirLightAzimuth: 80\n }\n },\n goldenHour: {\n description: '황금시간 — 따뜻, 풍부, 영화적',\n patch: {\n sky: 'sunny',\n exposure: 1.3,\n hemiIntensity: 4,\n hemiSkyColor: '#ffd5a0',\n hemiGroundColor: '#5a4030',\n dirLightEnabled: true,\n dirLightColor: '#ffaf60',\n dirLightIntensity: 2.2,\n dirLightFollowCamera: false,\n dirLightElevation: 20,\n dirLightAzimuth: 250\n }\n },\n noon: {\n description: '한낮 — 밝고 또렷, 사실적',\n patch: {\n sky: 'sunny',\n exposure: 1.4,\n hemiIntensity: 5,\n hemiSkyColor: '#cfe7ff',\n hemiGroundColor: '#5a5550',\n dirLightEnabled: true,\n dirLightColor: '#ffffff',\n dirLightIntensity: 3.0,\n dirLightFollowCamera: false,\n dirLightElevation: 85,\n dirLightAzimuth: 180\n }\n },\n dusk: {\n description: '황혼 — melancholy, 따뜻한 노을',\n patch: {\n sky: 'color',\n skyColor: '#3a4a6a',\n exposure: 0.95,\n hemiIntensity: 2.5,\n hemiSkyColor: '#a070a0',\n hemiGroundColor: '#2a2030',\n dirLightEnabled: true,\n dirLightColor: '#ff7050',\n dirLightIntensity: 1.6,\n dirLightFollowCamera: false,\n dirLightElevation: 8,\n dirLightAzimuth: 270\n }\n },\n night: {\n description: '밤 — 정적, 차가움, 달빛',\n patch: {\n sky: 'color',\n skyColor: '#0a0e1a',\n exposure: 0.7,\n hemiIntensity: 1.5,\n hemiSkyColor: '#3a4060',\n hemiGroundColor: '#0a0a14',\n dirLightEnabled: true,\n dirLightColor: '#a0b0d0',\n dirLightIntensity: 0.5,\n dirLightFollowCamera: false,\n dirLightElevation: 70,\n dirLightAzimuth: 200\n }\n }\n },\n\n indoor: {\n studioShowroom: {\n description: '스튜디오 / 매장 — 깨끗, 균일, 제품-photo',\n patch: {\n sky: 'studio',\n exposure: 1.3,\n hemiIntensity: 4.5,\n hemiSkyColor: '#ffffff',\n hemiGroundColor: '#a0a0a0',\n dirLightEnabled: true,\n dirLightColor: '#ffffff',\n dirLightIntensity: 2.0,\n dirLightFollowCamera: false,\n dirLightElevation: 70,\n dirLightAzimuth: 135\n }\n },\n industrialFactory: {\n description: '공장 — 기능적, 밝음, 약간 차가움',\n patch: {\n sky: 'factory',\n exposure: 1.2,\n hemiIntensity: 4.5,\n hemiSkyColor: '#e8eef5',\n hemiGroundColor: '#404040',\n dirLightEnabled: true,\n dirLightColor: '#f0f5ff',\n dirLightIntensity: 2.5,\n dirLightFollowCamera: false,\n dirLightElevation: 80,\n dirLightAzimuth: 90\n }\n },\n hospitalCleanroom: {\n description: '병원/클린룸 — 매우 밝음, 차갑고 균일',\n patch: {\n sky: 'studio',\n exposure: 1.5,\n hemiIntensity: 6,\n hemiSkyColor: '#ffffff',\n hemiGroundColor: '#d8e0e8',\n dirLightEnabled: true,\n dirLightColor: '#ffffff',\n dirLightIntensity: 1.5,\n dirLightFollowCamera: false,\n dirLightElevation: 90,\n dirLightAzimuth: 0\n }\n },\n cyberpunkLab: {\n description: '사이버펑크 실험실 — 네온, 마젠타+시안, 어두움',\n patch: {\n sky: 'color',\n skyColor: '#0a0a1a',\n exposure: 1.0,\n hemiIntensity: 3,\n hemiSkyColor: '#5040a0',\n hemiGroundColor: '#003a4a',\n dirLightEnabled: true,\n dirLightColor: '#a040c0',\n dirLightIntensity: 1.8,\n dirLightFollowCamera: false,\n dirLightElevation: 50,\n dirLightAzimuth: 135\n }\n }\n },\n\n surreal: {\n deepOcean: {\n description: '심해 — 차가운 청록, 위에서 약하게 비치는 빛',\n patch: {\n sky: 'color',\n skyColor: '#0a1929',\n exposure: 0.7,\n hemiIntensity: 2,\n hemiSkyColor: '#1a4060',\n hemiGroundColor: '#050a14',\n dirLightEnabled: true,\n dirLightColor: '#5080a0',\n dirLightIntensity: 0.8,\n dirLightFollowCamera: false,\n dirLightElevation: 75,\n dirLightAzimuth: 90,\n fillStyle: '#0a1929'\n }\n },\n mistyForest: {\n description: '안개 자욱한 숲 — 매우 diffuse, 채도 낮음',\n patch: {\n sky: 'cloudy',\n exposure: 0.95,\n hemiIntensity: 4,\n hemiSkyColor: '#c0d0c8',\n hemiGroundColor: '#3a4a3a',\n dirLightEnabled: true,\n dirLightColor: '#e0e0d0',\n dirLightIntensity: 0.8,\n dirLightFollowCamera: false,\n dirLightElevation: 35,\n dirLightAzimuth: 100\n }\n },\n deepSpace: {\n description: '우주 / SF — 검은 배경, 차갑고 강한 key',\n patch: {\n sky: 'color',\n skyColor: '#020205',\n exposure: 0.95,\n hemiIntensity: 0.5,\n hemiSkyColor: '#1a2040',\n hemiGroundColor: '#000005',\n dirLightEnabled: true,\n dirLightColor: '#ffffff',\n dirLightIntensity: 3,\n dirLightFollowCamera: false,\n dirLightElevation: 30,\n dirLightAzimuth: 70\n }\n },\n vintage70s: {\n description: '70년대 빈티지 — 따뜻한 베이지, 부드러운 그림자',\n patch: {\n sky: 'color',\n skyColor: '#d8b890',\n exposure: 1.15,\n hemiIntensity: 3.5,\n hemiSkyColor: '#f5d8a8',\n hemiGroundColor: '#705038',\n dirLightEnabled: true,\n dirLightColor: '#ffd098',\n dirLightIntensity: 1.8,\n dirLightFollowCamera: false,\n dirLightElevation: 45,\n dirLightAzimuth: 135\n }\n }\n }\n },\n\n modifiers: {\n warmCool:\n 'warm 으로 가려면 hemiSkyColor / dirLightColor 를 +30° hue red 방향. cool 은 반대.',\n drama:\n 'drama 강조 — hemiIntensity 낮추고 dirLightIntensity 올림. 그림자 강해짐.',\n saturation:\n 'vivid — 색채 그대로 유지하고 hemi 약간 낮춰 dir 가 punch 하게. muted — hemi 올리고 채도 낮은 색.',\n contrast:\n 'high — exposure 1.0 이하 + dir 강하게. low — exposure 1.3 이상 + hemi 강하게.'\n },\n\n workflow: [\n '1. 사용자 요청에서 archetype 키워드 식별 (시간대 / 실내 / 초현실 카테고리).',\n '2. archetypes 에서 가장 가까운 base 레시피 선택.',\n '3. modifiers 로 사용자 요청 뉘앙스 fine-tune (warm/cool/drama/...).',\n '4. sanity check — exposure × hemi × dir 어느 한쪽 극단 아닌지, hemi sky/ground 색 모순 없는지.',\n \"5. modifyBoard({ patch: { ...combined keys... } }) 한 번에 적용. 사용자에게 어떤 archetype + modifier 조합으로 갔는지 한 줄로 설명.\"\n ],\n\n pitfalls: [\n 'sky preset 위에 skyColor 같이 지정하면 preset 이 우선 (skyColor 무시).',\n 'exposure 와 hemi/dir 모두 max 면 washout. 한 쪽만 강하게.',\n 'dirLightEnabled=false 인데 dirLight 색/강도 설정해도 효과 없음.',\n 'dirLightFollowCamera=true 일 땐 azimuth/elevation 무의미 — false 로 바꿔야 적용.',\n \"fillStyle 만 바꾸면 floor tint 도 같이 바뀜 (floor preset 없을 때). 의도 없으면 floorMaterial3d 같이 점검.\"\n ]\n}\n\n/**\n * 색 팔레트 카탈로그 — 검증된 디자인 시스템 (industrial / financial /\n * control-room / medical / logistics / cyberpunk / paper).\n *\n * 의도: LLM 이 자유 색 작곡 (#3b82f6 + 보색?) 하지 않고 도메인에 맞는 검증된\n * 팔레트에서 고름. 결과 일관성 ↑, 비용 0, atmosphere primer 와 시너지.\n *\n * 사용 흐름:\n * 1. 사용자 의도 (산업 / 금융 / 의료 / SF / ...) 식별\n * 2. recommendations 에서 매칭 후보 1~2개 추림\n * 3. modifyBoard 로 board.fillStyle 을 palette.base 로 설정\n * 4. addPrefab / addComponent 시 palette 의 surface/accent/text 사용\n * 5. 일관된 룩 → 한 번 정한 팔레트 안에서만 색 선택\n *\n * 키 정의:\n * - base: 보드 / 큰 영역 background\n * - surface: 카드 / 패널 background (base 보다 1tier 밝음/어두움)\n * - border: subtle 경계선\n * - text: primary 본문\n * - muted: secondary 라벨 / 보조 텍스트\n * - accent: primary 강조 (값 / action / link)\n * - success/warning/danger/info: status 4종 (KPI 색상)\n */\nconst COLOR_PALETTES = {\n overview:\n '대시보드 색은 도메인에 따라 검증된 팔레트 7종 중 하나를 선택. 한 보드 안에서 같은 팔레트만 사용 → 일관성. 자유 색 조합은 보통 inconsistent — 카탈로그에서 골라 써라.',\n\n palettes: {\n 'industrial-steel': {\n description: '제조 / 공장 / 산업현장 — 차분한 강철색 + 강조용 cyan',\n moods: ['신뢰감', '엔지니어링', '차분', '기능적'],\n base: '#0f1722',\n surface: '#1a2332',\n border: '#2a3a52',\n text: '#e2e8f0',\n muted: '#94a3b8',\n accent: '#4fc3f7',\n success: '#10b981',\n warning: '#f59e0b',\n danger: '#ef4444',\n info: '#3b82f6'\n },\n 'financial-trader': {\n description: '금융 / 트레이딩 — 짙은 navy 위에 gold 강조, 상승 green / 하락 red',\n moods: ['프리미엄', '집중', '데이터 밀도'],\n base: '#0a0e1a',\n surface: '#131a2e',\n border: '#1f2a44',\n text: '#f1f5f9',\n muted: '#64748b',\n accent: '#fbbf24',\n success: '#22c55e',\n warning: '#eab308',\n danger: '#dc2626',\n info: '#60a5fa'\n },\n 'control-room-dark': {\n description: 'NOC / 관제실 — pure black + 네온 cyan/magenta 강조',\n moods: ['drama', 'mission-critical', 'high-contrast'],\n base: '#000000',\n surface: '#0a0a0a',\n border: '#1f1f1f',\n text: '#ffffff',\n muted: '#a3a3a3',\n accent: '#06b6d4',\n success: '#10b981',\n warning: '#f97316',\n danger: '#dc2626',\n info: '#a855f7'\n },\n 'medical-clean': {\n description: '의료 / 헬스케어 — soft white 위에 신뢰감 있는 blue / teal',\n moods: ['청결', '신뢰', '평온', '따뜻함'],\n base: '#f8fafc',\n surface: '#ffffff',\n border: '#e2e8f0',\n text: '#1e293b',\n muted: '#64748b',\n accent: '#0ea5e9',\n success: '#14b8a6',\n warning: '#f59e0b',\n danger: '#e11d48',\n info: '#3b82f6'\n },\n 'logistics-warm': {\n description: '물류 / 운송 — 따뜻한 baseline + amber 강조',\n moods: ['활동적', '에너지', '포근'],\n base: '#1c1410',\n surface: '#2a1f17',\n border: '#3d2e22',\n text: '#fef3c7',\n muted: '#a8916b',\n accent: '#f59e0b',\n success: '#84cc16',\n warning: '#fb923c',\n danger: '#dc2626',\n info: '#06b6d4'\n },\n 'neon-cyberpunk': {\n description: 'SF / 사이버펑크 — 새까만 배경 + magenta + cyan 네온',\n moods: ['미래적', 'edgy', 'attention-grabbing'],\n base: '#050008',\n surface: '#0d0118',\n border: '#1f0a35',\n text: '#f0e6ff',\n muted: '#7e6b96',\n accent: '#ec4899',\n success: '#22d3ee',\n warning: '#fde047',\n danger: '#ef4444',\n info: '#a78bfa'\n },\n 'paper-light': {\n description: '프레젠테이션 / 보고서 — 종이 느낌 light + 부드러운 ink',\n moods: ['클래식', '읽기 편함', '인쇄 친화'],\n base: '#fafaf9',\n surface: '#ffffff',\n border: '#e7e5e4',\n text: '#1c1917',\n muted: '#78716c',\n accent: '#1e40af',\n success: '#15803d',\n warning: '#a16207',\n danger: '#991b1b',\n info: '#0369a1'\n }\n },\n\n recommendations: {\n monitoring: ['industrial-steel', 'control-room-dark'],\n kpi: ['financial-trader', 'logistics-warm'],\n control: ['industrial-steel', 'neon-cyberpunk'],\n medical: ['medical-clean'],\n presentation: ['paper-light'],\n futuristic: ['neon-cyberpunk', 'control-room-dark'],\n classic: ['paper-light', 'industrial-steel']\n },\n\n workflow: [\n '1. 사용자 도메인 / 분위기 키워드 식별 — 산업/금융/관제/의료/SF/프레젠테이션',\n '2. recommendations 에서 매칭 후보 추림. 사용자 모호하면 가장 흔한 industrial-steel 디폴트.',\n \"3. modifyBoard({ patch: { fillStyle: palette.base } }) 으로 보드 배경 set.\",\n '4. 이후 모든 add / addPrefab 호출 시 palette.surface / accent / text / border 사용. 자유 색 X.',\n '5. status 표시는 success / warning / danger / info 4종에서만 — 자체 hex 만들지 마라.'\n ],\n\n pitfalls: [\n '한 보드 안에서 두 팔레트 섞으면 정신없음 — 한 번 정했으면 끝까지 그것만.',\n 'light palette (medical-clean, paper-light) 위에 dark prefab 옵션 넣으면 가독성 무너짐. fillStyle 같이 갱신.',\n 'accent 는 강조용 — 모든 텍스트에 쓰지 마라. 1~2개 핵심 값에만.',\n 'control-room-dark 에서 success(#10b981) 만 강조하면 화면 단조로움. accent(cyan) + status 색 섞어 써라.'\n ]\n}\n\n/**\n * Layout 템플릿 카탈로그 — 검증된 구도 레시피.\n *\n * 의도: 빈 보드에 컴포넌트를 어디에 배치할지 LLM 이 픽셀 노가다 하지 않고\n * 검증된 layout 에서 슬롯 좌표를 받아 사용. 1280x720 기준 — 다른 size 시\n * 비율 조정.\n */\nconst LAYOUT_TEMPLATES = {\n overview:\n '대시보드 구도는 보통 4~6 종 패턴 안에서 결정됨. 빈 보드 + 사용자 의도 명확하면 템플릿의 슬롯 좌표 그대로 addPrefab 호출. 1280×720 기준 — 다른 size 면 비율 조정.',\n\n templates: {\n 'kpi-row': {\n description: '상단 wide KPI 4-tile + 하단 메인 영역. 가장 흔한 dashboard 헤더.',\n bestFor: ['종합 모니터링', '경영 대시보드', '운영 status'],\n boardSize: { width: 1280, height: 720 },\n slots: [\n { name: 'kpi-1', region: { left: 20, top: 20, width: 290, height: 130 } },\n { name: 'kpi-2', region: { left: 330, top: 20, width: 290, height: 130 } },\n { name: 'kpi-3', region: { left: 640, top: 20, width: 290, height: 130 } },\n { name: 'kpi-4', region: { left: 950, top: 20, width: 290, height: 130 } },\n { name: 'main-area', region: { left: 20, top: 170, width: 1240, height: 530 } }\n ],\n recommendation:\n 'kpi-1~4 슬롯에 stat-tile 4개. main-area 슬롯에 큰 차트 / 맵 / 테이블. 같은 팔레트 사용.'\n },\n '3x3-grid': {\n description: '균등한 3×3 그리드 — 9개 동등 단위. 모니터링 매트릭스.',\n bestFor: ['센서 어레이', '여러 라인 동시 모니터링', '대조 표시'],\n boardSize: { width: 1280, height: 720 },\n slots: Array.from({ length: 9 }, (_, i) => {\n const col = i % 3\n const row = Math.floor(i / 3)\n return {\n name: `cell-${row}-${col}`,\n region: {\n left: 20 + col * 420,\n top: 20 + row * 240,\n width: 400,\n height: 220\n }\n }\n })\n },\n 't-shape-command': {\n description: '상단 wide alarm bar + 하단 좌측 큰 메인 + 우측 narrow side panel',\n bestFor: ['관제실', 'mission-critical', '알람 + 상세 분석 동시 보기'],\n boardSize: { width: 1280, height: 720 },\n slots: [\n { name: 'alarm-bar', region: { left: 20, top: 20, width: 1240, height: 80 } },\n { name: 'main-canvas', region: { left: 20, top: 120, width: 870, height: 580 } },\n { name: 'side-panel', region: { left: 910, top: 120, width: 350, height: 580 } }\n ],\n recommendation:\n 'alarm-bar 에 status 인디케이터들 가로 배치. main-canvas 에 layout map / chart. side-panel 에 detail / history.'\n },\n 'side-rail': {\n description: '좌측 narrow 네비/필터 + 메인 wide content',\n bestFor: ['exploration UI', '필터 + 결과', '카테고리 navigation'],\n boardSize: { width: 1280, height: 720 },\n slots: [\n { name: 'rail', region: { left: 20, top: 20, width: 240, height: 680 } },\n { name: 'main', region: { left: 280, top: 20, width: 980, height: 680 } }\n ]\n },\n 'split-half': {\n description: '50/50 가로 분할 — 비교 / 대조',\n bestFor: ['before/after', 'A/B 비교', '듀얼 라인 모니터링'],\n boardSize: { width: 1280, height: 720 },\n slots: [\n { name: 'left', region: { left: 20, top: 20, width: 610, height: 680 } },\n { name: 'right', region: { left: 650, top: 20, width: 610, height: 680 } }\n ]\n },\n 'header-content-footer': {\n description: '상단 헤더 (제목/메타) + 메인 콘텐츠 + 하단 푸터 (요약/시간)',\n bestFor: ['보고서 형식', '인쇄 친화적 layout', '프레젠테이션'],\n boardSize: { width: 1280, height: 720 },\n slots: [\n { name: 'header', region: { left: 20, top: 20, width: 1240, height: 80 } },\n { name: 'content', region: { left: 20, top: 120, width: 1240, height: 520 } },\n { name: 'footer', region: { left: 20, top: 660, width: 1240, height: 40 } }\n ]\n }\n },\n\n workflow: [\n '1. 사용자 의도 식별 — 종합 monitoring? 비교? 관제?',\n '2. bestFor 매칭으로 템플릿 후보 1~2개 추림.',\n '3. 보드 size 가 1280×720 다르면 슬롯 좌표/크기를 비율로 조정.',\n '4. 각 슬롯의 region 으로 addPrefab / addComponent 호출. 슬롯 1개에 1 prefab 권장 (단일 group 으로 wrap).',\n '5. 빈 슬롯 남겨두는 것도 OK — 사용자 후속 작업 여지.'\n ],\n\n pitfalls: [\n '슬롯끼리 겹치게 배치하지 마라 — 의도 없으면 시각 혼란.',\n 'kpi-row 의 main-area 에 너무 많은 위젯 욱여 넣지 마라 — 여백이 정보다.',\n \"보드 size 가 정사각이면 't-shape-command' 같은 wide-bias 템플릿은 비율 조정해도 어색. 'split-half' 또는 '3x3-grid' 가 더 적합.\",\n '템플릿은 시작점 — 사용자가 추가 요청 시 슬롯 안에서 자유 배치 가능. 슬롯에 갇혀 있을 필요 없다.'\n ]\n}\n\nexport function isReadTool(name: string): boolean {\n if (READ_TOOL_NAMES.has(name)) return true\n // tool-registry plugin point — 'read' 와 'external' 는 LLM 측에서 동일하게 다뤄짐\n // (server 즉시 실행 + 결과 회신). external 은 board model 외부 entity 변경이\n // 가능한 점에서 의미 차이가 있지만, dispatch path 는 read 와 같다.\n const kind = getToolKind(name)\n return kind === 'read' || kind === 'external'\n}\n\n/**\n * 등록된 색 팔레트 이름 목록 — catalog-resolver / 클라이언트 popup 데이터 source.\n * 호스트 패키지가 추가 팔레트 등록은 현재 미지원 (향후 별도 registry 패턴 필요).\n */\nexport function listColorPaletteNames(): string[] {\n return Object.keys(COLOR_PALETTES.palettes)\n}\n\n/**\n * 등록된 레이아웃 템플릿 이름 목록 — 위와 동일.\n */\nexport function listLayoutTemplateNames(): string[] {\n return Object.keys(LAYOUT_TEMPLATES.templates)\n}\n\n/**\n * agentic loop 의 비정상 종료 사유 → 사용자 메시지에 부기할 한국어 한 줄.\n *\n * 정상 종료 (abortReason undefined) 면 빈 문자열 — concat 해도 무해.\n * 사용자에게 \"왜 중간에 멈췄는지\" 단서 제공이 목적 — 침묵 종료 금지.\n */\nexport function formatAbortNotice(\n abortReason: AgenticLoopResult['abortReason']\n): string {\n if (!abortReason) return ''\n switch (abortReason.type) {\n case 'aborted':\n return '\\n\\n_(요청이 중단되어 일부만 처리됐어요.)_'\n case 'provider_error':\n /* 남의 말(SDK 원문)을 사용자에게 보여주지 않는다 — \"Error fetching from undefined: [503 …]\" 은\n * 사용자가 할 수 있는 일을 알려주지 않는다. 일시 장애는 이미 몇 번 다시 시도한 뒤이므로,\n * 지금 필요한 안내는 \"잠시 후 다시\" 하나다. 원문은 서버 로그에 남는다. */\n return isTransientAIError({ message: abortReason.message })\n ? '\\n\\n_(AI 서비스가 일시적으로 응답하지 않았어요. 잠시 후 다시 시도해 주세요.)_'\n : '\\n\\n_(처리 중 오류가 발생했어요. 같은 요청이 계속 실패하면 관리자에게 알려 주세요.)_'\n case 'max_iterations':\n return `\\n\\n_(작업이 너무 길어 ${abortReason.iter}회에서 중단했어요. 더 작게 나눠 요청해보세요.)_`\n case 'repeated_validation_failure':\n return `\\n\\n_(\\`${abortReason.toolName}\\` 호출이 ${abortReason.consecutive}회 연속 실패해 중단했어요. 요청을 다시 표현해보세요.)_`\n }\n}\n\n/**\n * tool 결과를 UI fold-able 박스에 보여줄 만한 크기로 요약.\n *\n * 원본 그대로면 findComponents 50개 / getAtmosphereGuide 같은 큰 객체가 ChatMessage\n * 영속까지 부담 — 핵심 모양만 유지하고 나머지는 marker.\n */\nexport function summarizeToolResult(value: any, depth = 0): any {\n if (value === null || value === undefined) return value\n if (typeof value === 'string') {\n return value.length > 200 ? `${value.slice(0, 200)}…[+${value.length - 200} chars]` : value\n }\n if (typeof value === 'number' || typeof value === 'boolean') return value\n if (Array.isArray(value)) {\n if (depth >= 2) return `[Array(${value.length})]`\n const out = value.slice(0, 5).map(v => summarizeToolResult(v, depth + 1))\n if (value.length > 5) out.push(`…[+${value.length - 5} items]`)\n return out\n }\n if (typeof value === 'object') {\n if (depth >= 3) {\n const keys = Object.keys(value).slice(0, 6).join(',')\n return `{${keys}${Object.keys(value).length > 6 ? ',…' : ''}}`\n }\n const out: any = {}\n for (const key of Object.keys(value)) {\n out[key] = summarizeToolResult(value[key], depth + 1)\n }\n return out\n }\n return undefined\n}\n\nexport function isWriteTool(name: string): boolean {\n if (WRITE_TOOL_NAMES.has(name)) return true\n return getToolKind(name) === 'write'\n}\n\nexport function isActionTool(name: string): boolean {\n if (ACTION_TOOL_NAMES.has(name)) return true\n return getToolKind(name) === 'action'\n}\n\n/**\n * 대화별 **도구 노출 게이트**.\n *\n * 왜 필요한가: 한 제품에 성격이 다른 대화면이 여럿 생긴다(보드 저작 도크 · 운영 도크 …).\n * 보드 편집은 patch/revert 로 되돌아가지만 운영 명령은 실 시스템에 영향을 준다 — 두 능력이\n * 한 대화에 모두 들려 있으면 경계가 UI 문패에 불과하다.\n *\n * **정의를 숨기는 것만으로는 부족하다**: 모델이 이름을 추측하거나 옛 대화가 재생되면 숨긴 도구도\n * 호출된다. 그래서 정의 조립과 **dispatch 판정(isRead/isWrite/isAction·spec 조회)** 에 같은 게이트를\n * 통과시킨다. 게이트를 통과하지 못한 이름은 loop 가 미등록 도구로 처리해 LLM 에 회신한다(조용한 무동작 아님).\n *\n * 기본값은 **현행 동작 그대로** — exposure 를 주지 않으면 코어 도구 on + 전 카테고리 허용.\n */\nexport interface ToolExposure {\n /** 코어 보드 편집 도구(addComponent·스타일링·씬 조작) 노출 여부. 기본 true. */\n boardTools?: boolean\n /** 외부 카테고리 화이트리스트(registerToolCategory 이름). 미지정 = 전부. */\n toolCategories?: ToolCategoryFilter\n}\n\nexport interface ToolGate {\n coreOn: boolean\n filter: ToolCategoryFilter\n isRead(name: string): boolean\n isWrite(name: string): boolean\n isAction(name: string): boolean\n spec(name: string): ToolSpec | undefined\n}\n\nexport function buildToolGate(exposure: ToolExposure = {}): ToolGate {\n const coreOn = exposure.boardTools !== false\n const filter = exposure.toolCategories\n const kind = (name: string) => getToolKind(name, filter)\n return {\n coreOn,\n filter,\n isRead: name => (coreOn && READ_TOOL_NAMES.has(name)) || kind(name) === 'read' || kind(name) === 'external',\n isWrite: name => (coreOn && WRITE_TOOL_NAMES.has(name)) || kind(name) === 'write',\n isAction: name => (coreOn && ACTION_TOOL_NAMES.has(name)) || kind(name) === 'action',\n spec: name => findToolSpec(name, filter)\n }\n}\n\n/**\n * tool-registry plugin point — 등록된 모든 외부 카테고리의 LLM tool 정의를 도출.\n * styling-tools 가 buildStylingToolDefinitions 로 자기 정의를 내보내듯, 외부 카테고리\n * (board-import 등) 도 본 함수로 합집합. buildBoardEditTools 의 spread 부분에서 호출.\n */\nfunction buildExternalCategoryDefinitions(\n filter?: ToolCategoryFilter\n): Array<{ name: string; description: string; parameters: any }> {\n return getToolSpecsFor(filter).map(spec => ({\n name: spec.name,\n description: spec.themeNote ? `${spec.description} ${spec.themeNote}` : spec.description,\n parameters: spec.schema\n }))\n}\n\n/**\n * Tool call → BoardActionOp 변환 (C-1 ephemeral scene 조작).\n * 잘못된 인자는 null — agentic loop 가 Unknown tool 비슷하게 처리.\n */\nexport function toolCallToBoardActionOp(\n tc: AIToolCall,\n gate: ToolGate = buildToolGate()\n): import('./types.js').BoardActionOp | null {\n const args = tc.arguments ?? {}\n /* 씬 조작 액션은 전부 코어(보드) 능력 — 노출 안 된 대화에서는 만들지 않는다.\n * loop 는 gate.isAction 으로 이미 걸러내지만, 다른 호출부의 오용도 막는다. */\n if (!gate.coreOn) return null\n switch (tc.name) {\n case 'selectComponents': {\n if (!Array.isArray(args.refids)) return null\n const refids = args.refids.filter((n: any) => typeof n === 'number') as number[]\n return { action: 'selectComponents', refids }\n }\n case 'centerToComponent': {\n if (typeof args.refid !== 'number') return null\n const out: any = { action: 'centerToComponent', refid: args.refid }\n if (typeof args.animated === 'boolean') out.animated = args.animated\n return out\n }\n case 'fitToView': {\n const allowed = new Set(['fit', 'ratio', 'width', 'height'])\n const out: any = { action: 'fitToView' }\n if (typeof args.mode === 'string' && allowed.has(args.mode)) out.mode = args.mode\n return out\n }\n case 'setSceneMode': {\n if (args.mode !== 'edit' && args.mode !== 'view') return null\n return { action: 'setSceneMode', mode: args.mode }\n }\n default:\n return null\n }\n}\n\n// ── Tool call → BoardEditOp 변환 ───────────────────────────────────\n\n/**\n * AIToolChatResult → ChatResponse.\n *\n * 정책 — followUp 항상 undefined: reply 와 동일 텍스트를 followUp 에 복제하면 클라이언트\n * 에서 .md-body 와 .followup 두 박스에 같은 내용이 표시되어 사용자에게 \"동일 응답이\n * 두 번 반복\" 으로 보인다. 명확화 질문이 필요한 경우 LLM 이 reply 자체에 포함시키도록\n * 설계.\n */\nexport function toolResultToChatResponse(result: AIToolChatResult): ChatResponse {\n const ops = result.toolCalls\n .flatMap(call => {\n const r = toolCallToBoardEditOp(call)\n if (r === null) return []\n return Array.isArray(r) ? r : [r]\n })\n\n const reply = result.text || (ops.length > 0 ? '변경했습니다.' : '')\n\n let patch: BoardEditPatch | undefined\n if (ops.length > 0) {\n patch = {\n ops,\n summary: result.text ?? `${ops.length} edit op(s) applied`,\n confidence: 0.9\n }\n }\n\n return { reply, patch, followUp: undefined }\n}\n\nexport function toolCallToBoardEditOp(\n tc: AIToolCall,\n components: ReadonlyArray<any> = [],\n gate: ToolGate = buildToolGate()\n): BoardEditOp | BoardEditOp[] | null {\n const args = tc.arguments ?? {}\n /* 노출되지 않은 코어(보드 편집) 도구는 op 를 만들지 않는다 — 정의를 숨겼어도 호출은 올 수 있다. */\n if (!gate.coreOn && !gate.spec(tc.name)) return null\n // styling registry 에 등록된 tool 은 위임 — 한 tool 씩 점진 이전 중.\n // registry 에 없는 styling tool 은 아래 switch 의 기존 case 가 처리.\n if (isStylingTool(tc.name)) {\n if (!gate.coreOn) return null\n return dispatchStylingTool(tc.name, args, components)\n }\n // tool-registry plugin point — 외부 등록 'write' 카테고리 dispatch.\n // builder 결과는 BoardEditOp[] | { ops, errors? } | null 셋 중 하나.\n // (read/external 카테고리는 별도 dispatch path — agentic loop 의 executeReadTool 이 직접 처리.)\n const registrySpec = gate.spec(tc.name)\n if (registrySpec && registrySpec.kind === 'write') {\n const r = registrySpec.builder(args, { components })\n if (!r) return null\n if (Array.isArray(r)) return r.length > 0 ? r : null\n return r.ops.length > 0 ? r.ops : null\n }\n if (!gate.coreOn) return null // 코어 도구 switch 는 보드 편집 — 노출 안 된 대화에서는 진입 금지\n switch (tc.name) {\n case 'addComponent': {\n if (typeof args.type !== 'string') return null\n return { op: 'add', component: args as BoardComponent }\n }\n case 'removeComponentByRefid': {\n if (typeof args.refid !== 'number') return null\n return { op: 'remove', refid: args.refid }\n }\n case 'modifyComponentByRefid': {\n if (typeof args.refid !== 'number' || !args.patch || typeof args.patch !== 'object') return null\n return { op: 'modify', refid: args.refid, patch: args.patch as Partial<BoardComponent> }\n }\n // 모든 styling tool (setFill/setStroke/setText/setFont/setShadow/setOpacity/\n // setVisible/setMaterial/setShadowProperties/clearStyle/copyStyle) 은 registry\n // 가 처리 — 상단 isStylingTool 분기 참조\n case 'modifyBoard': {\n if (!args.patch || typeof args.patch !== 'object' || Array.isArray(args.patch)) return null\n return { op: 'modifyBoard', patch: args.patch as Partial<BoardModel> }\n }\n case 'replaceBoard': {\n if (!Array.isArray(args.components)) return null\n return {\n op: 'replace',\n board: {\n width: typeof args.width === 'number' ? args.width : undefined,\n height: typeof args.height === 'number' ? args.height : undefined,\n fillStyle: typeof args.fillStyle === 'string' ? args.fillStyle : undefined,\n components: args.components as BoardComponent[]\n } as BoardModel\n }\n }\n // Phase 2 — Scene 조작\n case 'alignComponents': {\n if (!Array.isArray(args.refids) || args.refids.length === 0) return null\n const refids = args.refids.filter((n: any) => typeof n === 'number') as number[]\n if (refids.length === 0) return null\n const allowed = new Set(['left', 'right', 'center', 'top', 'middle', 'bottom'])\n if (typeof args.direction !== 'string' || !allowed.has(args.direction)) return null\n return { op: 'align', refids, direction: args.direction as any }\n }\n case 'distributeComponents': {\n if (!Array.isArray(args.refids)) return null\n const refids = args.refids.filter((n: any) => typeof n === 'number') as number[]\n if (refids.length === 0) return null\n if (args.axis !== 'horizontal' && args.axis !== 'vertical') return null\n return { op: 'distribute', refids, axis: args.axis }\n }\n case 'groupComponents': {\n if (!Array.isArray(args.refids)) return null\n const refids = args.refids.filter((n: any) => typeof n === 'number') as number[]\n if (refids.length < 2) return null\n return { op: 'group', refids }\n }\n case 'ungroupComponent': {\n if (typeof args.refid !== 'number') return null\n return { op: 'ungroup', refid: args.refid }\n }\n case 'changeZorder': {\n if (typeof args.refid !== 'number') return null\n const allowed = new Set(['front', 'back', 'forward', 'backward'])\n if (typeof args.direction !== 'string' || !allowed.has(args.direction)) return null\n return { op: 'zorder', refid: args.refid, direction: args.direction as any }\n }\n case 'arrangeInGrid': {\n if (!Array.isArray(args.refids)) return null\n const refids = args.refids.filter((n: any) => typeof n === 'number') as number[]\n if (refids.length < 2) return null\n const cols = typeof args.cols === 'number' && args.cols >= 1 ? Math.floor(args.cols) : null\n if (cols === null) return null\n const layout: any = { type: 'grid', cols }\n if (typeof args.gap === 'number') layout.gap = args.gap\n if (\n args.anchor &&\n typeof args.anchor === 'object' &&\n typeof args.anchor.left === 'number' &&\n typeof args.anchor.top === 'number'\n ) {\n layout.anchor = { left: args.anchor.left, top: args.anchor.top }\n }\n return { op: 'arrange', refids, layout }\n }\n case 'arrangeInRow':\n case 'arrangeInColumn': {\n if (!Array.isArray(args.refids)) return null\n const refids = args.refids.filter((n: any) => typeof n === 'number') as number[]\n if (refids.length < 2) return null\n const layout: any = {\n type: tc.name === 'arrangeInRow' ? 'row' : 'column'\n }\n if (typeof args.gap === 'number') layout.gap = args.gap\n if (\n args.anchor &&\n typeof args.anchor === 'object' &&\n typeof args.anchor.left === 'number' &&\n typeof args.anchor.top === 'number'\n ) {\n layout.anchor = { left: args.anchor.left, top: args.anchor.top }\n }\n if (args.align === 'start' || args.align === 'center' || args.align === 'end') {\n layout.align = args.align\n }\n return { op: 'arrange', refids, layout }\n }\n case 'addPrefab': {\n if (typeof args.name !== 'string' || args.name.length === 0) return null\n if (typeof args.left !== 'number' || typeof args.top !== 'number') return null\n const prefab = findBoardPrefab(args.name)\n if (!prefab) return null\n const options: any = {\n left: args.left,\n top: args.top,\n ...(typeof args.width === 'number' && { width: args.width }),\n ...(typeof args.height === 'number' && { height: args.height }),\n ...(args.options && typeof args.options === 'object' ? args.options : {})\n }\n let component: BoardComponent\n try {\n component = prefab.build(options)\n } catch {\n // 잘못된 옵션 (예: 잘못된 타입) — 무시. agentic loop 가 fallback 가능.\n return null\n }\n if (!component || typeof component !== 'object') return null\n return { op: 'add', component }\n }\n default:\n return null\n }\n}\n\n// ── 스킴 포맷 ──────────────────────────────────────────────────────\n\n/**\n * ComponentSchema[] 를 LLM 친화적 형태로 압축. 토큰 절감을 위해:\n * - knownTypes 에 포함된 schema 만\n * - properties 의 nested object 는 키 목록만\n */\nfunction formatSchemas(schemas: ComponentSchema[], knownTypes: string[]): string {\n if (!schemas || schemas.length === 0) return '(none provided)'\n const allowed = new Set(knownTypes)\n const filtered = schemas.filter(s => s && allowed.has(s.type))\n if (filtered.length === 0) return '(none provided)'\n\n const lines: string[] = []\n for (const s of filtered) {\n const desc = s.description ? ` — ${s.description}` : ''\n const grp = s.group ? ` [${s.group}]` : ''\n const geom =\n s.geometryKeys && s.geometryKeys.length > 0\n ? `\\n geometry: ${s.geometryKeys.join(', ')}`\n : ''\n const propKeys = s.properties ? formatProperties(s.properties) : ''\n const propLine = propKeys ? `\\n properties: ${propKeys}` : ''\n lines.push(`- ${s.type}${grp}${desc}${geom}${propLine}`)\n }\n return lines.join('\\n')\n}\n\nfunction formatProperties(props: Record<string, any>): string {\n const items: string[] = []\n for (const [k, v] of Object.entries(props)) {\n if (v === null || v === undefined) {\n items.push(k)\n } else if (typeof v === 'object' && !Array.isArray(v)) {\n const subKeys = Object.keys(v).slice(0, 6).join(',')\n items.push(`${k}:{${subKeys}}`)\n } else if (Array.isArray(v)) {\n items.push(`${k}:[]`)\n } else if (typeof v === 'string' && v.length > 24) {\n items.push(`${k}:string`)\n } else {\n items.push(`${k}=${JSON.stringify(v)}`)\n }\n }\n return items.join(', ')\n}\n\n// ── 보드 요약 (LLM 토큰 절감) ──────────────────────────────────────\n\nexport function summarizeBoard(board: BoardModel | null | undefined): any {\n if (!board || typeof board !== 'object') return null\n const components = board.components ?? []\n\n // 루트(보드 자체) 의 모든 비-internal 속성을 그대로 노출.\n // 단순 whitelist (width/height/fillStyle) 로 좁히면 AI 가 보드 자체의 다른 속성\n // (name 등) 을 모르고 또한 \"보드는 단순 컨테이너\" 로 오해할 수 있다. 보드도\n // 자체 속성을 가진 부모 노드임을 분명히 보이도록.\n const root: any = {}\n for (const key of Object.keys(board)) {\n if (key === 'components') continue // children 은 별도 처리\n if (key.startsWith('_')) continue\n root[key] = summarizeValue((board as any)[key], 0)\n }\n\n // group/container 자식까지 포함한 평면 list — AI 가 hierarchy 무관하게 모든\n // 컴포넌트를 인지할 수 있도록. 메타 (parentRefid, depth) 첨부.\n const flat = collectAllComponents(board)\n const flatSummary = flat\n .slice(0, MAX_BOARD_SUMMARY_COMPONENTS)\n .map(f => {\n const summary = summarizeComponent(f.component)\n // depth 0 은 메타 생략 (top-level — parentRefid undefined)\n if (f.depth > 0) {\n summary._parentRefid = f.parentRefid\n summary._depth = f.depth\n }\n return summary\n })\n\n return {\n // 'model' 은 things-scene 보드 root 의 type — 보드가 컴포넌트 같은 대상임을 명시.\n boardRoot: { type: 'model', ...root },\n componentCount: flat.length, // 평면 — group 자식 포함\n topLevelCount: components.length,\n components: flatSummary,\n truncated: flat.length > MAX_BOARD_SUMMARY_COMPONENTS\n }\n}\n\n// 요약에서 제외할 키 — things-scene 의 내부/transient 상태 (사용자가 편집 대상으로 삼지 않음)\nconst COMPONENT_OMIT_KEYS = new Set<string>([\n 'components', // group/container 의 children — 별도 처리\n '_state',\n '_cache',\n '_layout',\n '_dirty',\n '_internal'\n])\n\nconst MAX_STRING_LEN = 200\nconst MAX_ARRAY_LEN = 50\n\n/**\n * 컴포넌트 요약 — type-specific 속성 (text, value, cx/cy/radius, points, ...) 까지\n * 포함해 LLM 이 정확한 modify 대상을 판단할 수 있도록.\n *\n * 토큰 절감을 위해:\n * - 긴 문자열/배열은 길이 제한 (말미 truncated 마커)\n * - things-scene 내부 키 (_state 등) 는 제외\n * - nested object 는 1단계까지 그대로, 그 이상은 키 목록만\n */\nfunction summarizeComponent(c: BoardComponent): any {\n if (!c || typeof c !== 'object') return c\n const out: any = {}\n for (const key of Object.keys(c)) {\n if (COMPONENT_OMIT_KEYS.has(key)) continue\n if (key.startsWith('_')) continue\n out[key] = summarizeValue((c as any)[key], 0)\n }\n return out\n}\n\nfunction summarizeValue(v: any, depth: number): any {\n if (v === null || v === undefined) return v\n const t = typeof v\n if (t === 'string') {\n return v.length > MAX_STRING_LEN ? `${v.slice(0, MAX_STRING_LEN)}…[+${v.length - MAX_STRING_LEN} chars]` : v\n }\n if (t === 'number' || t === 'boolean') return v\n if (Array.isArray(v)) {\n if (v.length === 0) return []\n if (depth >= 2) return `[Array(${v.length})]`\n const out = v.slice(0, MAX_ARRAY_LEN).map(x => summarizeValue(x, depth + 1))\n if (v.length > MAX_ARRAY_LEN) out.push(`…[+${v.length - MAX_ARRAY_LEN} items]`)\n return out\n }\n if (t === 'object') {\n if (depth >= 2) {\n const keys = Object.keys(v).slice(0, 8)\n return `{${keys.join(',')}${Object.keys(v).length > 8 ? ',…' : ''}}`\n }\n const out: any = {}\n for (const key of Object.keys(v)) {\n if (key.startsWith('_')) continue\n out[key] = summarizeValue(v[key], depth + 1)\n }\n return out\n }\n return undefined\n}\n"]}
|