Skip to content

[Feature]: Include usage, user_id in post_llm_call plugin hook #4169

@suksim

Description

@suksim

Problem or Use Case

The post_llm_call plugin hook currently receives these kwargs:

session_id, user_message, assistant_response, conversation_history, model, platform

Missing: usage
Token counts (input_tokens, output_tokens) are already tracked internally in run_agent.py via self.session_input_tokens and self.session_output_tokens, but they are not passed to the hook.

Missing: user_id
The gateway has source.user_id and source.user_name (e.g. from Matrix event.sender), but these are not forwarded to AIAgent or the plugin hook.

This makes it difficult to build observability plugins (e.g. Langfuse, OpenTelemetry exporters) that need to track per-call cost and attribute traces to specific users.

Why this matters:

  • Observability plugins need token usage to calculate cost per model, per user, per session.
  • User attribution is essential for multi-user deployments (Matrix rooms, Discord servers, Slack workspaces).
  • Currently the only workaround for user_id is querying state.db from within the plugin, and for usage there is no workaround without patching run_agent.py.

Environment: Hermes Agent v0.6.0, Langfuse v4 SDK (4.0.4), Platform: Matrix (self-hosted Synapse)

Proposed Solution

Add usage and user_id to the post_llm_call invocation in run_agent.py:

_invoke_hook(
    "post_llm_call",
    session_id=self.session_id,
    user_message=original_user_message,
    assistant_response=final_response,
    conversation_history=list(messages),
    model=self.model,
    platform=getattr(self, "platform", None) or "",
    # --- proposed additions ---
    usage={
        "input_tokens": self.session_input_tokens,
        "output_tokens": self.session_output_tokens,
        "prompt_tokens": self.session_prompt_tokens,
        "completion_tokens": self.session_completion_tokens,
    },
    user_id=getattr(self, "user_id", "") or "",
)

For user_id, the gateway would need to pass source.user_id to AIAgent at construction or as an attribute before calling run_conversation.

I have a working Langfuse plugin using these patches. Happy to submit a PR if the team prefers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions