@@ -22,97 +22,39 @@ const DEFAULT_PERMISSION_CONFIG: NonNullable<OpencodeConfig["permission"]> = {
2222 webfetch : "allow" ,
2323} ;
2424
25- // Custom fetch with extended timeout and better error handling
26- const customFetch : typeof fetch = async ( input , init ) => {
27- const url = typeof input === "string" ? input : input . url ;
28- const method = init ?. method || "GET" ;
25+ // Custom fetch with focused error logging
26+ const customFetch = async ( request : Request ) : Promise < Response > => {
2927 const startTime = Date . now ( ) ;
3028
31- // Log request details
32- console . error ( `[opencode] ============ FETCH REQUEST START ============` ) ;
33- console . error ( `[opencode] ${ method } ${ url } ` ) ;
34- console . error ( `[opencode] Timeout: 600000ms (10 minutes)` ) ;
35-
36- if ( init ?. headers ) {
37- console . error ( `[opencode] Request Headers:` ) ;
38- const headers = init . headers ;
39- if ( headers instanceof Headers ) {
40- headers . forEach ( ( value , key ) => {
41- console . error ( `[opencode] ${ key } : ${ key . toLowerCase ( ) . includes ( 'auth' ) || key . toLowerCase ( ) . includes ( 'key' ) ? '***REDACTED***' : value } ` ) ;
42- } ) ;
43- } else if ( typeof headers === "object" ) {
44- Object . entries ( headers ) . forEach ( ( [ key , value ] ) => {
45- console . error ( `[opencode] ${ key } : ${ key . toLowerCase ( ) . includes ( 'auth' ) || key . toLowerCase ( ) . includes ( 'key' ) ? '***REDACTED***' : value } ` ) ;
46- } ) ;
47- }
48- } else {
49- console . error ( `[opencode] Request Headers: none` ) ;
50- }
51-
52- if ( init ?. body ) {
53- const bodyStr = typeof init . body === "string" ? init . body : String ( init . body ) ;
54- console . error ( `[opencode] Request Body Length: ${ bodyStr . length } bytes` ) ;
55- // Don't log full body to avoid sensitive data, but show a preview
56- if ( bodyStr . length < 500 ) {
57- console . error ( `[opencode] Request Body Preview: ${ bodyStr . substring ( 0 , 200 ) } ...` ) ;
58- }
59- }
60-
6129 try {
62- // Extend timeout to 10 minutes for long-running LLM requests
63- const controller = new AbortController ( ) ;
64- const timeoutId = setTimeout ( ( ) => {
65- const duration = Date . now ( ) - startTime ;
66- console . error ( `[opencode] ⏱️ REQUEST TIMEOUT after ${ duration } ms` ) ;
67- controller . abort ( ) ;
68- } , 600_000 ) ; // 10 minutes
69-
70- const response = await fetch ( input , {
71- ...init ,
72- signal : controller . signal ,
73- } ) ;
74-
75- clearTimeout ( timeoutId ) ;
30+ const response = await fetch ( request ) ;
7631 const duration = Date . now ( ) - startTime ;
7732
78- console . error ( `[opencode] ============ FETCH RESPONSE ============` ) ;
79- console . error ( `[opencode] Status: ${ response . status } ${ response . statusText } ` ) ;
80- console . error ( `[opencode] Duration: ${ duration } ms` ) ;
81-
82- // Log response headers
83- console . error ( `[opencode] Response Headers:` ) ;
84- response . headers . forEach ( ( value , key ) => {
85- console . error ( `[opencode] ${ key } : ${ value } ` ) ;
86- } ) ;
87-
88- if ( ! response . ok ) {
89- const responseText = await response . clone ( ) . text ( ) . catch ( ( ) => "Unable to read body" ) ;
90- console . error ( `[opencode] ❌ HTTP ${ response . status } Response Body:` ) ;
91- console . error ( responseText . substring ( 0 , 1000 ) ) ;
92- } else {
93- console . error ( `[opencode] ✅ Request successful` ) ;
33+ // Only log non-OK responses or slow requests
34+ if ( ! response . ok || duration > 60000 ) {
35+ console . error ( `[opencode] Request to ${ request . url } - Status: ${ response . status } , Duration: ${ duration } ms` ) ;
36+
37+ if ( ! response . ok ) {
38+ try {
39+ const clonedResponse = response . clone ( ) ;
40+ const responseText = await clonedResponse . text ( ) ;
41+ console . error ( `[opencode] Full error response body:` , responseText ) ;
42+ } catch ( e ) {
43+ console . error ( `[opencode] Could not read error response body` ) ;
44+ }
45+ }
9446 }
9547
96- console . error ( `[opencode] ============ FETCH REQUEST END ============` ) ;
9748 return response ;
9849 } catch ( error ) {
9950 const duration = Date . now ( ) - startTime ;
100- console . error ( `[opencode] ============ FETCH ERROR ============` ) ;
101- console . error ( `[opencode] ❌ Fetch failed for ${ method } ${ url } ` ) ;
102- console . error ( `[opencode] Duration: ${ duration } ms` ) ;
103- console . error ( `[opencode] Error Type: ${ error instanceof Error ? error . name : typeof error } ` ) ;
104- console . error ( `[opencode] Error Message: ${ error instanceof Error ? error . message : String ( error ) } ` ) ;
51+ console . error ( `[opencode] FETCH FAILED - URL: ${ request . url } , Duration: ${ duration } ms` ) ;
52+ console . error ( `[opencode] Error: ${ error instanceof Error ? error . message : String ( error ) } ` ) ;
10553
10654 if ( error instanceof Error && error . stack ) {
107- console . error ( `[opencode] Error Stack:` ) ;
108- console . error ( error . stack ) ;
109- }
110-
111- if ( error && typeof error === "object" && "cause" in error ) {
112- console . error ( `[opencode] Error Cause:` , error . cause ) ;
55+ console . error ( `[opencode] Stack:` , error . stack ) ;
11356 }
11457
115- console . error ( `[opencode] ============ FETCH ERROR END ============` ) ;
11658 throw error ;
11759 }
11860} ;
@@ -121,11 +63,12 @@ const opencodePort = await detectPort(4096);
12163
12264const opencode = await createOpencode ( {
12365 port : opencodePort ,
66+ timeout : 600_000 , // 10 minutes timeout for long-running LLM requests
12467 config : {
12568 permission : DEFAULT_PERMISSION_CONFIG ,
12669 } ,
127- fetch : customFetch ,
12870} ) ;
71+
12972process . once ( "beforeExit" , ( ) => opencode . server . close ( ) ) ;
13073
13174const sessionCache = new Map < string , string > ( ) ;
@@ -258,18 +201,12 @@ const opencodeAgent: AgentDefinition = {
258201
259202 let sessionID = sessionCache . get ( cacheKey ) ;
260203 if ( ! sessionID ) {
261- console . error ( `[opencode] Creating new session for ${ cacheKey } in directory ${ cwd } ` ) ;
262- const sessionStartTime = Date . now ( ) ;
263204 const { data : session } = await opencode . client . session . create ( {
264205 query : { directory : cwd } ,
265206 throwOnError : true ,
266207 } ) ;
267- const sessionDuration = Date . now ( ) - sessionStartTime ;
268208 sessionID = session . id ;
269209 sessionCache . set ( cacheKey , sessionID ) ;
270- console . error ( `[opencode] Session created with ID ${ sessionID } in ${ sessionDuration } ms` ) ;
271- } else {
272- console . error ( `[opencode] Reusing cached session ${ sessionID } for ${ cacheKey } ` ) ;
273210 }
274211
275212 const actions : string [ ] = [ ] ;
@@ -279,11 +216,7 @@ const opencodeAgent: AgentDefinition = {
279216 } ;
280217 try {
281218 const [ providerID , modelID ] = model . split ( "/" ) ;
282- console . error ( `[opencode] Sending prompt to session ${ sessionID } with model ${ providerID } /${ modelID } ` ) ;
283- console . error ( `[opencode] Prompt length: ${ prompt . length } characters` ) ;
284- console . error ( `[opencode] Working directory: ${ cwd } ` ) ;
285219
286- const promptStartTime = Date . now ( ) ;
287220 const { data } = await opencode . client . session . prompt ( {
288221 path : { id : sessionID ! } ,
289222 query : { directory : cwd } ,
@@ -295,15 +228,17 @@ const opencodeAgent: AgentDefinition = {
295228 parts : [ { type : "text" , text : prompt } ] ,
296229 } ,
297230 throwOnError : true ,
231+ fetch : customFetch ,
298232 } ) ;
299- const promptDuration = Date . now ( ) - promptStartTime ;
300-
301- console . error ( `[opencode] Prompt completed in ${ promptDuration } ms` ) ;
302- console . error ( `[opencode] Response parts count: ${ Array . isArray ( data . parts ) ? data . parts . length : 'invalid' } ` ) ;
303- console . error ( `[opencode] Token usage: input=${ data . info . tokens . input } , output=${ data . info . tokens . output } ` ) ;
304233
305- usage . input = data . info . tokens . input ;
306- usage . output = data . info . tokens . output ;
234+ if ( data . info ?. tokens ) {
235+ usage . input = data . info . tokens . input || 0 ;
236+ usage . output = data . info . tokens . output || 0 ;
237+ } else {
238+ console . error (
239+ `[opencode] WARNING: No token usage in response. Available fields: ${ Object . keys ( data . info || { } ) . join ( ", " ) } ` ,
240+ ) ;
241+ }
307242
308243 actions . push ( JSON . stringify ( data . info ) ) ;
309244 if ( Array . isArray ( data . parts ) ) {
@@ -312,11 +247,7 @@ const opencodeAgent: AgentDefinition = {
312247
313248 logPromptResult ( data , options ) ;
314249 } catch ( error ) {
315- console . error ( `[opencode] Error occurred during prompt execution for session ${ sessionID } ` ) ;
316- console . error ( `[opencode] Model: ${ model } , CWD: ${ cwd } ` ) ;
317- console . error ( `[opencode] Error details:` , serializeError ( error ) ) ;
318- console . error ( `[opencode] Clearing session cache for ${ cacheKey } ` ) ;
319-
250+ console . error ( `[opencode] Error in ${ model } :` , error instanceof Error ? error . message : String ( error ) ) ;
320251 sessionCache . delete ( cacheKey ) ;
321252 logError (
322253 {
0 commit comments