microsoft / microsoft/agent-framework
[Feature]: Support dynamic tool injection during ChatAgent.run() execution
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 13.6k
- Forks
- 2.3k
- Avg merge
- 2d 45m
- Merged PRs (30d)
- 358
Description
Description
Problem
When a tool function executed during ChatAgent.run() dynamically loads new tools (e.g., by discovering and registering additional capabilities from an MCP server), those new tools are not visible to the LLM within the same run() invocation. This is because run() captures the tool list at the start and uses that fixed list for all subsequent LLM calls within the run loop.
This forces callers to implement a workaround:
- Detect that tools were loaded mid-run (via a flag set by the tool function)
- Discard the current run() response (the LLM couldn't use the new tools, so its response is a throwaway)
- Re-invoke run() with the updated tool list
This wastes one full LLM round-trip per dynamic tool load (~2-5K tokens, 2-10 seconds latency).
Expected Behavior
A tool function executed during run() should be able to make new tools visible to the LLM on its next turn within the same run() call — without requiring the caller to discard the response and re-invoke run().
Possible approaches (in order of our preference):
- Live tool list reference — Instead of copying/snapshotting the tools list at the start of run(), reference it by reference so that mutations (appends) made by tool functions are visible on the next LLM call within the run loop. This is the simplest change and matches how most callers expect mutable lists to behave.
- Tool reload callback — Provide a hook that run() calls before each LLM request to refresh the tool list. For example: ChatAgent(tool_provider=lambda: current_tools).
- Tool injection API — Expose a method like run_context.inject_tools(new_tools) that tool functions can call to update the active tool set for the current run().
Impact
Eliminating the re-run would save ~2-5K tokens and 2-10 seconds of latency per dynamic tool load. For agents that load tools on every new conversation, this is a consistent per-session cost.
Code Sample
Language/SDK
Both
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at ChatAgent.run(), where the issue says the tool list is captured, and trace how that list is supplied to each later LLM call. The issue names no file or test; done means a tool executed during one run can register another tool and the next LLM turn can use it without re-invoking run().
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- ai, backend-api-design
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100