22 * Model client for LLM interaction
33 */
44
5- import { existsSync , readFileSync , appendFileSync } from 'fs' ;
5+ import { existsSync } from 'fs' ;
6+ import { readFile , appendFile } from 'fs/promises' ;
67import { initLogger } from '../logger.js' ;
78import { envVars } from '../env_vars.js' ;
89import { sleep } from '../utils/retry.js' ;
@@ -82,7 +83,7 @@ export class ModelClient {
8283 const lastResponseLine = await this . readLastResponseLine ( ) ;
8384
8485 if ( lastResponseLine === null ) {
85- this . appendResponse ( content ) ;
86+ await this . appendResponse ( content ) ;
8687 return ;
8788 }
8889
@@ -98,7 +99,7 @@ export class ModelClient {
9899 return ;
99100 }
100101
101- this . appendResponse ( content ) ;
102+ await this . appendResponse ( content ) ;
102103 }
103104
104105 /**
@@ -139,9 +140,15 @@ export class ModelClient {
139140 logger . debug ( `Last request is not the index ${ index } we want, waiting...` ) ;
140141 await sleep ( 1000 ) ;
141142 } catch ( e ) {
142- // Re-throw abort errors
143- if ( e instanceof Error && e . message . includes ( 'aborted' ) ) {
144- throw e ;
143+ // Re-throw abort errors and parse errors immediately
144+ if ( e instanceof Error ) {
145+ if ( e . message . includes ( 'aborted' ) ) {
146+ throw e ;
147+ }
148+ // Re-throw parse errors (invalid format) immediately - don't retry
149+ if ( e . message . includes ( 'Invalid request line format' ) ) {
150+ throw e ;
151+ }
145152 }
146153 // For other errors (like file not found), wait and retry
147154 logger . debug ( `Error reading request: ${ e } , waiting...` ) ;
@@ -177,7 +184,7 @@ export class ModelClient {
177184 continue ;
178185 }
179186
180- const content = readFileSync ( this . logFile , 'utf-8' ) ;
187+ const content = await readFile ( this . logFile , 'utf-8' ) ;
181188 const lines = content . split ( '\n' ) . filter ( ( l ) => l . trim ( ) ) ;
182189
183190 if ( lines . length === 0 ) {
@@ -195,25 +202,35 @@ export class ModelClient {
195202 return { requestJson : SESSION_END_MARKER , meta : { } } ;
196203 }
197204
198- const parts = lineContent . split ( REQUEST_END_MARKER ) ;
199- const metaJson = parts [ 1 ] ?? '' ;
200- const requestJson = parts [ 0 ] ?. split ( REQUEST_START_MARKER ) [ 1 ] ?? '' ;
201- const meta = JSON . parse ( metaJson ) ;
205+ try {
206+ const parts = lineContent . split ( REQUEST_END_MARKER ) ;
207+ const metaJson = parts [ 1 ] ?? '' ;
208+ const requestJson = parts [ 0 ] ?. split ( REQUEST_START_MARKER ) [ 1 ] ?? '' ;
209+ const meta = JSON . parse ( metaJson ) ;
202210
203- return { requestJson, meta } ;
211+ return { requestJson, meta } ;
212+ } catch ( e ) {
213+ logger . error ( `Failed to parse request line: ${ lineContent } , error: ${ e } ` ) ;
214+ throw new Error ( `Invalid request line format: ${ e } ` ) ;
215+ }
204216 }
205217
206218 private parseResponseLine ( lineContent : string ) : { responseJson : string ; meta : Record < string , unknown > } {
207- const parts = lineContent . split ( RESPONSE_END_MARKER ) ;
208- const metaJson = parts [ 1 ] ?? '' ;
209- const responseJson = parts [ 0 ] ?. split ( RESPONSE_START_MARKER ) [ 1 ] ?? '' ;
210- const meta = JSON . parse ( metaJson ) ;
211-
212- return { responseJson, meta } ;
219+ try {
220+ const parts = lineContent . split ( RESPONSE_END_MARKER ) ;
221+ const metaJson = parts [ 1 ] ?? '' ;
222+ const responseJson = parts [ 0 ] ?. split ( RESPONSE_START_MARKER ) [ 1 ] ?? '' ;
223+ const meta = JSON . parse ( metaJson ) ;
224+
225+ return { responseJson, meta } ;
226+ } catch ( e ) {
227+ logger . error ( `Failed to parse response line: ${ lineContent } , error: ${ e } ` ) ;
228+ throw new Error ( `Invalid response line format: ${ e } ` ) ;
229+ }
213230 }
214231
215232 private async readLastRequestLine ( ) : Promise < string > {
216- const content = readFileSync ( this . logFile , 'utf-8' ) ;
233+ const content = await readFile ( this . logFile , 'utf-8' ) ;
217234 const lines = content . split ( '\n' ) . filter ( ( l ) => l . trim ( ) ) ;
218235
219236 for ( let i = lines . length - 1 ; i >= 0 ; i -- ) {
@@ -227,7 +244,7 @@ export class ModelClient {
227244 }
228245
229246 private async readLastResponseLine ( ) : Promise < string | null > {
230- const content = readFileSync ( this . logFile , 'utf-8' ) ;
247+ const content = await readFile ( this . logFile , 'utf-8' ) ;
231248 const lines = content . split ( '\n' ) . filter ( ( l ) => l . trim ( ) ) ;
232249
233250 for ( let i = lines . length - 1 ; i >= 0 ; i -- ) {
@@ -240,8 +257,8 @@ export class ModelClient {
240257 return null ;
241258 }
242259
243- private appendResponse ( content : string ) : void {
244- appendFileSync ( this . logFile , content ) ;
260+ private async appendResponse ( content : string ) : Promise < void > {
261+ await appendFile ( this . logFile , content ) ;
245262 }
246263
247264 private constructResponse ( lastResponse : string , index : number ) : string {
0 commit comments