Skip to content

Add caller-supplied invocation_id and 0041 reserved keys#94

Merged
chris-colinsky merged 2 commits into
mainfrom
feature/caller-supplied-invocation-id
May 29, 2026
Merged

Add caller-supplied invocation_id and 0041 reserved keys#94
chris-colinsky merged 2 commits into
mainfrom
feature/caller-supplied-invocation-id

Conversation

@chris-colinsky
Copy link
Copy Markdown
Member

@chris-colinsky chris-colinsky commented May 29, 2026

Summary

Implements proposals 0039 (caller-supplied invocation_id) and 0041 (reserved metadata key names), plus a downstream-requested helper.

  • 0039: invoke() accepts a caller-supplied invocation_id — any non-empty URL-safe string, validated at the boundary (validate_invocation_id). A resume still mints a fresh id (each attempt is its own invocation).
  • Langfuse trace.id derivation (§8.4.1): _to_otel_trace_id now derives the trace id from a non-UUID invocation_id via the first 16 bytes of SHA-256 (== Langfuse's create_trace_id(seed)), and trace() surfaces the raw id under trace.metadata.invocation_id so lookup by the caller's value works. UUID ids still map to their dash-stripped hex.
  • Public langfuse_trace_id(invocation_id) helper exposes that mapping (for tooling that jumps from a logged id to a Langfuse trace URL).
  • 0041: caller metadata keys that exactly match an OA-emitted top-level key (the §8.4 Langfuse set plus invocation_id) are rejected, at both the invoke() and mid-invocation set_invocation_metadata() boundaries (both route through _validate_metadata_key).

Test plan

  • uv run pytest -q (949 passed)
  • ruff + pyright clean
  • CI

Follow-up (separate PR)

The conformance fixtures for these (035/036/057 for 0039, plus the 0041 fixtures) land with the spec submodule bump to v0.31.0 — that bump is shared with the 0040 work.

0039: invoke() accepts a caller-supplied invocation_id (any non-empty
URL-safe string, validated at the boundary); resume still mints a
fresh id. The Langfuse adapter derives the trace.id from a non-UUID id
via SHA-256 (matching create_trace_id) and surfaces the raw id under
trace.metadata.invocation_id; a public langfuse_trace_id() helper
exposes the mapping.

0041: reject caller metadata keys that exactly match an OA-emitted
top-level key (the 8.4 Langfuse set plus invocation_id), at both the
invoke() and mid-invocation set_invocation_metadata() boundaries.

Conformance fixtures (035/036/057, 0041) follow with the spec
submodule bump to v0.31.0.
Copilot AI review requested due to automatic review settings May 29, 2026 15:17
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Implements observability proposals 0039 and 0041 by adding a caller-supplied invocation_id, deriving Langfuse trace.id for non-UUID ids, and rejecting caller metadata keys that would collide with OA-emitted metadata keys.

Changes:

  • Add invoke(..., invocation_id=...) with boundary validation for URL-safe non-empty strings.
  • Update Langfuse adapter trace-id handling to derive OTel/Langfuse trace ids from non-UUID invocation ids (SHA-256 truncation) and surface raw ids in trace.metadata.invocation_id.
  • Reject caller metadata keys that exactly match reserved OA-emitted top-level metadata keys at both invoke() and set_invocation_metadata() boundaries.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/unit/test_observability_metadata.py Adds tests for reserved exact-key rejection and caller-supplied invocation_id.
tests/unit/test_observability_langfuse_adapter.py Updates/extends tests for Langfuse trace-id derivation and metadata surfacing.
src/openarmature/observability/metadata.py Adds reserved exact-key-name validation for invocation metadata.
src/openarmature/observability/langfuse/adapter.py Implements non-UUID trace-id derivation, adds langfuse_trace_id helper, surfaces raw id in trace metadata for non-UUID ids.
src/openarmature/observability/langfuse/init.py Exports the new langfuse_trace_id helper when adapter/extras are available.
src/openarmature/observability/correlation.py Adds validate_invocation_id and exports it.
src/openarmature/graph/compiled.py Adds invocation_id parameter to invoke() and applies boundary validation / minting rules.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/openarmature/observability/metadata.py
Comment thread tests/unit/test_observability_metadata.py
Comment thread src/openarmature/observability/langfuse/__init__.py
From PR #94 review: langfuse_trace_id is a pure mapping (uuid +
hashlib only) and meant for operator / tooling use (e.g. mapping a
logged invocation_id to a Langfuse trace URL), so gating it behind
the [langfuse] extra was unnecessary.

Move _is_uuid, _to_otel_trace_id, and langfuse_trace_id into a new
langfuse/trace_id.py with no SDK import. adapter.py imports the
internal helpers from there (so its own use and the existing
adapter._to_otel_trace_id test reference are unchanged).
langfuse_trace_id is now exported unconditionally from the langfuse
subpackage.
@chris-colinsky chris-colinsky merged commit e2abe86 into main May 29, 2026
6 checks passed
@chris-colinsky chris-colinsky deleted the feature/caller-supplied-invocation-id branch May 29, 2026 19:01
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