Skip to content

fix(runtime): keep per-sample request session ids distinct after sanitization and for overlong run ids - #101

Closed
ayush-or wants to merge 1 commit into
mainfrom
devin/1789786060-request-session-id-collisions
Closed

ayush-or wants to merge 1 commit into
mainfrom
devin/1789786060-request-session-id-collisions

Conversation

@ayush-or

Copy link
Copy Markdown
Contributor

TL;DR

Two samples can no longer share one x-session-id after #100: sanitized sample ids carry a hash of the original, and an overlong run id hashes the full identity instead of falling back to the run-level id.

What changed?

  • buildRequestSessionId appends a 12-hex sha256 of the original sample id whenever sanitization changed it, so q/17, q.17, q 17, and q-17 map to four different ids. Sample ids already in [A-Za-z0-9_-] are unchanged (wf.0.gpqa-42).
  • When <run>.<epoch>. leaves no room for any sample segment, the result is <run head>.<32-hex sha256 of run.epoch.sample> capped at 256 chars, instead of returning <run> for every sample.
  • Regression tests for punctuation variants, a 254-char run id, and a 256-char run id.

Why?

Devin Review and Perry flagged both on the openrouter-web subtree sync (OpenRouterTeam/openrouter-web#44957): the sanitizer is not injective, and the budget <= 0 branch silently reproduced the one-session-per-run shape that #100 fixes.

How to test

bun test src/runtime/request-session-id.test.ts
bun -e 'import {buildRequestSessionId as b} from "./src/runtime/request-session-id"; console.log(["q/17","q.17","q 17","q-17"].map(s=>b("wf",1,s)))'

Expected: four distinct values, the last one exactly wf.1.q-17.

Reviewer focus

  • The hash suffix only appears when the sample id needed sanitizing. Benchmarks with clean ids keep the exact <run>.<epoch>.<sample> shape the Datadog pipeline in openrouter-web parses.
  • The overlong-run fallback truncates the run id, so ClickHouse startsWith(session_id, '<run>.') will not roll those up. Run ids are capped at 128 in schedule-utils today, so this branch is unreachable for Temporal-launched runs.

Checklist

  • Tests cover changed behavior
  • Public API or configuration changes are backward compatible, or the break is documented
  • Benchmark changes document dataset provenance and licensing
  • No credentials, private results, or restricted dataset contents are included
  • Documentation is updated where needed

Link to Devin session: https://openrouter.devinenterprise.com/sessions/b91ee8adb7514c2fa3f15e8dfa1dfd1b
Open in Devin Desktop: https://openrouter.devinenterprise.com/desktop/session/b91ee8adb7514c2fa3f15e8dfa1dfd1b?variant=devin
Requested by: @ayush-or

@ayush-or
ayush-or requested a review from a team as a code owner September 19, 2026 02:50
@devin-ai-integration

Copy link
Copy Markdown
Contributor

I'll fix CI failures and address comments from users with write access that start with 'DevinAI' or '@devin'.

  • Disable automatic comment, CI, and merge conflict monitoring

Original prompt from Ayush

SYSTEM:
<latest_message>
Ayush Patel (U0B8L6RNMA9) [ts=1789782133.457669]: @Devincan you scope out in breadth where we'd run into side effects if we changed the session id for benchmark temporal workflows in benchmark-harness

and reporting/queries in openrouter-web etc
</latest_message>

=== BEGIN THREAD HISTORY (in #eng-benchmarks) ===
Ayush Patel (U0B8L6RNMA9) [ts=1789781836.317759]: is the shared session id across benchmark samples intentional for routing too, or just tracking? feels like sessions should be per task for stateful routers, right?

today it's session_id = &lt;child_workflow_id&gt;
should it be session_id = &lt;child_workflow_id&gt;.&lt;epoch&gt;.&lt;sample/task_id&gt;

e.g. our gpqa run used one session id for all the different questions, so openrouter/jev treated them as continuations of the same task. 390/396 requests kept claude fable high instead of trying to picking a model fresh for each question due to a policy

Abhinav Pola (U090K0G7JF3) [ts=1789781914.673809]: It was meant to be for tracking but has unintended routing effects

Abhinav Pola (U090K0G7JF3) [ts=1789781957.335589]: We should prob use user id instead but it might affect some queries

Ayush Patel (U0B8L6RNMA9) [ts=1789782133.457669]: @Devincan you scope out in breadth where we'd run into side effects if we changed the session id for benchmark temporal workflows in benchmark-harness

and reporting/queries in openrouter-web etc
=== END THREAD HISTORY ===
Channel ID: C0BMHG5CG1E
Thread URL: https://openrouter.slack.com/archives/C0BMHG5CG1E/p1789781836317759?thread_ts=1789781836.317759&amp;cid=C0BMHG5CG1E

The <latest_message> is the message that you should use to guide your goals + task for this session, and you should use the rest of the slack thread as context.
A [ts=...] marker on a Slack message is that message's timestamp. To act on a specific message with the slack tool (e.g. adding an emoji reaction via the reaction command), pass that value as timestamp along with the Channel ID — no extra ... (22 chars truncated...)

@ayush-or ayush-or closed this Sep 19, 2026
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.

1 participant