Skip to content

Add installation command for Semantic Kernel dependencies#663

Open
Premiermoney wants to merge 415 commits into
PostHog:no-contextfrom
Premiermoney:main
Open

Add installation command for Semantic Kernel dependencies#663
Premiermoney wants to merge 415 commits into
PostHog:no-contextfrom
Premiermoney:main

Conversation

@Premiermoney

Copy link
Copy Markdown

💡 Motivation and Context

💚 How did you test it?

📝 Checklist

  • 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

haacked and others added 30 commits December 15, 2025 17:06
…failures (PostHog#390)

* Add $feature_flag_error property to track flag evaluation failures

Track errors in feature flag evaluation by adding a `$feature_flag_error` property to the `$feature_flag_called` event.

* Refactor requests exception imports through request.py

Export RequestsTimeout and RequestsConnectionError from posthog/request.py
to keep all requests library imports in one place and avoid mypy issues.

* Address PR review feedback

- Fix fallback logic to only trigger on actual exceptions, not when
  errors_while_computing or flag_missing is set from a successful API response
- Change log.exception() to log.warning() for expected operational errors
  (quota limits, timeouts, connection errors, API errors) to reduce log noise
- Keep log.exception() only for truly unexpected errors (unknown_error)
- Extract stale cache fallback into _get_stale_flag_fallback() helper method

* Add tests for stale cache fallback and error absence

- Add TestFeatureFlagErrorWithStaleCacheFallback test class with 4 tests:
  - test_timeout_error_returns_stale_cached_value
  - test_connection_error_returns_stale_cached_value
  - test_api_error_returns_stale_cached_value
  - test_error_without_cache_returns_none

- Add negative assertions to verify $feature_flag_error is absent on success:
  - test_get_feature_flag_result_boolean_local_evaluation
  - test_get_feature_flag_result_variant_local_evaluation
  - test_get_feature_flag_result_boolean_decide
  - test_get_feature_flag_result_variant_decide

* Report combined errors when both errors_while_computing and flag_missing

When the server returns errorsWhileComputingFlags=true AND the requested
flag is not in the response, report both conditions as a comma-separated
string: "errors_while_computing_flags,flag_missing"

This provides better debugging context when both conditions occur.

* Add FeatureFlagError constants class for error type values

- Add FeatureFlagError class to types.py with constants:
  - ERRORS_WHILE_COMPUTING, FLAG_MISSING, QUOTA_LIMITED
  - TIMEOUT, CONNECTION_ERROR, UNKNOWN_ERROR
  - api_error(status) static method for dynamic error strings

- Update client.py to use FeatureFlagError constants instead of
  magic strings

- Update all tests to use constants for maintainability

This improves maintainability by:
- Single source of truth for error values
- IDE autocomplete and typo detection
- Documentation of analytics-stable values

* Remove print statements from test failure handlers

* Fix mypy type error in FeatureFlagError.api_error method

Accept Union[int, str] to match APIError.status type.
* Add urllib3-based retry for feature flag requests

Use urllib3's built-in Retry mechanism for feature flag POST requests
instead of application-level retry logic. This is simpler and leverages
well-tested library code.

Key changes:
- Add `RETRY_STATUS_FORCELIST` = [408, 500, 502, 503, 504]
- Add `_build_flags_session()` with POST retries and `status_forcelist`
- Update `flags()` to use dedicated flags session
- Add tests for retry configuration and session usage

The flags session retries on:
- Network failures (connect/read errors)
- Transient server errors (408, 500, 502, 503, 504)

It does NOT retry on:
- 429 (rate limit) - need to wait, not hammer
- 402 (quota limit) - won't resolve with retries

* Make examples run without requiring personal api key

* Add integration tests for network retry behavior

Add tests that verify actual retry behavior, not just configuration:

- test_retries_on_503_then_succeeds: Spins up a local HTTP server that
  returns 503 twice then 200, verifying 3 requests are made
- test_connection_errors_are_retried: Verifies connection errors trigger
  retries by measuring elapsed time with backoff

Both tests use dynamically allocated ports for CI safety.

* Bump version to 7.4.0
…_flag_events` in `get_feature_flag_payload` (PostHog#391)

* fix: Respect `send_feature_flags` when local eval is enabled

* fix: Deprecate `send_feature_flag_events` in `get_feature_flag_payload`
…tHog#395)

* fix: extract model from response for OpenAI stored prompts

When using OpenAI stored prompts, the model is defined in the OpenAI
dashboard rather than passed in the API request. This change adds a
fallback to extract the model from the response object when not
provided in kwargs.

Fixes PostHog/posthog#42861

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

* Apply suggestion from @greptile-apps[bot]

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* Apply suggestion from @greptile-apps[bot]

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* test: add tests for model extraction fallback and bump to 7.4.1

- Add 8 tests covering model extraction from response for stored prompts
- Fix utils.py to add 'unknown' fallback for consistency
- Bump version to 7.4.1
- Update CHANGELOG.md

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* style: format utils.py with ruff

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* fix: remove 'unknown' fallback from non-streaming to match original behavior

Non-streaming originally returned None when model wasn't in kwargs.
Streaming keeps "unknown" fallback as that was the original behavior.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* test: add test for None model fallback in non-streaming

Verifies that non-streaming returns None (not "unknown") when model
is not available in kwargs or response, matching original behavior.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* add in_app configuration for python SDK

* bump version

* add in_app_modules to init script as well
The "Create GitHub release" step was broken in PR PostHog#386, which removed
the GITHUB_TOKEN env var from the actions/create-release action. The
action requires the token to be passed explicitly, so releases were
being published to PyPI but GitHub tags/releases were not created.

This replaces the archived actions/create-release@v1 with the gh CLI,
which is already used elsewhere in this workflow. The gh CLI properly
uses GH_TOKEN for authentication.
* feat: llma / error tracking integration

* capture all metadata in llm event

* instrument with contexts

* bump version

* indentation

* linting

* tests

* raise

* test: add exception capture integration tests for langchain

Add 6 tests covering the new LLMA + error tracking integration:
- capture_exception called on span/generation errors
- $exception_event_id added to AI events
- No capture when autocapture disabled
- AI properties passed to exception event
- Handles None return from capture_exception

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* fix: pass context tags to capture() for test compatibility

- Export get_tags() from posthog module
- Explicitly pass context tags to capture() in AI utils
- Fix $ai_model fallback to extract from response.model
- Fix ruff formatting in langchain test_callbacks.py

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* fix: disable auto-capture exceptions in LLM context

The new_context() defaults to capture_exceptions=True which would
auto-capture any exception regardless of enable_exception_autocapture
setting. This was inconsistent with LangChain callbacks which
explicitly check the setting.

Pass capture_exceptions=False to let exception handling be controlled
explicitly by the enable_exception_autocapture setting.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* fix: isolate LLM context with fresh=True to avoid tag inheritance

Use fresh=True to start with a clean context for each LLM call.
This avoids inheriting $ai_* tags from parent contexts which could
cause mismatched AI metadata due to the tag merge order bug in
contexts.py (parent tags incorrectly override child tags).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* fix: correct tag merge order so child tags take precedence

The collect_tags() method had a bug where parent tags would overwrite
child tags, despite the comment saying the opposite. This fix ensures
child context tags properly override parent tags.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* refactor: remove fresh=True now that tag merge order is fixed

With the collect_tags() bug fixed, child tags properly override parent
tags. LLM events can now inherit useful parent context tags (request_id,
user info, etc.) while still having their $ai_* tags take precedence.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* test: add test for child tags overriding parent tags

Verifies that in non-fresh contexts, child tags properly override
parent tags with the same key while still inheriting other parent tags.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

* chore: add TODO for OpenAI/Anthropic/Gemini exception capture

Document that exception capture needs to be added for the direct SDK
wrappers, similar to how it's implemented in LangChain callbacks.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

---------

Co-authored-by: David Newell <david@Mac.communityfibre.co.uk>
Co-authored-by: Andrew Maguire <andrewm4894@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
…ostHog#403)

* chore: add a test to describe upload behaviour when there are errors

* refactor the test file

* add typehints to the test file
* docs: add Python version support table to README

Add a table documenting which SDK versions introduced or dropped
support for different Python versions, based on CHANGELOG.md entries.

* fix: correct Python 3.14 support version to 7.4.3

* Apply suggestions from code review

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
This is required to be able to run CodeQL against external contributors' PRs.
…PostHog#361)

* fix: Avoid return from finally: block

This fixes a SyntaxWarning on Python 3.14.

```
❯ uvx --no-cache --python 3.14.0 --with posthog==6.7.11 python -c "import posthog"
Installed 11 packages in 5ms
.../lib/python3.14/site-packages/posthog/consumer.py:92: SyntaxWarning: 'return' in a 'finally' block
  return success
````

* add versioning info

---------

Co-authored-by: Paul D'Ambra <paul.dambra@gmail.com>
Updated link formatting for clarity in changelog.
* feat: add device_id to flags request payload

Add device_id parameter to all feature flag methods, similar to how
distinct_id is handled. The device_id is included in the flags request
payload sent to the server.

- Add device_id parameter to Client methods and module-level functions
- Add context support via set_context_device_id() for automatic fallback
- Add tests for explicit device_id and context-based device_id
- Bump version to 7.6.0
* feat(ai): add OpenAI Agents SDK integration

Add PostHogTracingProcessor that implements the OpenAI Agents SDK
TracingProcessor interface to capture agent traces in PostHog.

- Maps GenerationSpanData to $ai_generation events
- Maps FunctionSpanData, AgentSpanData, HandoffSpanData, GuardrailSpanData
  to $ai_span events with appropriate types
- Supports privacy mode, groups, and custom properties
- Includes instrument() helper for one-liner setup
- 22 unit tests covering all span types

* feat(openai-agents): add $ai_group_id support for linking conversation traces

- Capture group_id from trace and include as $ai_group_id on all events
- Add _get_group_id() helper to retrieve group_id from trace metadata
- Pass group_id through all span handlers (generation, function, agent, handoff, guardrail, response, custom, audio, mcp, generic)
- Enables linking multiple traces in the same conversation thread

* feat(openai-agents): add enhanced span properties

- Add $ai_total_tokens to generation and response spans (required by PostHog cost reporting)
- Add $ai_error_type for cross-provider error categorization (model_behavior_error, user_error, input_guardrail_triggered, output_guardrail_triggered, max_turns_exceeded)
- Add $ai_output_choices to response spans for output content capture
- Add audio pass-through properties for voice spans:
  - first_content_at (time to first audio byte)
  - audio_input_format / audio_output_format
  - model_config
  - $ai_input for TTS text input
- Add comprehensive tests for all new properties

* Add $ai_framework property and standardize $ai_provider for OpenAI Agents

- Add $ai_framework="openai-agents" to all events for framework identification
- Standardize $ai_provider="openai" on all events (previously some used "openai_agents")
- Follows pattern from posthog-js where $ai_provider is the underlying LLM provider

* chore: bump version to 7.7.0 for OpenAI Agents SDK integration

* fix: add openai_agents package to setuptools config

Without this, the module is not included in the distribution
and users get an ImportError after pip install.

* fix: correct indentation in on_trace_start properties dict

* fix: prevent unbounded growth of span/trace tracking dicts

Add max entry limit and eviction for _span_start_times and
_trace_metadata dicts. If on_span_end or on_trace_end is never
called (e.g., due to an SDK exception), these dicts could grow
indefinitely in long-running processes.

* fix: resolve distinct_id from trace metadata in on_span_end

Previously on_span_end always called _get_distinct_id(None), which
meant callable distinct_id resolvers never received the trace object
for spans. Now the resolved distinct_id is stored at trace start and
looked up by trace_id during span end.

* refactor: extract _base_properties helper to reduce duplication

All span handlers repeated the same 6 base fields (trace_id, span_id,
parent_id, provider, framework, latency) plus the group_id conditional.
Extract into a shared helper to reduce ~100 lines of boilerplate.

* test: add missing edge case tests for openai agents processor

- test_generation_span_with_no_usage: zero tokens when usage is None
- test_generation_span_with_partial_usage: only input_tokens present
- test_error_type_categorization_by_type_field_only: type field without
  matching message content
- test_distinct_id_resolved_from_trace_for_spans: callable resolver
  uses trace context for span events
- test_eviction_of_stale_entries: memory leak prevention works

* fix: handle non-dict error_info in span error parsing

If span.error is a string instead of a dict, calling .get() would
raise AttributeError. Now falls back to str() for non-dict errors.

* style: apply ruff formatting

* style: replace lambda assignments with def (ruff E731)

* fix: restore full CHANGELOG.md history

The rebase conflict resolution accidentally truncated the changelog
to only the most recent entries. Restored all historical entries.

* fix: preserve personless mode for trace-id fallback distinct IDs

When no distinct_id is provided, _get_distinct_id falls back to
trace_id or "unknown". Since these are non-None strings, the
$process_person_profile=False check in _capture_event never fired,
creating unwanted person profiles keyed by trace IDs.

Track whether the user explicitly provided a distinct_id and use
that flag to control personless mode, matching the pattern used
by the langchain and openai integrations.

* fix: restore changelog history and fix personless mode edge cases

Two fixes from bot review:

1. CHANGELOG.md was accidentally truncated to 38 lines during rebase
   conflict resolution. Restored all 767 lines of history.

2. Personless mode now follows the same pattern as langchain/openai
   integrations: _get_distinct_id returns None when no user-provided
   ID is available, and callers set $process_person_profile=False
   before falling back to trace_id. This covers the edge case where
   a callable distinct_id returns None.

* fix: handle None token counts in generation span

Guard against input_tokens or output_tokens being None when computing
$ai_total_tokens to avoid TypeError.

* fix: check error_type_raw for all error categories

Check both error_type_raw and error_message for guardrail and
max_turns errors, consistent with how ModelBehaviorError and
UserError are already checked.

* fix: add type hints to instrument() function

* refactor: rename _safe_json to _ensure_serializable for clarity

The function validates JSON serializability and falls back to str(),
not serializes. Rename and update docstring to make the contract clear.

* refactor: emit $ai_trace at trace end instead of start

Move the $ai_trace event from on_trace_start to on_trace_end to
capture full metadata including latency, matching the LangChain
integration approach. on_trace_start now only stores metadata for
use by spans.

* style: fix ruff formatting

* fix: add TYPE_CHECKING imports for type hints in instrument()
…tions (PostHog#411)

* feat: pass raw provider usage metadata for backend cost calculations

Add raw_usage field to TokenUsage type to capture raw provider usage metadata (OpenAI, Anthropic, Gemini). This enables the backend to extract modality-specific token counts (text vs image vs audio) for accurate cost calculations.

- Add raw_usage field to TokenUsage TypedDict
- Update all provider converters to capture raw usage:
  - OpenAI: capture response.usage and chunk usage
  - Anthropic: capture usage from message_start and message_delta events
  - Gemini: capture usage_metadata from responses and chunks
- Pass raw usage as $ai_usage property in PostHog events
- Update merge_usage_stats to handle raw_usage in both modes
- Add tests verifying $ai_usage is captured for all providers

Backend will extract provider-specific details and delete $ai_usage after processing to avoid bloating properties.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: add serialize_raw_usage helper to ensure JSON serializability

Address PR review feedback from @andrewm4894:

1. **Serialization**: Add serialize_raw_usage() helper with fallback chain:
   - .model_dump() for Pydantic models (OpenAI/Anthropic)
   - .to_dict() for protobuf-like objects
   - vars() for simple objects
   - str() as last resort
   This ensures we never pass unserializable objects to PostHog client.

2. **Data loss prevention**: Change from replacing to merging raw_usage in
   incremental mode. For Anthropic streaming, message_start has input token
   details and message_delta has output token details - merging preserves
   both instead of losing input data.

3. **Test coverage**: Enhanced tests to verify:
   - JSON serializability with json.dumps()
   - Expected structure of raw_usage dicts
   - Coverage for both non-streaming and streaming modes
   - Fixed Gemini test mocks to return proper dicts from model_dump()

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* refactor: move raw_usage serialization from utils to converters

Address PR feedback from @andrewm4894 - serialize in converters, not utils.

**Problem:**
Utils was receiving raw Pydantic/protobuf objects and serializing them,
which meant provider-specific knowledge leaked into generic code.

**Solution:**
Move serialization into converters where provider context exists:

Converters (NEW):
- OpenAI: serialize_raw_usage(response.usage) → dict
- Anthropic: serialize_raw_usage(event.usage) → dict
- Gemini: serialize_raw_usage(metadata) → dict

Utils (SIMPLIFIED):
- Just passes dicts through, no serialization needed
- Merge operations work with dicts only

**Benefits:**
1. Type correctness: raw_usage is always Dict[str, Any]
2. Separation of concerns: converters handle provider formats
3. Fail fast: serialization errors in converters with context
4. Cleaner abstraction: utils doesn't know about Pydantic/protobuf

**Flow:**
Provider object → Converter serializes → dict → Utils → PostHog

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: add type annotation for current_raw to satisfy mypy

Fix mypy error: "Need type annotation for 'current_raw'"

Extract value first, then apply explicit type annotation with ternary
conditional to satisfy mypy's type checker.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
* feat(llma): add prompt management

* chore(llma): bump version

* fix(llma): use SDK session with retry logic for prompt fetching

Use _get_session() from posthog/request.py instead of raw requests.get()
to benefit from the SDK's existing retry configuration on transient
network failures.
* feat: SDK Compliance
* fix(llma): small fixes for prompt management

* fix(llma): tests

* fix(llma): tests
* Fix feature flag 401 errors causing HTTP request storm

Set feature_flags = [] on 401 error to prevent repeated requests.

* Clear flag_cache, group_type_mapping, cohorts on 401
Co-authored-by: Aleksander Błaszkiewicz <kqmdjc8@gmail.com>
* fix: Retry on 408 and respect Retry-After header

408 (Request Timeout) was incorrectly treated as a non-retryable client
error. Retry-After response headers were ignored during backoff. Replace
backoff library usage with a manual retry loop that honours Retry-After
when present and falls back to exponential backoff otherwise.

* fix: Parse HTTP-date Retry-After values

Retry-After can be seconds or an HTTP-date per RFC 7231. Fall back to
email.utils.parsedate_to_datetime when the numeric parse fails.

* fix: Don't retry on unclassifiable APIError status

When APIError.status is "N/A" (no HTTP status), treat it as
non-retryable to avoid unexpected retry loops on errors the SDK
cannot classify.

* test: Add retry delay tests for Retry-After and exponential backoff

Verify time.sleep is called with the Retry-After value when present,
uses exponential backoff (2^attempt) when absent, and that 408 is
retried.
* feat: limit max number of items in collection to scan

* feat: changelog

* fix: format

* feat: test

* feat: replace entire collection instead of truncating
…ostHog#424)

* feat: Support device_id as bucketing identifier for local evaluation

Add support for `bucketing_identifier` field on feature flags to allow
using `device_id` instead of `distinct_id` for hashing/bucketing in
local evaluation.
turnipdabeets and others added 25 commits June 3, 2026 11:12
* feat: emit $is_server property on captured events

* chore: add changeset for $is_server property

* feat: make $is_server configurable (default true)

* fix: set $is_server after super_properties merge so it cannot be overridden

* test: include $is_server in group_identify exact-match assertions

* chore: bump changeset to minor (new is_server option)

* docs: document is_server option
chore: update sentry license attribution
…ai-pydantic-ai (PostHog#649)

chore(deps): bump starlette in /examples/example-ai-pydantic-ai

Bumps [starlette](https://github.com/Kludex/starlette) from 1.0.0 to 1.0.1.
- [Release notes](https://github.com/Kludex/starlette/releases)
- [Changelog](https://github.com/Kludex/starlette/blob/main/docs/release-notes.md)
- [Commits](Kludex/starlette@1.0.0...1.0.1)

---
updated-dependencies:
- dependency-name: starlette
  dependency-version: 1.0.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…ai-openai-agents (PostHog#650)

chore(deps): bump starlette in /examples/example-ai-openai-agents

Bumps [starlette](https://github.com/Kludex/starlette) from 1.0.0 to 1.0.1.
- [Release notes](https://github.com/Kludex/starlette/releases)
- [Changelog](https://github.com/Kludex/starlette/blob/main/docs/release-notes.md)
- [Commits](Kludex/starlette@1.0.0...1.0.1)

---
updated-dependencies:
- dependency-name: starlette
  dependency-version: 1.0.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…ai-semantic-kernel (PostHog#651)

chore(deps): bump starlette in /examples/example-ai-semantic-kernel

Bumps [starlette](https://github.com/Kludex/starlette) from 1.0.0 to 1.0.1.
- [Release notes](https://github.com/Kludex/starlette/releases)
- [Changelog](https://github.com/Kludex/starlette/blob/main/docs/release-notes.md)
- [Commits](Kludex/starlette@1.0.0...1.0.1)

---
updated-dependencies:
- dependency-name: starlette
  dependency-version: 1.0.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…dates (PostHog#642)

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

| Package | From | To |
| --- | --- | --- |
| [openai](https://github.com/openai/openai-python) | `2.29.0` | `2.38.0` |
| [anthropic](https://github.com/anthropics/anthropic-sdk-python) | `0.102.0` | `0.104.1` |
| [langgraph](https://github.com/langchain-ai/langgraph) | `1.2.0` | `1.2.1` |
| [langchain-community](https://github.com/langchain-ai/langchain-community) | `0.4.1` | `0.4.2` |
| [langchain-openai](https://github.com/langchain-ai/langchain) | `1.1.12` | `1.2.2` |
| [google-genai](https://github.com/googleapis/python-genai) | `1.24.0` | `2.6.0` |



Updates `openai` from 2.29.0 to 2.38.0
- [Release notes](https://github.com/openai/openai-python/releases)
- [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md)
- [Commits](openai/openai-python@v2.29.0...v2.38.0)

Updates `anthropic` from 0.102.0 to 0.104.1
- [Release notes](https://github.com/anthropics/anthropic-sdk-python/releases)
- [Changelog](https://github.com/anthropics/anthropic-sdk-python/blob/main/CHANGELOG.md)
- [Commits](anthropics/anthropic-sdk-python@v0.102.0...v0.104.1)

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

Updates `langchain-community` from 0.4.1 to 0.4.2
- [Release notes](https://github.com/langchain-ai/langchain-community/releases)
- [Commits](langchain-ai/langchain-community@libs/community/v0.4.1...libs/community/v0.4.2)

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

Updates `google-genai` from 1.24.0 to 2.6.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@v1.24.0...v2.6.0)

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

Updates `langchain-text-splitters` from 1.1.1 to 1.1.2
- [Release notes](https://github.com/langchain-ai/langchain/releases)
- [Commits](langchain-ai/langchain@langchain-text-splitters==1.1.1...langchain-text-splitters==1.1.2)

---
updated-dependencies:
- dependency-name: openai
  dependency-version: 2.38.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ai-providers
- dependency-name: anthropic
  dependency-version: 0.104.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ai-providers
- dependency-name: langgraph
  dependency-version: 1.2.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ai-providers
- dependency-name: langchain-community
  dependency-version: 0.4.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ai-providers
- dependency-name: langchain-openai
  dependency-version: 1.2.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ai-providers
- dependency-name: google-genai
  dependency-version: 2.6.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: ai-providers
- dependency-name: langchain-classic
  dependency-version: 1.0.7
  dependency-type: indirect
  update-type: version-update:semver-patch
  dependency-group: ai-providers
- dependency-name: langchain-text-splitters
  dependency-version: 1.1.2
  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>
Co-authored-by: Anna Garcia <11654201+turnipdabeets@users.noreply.github.com>
* ci: skip flags project board workflow for Dependabot PRs

The reusable PostHog/.github flags-project-board workflow generates a
GitHub App token as its first step. Dependabot-triggered runs execute in
a restricted secret context that has no access to the App credentials, so
that step hard-fails with "The 'client-id' (or deprecated 'app-id') input
must be set to a non-empty string" on every dependency-bump PR (failing
since the 2025-09-09 PAT -> GitHub App migration upstream).

Guard the job with github.actor != 'dependabot[bot]'. A job-level if
reports as skipped, which branch protection treats as non-blocking, so it
won't leave a "waiting for status" check. Adding the App secret to the
Dependabot context would also work but would hand an org-write key to the
untrusted Dependabot context, so the skip is the safer fix.
…ostHog#653)

The Dependabot skip for the feature flags project board is now handled
centrally in the reusable workflow (PostHog/.github#52). Bump the pin to
that merged SHA and drop the redundant inline `github.actor !=
'dependabot[bot]'` guard so the conditional lives in one place.

No behavior change: Dependabot PRs are still skipped (now upstream), and
the pin bump pulls in only that single workflow change.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
)

* feat(feature-flags): support early_exit in local evaluation

Port PostHog/posthog-js#3705 to posthog-python.

When a flag enables `filters.early_exit`, condition evaluation now stops
and returns `False` as soon as a condition group's property filters match
but the rollout percentage excludes the user, instead of falling through
to later groups — matching the server-side (Rust) engine's
`OutOfRolloutBound` short-circuit.

- Introduce a `ConditionMatch` tri-state (MATCH / NO_MATCH /
  OUT_OF_ROLLOUT_BOUND) returned by `is_condition_match`, so the loop can
  distinguish a rollout exclusion from a property mismatch. Property
  mismatches still fall through, mirroring the Rust semantics exactly.
- Read `filters.early_exit` in `match_feature_flag_properties` and
  short-circuit to `False` on OUT_OF_ROLLOUT_BOUND when enabled.
- Tests for early-exit on, default off (regression), explicit off,
  rollout-only groups, and the property-mismatch case.

Generated-By: PostHog Code
Task-Id: 707b13a5-0e5d-4764-915a-21e1f2a80c63

* fix(feature-flags): remove redundant or False and add multivariate early_exit test
Bumps the ai-providers group with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [langchain](https://github.com/langchain-ai/langchain) | `1.3.1` | `1.3.2` |
| [anthropic](https://github.com/anthropics/anthropic-sdk-python) | `0.104.1` | `0.105.2` |
| [langgraph](https://github.com/langchain-ai/langgraph) | `1.2.1` | `1.2.2` |
| [langchain-anthropic](https://github.com/langchain-ai/langchain) | `1.4.3` | `1.4.4` |
| [google-genai](https://github.com/googleapis/python-genai) | `2.6.0` | `2.7.0` |


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

Updates `anthropic` from 0.104.1 to 0.105.2
- [Release notes](https://github.com/anthropics/anthropic-sdk-python/releases)
- [Changelog](https://github.com/anthropics/anthropic-sdk-python/blob/main/CHANGELOG.md)
- [Commits](anthropics/anthropic-sdk-python@v0.104.1...v0.105.2)

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

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

Updates `google-genai` from 2.6.0 to 2.7.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.6.0...v2.7.0)

---
updated-dependencies:
- dependency-name: langchain
  dependency-version: 1.3.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ai-providers
- dependency-name: anthropic
  dependency-version: 0.105.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ai-providers
- dependency-name: langgraph
  dependency-version: 1.2.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ai-providers
- dependency-name: langchain-anthropic
  dependency-version: 1.4.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ai-providers
- dependency-name: google-genai
  dependency-version: 2.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ai-providers
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* feat: dedicated ai endpoint routing

* fix: attempt AI and analytics sends independently, rename flag to _dedicated_ai_endpoint

Generated-By: PostHog Code
Task-Id: 142d3917-41e8-4bb5-ad6c-5778e13041c2

* fix: increase size limit for AI events
* chore: split CI checks into separate jobs

* address pr review feedback
…es (PostHog#644)

* fix(consumer): remove legacy Python 2 imports and type-guard retry status math

* fix(request): resolve type-shifting assignment, secure path concatenation, and strip dead ignore

* fix(client, flags): handle optional before_send type variance and drop dead code signatures

* fix: type external imports for mypy

* fix: keep request payload behavior unchanged

* test: preserve request payload behavior

---------

Co-authored-by: Manoel Aranda Neto <marandaneto@gmail.com>
…ostHog#658)

* feat(ai): warn when AI wrapper is pointed at the PostHog AI Gateway

An AI wrapper pointed at gateway.us.posthog.com captures each generation
twice (once by the wrapper, once by the gateway), doubling events and cost.
Warn on every routed call without dropping the event, since the wrapper
event carries groups, custom properties, and trace hierarchy the gateway
never sees. Ports posthog-js #3793.

Generated-By: PostHog Code
Task-Id: d4ca2f3d-2579-4155-b6d4-1f072c7e9ace

* fix(ai): port gateway warning faithfully from posthog-js#3793

Address review on PostHog#658 by matching gatewayWarning.ts as written:

- List all five deployed gateway hosts, not just gateway.us.posthog.com,
  so EU and ai-gateway hosts are detected too.
- Tolerate base URLs without a scheme (e.g. gateway.us.posthog.com/v1),
  which urlparse otherwise reads as a path with no hostname.
- Use a static warning message, dropping the redundant second urlparse.
- Detect the gateway on the OTel span path (server.address / url.full)
  in the processor and exporter, since those spans bypass the funnels.
- Consolidate tests with pytest.mark.parametrize.

Generated-By: PostHog Code
Task-Id: d4ca2f3d-2579-4155-b6d4-1f072c7e9ace

* chore(ai): mark gateway warning changeset as patch

Generated-By: PostHog Code
Task-Id: d4ca2f3d-2579-4155-b6d4-1f072c7e9ace
@Premiermoney Premiermoney requested a review from a team as a code owner June 13, 2026 20:33
@Premiermoney Premiermoney changed the base branch from main to no-context June 13, 2026 20:33
@greptile-apps

greptile-apps Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
Semantic/Kernel:1
**File placed in wrong location and duplicates existing content**

A fully-featured Semantic Kernel example already lives at `examples/example-ai-semantic-kernel/`, complete with `pyproject.toml` (declaring the same dependencies), `chat.py`, and a README. That example uses `uv sync` for dependency management, matching every other example in the repo — not a bare `pip install` command. A lone, extension-less file at `Semantic/Kernel` in the repo root has no counterpart anywhere in the project, will never be executed by any tooling, and duplicates existing, properly-structured content.

Reviews (1): Last reviewed commit: "Add installation command for Semantic Ke..." | Re-trigger Greptile

Comment thread Semantic/Kernel
@@ -0,0 +1 @@
pip install semantic-kernel openai opentelemetry-sdk "posthog[otel]" opentelemetry-instrumentation-openai-v2

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 File placed in wrong location and duplicates existing content

A fully-featured Semantic Kernel example already lives at examples/example-ai-semantic-kernel/, complete with pyproject.toml (declaring the same dependencies), chat.py, and a README. That example uses uv sync for dependency management, matching every other example in the repo — not a bare pip install command. A lone, extension-less file at Semantic/Kernel in the repo root has no counterpart anywhere in the project, will never be executed by any tooling, and duplicates existing, properly-structured content.

Prompt To Fix With AI
This is a comment left during a code review.
Path: Semantic/Kernel
Line: 1

Comment:
**File placed in wrong location and duplicates existing content**

A fully-featured Semantic Kernel example already lives at `examples/example-ai-semantic-kernel/`, complete with `pyproject.toml` (declaring the same dependencies), `chat.py`, and a README. That example uses `uv sync` for dependency management, matching every other example in the repo — not a bare `pip install` command. A lone, extension-less file at `Semantic/Kernel` in the repo root has no counterpart anywhere in the project, will never be executed by any tooling, and duplicates existing, properly-structured content.

How can I resolve this? If you propose a fix, please make it concise.

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.