Skip to content

Commit e97d34b

Browse files
authored
feat(api): add onRequestHeadersReady callback to capture request headers (#635)
1 parent 56ebcb2 commit e97d34b

File tree

3 files changed

+28
-7
lines changed

3 files changed

+28
-7
lines changed

src/api/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ export interface ApiHandlerCreateMessageMetadata {
6969
* @default true
7070
*/
7171
store?: boolean
72+
onRequestHeadersReady?: (headers: Record<string, string>) => void
7273
}
7374

7475
export interface ApiHandler {

src/api/providers/zgsm.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,11 @@ export class ZgsmAiHandler extends BaseProvider implements SingleCompletionHandl
180180
let selectReason: string | undefined
181181
try {
182182
this.logger.info(`[RequestID]:`, requestId)
183+
184+
if (metadata?.onRequestHeadersReady && typeof metadata.onRequestHeadersReady === "function") {
185+
metadata.onRequestHeadersReady(_headers)
186+
}
187+
183188
const { data, response } = await this.client.chat.completions
184189
.create(
185190
requestOptions,

src/core/task/Task.ts

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,8 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
237237
private static lastGlobalApiRequestTime?: number
238238
private autoApprovalHandler: AutoApprovalHandler
239239

240+
lastApiRequestHeaders?: Record<string, string>
241+
240242
/**
241243
* Reset the global API request timestamp. This should only be used for testing.
242244
* @internal
@@ -2484,14 +2486,20 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
24842486
// If there's no assistant_responses, that means we got no text
24852487
// or tool_use content blocks from API which we should assume is
24862488
// an error.
2489+
let requestId = null
2490+
if (this.lastApiRequestHeaders) {
2491+
requestId = this.lastApiRequestHeaders["X-Request-ID"]
2492+
}
24872493

24882494
// Check if we should auto-retry or prompt the user
24892495
const state = await this.providerRef.deref()?.getState()
24902496
if (state?.autoApprovalEnabled && state?.alwaysApproveResubmit) {
24912497
// Auto-retry with backoff - don't persist failure message when retrying
2492-
const errorMsg =
2498+
let errorMsg =
24932499
"Unexpected API Response: The language model did not provide any assistant messages. This may indicate an issue with the API or the model's output."
2494-
2500+
if (requestId) {
2501+
errorMsg += `\n\nRequestId: ${requestId}\n\n`
2502+
}
24952503
await this.backoffAndAnnounce(
24962504
currentItem.retryAttempt ?? 0,
24972505
new Error("Empty assistant response"),
@@ -2517,10 +2525,12 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
25172525
continue
25182526
} else {
25192527
// Prompt the user for retry decision
2520-
const { response } = await this.ask(
2521-
"api_req_failed",
2522-
"The model returned no assistant messages. This may indicate an issue with the API or the model's output.",
2523-
)
2528+
let errMsg = `The model returned no assistant messages. This may indicate an issue with the API or the model's output.`
2529+
if (requestId) {
2530+
errMsg += `\n\nRequestId: ${requestId}\n\n`
2531+
}
2532+
2533+
const { response } = await this.ask("api_req_failed", errMsg)
25242534

25252535
if (response === "yesButtonClicked") {
25262536
await this.say("api_req_retried")
@@ -2913,7 +2923,12 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
29132923
this.skipPrevResponseIdOnce = false
29142924
}
29152925

2916-
const stream = this.api.createMessage(systemPrompt, cleanConversationHistory, metadata)
2926+
const stream = this.api.createMessage(systemPrompt, cleanConversationHistory, {
2927+
...metadata,
2928+
onRequestHeadersReady: (headers: Record<string, string>) => {
2929+
this.lastApiRequestHeaders = headers
2930+
},
2931+
})
29172932
const iterator = stream[Symbol.asyncIterator]()
29182933

29192934
try {

0 commit comments

Comments
 (0)