Skip to content

chore: sync main into v1 (7.75.7–7.81.1) - #1169

Merged
eli-r-ph merged 60 commits into
v1from
eli/v1-sync-main-7.81
Nov 2, 2026
Merged

eli-r-ph merged 60 commits into
v1from
eli/v1-sync-main-7.81

Conversation

@eli-r-ph

@eli-r-ph eli-r-ph commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

💡 Motivation and Context

main shipped 7.75.7 through 7.81.1 after the last sync (#1120), so 8.0 would drop those features and fixes, including the privacy-mode fix that keeps content out of AI events (#1105), transactional email (#1093) and metrics autocapture (#992).

Changes

💚 How did you test it?

📝 Checklist

  • All commits are signed (see Commit signing)
  • I reviewed the submitted code.
  • I added tests to verify the changes.
  • I updated the docs if needed.
  • No breaking change or entry added to the changelog.

If releasing new changes

  • Ran sampo add to generate a changeset file

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

🤖 Generated with Claude Code

pcbeingused333 and others added 30 commits November 1, 2026 13:23
* fix(ai): keep streamed OpenAI tool calls that have no index

accumulate_openai_tool_calls skipped every delta without an index, so
tool calls from OpenAI-compatible providers that omit it never reached
$ai_output. A delta with a new id now opens a call, and one without an
id continues the latest call.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>

* fix(ai): keep synthetic tool call keys apart from provider indexes

A call without an index took key max + 1, which a later call with that real index overwrote, merging two calls and dropping one. Index-less calls now get string keys of their own.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>

* fix(ai): widen the streamed tool call accumulator key type

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(ai): update streamed tool call API snapshot

---------

Co-authored-by: Claude Sonnet 5.5 <[email protected]>
Co-authored-by: Manoel Aranda Neto <[email protected]>
(cherry picked from commit ffde3c5)
(cherry picked from commit 7f4c9be)
(cherry picked from commit b5eb2de)
Contributors often open PRs with unsigned commits because signing isn't documented here.

(cherry picked from commit e65ed67)
* fix(flags): fall back for incompatible local regex evaluation

* fix(flags): defer nested regex quantifiers and fast-path ASCII values

* fix(flags): defer strict-end searches with final newline backtracking

* perf(flags): cache pure regex pattern metadata

(cherry picked from commit d58380e)
(cherry picked from commit 72e0131)
(cherry picked from commit a020e70)
… example (#1109)

OpenAI shuts down gpt-image-1 on 2026-10-23 and lists gpt-image-2.5-sunburst or
gpt-image-2.5-flare as the replacement
(https://developers.openai.com/api/docs/deprecations).

Co-authored-by: Claude Sonnet 5.5 <[email protected]>
(cherry picked from commit efc866e)
* fix(mcp): send one $mcp_initialize per initialize request

The Python MCP SDK answers initialize itself, so posthog.mcp sent the
event on the first request of each session, once per process. A
stateless fleet sent one event per pod. A client that sent only
initialize sent no event.

Now MCP SDK 2.x reports the event from Server.middleware, on every
transport. MCP SDK 1.x over HTTP reports it from
PostHogMcpStatelessSessionMiddleware, which takes a new optional
server= argument. MCP SDK 1.x over stdio keeps the first-request
fallback.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* refactor(mcp): read only the initialize response head on mcp 1.x

The mcp 1.x hook now keeps only the status and the Mcp-Session-Id header
of the initialize response. It no longer parses the JSON or SSE body.
The event uses the protocol version that the client asked for.

record_initialize now reads the client name, version, and protocol from
the initialize params and reply, so both hooks pass them through. The
new tests share their request helpers and drop the SSE body case.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(mcp): address review on the initialize hooks

- SSE transport: the initialize event now lands in the session that the
  SSE calls use. On SDK 1.x the middleware leaves SSE requests to the
  first-request fallback. On SDK 2.x the hook uses the process session.
- The bound middleware marks each request that it passes on. The fallback
  now stops only for marked requests, not for every HTTP request.
- The hooks compute the handshake session without a write to the shared
  session that McpAnalytics.capture() reads.
- A server= value that cannot be bound no longer breaks requests.
- Remove the unused _mint_token_if_initialize.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(mcp): wait for the initialize capture inside its handshake task

Both handshake hooks run record_initialize in a tracked background task.
It started the capture as a second task, after flush() took its snapshot
of pending tasks. With a slow before_send, flush() returned early and
shutdown dropped $mcp_initialize. The handshake task now awaits the
capture itself.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(mcp): resolve the v2 handshake session from an incoming header

On MCP SDK 2.x, a stateless client can send initialize with an existing
Mcp-Session-Id and keep sending it. Its later calls resolve their
session from that header, but the handshake hook read only the
connection id and the minted token. The event landed in a generated
session. The hook now falls back to the incoming header.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(mcp): capture a v1 initialize that carries a session header

On MCP SDK 1.x, the middleware read the body only of a POST with no
Mcp-Session-Id, because only those need a token. A client that sent
initialize with an existing session id got no event: the middleware
marked the request, so the first-request fallback did not run either.

A middleware bound to a server now reads those bodies too, behind a
cheap check for "initialize". It still mints only without a header. The
event uses the header that the client keeps sending.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(mcp): pass a disconnect mid-body through the session middleware

When the client disconnected while it sent the body, the middleware
stopped its read and replayed the partial body as a complete request.
The app parsed half a request and never saw the disconnect. The
middleware now replays the partial body with more_body set, then hands
the app the disconnect.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(mcp): stop buffering tool calls once they are not an initialize

A bound middleware reads the body of a POST that carries a session id,
to catch an initialize that reuses one. That held every tool call in
memory, up to 256 KB, before the app saw it. The middleware now stops
after 4 KB when "initialize" is not in it, and streams the rest.
JSON-RPC clients put "method" before "params", so a handshake shows up
in that window.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* refactor(mcp): read the v2 handshake header through _resolve_ctx

The v2 handshake hook read the Mcp-Session-Id header and decoded the
token itself. Every later request gets the same pair from _resolve_ctx.
The hook now calls it, so the handshake and later requests follow one
rule and cannot drift apart into two sessions.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(mcp): run the initialize callbacks inline in the handshake request

Both handshake hooks ran identify and event_properties in a detached
background task. If a callback never returned, each handshake left one
more task pending, with no bound, and flush() waited for all of them.
The spec requires pending state to be bounded by count.

The hooks now run the callbacks inline, the same as a tool call does. A
hung callback holds that request, where the host sees it, and leaves no
task behind. The capture still runs in the background after the
callbacks, as for every other event.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(mcp): record the v1 handshake inside the request's auth context

The session middleware sits outside FastMCP's AuthContextMiddleware. It
ran identify after the app returned, when that middleware had already
reset the authenticated user. An identify that calls get_access_token()
got None, so $mcp_initialize stayed anonymous under OAuth. The
middleware now records the handshake when the response starts, while
the app still handles the request.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(mcp): stop the body peek only on a method that is not initialize

The 4 KB peek stopped when "initialize" was not in the first 4 KB. JSON
key order is arbitrary, so an initialize with large params before its
method got no event. The peek now stops only when the prefix shows a
"method" and no "initialize". Without a method yet, it reads up to the
full cap.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(mcp): drop the body byte checks from the session middleware

The middleware guessed from raw bytes whether a request was initialize.
A nested "method" key in params stopped the 4 KB peek too early, and a
JSON-escaped "initialize" failed the quick byte check. That second
case also stopped the token mint, which worked before this PR.

The middleware now parses the body as JSON, as main does, and reads
only requests with no Mcp-Session-Id. On MCP SDK 1.x, an initialize
that reuses an existing session id is not captured. The README lists
this limit. MCP SDK 2.x still captures it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
(cherry picked from commit 8cd8eb5)
… SDK message_delta (#1112)

The tracker only read output_tokens from a message_delta. Its usage is cumulative,
and with server tools (web search, ...) the input and cache counts exceed the
message_start values, so streamed generations under-reported them, and the
number of web searches was never recorded. Keep the larger input and cache
counts, as the Anthropic wrapper does, and set $ai_web_search_count from
server_tool_use.web_search_requests.

Co-authored-by: Claude Sonnet 5.5 <[email protected]>
(cherry picked from commit 48889b6)
(cherry picked from commit 5a2ea5f)
(cherry picked from commit e3fd9a4)
* fix(ai): record the HTTP status of google-genai errors

The generation and embedding wrappers read the HTTP status of a failed call from
the exception's status_code, which OpenAI and Anthropic errors have. google-genai's
APIError (ClientError, ServerError) carries it as code, so every failed Gemini
call was captured with $ai_http_status 0. Read either attribute through a small
helper; a code outside the HTTP range still counts as no status.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>

* fix: remove unused import from HTTP status tests

---------

Co-authored-by: Claude Sonnet 5.5 <[email protected]>
Co-authored-by: Manoel Aranda Neto <[email protected]>
(cherry picked from commit 25d2767)
(cherry picked from commit 82f948b)
(cherry picked from commit b0a2783)
* fix: ai privacy mode leaks

* fix: address privacy mode review findings

* fix: strip remaining otel content in privacy mode

* fix: redact mcp credentials in otel tool definitions

* fix: address otel privacy review findings

* fix: always redact mcp credentials in otel tool definitions

* fix: strip otel embedding vectors in privacy mode

* fix: drop only the otel span that fails redaction

* fix: keep vercel rerank scores in otel privacy mode

* fix: strip logfire payload attributes in otel privacy mode

(cherry picked from commit 04e6a4c)
(cherry picked from commit fb9b66b)
(cherry picked from commit 16d618b)
Bumps [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python) from 1.40.0 to 1.45.1.
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

---
updated-dependencies:
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
(cherry picked from commit bc7b403)
Bumps [djangorestframework](https://github.com/encode/django-rest-framework) from 3.18.1 to 3.18.2.
- [Release notes](https://github.com/encode/django-rest-framework/releases)
- [Commits](encode/django-rest-framework@3.18.1...3.18.2)

---
updated-dependencies:
- dependency-name: djangorestframework
  dependency-version: 3.18.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
(cherry picked from commit 125b266)
…1119)

Bumps the uv group with 1 update in the /examples/example-ai-anthropic directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-autogen directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-aws-bedrock directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-azure-openai directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-cerebras directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-cloudflare-ai-gateway directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-cohere directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-crewai directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-dedalus directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-deepseek directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-fireworks-ai directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-gemini directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-groq directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-helicone directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-hugging-face directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-instructor directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-langchain directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-langgraph directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-llamaindex directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-mirascope directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-mistral directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-ollama directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-openai directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-openrouter directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-perplexity directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-portkey directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-semantic-kernel directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-smolagents directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-together-ai directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-vercel-ai-gateway directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).
Bumps the uv group with 1 update in the /examples/example-ai-xai directory: [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python).

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.34.1 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

Updates `opentelemetry-api` from 1.40.0 to 1.45.1
- [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md)
- [Commits](open-telemetry/opentelemetry-python@v1.40.0...v1.45.1)

---
updated-dependencies:
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: opentelemetry-api
  dependency-version: 1.45.1
  dependency-type: indirect
  dependency-group: uv
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
(cherry picked from commit 3f6c80e)
(cherry picked from commit 7d15127)
(cherry picked from commit 7833e95)
…back handler (#1097)

* feat(ai): record the Anthropic web search count in the LangChain callback handler

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>

* chore: update public API snapshot for ModelUsage.web_search_count

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* chore: regenerate LangChain ModelUsage API snapshot

* fix(ai): read the LangChain web search count from llm_output usage and omit zero

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>

---------

Co-authored-by: Claude Sonnet 5.5 <[email protected]>
Co-authored-by: Manoel Aranda Neto <[email protected]>
(cherry picked from commit b0a2b59)
(cherry picked from commit a736b43)
(cherry picked from commit 3044d8e)
* feat(mcp): add a capture_initialize option

MCPAnalyticsOptions(capture_initialize=False) stops $mcp_initialize. The
option is on by default. Many clients reconnect before every few tool
calls, so the handshake event can outnumber $mcp_tool_call.

With the option off, record_initialize and the first-request fallback
return early. Nothing else changes: the middleware still mints the
session token, so tool calls keep their sessions and client names.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(mcp): keep the handshake identity with capture_initialize off

record_initialize returned before handle_identify when the option was
off. An identify callback that resolves the user only from the
initialize request then left the session anonymous, so later tool calls
lost the user. Identify now runs first, and the option stops only the
event.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* refactor(mcp): rename capture_initialize to send_initialize_event

PostHogMCP already has a capture_initialize() method that sends the
event by hand. An option with the same name next to that method makes
readers link the two. The new name says what the option controls.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(mcp): name the PostHog screens that read $mcp_initialize

MCP onboarding and the users and sessions tiles of the default MCP
dashboard read $mcp_initialize. The README now says that they show no
data while send_initialize_event is off.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
(cherry picked from commit d8a1b97)
(cherry picked from commit 786db57)
(cherry picked from commit 0894015)
pcbeingused333 and others added 20 commits November 1, 2026 13:39
…e caller's dict (#1144)

Co-authored-by: Claude Sonnet 5.5 <[email protected]>
(cherry picked from commit 1625f4f)
(cherry picked from commit 58d69e3)
(cherry picked from commit e4f43a4)
…l fails (#1143)

Co-authored-by: Claude Sonnet 5.5 <[email protected]>
(cherry picked from commit ad1b1cb)
(cherry picked from commit 9a9d806)
(cherry picked from commit ad79bd0)
* fix(ai): report OpenAI Agents cached and reasoning tokens

The Agents SDK nests cached input and reasoning tokens under the usage
details fields: input_tokens_details/output_tokens_details on generation
span usage and on the Responses usage object of response spans. The
processor read flat keys that the SDK never sets, so both were always
dropped. Read the nested fields, keeping the flat keys for custom models.

* fix(ai): declare inclusive cache reporting for nested Agents usage

OpenAI-shaped usage counts cached tokens inside input_tokens. Declare
$ai_cache_reporting_exclusive: False when the cache count comes from the
nested usage details, as the Node Agents processor does, so the cost backend
does not infer exclusive reporting from a Claude model name served through an
OpenAI-compatible endpoint. Flat custom-model keys keep their own convention,
and a caller-supplied value still takes precedence.

* fix(ai): don't forward inclusive Agents reasoning tokens

OpenAI-compatible providers such as OpenRouter count reasoning inside
completion_tokens, while the cost backend adds reasoning on top for Gemini
model names, so forwarding the nested count priced reasoning twice. Keep
the original flat reasoning_tokens key only; cached tokens are unchanged.

(cherry picked from commit 4d6e447)
(cherry picked from commit 2989cd2)
(cherry picked from commit c380dc8)
…le-ai-autogen in the uv group across 1 directory (#1131)

chore(deps): bump setuptools

Bumps the uv group with 1 update in the /examples/example-ai-llamaindex directory: [setuptools](https://github.com/pypa/setuptools).

Updates `setuptools` from 83.0.0 to 84.1.0
- [Release notes](https://github.com/pypa/setuptools/releases)
- [Changelog](https://github.com/pypa/setuptools/blob/main/NEWS.rst)
- [Commits](pypa/setuptools@v83.0.0...v84.1.0)

---
updated-dependencies:
- dependency-name: setuptools
  dependency-version: 84.1.0
  dependency-type: indirect
  dependency-group: uv
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
(cherry picked from commit 6f765a3)
Bumps [authlib](https://github.com/authlib/authlib) from 1.7.2 to 1.9.1.
- [Release notes](https://github.com/authlib/authlib/releases)
- [Commits](authlib/authlib@v1.7.2...v1.9.1)

---
updated-dependencies:
- dependency-name: authlib
  dependency-version: 1.9.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
(cherry picked from commit 871ad9e)
…dates (#1145)

Bumps the ai-providers group with 7 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [langchain](https://github.com/langchain-ai/langchain) | `1.4.4` | `1.4.7` |
| [langgraph](https://github.com/langchain-ai/langgraph) | `1.2.14` | `1.2.16` |
| [langchain-core](https://github.com/langchain-ai/langchain) | `1.6.9` | `1.6.13` |
| [langchain-openai](https://github.com/langchain-ai/langchain) | `1.7.0` | `1.7.2` |
| [langchain-anthropic](https://github.com/langchain-ai/langchain) | `1.7.5` | `1.7.6` |
| [google-genai](https://github.com/googleapis/python-genai) | `2.29.0` | `2.32.0` |
| [langchain-protocol](https://github.com/langchain-ai/agent-protocol) | `0.0.19` | `0.0.20` |

Updates `langchain` from 1.4.4 to 1.4.7
- [Release notes](https://github.com/langchain-ai/langchain/releases)
- [Commits](langchain-ai/langchain@langchain==1.4.4...langchain==1.4.7)

Updates `langgraph` from 1.2.14 to 1.2.16
- [Release notes](https://github.com/langchain-ai/langgraph/releases)
- [Commits](langchain-ai/langgraph@1.2.14...1.2.16)

Updates `langchain-core` from 1.6.9 to 1.6.13
- [Release notes](https://github.com/langchain-ai/langchain/releases)
- [Commits](langchain-ai/langchain@langchain-core==1.6.9...langchain-core==1.6.13)

Updates `langchain-openai` from 1.7.0 to 1.7.2
- [Release notes](https://github.com/langchain-ai/langchain/releases)
- [Commits](langchain-ai/langchain@langchain-openai==1.7.0...langchain-openai==1.7.2)

Updates `langchain-anthropic` from 1.7.5 to 1.7.6
- [Release notes](https://github.com/langchain-ai/langchain/releases)
- [Commits](langchain-ai/langchain@langchain-anthropic==1.7.5...langchain-anthropic==1.7.6)

Updates `google-genai` from 2.29.0 to 2.32.0
- [Release notes](https://github.com/googleapis/python-genai/releases)
- [Changelog](https://github.com/googleapis/python-genai/blob/main/CHANGELOG.md)
- [Commits](googleapis/python-genai@v2.29.0...v2.32.0)

Updates `langchain-protocol` from 0.0.19 to 0.0.20
- [Release notes](https://github.com/langchain-ai/agent-protocol/releases)
- [Commits](langchain-ai/agent-protocol@langchain-protocol==0.0.19...langchain-protocol==0.0.20)

---
updated-dependencies:
- dependency-name: langchain
  dependency-version: 1.4.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ai-providers
- dependency-name: langgraph
  dependency-version: 1.2.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ai-providers
- dependency-name: langchain-core
  dependency-version: 1.6.13
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ai-providers
- dependency-name: langchain-openai
  dependency-version: 1.7.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ai-providers
- dependency-name: langchain-anthropic
  dependency-version: 1.7.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ai-providers
- dependency-name: google-genai
  dependency-version: 2.32.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ai-providers
- dependency-name: langchain-protocol
  dependency-version: 0.0.20
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: ai-providers
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
(cherry picked from commit c9105c5)
* feat: send transactional email from posthog templates

Add posthog.emails.send() on Client and AsyncClient, plus standalone Emails and AsyncEmails in posthog.emails for processes that only send email. Sends go to the app host with a project secret API key and an Idempotency-Key, and retry network errors, rate limits, an in-flight key and 503 with the same key. Errors raise EmailError with PostHog's code and a Resend-style name.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

Generated-By: PostHog Desktop
Task-Id: c62b30cd-eb2e-496c-a73d-2a6e7a52a62e

* fix: keep the email secret key off custom hosts and close email transports

client.emails only infers PostHog Cloud app hosts. A custom host raises app_host_required before any request, so an ingestion proxy never receives the project secret key. A kept emails reference now reads the client's disabled state on every send. Shutdown closes the email transport, a forked child drops the parent's email session, and the retry ceiling applies after jitter. Docs examples use client.emails.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

Generated-By: PostHog Desktop
Task-Id: c62b30cd-eb2e-496c-a73d-2a6e7a52a62e

* fix: refuse email sends after shutdown and drain async sends first

client.emails now asks the parent client to admit each send. After shutdown, a kept or new client.emails raises EmailError with code client_closed and makes no request. On AsyncClient, an admitted send is an in-flight operation, so shutdown waits for it, retries included, before it closes the email transport.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

Generated-By: PostHog Desktop
Task-Id: c62b30cd-eb2e-496c-a73d-2a6e7a52a62e

* feat: configure email sends on the client and document setup

Posthog and AsyncPosthog take app_host, email_request_timeout_seconds and email_request_max_retries, so client.emails works behind a custom host and a job runner can turn retries off. Emails takes a session and AsyncEmails an http_client, which gives tests a supported no-network path. The posthog.emails module docs now hold a setup quickstart: keys and scope, template ID, hosts, retries, errors to expect, cleanup and testing. The release note names client.emails.send().

Co-Authored-By: Claude Opus 5.5 <[email protected]>

Generated-By: PostHog Desktop
Task-Id: c62b30cd-eb2e-496c-a73d-2a6e7a52a62e

* fix: match the email contract's missing_app_host and keep network causes

- A non-Cloud host without app_host now fails with missing_app_host, the code the cross-SDK contract in PostHog/posthog#120921 defines, matching posthog-node.
- A network_error keeps the requests or httpx exception as __cause__, so a failed send is easier to debug.
- Regenerate the public API snapshot after the rebase onto main.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

Generated-By: PostHog Desktop
Task-Id: e72a2c10-f145-4f7c-8754-a4fcc06a18be

* fix: keep the bearer token and send timeout on injected async clients

An httpx.AsyncClient passed as http_client can carry its own auth and timeout. Its auth replaced the email's Bearer header, and its timeout replaced the send timeout, so a client built with timeout=None left sends unbounded. Each async send now passes auth=None and timeout=self.timeout.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

Generated-By: PostHog Desktop
Task-Id: e72a2c10-f145-4f7c-8754-a4fcc06a18be

* fix: name 422 send checks validation_error

The template send route answers 422 for recipient_suppressed, sending_paused and sending_suspended as well as idempotency_key_reused. Only idempotency_key_reused is now invalid_idempotent_request; the send checks are validation_error, as the cross-SDK contract names them and posthog-node does.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

Generated-By: PostHog Desktop
Task-Id: e72a2c10-f145-4f7c-8754-a4fcc06a18be

* fix: raise client_disabled for email sends from a disabled client

A disabled client returned SendEmailResult(id=None), so a caller that treats a returned result as sent dropped the email silently. It now sends nothing and raises EmailError with code client_disabled (name application_error), as the cross-SDK contract in PostHog/posthog#120921 defines and posthog-node does. SendEmailResult.id is always the queued message ID, so its type is str.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

Generated-By: PostHog Desktop
Task-Id: e72a2c10-f145-4f7c-8754-a4fcc06a18be

* feat: send transactional email through the single send endpoint

`emails.send()` now posts to `/api/projects/@current/messaging/send/email/` with the template ID in the body as `template.id`, instead of the template-scoped route.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

Generated-By: PostHog Desktop
Task-Id: e72a2c10-f145-4f7c-8754-a4fcc06a18be

* feat: read a transactional email's status with emails.get

`emails.get(message_id)` on `Emails` and `AsyncEmails` reads `/api/projects/@current/messaging/emails/{id}/` and returns an `EmailStatus` with `status`, `created_at`, `status_at` and `reason`. It retries network errors, rate limits and an unavailable service like `send`, which now shares that attempt loop.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

Generated-By: PostHog Desktop
Task-Id: e72a2c10-f145-4f7c-8754-a4fcc06a18be

* docs: describe the email error name as a category

Co-Authored-By: Claude Opus 5.5 <[email protected]>

Generated-By: PostHog Desktop
Task-Id: e72a2c10-f145-4f7c-8754-a4fcc06a18be

* feat: add a per-send max_retries to emails.send

`send(max_retries=...)` on `Emails` and `AsyncEmails` overrides the client's retry limit for one send, like posthog-node's `maxRetries`. A negative or non-integer value raises `ValueError` before any request.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

Generated-By: PostHog Desktop
Task-Id: e72a2c10-f145-4f7c-8754-a4fcc06a18be
(cherry picked from commit 01e91db)
(cherry picked from commit 139161e)
(cherry picked from commit af8e1aa)
Co-authored-by: Manoel Aranda Neto <[email protected]>
(cherry picked from commit be77b83)
Gemini returns IDs on function calls and function responses, but the
captured $ai_output_choices and $ai_input dropped them, so tool results
could not be matched to their calls. Keep the call ID on output (streaming
and non-streaming) and on input history calls, and the result's ID as
tool_use_id, matching PostHog/posthog-js#5087.

Co-authored-by: Manoel Aranda Neto <[email protected]>
(cherry picked from commit a61e64d)
(cherry picked from commit f23efe9)
(cherry picked from commit dca2207)
@eli-r-ph
eli-r-ph requested a review from a team as a code owner November 1, 2026 21:45
@eli-r-ph eli-r-ph changed the title chore: sync main 7.75.7-7.81.1 into v1 chore: sync main into v1 (7.75.7–7.81.1) Nov 1, 2026

@marandaneto marandaneto left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Automated advisory code review.

@marandaneto
marandaneto requested a review from a team November 2, 2026 15:25
@eli-r-ph
eli-r-ph merged commit 3f429dd into v1 Nov 2, 2026
42 of 43 checks passed
@eli-r-ph
eli-r-ph deleted the eli/v1-sync-main-7.81 branch November 2, 2026 17:06
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.