Skip to content

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

Open
eli-r-ph wants to merge 60 commits into
v1from
eli/v1-sync-main-7.81
Open

eli-r-ph wants to merge 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 <noreply@anthropic.com>

* 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 <noreply@anthropic.com>

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

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

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

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: Manoel Aranda Neto <marandaneto@gmail.com>
(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 <noreply@anthropic.com>
(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 <noreply@anthropic.com>

* 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 <noreply@anthropic.com>

* 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 <noreply@anthropic.com>

* 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 <noreply@anthropic.com>

* 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 <noreply@anthropic.com>

* 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 <noreply@anthropic.com>

* 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 <noreply@anthropic.com>

* 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 <noreply@anthropic.com>

* 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 <noreply@anthropic.com>

* 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 <noreply@anthropic.com>

* 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 <noreply@anthropic.com>

* 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 <noreply@anthropic.com>

* 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 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(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 <noreply@anthropic.com>
(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 <noreply@anthropic.com>

* fix: remove unused import from HTTP status tests

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: Manoel Aranda Neto <marandaneto@gmail.com>
(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] <support@github.com>
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] <support@github.com>
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] <support@github.com>
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 <noreply@anthropic.com>

* chore: update public API snapshot for ModelUsage.web_search_count

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* 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 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: Manoel Aranda Neto <marandaneto@gmail.com>
(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 <noreply@anthropic.com>

* 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 <noreply@anthropic.com>

* 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 <noreply@anthropic.com>

* 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 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit d8a1b97)
(cherry picked from commit 786db57)
(cherry picked from commit 0894015)
releaser-posthog-python Bot and others added 28 commits November 1, 2026 13:39
(cherry picked from commit 75a1794)
Bumps the github-actions group with 3 updates: [github/codeql-action/init](https://github.com/github/codeql-action), [github/codeql-action/analyze](https://github.com/github/codeql-action) and [PostHog/posthog-sdk-test-harness/.github/workflows/test-sdk-action.yml](https://github.com/posthog/posthog-sdk-test-harness).

Updates `github/codeql-action/init` from 4.38.3 to 4.39.0
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](github/codeql-action@24c5418...6f2ac81)

Updates `github/codeql-action/analyze` from 4.38.3 to 4.39.0
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](github/codeql-action@24c5418...6f2ac81)

Updates `PostHog/posthog-sdk-test-harness/.github/workflows/test-sdk-action.yml` from 1.15.0 to 1.17.0
- [Release notes](https://github.com/posthog/posthog-sdk-test-harness/releases)
- [Changelog](https://github.com/PostHog/posthog-sdk-test-harness/blob/main/CHANGELOG.md)
- [Commits](PostHog/posthog-sdk-test-harness@64ffa6a...8ca75c4)

---
updated-dependencies:
- dependency-name: github/codeql-action/init
  dependency-version: 4.39.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.39.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: PostHog/posthog-sdk-test-harness/.github/workflows/test-sdk-action.yml
  dependency-version: 1.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
(cherry picked from commit 7083998)
* feat: report unresolved local flags on evaluate_flags snapshots

Implements the "Snapshot unresolved flag reporting" and "Warning for flags local evaluation never resolves" requirements of the evaluate-flags spec (PostHog/sdk-specs#85).

- Add `FeatureFlagEvaluations.unresolved_flags`, with an `UnresolvedFlagReason` for each flag and the spec's fixed precedence.
- Report `local_evaluation_inconclusive` instead of `flag_missing` when a snapshot read hits an unresolved flag.
- Do not stop a condition at the first inconclusive filter, so a filter that does not match resolves the condition locally.
- Check `active` before experience continuity, also for dependencies.
- Log one warning per flag that local evaluation can never resolve, repeated only when its definition changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Generated-By: PostHog Desktop
Task-Id: 39793b31-809e-4689-a5d8-b4359cbb22c1

* fix: address review findings for unresolved local flags

* test(flags): check flag warnings run outside the publication lock

* fix(flags): fall back to the server when a flag dependency needs server data

* fix(flags): keep server fallback when the definition reason lookup fails

(cherry picked from commit bb2b9d6)
(cherry picked from commit 91d3188)
(cherry picked from commit 130f5a1)
…rics (#992)

* feat(metrics): add metrics autocapture for HTTP, database and runtime metrics

`metrics={"autocapture": True}` starts the installed OpenTelemetry instrumentors with private meter and tracer providers and exports to `/i/v1/metrics`. The packages come from the new `posthog[metrics]` extra.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Generated-By: PostHog Desktop
Task-Id: ef9b57c2-47ff-47e6-a509-8873ffe1fab4

* test: check concurrent LangChain traces without assuming order

Generated-By: PostHog Desktop
Task-Id: c0218209-575c-46f0-a201-d0c831e38096

* fix(metrics): address autocapture review findings

- Honour send=False in the autocapture export gate.
- Strip trailing slashes from the host before building the metrics endpoint.
- Set OTEL_SEMCONV_STABILITY_OPT_IN only while the instrumentors load, then
  restore the process environment.
- Limit each synchronous instrument to 2000 attribute sets; send the rest to
  an otel.metric.overflow series, so user-supplied hosts cannot grow the SDK cache.
- After fork, replace the module lock and point the runtime instrumentor at
  the child process.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Generated-By: PostHog Desktop
Task-Id: 10838116-90e2-4d23-af38-8099d7887d07

* fix(metrics): keep app-owned instrumentors intact and hold ownership through shutdown

- Skip an instrumentor whose singleton the app already instrumented before creating it. Creating it ran __init__ again and reset the app's system metrics config.
- Uninstrument while the module lock is held, so a client that starts during shutdown cannot skip libraries that are about to be uninstrumented. The last export still runs outside the lock.
- Correct the module docstring: an app cannot instrument a library again with its own OpenTelemetry setup while autocapture instruments it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Generated-By: PostHog Desktop
Task-Id: a129c1a0-57e3-4370-a4df-6542e710ab75

* fix(metrics): use stable HTTP metric names when another instrumentor read the opt-in first

OpenTelemetry reads OTEL_SEMCONV_STABILITY_OPT_IN once per process. If any instrumentor ran before the client started, autocapture sent http.client.duration (ms) and not http.client.request.duration (s). When the app has not set an opt-in, autocapture now sets the HTTP mode to stable after initialisation, so the names do not depend on import order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Generated-By: PostHog Desktop
Task-Id: a129c1a0-57e3-4370-a4df-6542e710ab75

* fix(metrics): address the second review round of metrics autocapture

- Do not send the app's OTEL_EXPORTER_OTLP_* settings (other vendors' headers, endpoint, TLS files) to PostHog: the private exporter is built without them.
- Give HTTP instrumentors a no-op tracer, so app requests no longer carry an unsampled traceparent that makes downstream services drop their traces.
- Record nothing while the client is disabled, and apply metrics.before_send to autocaptured measurements and runtime observations (value and attributes, or drop).
- Exclude the PostHog host in any case and with or without its default port, escape commas, keep OTEL_PYTHON_*_EXCLUDED_URLS, and apply the exclusion to httpx.
- Reset the reader's export lock in a forked child, export autocaptured metrics on Client.flush() and within the client's exit budget (no 10 s exit wait), roll back on a failed start, and uninstrument and reinstrument Flask apps across a restart.
- Start autocapture on a later module-level setup(), once per client.
- Validate flush_interval like client.metrics, use the same resource as client.metrics, keep the first word of db.operation.name, and raise the minimum OpenTelemetry versions to the first ones with the runtime metric names.
- Rename the module to posthog/_metrics_autocapture.py to keep internals out of the public API.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Generated-By: PostHog Desktop
Task-Id: a129c1a0-57e3-4370-a4df-6542e710ab75

* fix(metrics): keep app middleware on shutdown, stop context propagation, and fix fork and flush issues

- Flask: shutdown uninstruments an app only when its WSGI app is still the one the instrumentation set. uninstrument_app() would otherwise remove middleware the app added later, such as authentication. Instrumentation left in place records nothing after shutdown.
- Do not propagate context: the instrumentors that autocapture starts no longer inject trace context or baggage into outgoing requests, including a trace extracted from an incoming request.
- Keep the attributes that a database span starts with (asyncpg passes db.system then).
- Export the last window at exit in sync mode.
- Replace the metrics SDK collection and aggregation locks in a forked child, where a parent thread could hold them.
- Use one flush thread at a time, with one follow-up export for calls made during a flush.
- Run metrics.before_send as an SDK callback, so a flush() it calls is deferred and cannot deadlock the collection.
- Raise the minimum OpenTelemetry instrumentation version to 0.60b0, the first in which the httpx instrumentor excludes URLs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Generated-By: PostHog Desktop
Task-Id: a129c1a0-57e3-4370-a4df-6542e710ab75

* fix(metrics): do not let the Django instrumentor configure empty settings

Without configured settings, DjangoInstrumentor calls settings.configure() with empty settings, so an app that configures its settings in code after creating the client fails with "Settings already configured". Autocapture now starts the Django instrumentor only when the settings are configured, as in AppConfig.ready().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Generated-By: PostHog Desktop
Task-Id: a129c1a0-57e3-4370-a4df-6542e710ab75

* fix(metrics): drop raw URL attributes, normalize hook attributes, and stop flush loops from hooks

- Never record raw URLs and paths (url.full, http.url, http.target, ...), client addresses, user agents or captured headers. Instrumentors such as Tornado put them on metrics, and they can hold tokens and emails. Routes stay.
- Keep only valid OpenTelemetry attribute values, with sequences as tuples, before and after metrics.before_send. SDK 1.39 raised TypeError for a list value inside the app's request. Recording errors no longer reach the instrumented call.
- A flush() called from a metrics before_send hook still flushes events and spans, but does not start another autocapture export, which ran the hook again without end.
- Each flush request waits only for the first export that starts after it, not for later exports.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Generated-By: PostHog Desktop
Task-Id: a129c1a0-57e3-4370-a4df-6542e710ab75

* fix(metrics): isolate exporter settings and autocapture lifecycle state

* fix(metrics): address remaining autocapture lifecycle feedback

---------

Co-authored-by: Manoel Aranda Neto <marandaneto@gmail.com>
(cherry picked from commit febb3ed)
(cherry picked from commit ce03e47)
(cherry picked from commit 175fac6)
…e caller's dict (#1144)

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
(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 <noreply@anthropic.com>
(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] <support@github.com>
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] <support@github.com>
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] <support@github.com>
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 <noreply@anthropic.com>

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 <noreply@anthropic.com>

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 <noreply@anthropic.com>

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 <noreply@anthropic.com>

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 <noreply@anthropic.com>

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 <noreply@anthropic.com>

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 <noreply@anthropic.com>

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 <noreply@anthropic.com>

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 <noreply@anthropic.com>

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 <noreply@anthropic.com>

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 <noreply@anthropic.com>

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 <noreply@anthropic.com>

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 <marandaneto@gmail.com>
(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 <marandaneto@gmail.com>
(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

This branch has not been deployed

No deployments
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.