Skip to content

fix(aio): enable multimodal for PostHog Desktop - #74135

Merged
carlos-marchal-ph merged 2 commits into
masterfrom
fix(aio)/llm-gateway-multimodal-capture
Jul 28, 2026
Merged

fix(aio): enable multimodal for PostHog Desktop#74135
carlos-marchal-ph merged 2 commits into
masterfrom
fix(aio)/llm-gateway-multimodal-capture

Conversation

@carlos-marchal-ph

Copy link
Copy Markdown
Contributor

Problem

services/llm-gateway — the separate deploy unit (own pyproject.toml/uv.lock) backing gateway.{region}.posthog.com for posthog_code, background_agents, posthog_ai, slack_app, conversations, wizard, review_hog, array, bedrock, and llm_gateway — never joined the AI capture lane rollout in #73448/#73950. It pinned posthoganalytics>=3.0.0 (resolved to 7.4.2, six minors behind), and its single capture call site never set _use_ai_lane/_enable_multimodal_capture.

Bumping the SDK and setting those two flags on the constructed client turned out not to be enough on its own. The public Posthog.capture() method always routes to the plain analytics lane regardless of _use_ai_lane — the SDK only reaches the dedicated AI lane (the endpoint the S3 multimodal-blob-offload ingestion pipeline consumes from) through the internal _capture_ai() method, dispatched via posthoganalytics.ai.utils._capture_ai_event(). Every other capture site fixed by #73448/#73950 goes through the SDK's own AI-wrapper classes (posthoganalytics.ai.openai.OpenAI, the LangChain CallbackHandler, etc.), which call that dispatcher internally. services/llm-gateway builds its $ai_generation properties by hand from LiteLLM's logging object and called the plain client.capture(...), bypassing it entirely — so the flags were set but nothing ever read them.

Net effect: multimodal content proxied through this gateway (e.g. a screenshot sent by a PostHog Code agent session) never reached the AI ingestion pipeline, so it never got the S3 blob offload that direct-SDK traffic already gets — it stayed as a raw, uncapped base64 blob inline in the captured event.

Changes

  • Bump posthoganalytics to >=7.30.1, with an exclude-newer-package override so this service's 7-day exclude-newer window doesn't reject a same-day release (mirrors the override on the root pyproject.toml).
  • Set _use_ai_lane=True and _enable_multimodal_capture=True on the Posthog(...) client in PostHogCallback._capture_to_destination (callbacks/posthog.py).
  • Swap client.capture(**capture_kwargs) for _capture_ai_event(client, **capture_kwargs) in the same method — the actual fix that gets these events routed onto the AI lane.
  • Update test_on_success_captures_event's constructor assertion to match.

How did you test this code?

  • uv run pytest (full services/llm-gateway suite): 1371 passed, 50 skipped, 30 xfailed, 22 xpassed.
  • uv run ruff check . / uv run ruff format --check .: clean.
  • Manual local end-to-end verification against a local PostHog instance, using llm-analytics-apps/scripts/test_multimodal_passthrough.py's pattern as a direct-SDK baseline:
    • Direct SDK (Anthropic image call, _enable_multimodal_capture=True): resulting ai_events row carries a phaiblob:// pointer, no inline base64 — confirms the local offload pipeline is live.
    • Same image proxied through this patched gateway, before the _capture_ai_event fix: raw base64 stayed inline (451,826 chars).
    • Same request, after the fix: phaiblob:// pointer, 317 chars — matches the direct-SDK result.
  • Did not exercise the gateway against a live provider in prod — no deploy from this branch.

Automatic notifications

  • Publish to changelog?
  • Alert Sales and Marketing teams?

Docs update

No doc references this rollout switch.

🤖 Agent context

Autonomy: Human-driven (agent-assisted) — assign @carlos-marchal-ph as DRI.

Found while auditing, with Carlos, which AI capture paths landed on the new multimodal lane after #73950. Initial fix (SDK bump + the two flags) turned out to be necessary but insufficient — local end-to-end testing via PostHog Code showed generations from the same conversation still carrying raw, unoffloaded base64 images. Traced it to Posthog.capture() never checking _use_ai_lane; only _capture_ai_event()/_capture_ai() do. Verified the gap and the fix empirically against a local PostHog instance using llm-analytics-apps' multimodal test scripts as a direct-SDK comparison point.

Generated-By: PostHog Code
Task-Id: 2b999b3c-3652-4b53-a9fa-ded25207d1e2
Generated-By: PostHog Code
Task-Id: 2b999b3c-3652-4b53-a9fa-ded25207d1e2
@carlos-marchal-ph carlos-marchal-ph self-assigned this Jul 28, 2026
@pr-assigner-resolver-posthog
pr-assigner-resolver-posthog Bot requested a review from a team July 28, 2026 10:00
@greptile-apps

greptile-apps Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Reviews (1): Last reviewed commit: "fix(aio): route llm-gateway captures ont..." | Re-trigger Greptile

@carlos-marchal-ph
carlos-marchal-ph enabled auto-merge (squash) July 28, 2026 10:06
@carlos-marchal-ph
carlos-marchal-ph merged commit 9d7f07d into master Jul 28, 2026
186 checks passed
@carlos-marchal-ph
carlos-marchal-ph deleted the fix(aio)/llm-gateway-multimodal-capture branch July 28, 2026 10:16
@deployment-status-posthog

deployment-status-posthog Bot commented Jul 28, 2026

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-07-28 10:39 UTC Run
prod-us ✅ Deployed 2026-07-28 10:56 UTC Run
prod-eu ✅ Deployed 2026-07-28 11:00 UTC Run

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.

2 participants