Skip to content

Commit 8d8bce1

Browse files
committed
Merge remote-tracking branch 'origin/main' into fix/versioned-boolean-local-evaluation
2 parents a5a6dfb + 2968618 commit 8d8bce1

112 files changed

Lines changed: 70389 additions & 510 deletions

File tree

Some content is hidden

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

‎.github/workflows/ci.yml‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,11 @@ jobs:
155155
# The MCP suite as a named gate per MCP Python SDK major. The v1 leg uses
156156
# the lockfile's mcp 1.x (also exercised incidentally by the `tests`
157157
# matrix — this leg exists as an explicit, named signal); the v2 leg
158-
# (spec 2026-07-28) swaps in mcp>=2 and drops jlowin fastmcp, which pins
159-
# mcp<2. posthog/test/mcp/conftest.py splits collection by major.
158+
# (spec 2026-07-28) swaps in mcp>=2 and standalone FastMCP 4, which uses
159+
# the v2 registry. posthog/test/mcp/conftest.py splits collection by major.
160160
name: MCP SDK ${{ matrix.mcp-major }} (Python ${{ matrix.python-version }})
161161
runs-on: ubuntu-latest
162+
timeout-minutes: 20
162163
strategy:
163164
matrix:
164165
python-version: ['3.10', '3.14']
@@ -189,8 +190,8 @@ jobs:
189190
if: matrix.mcp-major == 'v2'
190191
shell: bash
191192
run: |
192-
uv pip uninstall --python $pythonLocation fastmcp
193-
uv pip install --python $pythonLocation 'mcp>=2,<3'
193+
uv pip uninstall --python "$pythonLocation" fastmcp
194+
uv pip install --python "$pythonLocation" 'mcp>=2,<3' 'fastmcp>=4,<5'
194195
195196
- name: Run MCP tests against SDK ${{ matrix.mcp-major }}
196197
run: |

‎.github/workflows/codeql.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
3131

3232
- name: Initialize CodeQL
33-
uses: github/codeql-action/init@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4.37.8
33+
uses: github/codeql-action/init@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9
3434
with:
3535
languages: ${{ matrix.language }}
3636
build-mode: ${{ matrix.build-mode }}
@@ -40,6 +40,6 @@ jobs:
4040
trap-caching: false
4141

4242
- name: Perform CodeQL Analysis
43-
uses: github/codeql-action/analyze@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4.37.8
43+
uses: github/codeql-action/analyze@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9
4444
with:
4545
category: '/language:${{matrix.language}}'

‎.github/workflows/release.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ jobs:
6666
if: always() && needs.check-changesets.outputs.has-changesets == 'true'
6767
environment: "Release" # This will require an approval from a maintainer, they are notified in Slack above
6868
permissions:
69-
contents: write
69+
contents: read
7070
outputs:
7171
commit-hash: ${{ steps.commit-release.outputs.commit-hash }}
7272
new_version: ${{ steps.sampo-release.outputs.new_version }}

‎AGENTS.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Guidance for coding agents working in `posthog-python`.
77
- This repository contains the PostHog Python SDK, published as `posthog`.
88
- The main runtime package is `posthog/`; tests live under `posthog/test/`.
99
- The project uses `uv` for local development. See `CONTRIBUTING.md` for setup.
10+
- Before adding or changing public API, follow "Public API changes" in [CONTRIBUTING.md](./CONTRIBUTING.md): the API shape must be agreed on the issue first. For SDK design guidance, read https://posthog.com/handbook/engineering/sdks/guidelines.md.
1011
- Keep edits targeted and follow existing patterns. Prefer adding or updating tests near the behavior you change.
1112

1213
## Capture protocol (`capture_mode`)

‎CONTRIBUTING.md‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,15 @@ posthoganalytics = { path = "../posthog-python-local" }
4848
```
4949

5050
This lets you test SDK changes fully locally inside the PostHog app stack. It mainly takes care of the `posthog -> posthoganalytics` module renaming. Re-run `make prep_local` each time you make a change, and then run `uv sync --active` in the PostHog app project.
51+
52+
## Public API changes
53+
54+
Public API is hard to change once it ships, so agree on it before writing the implementation. Our [SDK guidelines](https://posthog.com/handbook/engineering/sdks/guidelines) explain how we design it.
55+
56+
- If you need something the SDK doesn't support and it would add or change a public option, method, or type, open an issue describing your use case first. At this stage, context is more useful to us than code.
57+
- Wait for a maintainer to agree on the API shape on the issue before implementing it.
58+
- Check first whether an existing option or hook, such as `before_send`, already covers the use case. We avoid offering two ways to do the same thing.
59+
- If a reviewer suggests a different API on your PR, confirm it with them before re-implementing. Treat it as a question, not an instruction.
60+
- AI agents: stop and ask before implementing a public API change that hasn't been agreed on the issue.
61+
62+
`make public_api_snapshot` regenerates `references/public_api_snapshot.txt`, and CI runs `make public_api_check` to catch an outdated snapshot. A diff in that file means your change touches public API.

‎examples/example-ai-crewai/uv.lock‎

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎examples/example-ai-dspy/uv.lock‎

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎examples/example-ai-instructor/uv.lock‎

Lines changed: 5 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎examples/example-ai-langchain/README.md‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,18 @@ uv sync
1414
## Examples
1515

1616
- **callback_handler.py** - PostHog callback handler with tool calling
17+
- **agent_middleware.py** - LangChain v1 agent middleware with model and tool tracking
1718
- **otel.py** - OpenTelemetry instrumentation exporting to PostHog
1819

1920
## Run
2021

2122
```bash
2223
source .env
2324
uv run python callback_handler.py
25+
uv run python agent_middleware.py
2426
uv run python otel.py
2527
```
28+
29+
Use either `PostHogMiddleware` or `CallbackHandler` for an agent invocation, not
30+
both, to avoid recording duplicate events. Put `PostHogMiddleware` last in the
31+
middleware list so it records the final model selection and each retry attempt.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
"""Track a LangChain v1 agent with PostHog middleware."""
2+
3+
import os
4+
5+
from langchain.agents import create_agent
6+
from langchain_core.messages import HumanMessage
7+
from langchain_core.tools import tool
8+
from langchain_openai import ChatOpenAI
9+
10+
from posthog import Posthog
11+
from posthog.ai.langchain.middleware import PostHogMiddleware
12+
13+
14+
@tool
15+
def get_weather(city: str) -> str:
16+
"""Get the weather for a city."""
17+
return f"It is sunny in {city}."
18+
19+
20+
client = Posthog(
21+
os.environ["POSTHOG_API_KEY"],
22+
host=os.environ.get("POSTHOG_HOST", "https://us.i.posthog.com"),
23+
)
24+
agent = create_agent(
25+
model=ChatOpenAI(model="gpt-4.1-mini"),
26+
tools=[get_weather],
27+
middleware=[PostHogMiddleware(client, distinct_id="example-user")],
28+
)
29+
30+
result = agent.invoke(
31+
{"messages": [HumanMessage(content="What is the weather in Berlin?")]}
32+
)
33+
print(result["messages"][-1].content)
34+
client.shutdown()

0 commit comments

Comments
 (0)