Skip to content

Design proposal: ToolboxClient middleware / hooks for interceptors #2728

@Deeven-Seru

Description

@Deeven-Seru

Prerequisites

What are you trying to do that currently feels hard or impossible?

Design proposal #2147

Suggested Solution(s)

Proposal: ToolboxClient Middleware / Hooks

AIM
Making things easier to add cross‑cutting behavior around tool calls (logging, input cleanup, retries, recoverable errors) without wrapping every tool manually.

Possible API (Python SDK example)

  from typing import Dict, Any                                                 
                                                                               
  ToolCall = Dict[str, Any]                                                    
  ToolResult = Any                                                             
                                                                               
  class ToolboxMiddleware:                                                     
      def before_call(self, call: ToolCall) -> ToolCall:                       
          return call                                                          
                                                                               
      def after_call(self, call: ToolCall, result: ToolResult) -> ToolResult:  
          return result                                                        
                                                                               
      def on_error(self, call: ToolCall, err: Exception) -> ToolResult |       
Exception:                                                                     
          return err  # default: re-raise                                      
  client = ToolboxClient(                                                      
      ...,                                                                     
      middlewares=[LoggingMW(), RecoverableErrorMW(), InputNormalizeMW()]      
  )                                                                            

Semantics (my guess)

  • before_call: validate or normalize inputs, maybe add metadata
  • after_call: post‑process tool outputs
  • on_error: if the error is “recoverable,” return a tool message instead of raising so the LLM can retry

Example: recoverable error

If params are invalid and we can guess the intended value:

  "Error: input invalid. Did you mean 'X'? Please retry."                      

This seems close to the LangChain “recoverable” pattern the issue mentioned.

Ordering

I think middleware could run in order for before_call, and reverse order for after_call / on_error (stack‑style).

Async

Maybe async versions: before_call_async, after_call_async, on_error_async.

Scope

Maybe support:

  • global middlewares on the client
  • optional per‑tool ooverride if needed

Backwards compatibility

If no middleware is configured, behavior should not be changd.

Alternatives Considered

No response

Additional Details

#2147

Metadata

Metadata

Labels

priority: p3Desirable enhancement or fix. May not be included in next release.type: feature request‘Nice-to-have’ improvement, new feature or different behavior or design.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions