@@ -39,7 +39,10 @@ import type {
3939 OpenRouterChatModelToolCapabilitiesByName ,
4040 OpenRouterModelInputModalitiesByName ,
4141} from '../model-meta'
42- import type { OpenRouterMessageMetadataByModality } from '../message-types'
42+ import type {
43+ OpenRouterMessageMetadataByModality ,
44+ OpenRouterResponsesToolCallMetadata ,
45+ } from '../message-types'
4346
4447/** Element type of `ResponsesRequest.input` when it's the array form (the
4548 * SDK union also allows a bare string). Pinning to the array element lets
@@ -49,6 +52,16 @@ type InputsItem = Extract<InputsUnion, ReadonlyArray<unknown>>[number]
4952/** ResponsesRequest input content part shape (per-content-part discriminated union). */
5053type ResponsesInputContent = unknown
5154
55+ interface StreamedFunctionCallMetadata {
56+ callId : string
57+ index : number
58+ itemId : string
59+ name : string
60+ started : boolean
61+ ended ?: boolean
62+ pendingArguments ?: string
63+ }
64+
5265export interface OpenRouterResponsesConfig extends SDKOptions { }
5366export type OpenRouterResponsesTextModels =
5467 ( typeof OPENROUTER_CHAT_MODELS ) [ number ]
@@ -91,7 +104,8 @@ export class OpenRouterResponsesTextAdapter<
91104 OpenRouterResponsesTextProviderOptions ,
92105 ResolveInputModalities < TModel > ,
93106 OpenRouterMessageMetadataByModality ,
94- TToolCapabilities
107+ TToolCapabilities ,
108+ OpenRouterResponsesToolCallMetadata
95109> {
96110 override readonly kind = 'text' as const
97111 readonly name = 'openrouter-responses' as const
@@ -109,16 +123,7 @@ export class OpenRouterResponsesTextAdapter<
109123 // Track tool call metadata by unique ID. The Responses API streams tool
110124 // calls with deltas — first chunk has ID/name, subsequent chunks only
111125 // have args. We assign our own indices as we encounter unique ids.
112- const toolCallMetadata = new Map <
113- string ,
114- {
115- index : number
116- name : string
117- started : boolean
118- ended ?: boolean
119- pendingArguments ?: string
120- }
121- > ( )
126+ const toolCallMetadata = new Map < string , StreamedFunctionCallMetadata > ( )
122127
123128 // AG-UI lifecycle tracking
124129 const aguiState = {
@@ -777,16 +782,7 @@ export class OpenRouterResponsesTextAdapter<
777782 */
778783 protected async * processStreamChunks (
779784 stream : AsyncIterable < StreamEvents > ,
780- toolCallMetadata : Map <
781- string ,
782- {
783- index : number
784- name : string
785- started : boolean
786- ended ?: boolean
787- pendingArguments ?: string
788- }
789- > ,
785+ toolCallMetadata : Map < string , StreamedFunctionCallMetadata > ,
790786 options : TextOptions < OpenRouterResponsesTextProviderOptions > ,
791787 aguiState : {
792788 runId : string
@@ -1159,24 +1155,30 @@ export class OpenRouterResponsesTextAdapter<
11591155 let metadata = toolCallMetadata . get ( item . id )
11601156 if ( ! metadata ) {
11611157 metadata = {
1158+ callId : item . callId || item . id ,
11621159 index : chunk . outputIndex ?? 0 ,
1163- name : item . name ,
1160+ itemId : item . id ,
1161+ name : item . name || '' ,
11641162 started : false ,
11651163 }
11661164 toolCallMetadata . set ( item . id , metadata )
1167- } else if ( ! metadata . name ) {
1168- metadata . name = item . name
1165+ } else {
1166+ if ( item . callId ) metadata . callId = item . callId
1167+ if ( ! metadata . name && item . name ) metadata . name = item . name
11691168 }
11701169 if ( ! metadata . started && metadata . name ) {
11711170 yield {
11721171 type : EventType . TOOL_CALL_START ,
1173- toolCallId : item . id ,
1172+ toolCallId : metadata . callId ,
11741173 toolCallName : metadata . name ,
11751174 toolName : metadata . name ,
11761175 parentMessageId : aguiState . messageId ,
11771176 model : model || options . model ,
11781177 timestamp : Date . now ( ) ,
11791178 index : chunk . outputIndex ?? 0 ,
1179+ metadata : {
1180+ itemId : metadata . itemId ,
1181+ } satisfies OpenRouterResponsesToolCallMetadata ,
11801182 }
11811183 metadata . started = true
11821184 }
@@ -1195,15 +1197,17 @@ export class OpenRouterResponsesTextAdapter<
11951197 `${ this . name } .processStreamChunks orphan function_call_arguments.delta` ,
11961198 {
11971199 source : `${ this . name } .processStreamChunks` ,
1198- toolCallId : itemId ,
1200+ // No metadata yet, so the `call_id` is unknown here — only the
1201+ // output item id the delta referenced.
1202+ itemId,
11991203 rawDelta : chunk . delta ,
12001204 } ,
12011205 )
12021206 continue
12031207 }
12041208 yield {
12051209 type : EventType . TOOL_CALL_ARGS ,
1206- toolCallId : itemId ,
1210+ toolCallId : metadata . callId ,
12071211 model : model || options . model ,
12081212 timestamp : Date . now ( ) ,
12091213 delta : typeof chunk . delta === 'string' ? chunk . delta : '' ,
@@ -1222,7 +1226,8 @@ export class OpenRouterResponsesTextAdapter<
12221226 `${ this . name } .processStreamChunks deferring function_call_arguments.done — TOOL_CALL_START not yet emitted (waiting for name)` ,
12231227 {
12241228 source : `${ this . name } .processStreamChunks` ,
1225- toolCallId : itemId ,
1229+ ...( metadata && { toolCallId : metadata . callId } ) ,
1230+ itemId,
12261231 rawArguments : chunk . arguments ,
12271232 } ,
12281233 )
@@ -1243,10 +1248,11 @@ export class OpenRouterResponsesTextAdapter<
12431248 {
12441249 error : toRunErrorPayload (
12451250 parseError ,
1246- `tool ${ name } (${ itemId } ) returned malformed JSON arguments` ,
1251+ `tool ${ name } (${ metadata . callId } ) returned malformed JSON arguments` ,
12471252 ) ,
12481253 source : `${ this . name } .processStreamChunks` ,
1249- toolCallId : itemId ,
1254+ toolCallId : metadata . callId ,
1255+ itemId,
12501256 toolName : name ,
12511257 rawArguments : chunk . arguments ,
12521258 } ,
@@ -1257,7 +1263,7 @@ export class OpenRouterResponsesTextAdapter<
12571263
12581264 yield {
12591265 type : EventType . TOOL_CALL_END ,
1260- toolCallId : itemId ,
1266+ toolCallId : metadata . callId ,
12611267 toolCallName : name ,
12621268 toolName : name ,
12631269 model : model || options . model ,
@@ -1272,25 +1278,31 @@ export class OpenRouterResponsesTextAdapter<
12721278 const item = chunk . item
12731279 if ( item ?. type === 'function_call' && item . id ) {
12741280 const metadata = toolCallMetadata . get ( item . id ) ?? {
1281+ callId : item . callId || item . id ,
12751282 index : chunk . outputIndex ?? 0 ,
1276- name : item . name ,
1283+ itemId : item . id ,
1284+ name : item . name || '' ,
12771285 started : false ,
12781286 }
12791287 if ( ! toolCallMetadata . has ( item . id ) ) {
12801288 toolCallMetadata . set ( item . id , metadata )
1281- } else if ( ! metadata . name ) {
1282- metadata . name = item . name
1289+ } else {
1290+ if ( item . callId ) metadata . callId = item . callId
1291+ if ( ! metadata . name && item . name ) metadata . name = item . name
12831292 }
12841293 if ( ! metadata . started && metadata . name ) {
12851294 yield {
12861295 type : EventType . TOOL_CALL_START ,
1287- toolCallId : item . id ,
1296+ toolCallId : metadata . callId ,
12881297 toolCallName : metadata . name ,
12891298 toolName : metadata . name ,
12901299 parentMessageId : aguiState . messageId ,
12911300 model : model || options . model ,
12921301 timestamp : Date . now ( ) ,
12931302 index : metadata . index ,
1303+ metadata : {
1304+ itemId : metadata . itemId ,
1305+ } satisfies OpenRouterResponsesToolCallMetadata ,
12941306 }
12951307 metadata . started = true
12961308 }
@@ -1312,10 +1324,11 @@ export class OpenRouterResponsesTextAdapter<
13121324 {
13131325 error : toRunErrorPayload (
13141326 parseError ,
1315- `tool ${ name } (${ item . id } ) returned malformed JSON arguments` ,
1327+ `tool ${ name } (${ metadata . callId } ) returned malformed JSON arguments` ,
13161328 ) ,
13171329 source : `${ this . name } .processStreamChunks` ,
1318- toolCallId : item . id ,
1330+ toolCallId : metadata . callId ,
1331+ itemId : item . id ,
13191332 toolName : name ,
13201333 rawArguments : rawArgs ,
13211334 } ,
@@ -1325,7 +1338,7 @@ export class OpenRouterResponsesTextAdapter<
13251338 }
13261339 yield {
13271340 type : EventType . TOOL_CALL_END ,
1328- toolCallId : item . id ,
1341+ toolCallId : metadata . callId ,
13291342 toolCallName : name ,
13301343 toolName : name ,
13311344 model : model || options . model ,
@@ -1348,25 +1361,31 @@ export class OpenRouterResponsesTextAdapter<
13481361 for ( const item of outputItems ) {
13491362 if ( item . type !== 'function_call' || ! item . id ) continue
13501363 const metadata = toolCallMetadata . get ( item . id ) ?? {
1364+ callId : item . callId || item . id ,
13511365 index : 0 ,
1366+ itemId : item . id ,
13521367 name : item . name || '' ,
13531368 started : false ,
13541369 }
13551370 if ( ! toolCallMetadata . has ( item . id ) ) {
13561371 toolCallMetadata . set ( item . id , metadata )
1357- } else if ( ! metadata . name && item . name ) {
1358- metadata . name = item . name
1372+ } else {
1373+ if ( item . callId ) metadata . callId = item . callId
1374+ if ( ! metadata . name && item . name ) metadata . name = item . name
13591375 }
13601376 if ( ! metadata . started && metadata . name ) {
13611377 yield {
13621378 type : EventType . TOOL_CALL_START ,
1363- toolCallId : item . id ,
1379+ toolCallId : metadata . callId ,
13641380 toolCallName : metadata . name ,
13651381 toolName : metadata . name ,
13661382 parentMessageId : aguiState . messageId ,
13671383 model : model || options . model ,
13681384 timestamp : Date . now ( ) ,
13691385 index : metadata . index ,
1386+ metadata : {
1387+ itemId : metadata . itemId ,
1388+ } satisfies OpenRouterResponsesToolCallMetadata ,
13701389 }
13711390 metadata . started = true
13721391 }
@@ -1388,10 +1407,11 @@ export class OpenRouterResponsesTextAdapter<
13881407 {
13891408 error : toRunErrorPayload (
13901409 parseError ,
1391- `tool ${ name } (${ item . id } ) returned malformed JSON arguments` ,
1410+ `tool ${ name } (${ metadata . callId } ) returned malformed JSON arguments` ,
13921411 ) ,
13931412 source : `${ this . name } .processStreamChunks` ,
1394- toolCallId : item . id ,
1413+ toolCallId : metadata . callId ,
1414+ itemId : item . id ,
13951415 toolName : name ,
13961416 rawArguments : rawArgs ,
13971417 } ,
@@ -1401,7 +1421,7 @@ export class OpenRouterResponsesTextAdapter<
14011421 }
14021422 yield {
14031423 type : EventType . TOOL_CALL_END ,
1404- toolCallId : item . id ,
1424+ toolCallId : metadata . callId ,
14051425 toolCallName : name ,
14061426 toolName : name ,
14071427 model : model || options . model ,
@@ -1631,10 +1651,15 @@ export class OpenRouterResponsesTextAdapter<
16311651 typeof toolCall . function . arguments === 'string'
16321652 ? toolCall . function . arguments
16331653 : JSON . stringify ( toolCall . function . arguments )
1654+ const itemId = (
1655+ toolCall . metadata as
1656+ | OpenRouterResponsesToolCallMetadata
1657+ | undefined
1658+ ) ?. itemId
16341659 result . push ( {
16351660 type : 'function_call' ,
16361661 callId : toolCall . id ,
1637- id : toolCall . id ,
1662+ id : itemId || toolCall . id ,
16381663 name : toolCall . function . name ,
16391664 arguments : argumentsString ,
16401665 } )
0 commit comments