fix: 작업실 채팅에 현재 프로젝트 컨텍스트 주입

ws_ 세션(작업실 앱 전용 채팅)이 "지금 어떤 프로젝트를 보고 있는지" 정보를
시스템 프롬프트에 전혀 못 받고 있었음 — tool-scope.ts의 isWorkshopAppSession은
"작업실 세션이다"만 판별하지 활성 프로젝트 ID는 안 넘김.

그 결과 모델이 STL/scad 파일을 찾을 때 워크스페이스 전체를 뒤져서 다른
프로젝트 파일까지 후보로 내놓는 혼동이 있었음(예: proj_scan_dental_diy
채팅에서 STL 요청했는데 proj_scan_dental 쪽 scad까지 같이 나열).

workshop.json의 activeProjectId를 읽어 "지금 프로젝트는 이거고 파일은
workshop/<id>/ 아래만 볼 것"을 callerContext에 주입하도록 수정.
실제 ws_ 세션으로 테스트해 크로스 프로젝트 혼동 없어진 것 확인.

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
kim
2026-09-22 15:45:19 +09:00
co-authored by Claude Code
parent c79364312c
commit 88662663b1
+23 -1
View File
@@ -1,6 +1,7 @@
import fs from 'fs';
import path from 'path';
import { getConfig, getUserWorkspace } from '../../config/config';
import { loadWorkshop } from '../routes/workshop-storage';
import { getModelForRole } from '../../providers/factory';
import { getOllamaClient } from '../../agents/ollama-client';
import { getSession, addMessage, getHistoryForApiCall, getWorkspace, setWorkspace } from '../session';
@@ -245,6 +246,27 @@ async function handleChat(
const isCodeAiSession = String(sessionId || '').startsWith('code_ai_');
const isTranslateSession = String(sessionId || '').startsWith('translate-');
const isProjSession = String(sessionId || '').startsWith('proj-');
// 작업실 앱(workshop-app.html) 전용 채팅 패널 세션('ws_' 접두어) — tool-scope.ts의
// isWorkshopAppSession과 같은 판별이지만 여기선 "지금 보고 있는 프로젝트가 뭔지"를 시스템
// 프롬프트에 심어주는 데 쓴다. 이게 없으면 모델이 워크스페이스 전체를 뒤져서 다른 프로젝트
// 파일(예: proj_scan_dental)까지 후보로 내놓는 혼동이 생긴다(2026-09-22 사용자 지적 — DIY
// 스캐너 프로젝트 채팅에서 STL 만들어달라 했는데 임상급 프로젝트 scad까지 같이 나열함).
const isWorkshopAppSession = /^ws_/.test(String(sessionId || ''));
const workshopProjectCtx = (() => {
if (!isWorkshopAppSession || !workspacePath) return '';
try {
const wd = loadWorkshop(workspacePath);
const proj = wd.projects.find(p => p.id === wd.activeProjectId);
if (!proj) return '';
return `[작업실(workshop) 세션 — 지금 사용자가 보고 있는 프로젝트: "${proj.name}" (id: ${proj.id}). ` +
`이 프로젝트의 파일(STL/scad/사진 등)은 워크스페이스 기준 workshop/${proj.id}/ 아래에만 있다. ` +
`파일을 찾거나 만들 때 이 프로젝트 폴더만 보고, 다른 프로젝트 폴더(workshop/<다른id>/)는 ` +
`사용자가 명시적으로 그 프로젝트를 언급하지 않는 한 후보로 내놓지 말 것.]`;
} catch { return ''; }
})();
const callerContextWithWorkshop = workshopProjectCtx
? `${callerContext || ''}${callerContext ? '\n\n' : ''}${workshopProjectCtx}`
: callerContext;
// 도구 선택 로직은 tool-scope.ts로 분리됨(2026-07-29) — handleChat 안의 클로저라 테스트가
// 불가능했고, 게이트 하나가 조용히 어긋나도 아무 에러 없이 프롬프트만 뚱뚱해지던 구간.
const tools = selectToolsForTurn(buildTools(),
@@ -708,7 +730,7 @@ async function handleChat(
isTranslateSession,
isProjSession,
modelProfileBlock: getModelProfileExtraPrompt(getModelForRole('executor')),
callerContext,
callerContext: callerContextWithWorkshop,
browserStateCtx,
personalityCtx,
skillsCtx: skillsManager.buildPromptContextForUser(username ? getUserWorkspace(username) : null, 16000, message),