Skip to content

feat(telemetry): emit AgentConfigUpdate in OTLP session logs#1436

Closed
toubatbrian wants to merge 1 commit into
mainfrom
claude/quirky-galileo-SVAAA
Closed

feat(telemetry): emit AgentConfigUpdate in OTLP session logs#1436
toubatbrian wants to merge 1 commit into
mainfrom
claude/quirky-galileo-SVAAA

Conversation

@toubatbrian
Copy link
Copy Markdown
Contributor

Summary

Ports livekit/agents#5601 from livekit/agents (Python) into agents-js.

The Python PR makes AgentConfigUpdate items reach the OTLP chat_history exporter so config changes (instructions / tool list) appear alongside the surrounding conversation in session logs, while skipping no-op updates.

In agents-js, AgentConfigUpdate was not yet ported (existing TODO(parity) markers in chat_context.ts, agent_activity.ts:462, and agent_activity.ts:726), so this PR also lays the prerequisite foundation, then layers PR #5601's behavior on top.

cc @toubatbrian @livekit/agent-devs

What changed

Foundation (prerequisite, not in #5601 itself but required to make it meaningful in JS):

  • agents/src/llm/chat_context.ts
    • New AgentConfigUpdate class (id, optional instructions, optional toolsAdded/toolsRemoved, createdAt, in-memory _tools ToolContext that is intentionally not serialized).
    • ChatItem union now includes AgentConfigUpdate.
    • ChatContext.copy() and ChatContext.merge() gain an excludeConfigUpdate option (mirroring Python's exclude_config_update).
  • agents/src/llm/index.ts — re-exports AgentConfigUpdate.
  • agents/src/llm/provider_format/utils.ts — provider formatters skip agent_config_update items (same behavior as agent_handoff); they aren't serialized into the model input.
  • agents/src/llm/utils.ts — chat-history pretty printer formats agent_config_update items.
  • agents/src/voice/remote_session.tschatItemToProto returns an empty ChatContext_ChatItem wrapper for agent_config_update since the remote-session protobuf does not yet have a corresponding case (keeps wire compat with peers that don't know the type).

Equivalent of PR #5601:

  • agents/src/telemetry/traces.ts
    • New ProtoAgentConfigUpdate shape and agentConfigUpdate field on ProtoChatItem.
    • chatItemToProto emits the new field for agent_config_update items so they appear in the OTLP chat_history log records.
  • agents/src/voice/agent_activity.ts
    • Initial setup (replaces the TODO(parity) at line 462): records an initial AgentConfigUpdate (instructions + tool names) into both agent._chatCtx and agentSession._chatCtx — skipped when there are no instructions and no tools.
    • updateTools (replaces the TODO at line 726): computes toolsAdded/toolsRemoved against the previous tool set, inserts an AgentConfigUpdate into both contexts, and skips when the diff is empty.
  • agents/src/voice/agent_session.ts_chatCtx switched from private to /** @internal */ so AgentActivity can insert into it (matches the existing pattern on Agent._chatCtx).

Implementation nuances (where 1:1 parity wasn't possible)

  • agent_id field: the Python construction sites pass agent_id=self._agent.id, but the Python AgentConfigUpdate Pydantic model does not declare an agent_id field — it is silently dropped. The JS port omits agentId accordingly.
  • update_instructions insertion: the Python PR also wires self._session._chat_ctx.insert(config_update) inside update_instructions. agents-js does not currently have an equivalent updateInstructions method on AgentActivity (instructions are read off agent.instructions and re-applied via updateInstructions(...) from generation.ts — not a config-mutating user-facing API). Therefore only the initial-config and updateTools insertion sites were ported. If/when an updateInstructions method is added to AgentActivity, the same dual-insertion should be wired there.
  • Remote session protobuf: the Python PR doesn't touch this path; in JS we needed an explicit agent_config_update case in chatItemToProto for exhaustiveness. Returning an empty wrapper is the least-invasive option until pb.AgentConfigUpdate lands in @livekit/protocol.
  • get_fnc_tool_names equivalent: Python computes get_fnc_tool_names(self.tools) or None (returns names of function-tools, excluding toolsets). agents-js's ToolContext is { [name: string]: FunctionTool }, so Object.keys(this.tools) is the direct equivalent.

Test plan

  • pnpm build:agents — clean build, no type errors.
  • pnpm lint — no new errors (only pre-existing warnings unrelated to this change).
  • pnpm test -- agents/src/llm/ agents/src/voice/agent_activity — all 284 tests pass.
  • Manual: run a session that calls updateTools and verify agent_config_update items appear in the uploaded session report / OTLP chat history with toolsAdded / toolsRemoved populated and that no-op calls are skipped.

Generated by Claude Code

Ports livekit/agents#5601 from Python.

Adds an AgentConfigUpdate chat item recording changes to the agent's
instructions and tools. The initial agent configuration and subsequent
updateTools calls insert an AgentConfigUpdate into both the agent's
and the session's chat context, and the OTLP chat_history exporter
serializes these items so config changes are visible alongside the
surrounding conversation. Insertions are skipped when there is no
visible diff.
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 8, 2026

🦋 Changeset detected

Latest commit: 6fb4cc2

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

@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 sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6fb4cc21f2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

case 'agent_config_update': {
// The remote session protocol does not yet support agent_config_update items;
// emit an empty wrapper so the wire format stays valid for older peers.
return new pb.ChatContext_ChatItem({});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Drop unsupported config updates from remote history responses

When a session has an initial config update or updateTools() is called, handleGetChatHistory and handleGetAgentInfo map every history item through this helper, so remote clients receive a ChatContext_ChatItem whose item oneof is unset. Older peers do not know agent_config_update, but an empty chat item is still a malformed history entry for clients that switch on item.case; filter these items out of remote-session responses until the protobuf supports the new case.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 5 additional findings.

Open in Devin Review

@u9g u9g closed this May 8, 2026
@u9g u9g deleted the claude/quirky-galileo-SVAAA branch May 8, 2026 18:34
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.

4 participants