Skip to content

Commit 1c3fa8c

Browse files
committed
Merge remote-tracking branch 'upstream/main' into feature/valkey
; Conflicts: ; CHANGELOG.md
2 parents 71d14f1 + c87e487 commit 1c3fa8c

757 files changed

Lines changed: 10199 additions & 8843 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.git-blame-ignore-revs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Switch to SPDX license headers (#4533)
2+
# TODO: update with the squash-merge commit SHA after merge
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
---
2+
applyTo: "instrumentation-genai/**"
3+
---
4+
5+
Review rules for PRs touching `instrumentation-genai/**`. Flag violations with a link to the rule.
6+
7+
These rules are additive to
8+
[`instrumentation.instructions.md`](instrumentation.instructions.md), which applies to all
9+
instrumentation packages.
10+
11+
## 1. Scope of `instrumentation-genai/`
12+
13+
Only for:
14+
15+
- Generative AI inference providers,
16+
- Agentic frameworks,
17+
- Libraries directly supporting the above (e.g., MCP, GenAI protocols).
18+
19+
Database clients (including vector DBs used outside a GenAI-specific client) and CLI libs belong
20+
in `instrumentation/`, not here.
21+
22+
## 2. GenAI component ownership
23+
24+
See [`CONTRIBUTING.md#guideline-for-genai-instrumentations`](../../CONTRIBUTING.md#guideline-for-genai-instrumentations)
25+
for GenAI-specific maintenance expectations on top of the general
26+
[instrumentation checklist](../../CONTRIBUTING.md#guideline-for-instrumentations).
27+
28+
## 3. Telemetry and configuration via `opentelemetry-util-genai`
29+
30+
- Spans, logs, metrics, and events must go through `opentelemetry-util-genai`. Direct use of
31+
`Tracer`, `Meter`, `Logger`, or event APIs is not allowed.
32+
- Content capture, hooks, and other cross-cutting configuration are owned by the util.
33+
Instrumentations must not introduce their own env vars, settings, or hook interfaces.
34+
- Message content, prompts, and tool call arguments must only be set through the util's content
35+
capture path — never as unconditional span/log attributes.
36+
- Adding attributes to invocations produced by the util is fine.
37+
- If a capability is missing in `opentelemetry-util-genai`, land it in the util first.
38+
39+
## 4. GenAI semantic conventions
40+
41+
- Attributes, spans, events, and metrics must match the
42+
[GenAI semantic conventions](https://github.com/open-telemetry/semantic-conventions/tree/main/docs/gen-ai).
43+
- `gen_ai.*` attribute names must come from
44+
`opentelemetry.semconv._incubating.attributes.gen_ai_attributes`.
45+
- For attributes with a well-known value set, use the generated enum from the same module
46+
(e.g. `GenAiOutputTypeValues` for `gen_ai.output.type`) instead of string literals.
47+
48+
## 5. Tests
49+
50+
- Use recorded VCR cassettes for provider calls. No live-key-only tests; skipping on missing key
51+
is not acceptable.
52+
- Cover streaming and non-streaming variants when both exist.
53+
- For error scenarios, at minimum include: provider error / endpoint unavailable, stream
54+
interrupted by network, stream closed early by the caller.
55+
56+
## 6. Examples
57+
58+
New instrumentations must ship a minimal example under the package's `examples/`, with both a
59+
`manual/` and a `zero-code/` (auto-instrumentation) variant.
60+
61+
## 7. PR description
62+
63+
- Cover which part of the GenAI semconv the change implements or follows (when applicable) and
64+
how instrumentations should consume it.
65+
66+
See also [AGENTS.md](../../AGENTS.md) for general repo rules.
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
---
2+
applyTo: "{instrumentation,instrumentation-genai}/**"
3+
---
4+
5+
Review rules for PRs touching `instrumentation/**` and `instrumentation-genai/**`. Flag violations
6+
with a link to the rule.
7+
8+
## 0. Reviewer mindset
9+
10+
Review as long-term maintainer.
11+
12+
For new instrumentations, consult upstream library docs and judge:
13+
14+
- Does the library already emit its own telemetry, making this instrumentation redundant?
15+
- Is the library used widely enough to warrant a package in this repo?
16+
- Does it avoid unbounded in-memory accumulation or other side-effects?
17+
18+
For changes to existing instrumentations: prefer back-compat. Break users only for a real reason;
19+
prefer opt-in or additive. Breaking changes need explicit justification in the PR.
20+
21+
## 1. Component ownership & maintenance commitment
22+
23+
- New instrumentations must add an entry under the correct folder in
24+
[`component_owners.yml`](../component_owners.yml) in the same PR. Contributor must commit to
25+
long-term maintenance. See
26+
[Expectations from contributors](../../CONTRIBUTING.md#expectations-from-contributors) and the
27+
general [instrumentation checklist](../../CONTRIBUTING.md#guideline-for-instrumentations).
28+
29+
## 2. Semantic conventions
30+
31+
- Attribute names must come from the semconv attribute modules, not hardcoded strings. Use the
32+
module matching the namespace under `opentelemetry.semconv` (e.g. `server_attributes`,
33+
`error_attributes`, `http_attributes`, `db_attributes`, …).
34+
- For attributes with a well-known value set in semconv, use the generated enum from the same
35+
modules instead of string literals.
36+
- If a signal is not in semconv, wait until semconv lands.
37+
38+
## 3. Exception handling
39+
40+
- When catching exceptions from the underlying library to record telemetry, always re-raise the
41+
original exception unmodified.
42+
- Do not raise **new** exceptions in instrumentation/telemetry code.
43+
44+
## 4. Tests
45+
46+
- For every public API instrumented, cover sync/async variants when both exist.
47+
- Cover happy path and error scenarios.
48+
- Tests must verify exact attribute names **and value types**, checked against the semconv spec.
49+
- Test against oldest and latest supported library versions via `tests/requirements.{oldest,latest}.txt`
50+
and `{oldest,latest}` `tox.ini` factors.
51+
52+
See also [AGENTS.md](../../AGENTS.md) for general repo rules.
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
---
2+
applyTo: "util/opentelemetry-util-genai/**"
3+
---
4+
5+
Review rules for PRs touching `util/opentelemetry-util-genai/**`. Flag violations with a link to
6+
the rule.
7+
8+
## 0. Reviewer mindset
9+
10+
Review as long-term maintainer. Every GenAI instrumentation in the repo depends on this package;
11+
churn breaks them. Default to back-compat changes. Every public addition is a long-term
12+
commitment — limit public API.
13+
14+
## 1. Semconv first
15+
16+
No code without semconv. If a signal, attribute, or operation is not in the
17+
[GenAI semconv](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/),
18+
land the semconv change first.
19+
20+
## 2. Semantic conventions
21+
22+
- Names (attributes, operations, spans) must match semconv exactly.
23+
- Use matching `opentelemetry.semconv` modules per namespace (`gen_ai`, `server`, `error`, …).
24+
Do not hardcode name strings if a constant exists.
25+
- Shared attributes must behave consistently across invocation types (same conditions, same
26+
defaults). If semconv marks an attribute for multiple invocations, set it on all.
27+
28+
## 3. API backwards compatibility
29+
30+
- Do not remove or rename public objects. Deprecate first via a docstring note pointing to the
31+
replacement (not `@deprecated` — unreliable).
32+
- Private modules and module-private objects start with `_`.
33+
- Default to internal (`_`-prefixed) unless instrumentations need it public.
34+
35+
## 4. Invocation shape
36+
37+
- `start_*()` factories must accept all sampling-relevant semconv attributes as parameters.
38+
Attributes also marked required by semconv must be required parameters (no default value).
39+
- `start_*()` factories must map 1:1 to distinct semconv operation types (inference, embeddings,
40+
tool execution, agent invocation, workflow invocation). Names must match the operation
41+
unambiguously — e.g., `create_agent` vs `invoke_agent` are distinct ops; `start_agent()` alone
42+
is ambiguous.
43+
- Each operation exposes both a factory (`start_inference(...)`) and a context-manager
44+
(`inference(...)`) form.
45+
- Never construct invocation types directly (`InferenceInvocation(...)`) — skips span creation,
46+
silent no-ops. Always use `handler.start_*()` or the context manager.
47+
48+
## 5. Exception handling
49+
50+
- When catching exceptions from the underlying library to record telemetry, always re-raise the
51+
original exception unmodified.
52+
- Do not raise **new** exceptions in utils code.
53+
54+
## 6. Performance
55+
56+
Keep the hot path tight:
57+
58+
- Avoid per-invocation allocations; do not accumulate state unboundedly.
59+
- Skip content capture when content capture is disabled.
60+
- Skip setting span attributes when the span is not recording.
61+
- Still record attributes that feed metrics — metric recording is independent of span sampling.
62+
63+
## 7. DRY
64+
65+
Do not copy-paste logic across invocation types. Extract shared helpers.
66+
67+
## 8. Tests
68+
69+
- Every new operation type or attribute change needs tests asserting exact attribute names **and
70+
value types**, checked against semconv.
71+
- Cover success (`invocation.stop()`), failure (`invocation.fail(exc)`), and conditional
72+
attribute logic.
73+
- Prefer public API in tests.
74+
75+
## 9. Documentation
76+
77+
- Docstrings for invocation types and span/event helpers must link to the corresponding semconv
78+
op.
79+
- When adding/changing attributes, update the docstring with what is set and when.
80+
81+
## 10. PR description
82+
83+
- Cover which part of the GenAI semconv the change implements or follows (when applicable) and
84+
how instrumentations should consume it.
85+
86+
See also [AGENTS.md](../../AGENTS.md) for general repo rules.

.github/labeler.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
gen-ai:
2+
- changed-files:
3+
- any-glob-to-any-file:
4+
- 'instrumentation-genai/**'
5+
- 'util/opentelemetry-util-genai/**'
6+
- 'docs/instrumentation-genai/**'
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Add PR to project board
2+
3+
on:
4+
pull_request_target:
5+
types: [opened, reopened, ready_for_review]
6+
7+
permissions:
8+
contents: read
9+
10+
jobs:
11+
add-to-project:
12+
name: add to project board
13+
runs-on: ubuntu-latest
14+
if: github.event.pull_request.draft == false
15+
steps:
16+
# NOTE: do NOT add an actions/checkout step here. This workflow uses
17+
# pull_request_target (which has access to secrets) but must never
18+
# execute code from the fork branch. See open-telemetry/opentelemetry-python#4955 for context.
19+
- uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
20+
id: otelbot-token
21+
with:
22+
app-id: ${{ vars.OTELBOT_PYTHON_APP_ID }}
23+
private-key: ${{ secrets.OTELBOT_PYTHON_PRIVATE_KEY }}
24+
25+
- uses: actions/add-to-project@v1.0.2
26+
with:
27+
project-url: https://github.com/orgs/open-telemetry/projects/88
28+
github-token: ${{ steps.otelbot-token.outputs.token }}

.github/workflows/check-links.yml

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
name: check-links
2+
on:
3+
push:
4+
branches: [ main ]
5+
paths:
6+
- '**/*.md'
7+
- '**/*.rst'
8+
- '.github/workflows/check-links.yml'
9+
- '.github/workflows/check_links_config.json'
10+
pull_request:
11+
paths:
12+
- '**/*.md'
13+
- '**/*.rst'
14+
- '.github/workflows/check-links.yml'
15+
- '.github/workflows/check_links_config.json'
16+
17+
permissions:
18+
contents: read
19+
20+
concurrency:
21+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
22+
cancel-in-progress: true
23+
24+
jobs:
25+
check-links:
26+
runs-on: ubuntu-latest
27+
if: ${{ github.actor != 'dependabot[bot]' && github.actor != 'otelbot[bot]' }}
28+
timeout-minutes: 15
29+
steps:
30+
- name: Checkout Repo
31+
uses: actions/checkout@v6
32+
with:
33+
fetch-depth: 0
34+
35+
- name: Get changed markdown files
36+
id: changed-files
37+
uses: tj-actions/changed-files@v46
38+
with:
39+
files: |
40+
**/*.md
41+
**/*.rst
42+
43+
- name: Install markdown-link-check
44+
if: steps.changed-files.outputs.any_changed == 'true'
45+
run: npm install -g markdown-link-check@v3.12.2
46+
47+
- name: Check links on push to main
48+
if: steps.changed-files.outputs.any_changed == 'true' && github.event_name == 'push'
49+
run: |
50+
markdown-link-check \
51+
--verbose \
52+
--config .github/workflows/check_links_config.json \
53+
${{ steps.changed-files.outputs.all_changed_files }} \
54+
|| { echo "Check that anchor links are lowercase"; exit 1; }
55+
56+
- name: Check new links only on pull requests
57+
if: steps.changed-files.outputs.any_changed == 'true' && github.event_name == 'pull_request'
58+
run: |
59+
# Extract URLs only from added lines in the diff to avoid
60+
# rate limiting when checking all links in large files like
61+
# CHANGELOG.md. Only new/changed links are checked on PRs;
62+
# pushes to main still check all links in changed files.
63+
git diff "origin/${{ github.base_ref }}...HEAD" -- \
64+
${{ steps.changed-files.outputs.all_changed_files }} \
65+
| grep '^+' | grep -v '^+++' \
66+
| grep -oP 'https?://[^\s\)\]\"'"'"'`>]+' \
67+
| sort -u > /tmp/new_links.txt
68+
69+
if [ ! -s /tmp/new_links.txt ]; then
70+
echo "No new links found in diff, skipping check"
71+
exit 0
72+
fi
73+
74+
echo "Checking $(wc -l < /tmp/new_links.txt) new links:"
75+
cat /tmp/new_links.txt
76+
77+
# Write links as markdown so markdown-link-check can parse them
78+
awk '{print "- <" $0 ">"}' /tmp/new_links.txt > /tmp/new_links.md
79+
80+
markdown-link-check \
81+
--verbose \
82+
--config .github/workflows/check_links_config.json \
83+
/tmp/new_links.md \
84+
|| { echo "Check that anchor links are lowercase"; exit 1; }
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"ignorePatterns": [
3+
{
4+
"pattern": "http(s)?://\\d+\\.\\d+\\.\\d+\\.\\d+"
5+
},
6+
{
7+
"pattern": "http(s)?://localhost"
8+
},
9+
{
10+
"pattern": "http(s)?://example.com"
11+
}
12+
],
13+
"aliveStatusCodes": [429, 200]
14+
}

.github/workflows/labeler.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: PR Labeler
2+
3+
on:
4+
pull_request_target:
5+
6+
permissions:
7+
contents: read
8+
9+
jobs:
10+
label:
11+
runs-on: ubuntu-latest
12+
permissions:
13+
contents: read
14+
pull-requests: write
15+
steps:
16+
- uses: actions/labeler@v6
17+
with:
18+
sync-labels: false

.github/workflows/lint.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1371,3 +1371,22 @@ jobs:
13711371

13721372
- name: Run tests
13731373
run: tox -e lint-opamp-client
1374+
1375+
lint-license-header-check:
1376+
name: license-header-check
1377+
runs-on: ubuntu-latest
1378+
timeout-minutes: 30
1379+
steps:
1380+
- name: Checkout repo @ SHA - ${{ github.sha }}
1381+
uses: actions/checkout@v4
1382+
1383+
- name: Set up Python 3.14
1384+
uses: actions/setup-python@v5
1385+
with:
1386+
python-version: "3.14"
1387+
1388+
- name: Install tox
1389+
run: pip install tox-uv
1390+
1391+
- name: Run tests
1392+
run: tox -e lint-license-header-check

0 commit comments

Comments
 (0)