@@ -266,6 +266,16 @@ function synthesizeToolUseId(): string {
266266 return `toolu_${ crypto . randomUUID ( ) . replace ( / - / g, "" ) . slice ( 0 , 24 ) } ` ;
267267}
268268
269+ /**
270+ * A tool_use id that a client can actually echo back. `??` only catches a missing
271+ * field, so an Anthropic-compatible relay that sends `""` or `" "` produced a
272+ * call whose id round-trips as blank — the next turn then cannot pair the result
273+ * with its call. Treat blank as absent and synthesize (#765).
274+ */
275+ function usableToolUseId ( id : unknown ) : string {
276+ return typeof id === "string" && id . trim ( ) ? id : synthesizeToolUseId ( ) ;
277+ }
278+
269279function toolUseArguments ( input : unknown ) : string {
270280 if ( typeof input === "string" ) {
271281 const trimmed = input . trim ( ) ;
@@ -824,7 +834,7 @@ export function createAnthropicAdapter(provider: OcxProviderConfig, cacheRetenti
824834 if ( ! block ) break ;
825835 currentBlockType = block . type ;
826836 if ( block . type === "tool_use" ) {
827- currentToolCallId = block . id ?? synthesizeToolUseId ( ) ;
837+ currentToolCallId = usableToolUseId ( block . id ) ;
828838 currentToolCallName = toolNames . fromWire ( block . name ?? "" ) ;
829839 currentToolCallJson = "" ;
830840 yield { type : "tool_call_start" , id : currentToolCallId , name : currentToolCallName } ;
@@ -938,7 +948,7 @@ export function createAnthropicAdapter(provider: OcxProviderConfig, cacheRetenti
938948 } else if ( block . type === "redacted_thinking" && typeof block . data === "string" ) {
939949 events . push ( { type : "redacted_thinking" , data : block . data } ) ;
940950 } else if ( block . type === "tool_use" ) {
941- const id = block . id ?? synthesizeToolUseId ( ) ;
951+ const id = usableToolUseId ( block . id ) ;
942952 events . push ( { type : "tool_call_start" , id, name : toolNames . fromWire ( block . name ?? "" ) } ) ;
943953 events . push ( { type : "tool_call_delta" , arguments : toolUseArguments ( block . input ) } ) ;
944954 events . push ( { type : "tool_call_end" } ) ;
0 commit comments