@@ -50,8 +50,62 @@ function createWindow(): void {
5050 }
5151}
5252
53+ interface RunGenerateArgs {
54+ payload : GeneratePayload ;
55+ controller : AbortController ;
56+ logIpc : ReturnType < typeof getLogger > ;
57+ }
58+
59+ async function runGenerate ( { payload, controller, logIpc } : RunGenerateArgs ) : Promise < unknown > {
60+ const apiKey = getApiKeyForProvider ( payload . model . provider ) ;
61+ const storedBaseUrl = getBaseUrlForProvider ( payload . model . provider ) ;
62+ const baseUrl = payload . baseUrl ?? storedBaseUrl ;
63+ const id = payload . generationId ?? `gen-${ Date . now ( ) } ` ;
64+
65+ logIpc . info ( 'generate' , {
66+ id,
67+ provider : payload . model . provider ,
68+ modelId : payload . model . modelId ,
69+ promptLen : payload . prompt . length ,
70+ historyLen : payload . history . length ,
71+ baseUrl : baseUrl ?? '<default>' ,
72+ } ) ;
73+ const t0 = Date . now ( ) ;
74+ try {
75+ const result = await generate ( {
76+ prompt : payload . prompt ,
77+ history : payload . history ,
78+ model : payload . model ,
79+ apiKey,
80+ ...( baseUrl !== undefined ? { baseUrl } : { } ) ,
81+ signal : controller . signal ,
82+ } ) ;
83+ logIpc . info ( 'generate.ok' , {
84+ id,
85+ ms : Date . now ( ) - t0 ,
86+ artifacts : ( result as { artifacts ?: unknown [ ] } ) . artifacts ?. length ?? 0 ,
87+ cost : ( result as { costUsd ?: number } ) . costUsd ,
88+ } ) ;
89+ return result ;
90+ } catch ( err ) {
91+ logIpc . error ( 'generate.fail' , {
92+ id,
93+ ms : Date . now ( ) - t0 ,
94+ provider : payload . model . provider ,
95+ modelId : payload . model . modelId ,
96+ baseUrl : baseUrl ?? '<default>' ,
97+ message : err instanceof Error ? err . message : String ( err ) ,
98+ code : err instanceof CodesignError ? err . code : undefined ,
99+ } ) ;
100+ throw err ;
101+ }
102+ }
103+
53104function registerIpcHandlers ( ) : void {
54- const logIpc = getLogger ( 'main:ipc' ) ;
105+ const logIpc = getLogger ( 'ipc' ) ;
106+
107+ /** In-flight requests: generationId → AbortController */
108+ const inFlight = new Map < string , AbortController > ( ) ;
55109
56110 ipcMain . handle ( 'codesign:detect-provider' , ( _e , key : unknown ) => {
57111 if ( typeof key !== 'string' ) {
@@ -62,41 +116,31 @@ function registerIpcHandlers(): void {
62116
63117 ipcMain . handle ( 'codesign:generate' , async ( _e , raw : unknown ) => {
64118 const payload = GeneratePayload . parse ( raw ) ;
65- const apiKey = getApiKeyForProvider ( payload . model . provider ) ;
66- const storedBaseUrl = getBaseUrlForProvider ( payload . model . provider ) ;
67- const baseUrl = payload . baseUrl ?? storedBaseUrl ;
68- logIpc . info ( 'generate' , {
69- provider : payload . model . provider ,
70- modelId : payload . model . modelId ,
71- promptLen : payload . prompt . length ,
72- historyLen : payload . history . length ,
73- baseUrl : baseUrl ?? '<default>' ,
74- } ) ;
75- const t0 = Date . now ( ) ;
119+ const controller = new AbortController ( ) ;
120+ const id = payload . generationId ?? `gen-${ Date . now ( ) } ` ;
121+ inFlight . set ( id , controller ) ;
76122 try {
77- const result = await generate ( {
78- prompt : payload . prompt ,
79- history : payload . history ,
80- model : payload . model ,
81- apiKey,
82- ...( baseUrl !== undefined ? { baseUrl } : { } ) ,
83- } ) ;
84- logIpc . info ( 'generate.ok' , {
85- ms : Date . now ( ) - t0 ,
86- artifacts : ( result as { artifacts ?: unknown [ ] } ) . artifacts ?. length ?? 0 ,
87- cost : ( result as { costUsd ?: number } ) . costUsd ,
88- } ) ;
89- return result ;
90- } catch ( err ) {
91- logIpc . error ( 'generate.fail' , {
92- ms : Date . now ( ) - t0 ,
93- provider : payload . model . provider ,
94- modelId : payload . model . modelId ,
95- baseUrl : baseUrl ?? '<default>' ,
96- message : err instanceof Error ? err . message : String ( err ) ,
97- code : err instanceof CodesignError ? err . code : undefined ,
98- } ) ;
99- throw err ;
123+ return await runGenerate ( { payload, controller, logIpc } ) ;
124+ } finally {
125+ inFlight . delete ( id ) ;
126+ }
127+ } ) ;
128+
129+ ipcMain . handle ( 'codesign:cancel-generation' , ( _e , raw : unknown ) => {
130+ const id = typeof raw === 'string' ? raw : undefined ;
131+ if ( id !== undefined ) {
132+ const controller = inFlight . get ( id ) ;
133+ if ( controller ) {
134+ controller . abort ( ) ;
135+ inFlight . delete ( id ) ;
136+ logIpc . info ( 'generate.cancelled' , { id } ) ;
137+ }
138+ } else {
139+ for ( const [ key , controller ] of inFlight ) {
140+ controller . abort ( ) ;
141+ logIpc . info ( 'generate.cancelled' , { id : key } ) ;
142+ }
143+ inFlight . clear ( ) ;
100144 }
101145 } ) ;
102146
0 commit comments