Skip to content

[NA] [SDK] fix: map Hermes provider names to Opik canonical so cost is computed - #21

Merged
JetoPistola merged 2 commits into
mainfrom
danield/NA-map-provider-names-for-opik-cost
Jul 6, 2026
Merged

[NA] [SDK] fix: map Hermes provider names to Opik canonical so cost is computed#21
JetoPistola merged 2 commits into
mainfrom
danield/NA-map-provider-names-for-opik-cost

Conversation

@JetoPistola

@JetoPistola JetoPistola commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

User description

Details

image

Reviewer feedback: the plugin wrote Hermes' provider string (e.g. openai-api) straight onto the Opik LLM span, but Opik only computes/attributes cost when the provider is one it recognizes (opik.types.LLMProvider: openai, anthropic, groq, bedrock, google_ai, google_vertexai, anthropic_vertexai). So openai-api → Opik couldn't calculate cost.

Add providers.to_opik_provider() and apply it to the span's provider field at both LLM-span creation sites (hooks.py):

  • Known Hermes identifiers → Opik canonical: openai-api / openai_responses / codex_responses / azure-openaiopenai; anthropic-api / anthropic_messagesanthropic; gemini / googlegoogle_ai; vertexgoogle_vertexai; bedrock*bedrock; groqgroq.
  • Already-canonical or unrecognized (custom / user-defined Hermes providers) pass through unchanged — Opik simply won't cost an unknown provider, exactly as before, so nothing regresses.
  • Case/whitespace-insensitive; None/empty → None.

Scope: mapping is applied only to the value written to Opik's span provider field (what unlocks Opik's cost calc). Hermes' own pricing path (usage.pyagent.usage_pricing) keeps using the raw Hermes provider name, since Hermes understands its own identifiers — mapping there could break it.

Change checklist

  • Bug fix (cost attribution)
  • Unit tests added
  • User-facing
  • Documentation

Issues

NA — addresses reviewer feedback on the plugin's Opik cost attribution.

Testing

  • New tests/test_providers.py (20 tests): the mapping table, already-canonical pass-through, unknown pass-through, case/whitespace, None/empty, and an end-to-end check that a turn with provider="openai-api" produces an LLM span with provider="openai".
  • Full suite: 90 passed (was 70). ruff check + ruff format --check clean (CI scope).

Documentation

N/A — internal mapping; no API/behavior change beyond correct cost attribution.

🤖 Generated with Claude Code



Generated description

graph LR
on_post_llm_call_("on_post_llm_call"):::modified
to_opik_provider_("to_opik_provider"):::added
on_api_request_error_("on_api_request_error"):::modified
on_post_llm_call_ -- "Normalizes Hermes provider names so Opik costs compute correctly." --> to_opik_provider_
on_api_request_error_ -- "Normalizes provider during error span recording for consistent Opik matching." --> to_opik_provider_
classDef added stroke:#15AA7A
classDef removed stroke:#CD5270
classDef modified stroke:#EDAC4C
linkStyle default stroke:#CBD5E1,font-size:13px
Loading

Map Hermes provider identifiers through providers.to_opik_provider before writing to Opik spans so recognized cost attribution runs on canonical opik.types.LLMProvider names. Cover canonical, custom, and whitespace variants plus the hooks’ LLM span path to ensure the mapping behaves correctly.

TopicDetails
Mapping tests Exercise providers.to_opik_provider and the hook flow against known, canonical, unknown, and whitespace/case variants plus an end-to-end turn so spans emit the expected provider names.
Modified files (1)
  • tests/test_providers.py
Latest Contributors(1)
UserCommitDate
danield@comet.comtest(providers): cover...July 06, 2026
Provider mapping Map Hermes provider identifiers through providers.to_opik_provider before setting the span provider in the hooks so Opik recognizes canonical opik.types.LLMProvider names for cost attribution.
Modified files (2)
  • observability/opik/hooks.py
  • observability/opik/providers.py
Latest Contributors(1)
UserCommitDate
danield@comet.com[NA] [SDK] fix: map He...July 06, 2026
Review this PR on Baz | Customize your next review

…s computed

Opik only calculates/attributes LLM cost when a span's provider is one it
recognizes (opik.types.LLMProvider: openai, anthropic, groq, bedrock, google_ai,
google_vertexai, anthropic_vertexai). The plugin passed Hermes' own provider
string straight through — e.g. 'openai-api' — which Opik doesn't recognize, so
cost was silently not computed on LLM spans.

Add providers.to_opik_provider(): maps known Hermes identifiers (openai-api /
openai_responses / codex_responses -> openai, anthropic_messages -> anthropic,
gemini/google -> google_ai, vertex -> google_vertexai, bedrock* -> bedrock, groq)
to Opik canonical names; already-canonical or unrecognized (custom/user-defined)
providers pass through unchanged so cost calc degrades gracefully. Applied only
to the span's provider field — Hermes' own pricing path (usage.py) keeps using
the raw Hermes name, which it understands.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the single openai end-to-end test with a parametrized one that drives a
real turn through the hooks for each provider (openai-api/_responses/
codex_responses, anthropic*, gemini/google, vertex, bedrock*, groq) and asserts
the emitted LLM span carries Opik's canonical name. Plus an unknown-provider
pass-through-through-hooks case. Proves the whole plugin path per provider with
no real keys; whether Opik then costs each is Opik's job (we stop at the span
boundary). Suite: 100 passed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@JetoPistola
JetoPistola marked this pull request as ready for review July 6, 2026 15:34
@JetoPistola
JetoPistola merged commit f7fd179 into main Jul 6, 2026
10 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.

1 participant