@@ -1200,6 +1200,44 @@ export async function startRuntimeRotationProxy(
12001200 continue ;
12011201 }
12021202
1203+ if ( isThreadGoalRequest && isThreadGoalFallbackStatus ( upstream . status ) ) {
1204+ const parsedGoalBody = parseRequestBody ( context . body ) ;
1205+ const fallbackKey = context . sessionKey ;
1206+ const goal =
1207+ typeof parsedGoalBody ?. goal === "string" ? parsedGoalBody . goal : null ;
1208+ if ( ! fallbackKey ) {
1209+ await usageRecorder . record ( {
1210+ outcome : "failure" ,
1211+ statusCode : HTTP_STATUS . BAD_REQUEST ,
1212+ errorCode : "thread_goal_session_key_required" ,
1213+ account : refreshed . account ,
1214+ } ) ;
1215+ writeJson ( res , HTTP_STATUS . BAD_REQUEST , {
1216+ error : {
1217+ message :
1218+ "Thread goal fallback requires a thread_id, threadId, or session header." ,
1219+ code : "thread_goal_session_key_required" ,
1220+ } ,
1221+ } ) ;
1222+ return ;
1223+ }
1224+ await usageRecorder . record ( {
1225+ outcome : "failure" ,
1226+ statusCode : upstream . status ,
1227+ errorCode : "thread_goal_upstream_blocked" ,
1228+ account : refreshed . account ,
1229+ } ) ;
1230+ if ( context . upstreamPath . endsWith ( "/set" ) ) {
1231+ setThreadGoalFallback ( threadGoalFallbacks , fallbackKey , goal ) ;
1232+ writeJson ( res , HTTP_STATUS . OK , { ok : true , goal } ) ;
1233+ return ;
1234+ }
1235+ writeJson ( res , HTTP_STATUS . OK , {
1236+ goal : getThreadGoalFallback ( threadGoalFallbacks , fallbackKey ) ,
1237+ } ) ;
1238+ return ;
1239+ }
1240+
12031241 res . writeHead ( upstream . status , responseHeadersForClient ( upstream . headers ) ) ;
12041242 res . end ( bodyText ) ;
12051243 await usageRecorder . record ( {
@@ -1247,45 +1285,6 @@ export async function startRuntimeRotationProxy(
12471285 continue ;
12481286 }
12491287
1250- if ( isThreadGoalRequest && isThreadGoalFallbackStatus ( upstream . status ) ) {
1251- await readErrorBody ( upstream ) ;
1252- const parsedGoalBody = parseRequestBody ( context . body ) ;
1253- const fallbackKey = context . sessionKey ;
1254- const goal =
1255- typeof parsedGoalBody ?. goal === "string" ? parsedGoalBody . goal : null ;
1256- if ( ! fallbackKey ) {
1257- await usageRecorder . record ( {
1258- outcome : "failure" ,
1259- statusCode : HTTP_STATUS . BAD_REQUEST ,
1260- errorCode : "thread_goal_session_key_required" ,
1261- account : refreshed . account ,
1262- } ) ;
1263- writeJson ( res , HTTP_STATUS . BAD_REQUEST , {
1264- error : {
1265- message :
1266- "Thread goal fallback requires a thread_id, threadId, or session header." ,
1267- code : "thread_goal_session_key_required" ,
1268- } ,
1269- } ) ;
1270- return ;
1271- }
1272- await usageRecorder . record ( {
1273- outcome : "failure" ,
1274- statusCode : upstream . status ,
1275- errorCode : "thread_goal_upstream_blocked" ,
1276- account : refreshed . account ,
1277- } ) ;
1278- if ( context . upstreamPath . endsWith ( "/set" ) ) {
1279- setThreadGoalFallback ( threadGoalFallbacks , fallbackKey , goal ) ;
1280- writeJson ( res , HTTP_STATUS . OK , { ok : true , goal } ) ;
1281- return ;
1282- }
1283- writeJson ( res , HTTP_STATUS . OK , {
1284- goal : getThreadGoalFallback ( threadGoalFallbacks , fallbackKey ) ,
1285- } ) ;
1286- return ;
1287- }
1288-
12891288 if ( isThreadGoalRequest && upstream . status >= 400 ) {
12901289 const forwarded = await forwardStreamingResponse (
12911290 upstream ,
0 commit comments