@@ -239,6 +239,38 @@ function rewriteToolChoice(value: unknown, plan: NamespaceRewritePlan): unknown
239239 return changed ? { ...value , tools } : value ;
240240}
241241
242+ /**
243+ * Keep response restoration inside the caller's per-turn tool authorization boundary. The
244+ * upstream sees every flattened declaration even when `tool_choice` narrows the tools it may call,
245+ * so its output cannot be trusted merely because a wire name appeared in that catalog.
246+ */
247+ function authorizedAliases (
248+ aliases : Map < string , RoutedNamespaceToolIdentity > ,
249+ toolChoice : unknown ,
250+ ) : Map < string , RoutedNamespaceToolIdentity > {
251+ if ( toolChoice === undefined || toolChoice === "auto" || toolChoice === "required" ) return aliases ;
252+ if ( toolChoice === "none" || ! isPlainObject ( toolChoice ) ) return new Map ( ) ;
253+
254+ let authorizedNames : Set < string > ;
255+ if (
256+ ( toolChoice . type === "function" || toolChoice . type === "custom" )
257+ && typeof toolChoice . name === "string"
258+ ) {
259+ authorizedNames = new Set ( [ toolChoice . name ] ) ;
260+ } else if ( toolChoice . type === "allowed_tools" && Array . isArray ( toolChoice . tools ) ) {
261+ authorizedNames = new Set (
262+ toolChoice . tools
263+ . filter ( tool => isPlainObject ( tool ) && typeof tool . name === "string" )
264+ . map ( tool => tool . name as string ) ,
265+ ) ;
266+ } else {
267+ // An explicit selector for another tool kind does not authorize a client namespace call.
268+ return new Map ( ) ;
269+ }
270+
271+ return new Map ( [ ...aliases ] . filter ( ( [ wireName ] ) => authorizedNames . has ( wireName ) ) ) ;
272+ }
273+
242274function rewriteInputItem ( item : unknown , plan : NamespaceRewritePlan , emitted : Set < string > ) : unknown {
243275 if ( ! isPlainObject ( item ) ) return item ;
244276 if ( item . type === "additional_tools" && Array . isArray ( item . tools ) ) {
@@ -292,7 +324,7 @@ export function rewriteRoutedNamespaceToolsForUpstream(body: unknown): {
292324 ...( input !== body . input ? { input } : { } ) ,
293325 ...( toolChoice !== body . tool_choice ? { tool_choice : toolChoice } : { } ) ,
294326 } ,
295- aliases : plan . aliases ,
327+ aliases : authorizedAliases ( plan . aliases , toolChoice ) ,
296328 } ;
297329}
298330
0 commit comments