Skip to content

plugins/phonic: add configs_for_tools for per-tool behavior overrides - #6634

Merged
tinalenguyen merged 8 commits into
livekit:mainfrom
Phonic-Co:arun/phonic-configs-for-tools
Jul 31, 2026
Merged

plugins/phonic: add configs_for_tools for per-tool behavior overrides#6634
tinalenguyen merged 8 commits into
livekit:mainfrom
Phonic-Co:arun/phonic-configs-for-tools

Conversation

@arunwpm-work

Copy link
Copy Markdown
Contributor

What

Adds configs_for_tools to the Phonic realtime model — per-tool behavior overrides forwarded to Phonic's tool config. One entry per tool (keyed by name); each may set require_speech_before_tool_call, forbid_speech_after_tool_call, and forbid_tool_call_after_speech. Omitted fields fall back to the plugin defaults; tools with no entry are unchanged. wait_for_speech_before_tool_call (on) and allow_tool_chaining (off) remain fixed by the plugin.

This generalizes the existing forbid_speech_after_tool_call: list[str] option into a single per-tool config object, and adds forbid_tool_call_after_speech (drop a tool call if the agent already spoke that turn). See the plugin README for the field reference.

arunwpm-work and others added 6 commits June 17, 2026 16:07
…ll_after_speech)

Replace the forbid_speech_after_tool_call: list[str] option with configs_for_tools:
list[PhonicToolConfig] — one object per tool ({name, ...}) carrying up to the full
behavior set (wait_for_speech_before_tool_call, forbid_speech_after_tool_call,
forbid_tool_call_after_speech, allow_tool_chaining); omitted fields fall back to the
plugin defaults. The plugin forwards each object as the tool's Phonic tool_config
(passthrough) and reads forbid_speech_after_tool_call for its own assistant-turn logic.

Adds forbid_tool_call_after_speech (echo drops the tool call if the agent spoke that
turn). Supersedes the un-PR'd arun/phonic-forbid-speech-after-tool-call branch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…or-tools

# Conflicts:
#	livekit-plugins/livekit-plugins-phonic/livekit/plugins/phonic/realtime/realtime_model.py
Add the remaining per-tool field (require_speech_before_tool_call) and move the
per-field behavior docs out of inline comments/docstrings into the plugin README.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…configurable

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@arunwpm-work
arunwpm-work marked this pull request as ready for review July 31, 2026 00:32
@arunwpm-work
arunwpm-work requested a review from a team as a code owner July 31, 2026 00:32

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

View 1 additional finding in Devin Review.

Open in Devin Review

Comment on lines 459 to 466
return

self._tools = llm.ToolContext(tools)
self._forbid_speech_after_tool_call = set(
self._opts.forbid_speech_after_tool_call
if is_given(self._opts.forbid_speech_after_tool_call)
else []
self._configs_for_tools = (
{c["name"]: c for c in self._opts.configs_for_tools}
if is_given(self._opts.configs_for_tools)
else {}
)

@devin-ai-integration devin-ai-integration Bot Jul 31, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Leaving out a tool's name in the new per-tool settings crashes the session start with an unclear error

A per-tool settings entry with no tool name is looked up by name without a fallback (c["name"] at livekit-plugins/livekit-plugins-phonic/livekit/plugins/phonic/realtime/realtime_model.py:463) while the type definition marks every field as optional, so a misconfigured entry aborts session setup with an unhelpful crash instead of a clear message.
Impact: Users who omit a tool name see an opaque failure when the agent starts instead of a readable configuration error.

TypedDict total=False makes `name` optional to the type checker, so the missing key is only caught at runtime

PhonicToolConfig is declared TypedDict, total=False (livekit-plugins/livekit-plugins-phonic/livekit/plugins/phonic/realtime/realtime_model.py:59-66), so mypy accepts {"forbid_speech_after_tool_call": True} without name, even though the docstring and README state name is required. update_tools then builds the lookup with {c["name"]: c for c in ...} which raises KeyError: 'name'. Making name a required key (e.g. a total=True base TypedDict inherited by the optional-field TypedDict) would surface the mistake statically and avoid the runtime crash. Duplicate name entries also silently overwrite each other in the same comprehension.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Re-add the removed forbid_speech_after_tool_call: list[str] option for backwards
compatibility. It logs a deprecation warning and folds each listed tool into
configs_for_tools (an explicit configs_for_tools entry wins).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@tinalenguyen tinalenguyen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, left a small comment!

Parity with the JS plugin's realtime index export so callers can import the
per-tool config type.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@tinalenguyen
tinalenguyen merged commit 4b80b93 into livekit:main Jul 31, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants