cuddly-vr-85751
12/23/2025, 4:48 PMtall-airline-16756
12/23/2025, 4:48 PMtall-airline-16756
12/23/2025, 4:48 PMcuddly-vr-85751
12/23/2025, 4:50 PMtall-airline-16756
12/23/2025, 4:50 PMmeta_data that should run at specific hooks like before start, on each user turn, or on session end).
• Use dependency injection for testability — pass function objects into WebAgent or AgentSession at construction time.
• Evaluate arbitrary code strings (e.g., exec) supplied in metadata (I can note security risks if you need this).
• Use an event/handler registry so external modules can subscribe to named events (e.g., "on_user_turn", "on_session_end").
Also tell me:
• Which hooks do you want to support (pre-warm, on start, on_user_turn_completed, on session end, other)?
• Do you control the process filesystem (can we import modules) or must everything come from `meta_data`/a remote source?
• Any security constraints (no exec allowed, limited sandbox, only signed plugins)?
Answering those will let me give a focused implementation pattern and a short code example that fits your constraints.cuddly-vr-85751
12/23/2025, 4:51 PMtall-airline-16756
12/23/2025, 4:51 PMexec, only signed plugins, or fully trusted code)
If you confirm, I’ll give a short code pattern for the best-fit option.
Meanwhile, the recommended approaches (pick one after you answer the clarifying questions):
• If tools are local Python modules: import them and call await agent.update_tools([...]) before starting each simulation.
• If tools come from config/meta_data: build tools with function_tool() dynamically and call await agent.update_tools(tools) inside your entrypoint.
• If tools come from an external tool server: configure MCP with mcp.MCPServerHTTP(...) and let the agent load simulation-specific tools at startup.
Tell me which source (a/b/c) and which hook you need and I’ll provide a compact code example.
Sources: Tool definition and use | LiveKit docscuddly-vr-85751
12/23/2025, 4:52 PMtall-airline-16756
12/23/2025, 4:52 PMfunction_tool() and await agent.update_tools(...). This fits your need to reuse one agent for multiple simulations with different tool sets.
1) Define a factory to create tools dynamically:
from livekit.agents import function_tool
def make_tool(name: str, desc: str):
async def impl(*args, **kwargs):
# your tool logic per simulation
return {"name": name, "args": args, "kwargs": kwargs}
return function_tool(impl, name=name, description=desc)
2) In your entrypoint, build tools from meta_data and update the agent before starting the session:
async def entrypoint(ctx: JobContext):
meta_data = await get_all_metadata(ctx)
agent = WebAgent(meta_data)
# Build simulation-specific tools from meta_data (example)
tool_defs = meta_data.get("tools", []) # e.g., [{"name":"simA_calc","desc":"..."}]
tools = [make_tool(td["name"], td.get("desc","")) for td in tool_defs]
# Replace agent's tools for this simulation
await agent.update_tools(tools)
session = AgentSession(vad=ctx.proc.userdata.get("vad"))
await session.start(agent=agent, room=ctx.room)
...
3) If you need to change tools mid-session (per-turn or per-phase), call await agent.update_tools(...) whenever required:
# example inside an event/hook
await agent.update_tools([make_tool("phase2_op", "phase2")])
Notes and tips:
• Define tool behavior in impl to use simulation-specific parameters from meta_data.
• Avoid exec for untrusted code; prefer factories that map names to safe implementations.
• You can also load tool definitions from files or an MCP server, then convert them to function_tool and call update_tools.
If you want, share a sample meta_data["tools"] shape or one tool’s intended behavior and I’ll convert it into a ready-to-run tool factory for your agent.