11import path_module from 'node:path' ;
22import {
33 type AgentEvent ,
4- type AskAnswer ,
54 type AskInput ,
5+ applyRunPreferenceAnswers ,
66 buildApplyCommentUserPrompt ,
77 buildDesignContextPack ,
88 type CoreLogger ,
@@ -15,14 +15,14 @@ import {
1515 inspectWorkspaceFiles ,
1616 loadDesignSkills ,
1717 loadFrameTemplates ,
18+ routeRunPreferences ,
1819 updateDesignSessionBrief ,
1920} from '@open-codesign/core' ;
2021import { detectProviderFromKey , generateImage } from '@open-codesign/providers' ;
2122import {
2223 ApplyCommentPayload ,
2324 CancelGenerationPayloadV1 ,
2425 CodesignError ,
25- type DesignRunPreferencesV1 ,
2626 deriveResourceStateFromChatRows ,
2727 GeneratePayloadV1 ,
2828} from '@open-codesign/shared' ;
@@ -88,65 +88,28 @@ export function shouldRunUserMemoryCandidateCapture(prefs: {
8888 return prefs . memoryEnabled === true && prefs . userMemoryAutoUpdate === true ;
8989}
9090
91- const DEFAULT_RUN_PREFERENCES : DesignRunPreferencesV1 = {
92- schemaVersion : 1 ,
93- tweaks : 'auto' ,
94- bitmapAssets : 'auto' ,
95- reusableSystem : 'auto' ,
96- } ;
97-
98- export function shouldRequestRunPreferencePreflight ( input : {
99- hasSource : boolean ;
100- existingPreferences : DesignRunPreferencesV1 | null ;
101- prompt : string ;
102- } ) : boolean {
103- if ( input . existingPreferences !== null ) return false ;
104- if ( input . hasSource ) return false ;
105- return input . prompt . trim ( ) . length > 0 ;
106- }
107-
108- export function buildRunPreferenceAskInput ( _prompt : string ) : AskInput {
91+ export function buildRunPreferenceAskInput ( questions : AskInput [ 'questions' ] ) : AskInput {
10992 return {
11093 rationale : 'A few setup choices help Open CoDesign avoid unnecessary work.' ,
111- questions : [
112- {
113- id : 'tweaks' ,
114- type : 'text-options' ,
115- prompt : 'Do you want tweak controls for this design?' ,
116- options : [ 'auto' , 'no' , 'yes' ] ,
117- } ,
118- ] ,
94+ questions,
11995 } ;
12096}
12197
122- function answerValue ( answers : AskAnswer [ ] , questionId : string ) : string | null {
123- const value = answers . find ( ( answer ) => answer . questionId === questionId ) ?. value ;
124- return typeof value === 'string' ? value : null ;
125- }
126-
127- export function mergeRunPreferenceAnswers (
128- base : DesignRunPreferencesV1 | null ,
129- answers : AskAnswer [ ] ,
130- prompt : string ,
131- ) : DesignRunPreferencesV1 {
132- const next : DesignRunPreferencesV1 = { ...( base ?? DEFAULT_RUN_PREFERENCES ) } ;
133- const tweakAnswer = answerValue ( answers , 'tweaks' ) ;
134- if ( tweakAnswer === 'yes' || tweakAnswer === 'no' || tweakAnswer === 'auto' ) {
135- next . tweaks = tweakAnswer ;
136- }
137- const lower = prompt . toLowerCase ( ) ;
138- const disablesTweaks = / 不 要 .* 微 调 | 不 .* 微 调 | n o t w e a k s ? | w i t h o u t t w e a k s ? / . test ( lower ) ;
139- if ( disablesTweaks ) {
140- next . tweaks = 'no' ;
141- } else if ( / 加 .* 微 调 | 要 .* 微 调 | a d d t w e a k s ? | w i t h t w e a k s ? / . test ( lower ) ) {
142- next . tweaks = 'yes' ;
143- }
144- if ( / 不 要 .* ( 图 片 | 图 像 ) | 不 .* 生 成 .* ( 图 片 | 图 像 ) | n o i m a g e s ? | w i t h o u t i m a g e s ? / . test ( lower ) ) {
145- next . bitmapAssets = 'no' ;
146- } else if ( / 生 成 .* ( 图 片 | 图 像 ) | 加 .* ( 图 片 | 图 像 ) | g e n e r a t e i m a g e s ? | w i t h i m a g e s ? / . test ( lower ) ) {
147- next . bitmapAssets = 'yes' ;
148- }
149- return next ;
98+ function recentHistoryForRunPreferenceRouter (
99+ chatRows : ReturnType < typeof listSessionChatMessages > ,
100+ ) : string {
101+ return chatRows
102+ . slice ( - 12 )
103+ . map ( ( row ) => {
104+ if ( row . kind !== 'user' && row . kind !== 'assistant_text' ) return null ;
105+ const text =
106+ typeof ( row . payload as { text ?: unknown } ) . text === 'string'
107+ ? ( row . payload as { text : string } ) . text
108+ : '' ;
109+ return text . trim ( ) . length > 0 ? `[${ row . kind } ] ${ text . trim ( ) . slice ( 0 , 800 ) } ` : null ;
110+ } )
111+ . filter ( ( line ) : line is string => line !== null )
112+ . join ( '\n' ) ;
150113}
151114
152115function designMdSummaryForMemory (
@@ -797,27 +760,42 @@ export function registerGenerateIpc({ db, getMainWindow }: RegisterGenerateIpcDe
797760 runPreferenceStoreOptions !== null
798761 ? readSessionRunPreferences ( runPreferenceStoreOptions , designId )
799762 : null ;
800- let runPreferences = mergeRunPreferenceAnswers (
801- existingRunPreferences ,
802- [ ] ,
803- payload . prompt ,
804- ) ;
805- if (
806- shouldRequestRunPreferencePreflight ( {
807- hasSource : Boolean ( payload . previousSource ?. trim ( ) ) ,
808- existingPreferences : existingRunPreferences ,
809- prompt : payload . prompt ,
810- } )
811- ) {
763+ const workspaceState = {
764+ sourcePath : payload . previousSource ? 'App.jsx' : null ,
765+ hasSource : Boolean ( payload . previousSource ?. trim ( ) ) ,
766+ hasDesignMd : Boolean ( promptContext . projectContext . designMd ?. trim ( ) ) ,
767+ hasAgentsMd : Boolean ( promptContext . projectContext . agentsMd ?. trim ( ) ) ,
768+ hasSettingsJson : Boolean ( promptContext . projectContext . settingsJson ?. trim ( ) ) ,
769+ } ;
770+ const routedPreferences = await routeRunPreferences ( {
771+ prompt : payload . prompt ,
772+ existingPreferences : existingRunPreferences ,
773+ recentHistory : recentHistoryForRunPreferenceRouter ( chatRows ) ,
774+ workspaceState,
775+ designBrief : existingBrief ? JSON . stringify ( existingBrief ) : null ,
776+ userMemory : memoryContext ?. userMemory ?. content ?? null ,
777+ workspaceMemory : memoryContext ?. workspaceMemory ?. content ?? null ,
778+ model : active . model ,
779+ apiKey,
780+ ...( baseUrl !== undefined ? { baseUrl } : { } ) ,
781+ wire : active . wire ,
782+ ...( active . httpHeaders !== undefined ? { httpHeaders : active . httpHeaders } : { } ) ,
783+ ...( active . reasoningLevel !== undefined
784+ ? { reasoningLevel : active . reasoningLevel }
785+ : { } ) ,
786+ ...( allowKeyless ? { allowKeyless : true } : { } ) ,
787+ logger : coreLogger ,
788+ } ) ;
789+ let runPreferences = routedPreferences . preferences ;
790+ if ( routedPreferences . needsClarification && routedPreferences . clarificationQuestions ) {
812791 const askResult = await requestAsk (
813792 id ,
814- buildRunPreferenceAskInput ( payload . prompt ) ,
793+ buildRunPreferenceAskInput ( routedPreferences . clarificationQuestions ) ,
815794 ( ) => getMainWindow ( ) ,
816795 ) ;
817- runPreferences = mergeRunPreferenceAnswers (
796+ runPreferences = applyRunPreferenceAnswers (
818797 runPreferences ,
819798 askResult . status === 'answered' ? askResult . answers : [ ] ,
820- payload . prompt ,
821799 ) ;
822800 }
823801 if ( runPreferenceStoreOptions !== null ) {
0 commit comments