Skip to content

Add base Toolset support #1485

Open
toubatbrian wants to merge 9 commits into
mainfrom
brian/base-toolset
Open

Add base Toolset support #1485
toubatbrian wants to merge 9 commits into
mainfrom
brian/base-toolset

Conversation

@toubatbrian
Copy link
Copy Markdown
Contributor

@toubatbrian toubatbrian commented May 13, 2026

Summary

Adds base Toolset support to the JS agents package. Users compose tools and toolsets through a single tools map; toolset lifecycle is discovered implicitly from a symbol back-reference attached to each tool when accessed via Toolset.toolCtx.

This includes:

  • llm.Toolset with id, a toolCtx getter, and default no-op setup() / aclose() hooks for subclasses to override.
  • getOwningToolset(tool) and collectToolsets(toolCtx) helpers for finding the Toolsets backing a ToolContext.
  • ToolCalledEvent and ToolCompletedEvent payload types.
  • AgentActivity lifecycle setup/cleanup for agent-scoped toolsets — discovered by walking agent.toolCtx and deduping by reference.
  • examples/src/basic_toolsets.ts demonstrating Toolset usage.

How it works

Toolset.toolCtx returns shallow clones of its tools with the owning Toolset attached via Symbol.for("livekit.agents.Toolset"). Stamping is lazy and clone-based, so the original tool objects are never mutated: a tool used directly stays unowned, while the same tool spread from someToolset.toolCtx carries the back-reference for lifecycle discovery.

AgentActivity calls collectToolsets(agent.toolCtx) on init / resume to set up the active Toolsets, on close to tear them down, and diffs the discovered sets on updateTools(tools) to setup added / close removed.

Usage

const getWeather = llm.tool({
  description: 'Get the weather for a given location.',
  parameters: z.object({
    location: z.string().describe('The location to get the weather for'),
  }),
  execute: async ({ location }) => {
    return `The weather in ${location} is sunny.`;
  },
});

const lookupTimezone = llm.tool({
  description: 'Look up the timezone for a city or region.',
  parameters: z.object({
    location: z.string().describe('The city or region to look up'),
  }),
  execute: async ({ location }) => {
    return `${location} is in the America/Los_Angeles timezone.`;
  },
});

const locationTools = new llm.Toolset({
  id: 'location_tools',
  tools: {
    getWeather,
    lookupTimezone,
  },
});

const agent = new voice.Agent({
  instructions: 'You are a helpful assistant.',
  tools: {
    ...locationTools.tools,
  },
});

Updating tools later follows the same pattern:

await agent.updateTools({
  ...locationTools.tools,
  extraTool,
});

Test Plan

  • pnpm test agents/src/llm/tool_context.test.ts agents/src/voice/agent.test.ts agents/src/voice/agent_activity.test.ts
  • pnpm --filter @livekit/agents build:types
  • pnpm --filter livekit-agents-examples build

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 13, 2026

🦋 Changeset detected

Latest commit: c5d0149

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 31 packages
Name Type
@livekit/agents Patch
@livekit/agents-plugin-anam Patch
@livekit/agents-plugin-assemblyai Patch
@livekit/agents-plugin-baseten Patch
@livekit/agents-plugin-bey Patch
@livekit/agents-plugin-cartesia Patch
@livekit/agents-plugin-cerebras Patch
@livekit/agents-plugin-deepgram Patch
@livekit/agents-plugin-elevenlabs Patch
@livekit/agents-plugin-fishaudio Patch
@livekit/agents-plugin-google Patch
@livekit/agents-plugin-hedra Patch
@livekit/agents-plugin-hume Patch
@livekit/agents-plugin-inworld Patch
@livekit/agents-plugin-lemonslice Patch
@livekit/agents-plugin-liveavatar Patch
@livekit/agents-plugin-livekit Patch
@livekit/agents-plugin-minimax Patch
@livekit/agents-plugin-mistral Patch
@livekit/agents-plugin-mistralai Patch
@livekit/agents-plugin-neuphonic Patch
@livekit/agents-plugin-openai Patch
@livekit/agents-plugin-phonic Patch
@livekit/agents-plugin-resemble Patch
@livekit/agents-plugin-rime Patch
@livekit/agents-plugin-runway Patch
@livekit/agents-plugin-sarvam Patch
@livekit/agents-plugin-silero Patch
@livekit/agents-plugins-test Patch
@livekit/agents-plugin-trugen Patch
@livekit/agents-plugin-xai Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@toubatbrian toubatbrian changed the title Add Toolsets base class Add base Toolset support May 13, 2026
chatgpt-codex-connector[bot]

This comment was marked as resolved.

toubatbrian and others added 3 commits May 12, 2026 19:19
Drop the dedicated `toolsets` slot from Agent/AgentActivity in favor of
spreading `someToolset.toolCtx` into the agent's regular `tools` map.
Each tool gets stamped in the Toolset constructor with a back-reference
to its owning Toolset via `Symbol.for("livekit.agents.Toolset")`.
AgentActivity discovers the live Toolsets to set up / close by walking
the ToolContext through the new `collectToolsets()` helper, with
`getToolsetReference()` exposed for per-tool access.

This brings the API closer to Python parity (no JS-only `toolsets`
parameter on Agent) and lets users compose tools and toolsets via the
same `tools` map without thinking about lifecycle hooks.
@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ toubatbrian
❌ claude
You have signed the CLA already but the status is still pending? Let us recheck it.

claude and others added 3 commits May 13, 2026 23:44
The Toolset constructor no longer mutates the tool objects it was given.
Instead, the toolCtx getter returns shallow clones with the back-reference
attached, so the same tool used directly via `new Agent({ tools: { tool } })`
stays unowned while `new Agent({ tools: { ...toolset.toolCtx } })` carries
the owning Toolset for lifecycle discovery.
@toubatbrian toubatbrian changed the title Add base Toolset support brianyin/agt-2864-toolsets May 14, 2026
@toubatbrian toubatbrian changed the title brianyin/agt-2864-toolsets Add base Toolset support May 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants