Repository navigation
fix(ai): capture Gemini tool history in generation input - #5088
Conversation
|
@greptileai review |
|
The PR appears safe to merge; the previous unbounded tool-result capture finding is addressed. Reviews (2) · Last reviewed commit: "fix(ai): bound captured Gemini tool resu..." |
|
@greptileai review |
marandaneto
left a comment
There was a problem hiding this comment.
The code looks good; no qualifying findings. Verdict: correct.
|
Comparison with the other AI integrations:
The whole-result bound here is stronger against oversized tool results; identical truncation behavior across providers is not required for this fix. |
|
suggestion: Non-blocking follow-up — standardize tool-result capture policy across the AI adapters. Keep the stronger whole-result bound in this PR. Separately, agree on a shared policy for per-result byte limits, whether the truncation marker counts toward the limit, preserving structured content versus falling back to truncated text, and how any conversation-wide budget should work. OpenAI, direct Anthropic, Claude Agent, and Gemini do not currently have one uniform formatting/truncation contract. Once agreed, extract shared internal formatting utilities with a consistent JSON-safety → binary-redaction → size-bounding order, while retaining provider-specific message shapes and IDs. Add cross-adapter contract tests for nested results, many small fields, multibyte text, binary content, full-capture bypass, and privacy-mode suppression. Full capture should continue to bypass redaction/size limits without overriding privacy mode. This is a separate consistency/resource-safety improvement, not a blocker for merging this PR. |
|
@PostHog/team-ai-observability looks good to me but worth checking since i never used gemini |
|
Hey @marandaneto, thanks for the review! Is there anything else you need from me to get this PR merged? |
Problem
On a Gemini follow-up request, the Google SDK sends the model's
functionCalland the matchingfunctionResponse, but@posthog/aicaptures both messages in$ai_inputwith empty content. This is the input-history half of #5085; #5087 addresses the output IDs.Changes
functionblock, including the ID when available.tool_resultblocks linked bytool_use_id, following the Claude Agent SDK convention already in this package.parts, and responses containing both.@posthog/aipatch changeset.Tests were committed first and failed on the previous formatter: six focused unit cases and both real-SDK local recorder/replay cases reproduced empty captured content; two parts-only unit cases reproduced missing result content. They pass after the fix. A review follow-up also reproduced oversized results in both modes before adding the cap. Final validation: 1,040 package unit tests, 279 offline cassette tests, build, type check, package lint, and formatting. The recorder/replay tests use the real Google SDK with a local server, not a live-provider second turn.
Tool-result JSON and media-part metadata will now be captured when privacy mode is off. The existing binary redactor still redacts inline base64, and
posthogPrivacyModestill suppresses captured input/output entirely. It does not redact arbitrary URLs in tool results. The size limit is per result, not a total conversation-history limit.The automated draft #5086 overlaps #5085. This PR keeps the input change separate from #5087 and uses a private formatter type rather than adding a public exported type.
Release info Sub-libraries affected
Libraries affected
Checklist
@posthog/aipatch changeset🤖 Agent context
Autonomy: Human-driven (agent-assisted)
I directed the scope and reviewed the implementation with Codex. We used Vitest, the existing Gemini recorder/replay harness, and GitHub CLI. Each change was committed as a failing test followed by its fix; all four commits are signed. No agent session link is shared because this private work session also includes unrelated workspace context. GitHub would not allow assigning my external account to this PR.