fix(vertex): scope replay by client thread - #1335
Conversation
📝 WalkthroughWalkthroughVertex replay sessions now use the trimmed client thread ID when available and retain the existing fallback otherwise. Tests cover isolation across client threads and deterministic replay for threadless requests. ChangesVertex replay session scoping
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
✅ Deterministic PR hygiene checks passed. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/adapters/google.ts`:
- Around line 57-58: Update the thread ID selection near antigravitySessionId so
a trimmed client thread ID is transformed with the same one-way hashing used by
antigravitySessionId before being returned as the replay-session key. Preserve
the existing fallback to antigravitySessionId(parsed) when the client ID is
absent or blank, and ensure vertexReplaySession/applyAntigravityReplay receive
only the hashed value.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: b3ca2332-f0e5-4cbd-a25b-0bfbc84ebb06
📒 Files selected for processing (2)
src/adapters/google.tstests/google-vertex-thought-signature.test.ts
| const threadId = parsed._clientThreadId?.trim(); | ||
| return threadId || antigravitySessionId(parsed); |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Hash the client thread ID before using it as the replay-session key.
Line 58 returns the raw x-codex-parent-thread-id value. vertexReplaySession receives it at Line 454 and passes it to applyAntigravityReplay at Lines 459-463, so the replay cache retains the raw client identifier.
Use the same one-way hash used by antigravitySessionId, and keep the existing fallback for an absent or blank ID.
Proposed fix
function vertexReplaySessionId(parsed: OcxParsedRequest): string {
const threadId = parsed._clientThreadId?.trim();
- return threadId || antigravitySessionId(parsed);
+ if (!threadId) return antigravitySessionId(parsed);
+ const digest = createHash("sha256").update(threadId, "utf8").digest();
+ const masked = digest.readBigUInt64BE(0) & 0x7fffffffffffffffn;
+ return `-${masked.toString()}`;
}Based on the PR objective to avoid persisting raw thread identifiers and the supplied replay-session contract.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const threadId = parsed._clientThreadId?.trim(); | |
| return threadId || antigravitySessionId(parsed); | |
| const threadId = parsed._clientThreadId?.trim(); | |
| if (!threadId) return antigravitySessionId(parsed); | |
| const digest = createHash("sha256").update(threadId, "utf8").digest(); | |
| const masked = digest.readBigUInt64BE(0) & 0x7fffffffffffffffn; | |
| return `-${masked.toString()}`; |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/adapters/google.ts` around lines 57 - 58, Update the thread ID selection
near antigravitySessionId so a trimmed client thread ID is transformed with the
same one-way hashing used by antigravitySessionId before being returned as the
replay-session key. Preserve the existing fallback to
antigravitySessionId(parsed) when the client ID is absent or blank, and ensure
vertexReplaySession/applyAntigravityReplay receive only the hashed value.
|
Landed on Verified before merge: Thanks — the test where two different threads share one cache key is the one that actually proves the bug, and keeping |
Summary
Closes #1312
Verification
taskset -c 0-1 bun run typechecktaskset -c 0-1 bun test tests/antigravity-static-catalog.test.ts tests/google-adapter.test.ts tests/google-antigravity-oauth.test.ts tests/google-antigravity-replay.test.ts tests/google-antigravity-wire.test.ts tests/google-empty-content.test.ts tests/google-hardening.test.ts tests/google-models-listing.test.ts tests/google-tool-schema.test.ts tests/google-vertex-http.test.ts tests/google-vertex-stream.test.ts tests/google-vertex-thought-signature.test.ts tests/google-wire-compiler.test.ts tests/vertex-catalog.test.ts(227 pass, 0 fail)git diff --check origin/dev...HEADChecklist
Summary by CodeRabbit