Fix session key extraction for Claude Code 2.1.x user_id format

metadata.user_id is now a JSON-ish blob containing "session_id":"<uuid>"
(verified against the 2.1.173 binary: user_id is built from an object
with device_id/account_uuid/session_id). split("session_") was matching
inside "session_id":" and producing mangled keys like `id":"a78…`,
which broke the embed-session match — so the pane never grew for
interactive prompts. New session_key() handles both the JSON blob and
the legacy user_…_session_<uuid> format, with tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Jonas H
2026-06-11 09:08:28 +02:00
parent ee429be917
commit 255c67de3f

View File

@@ -10,6 +10,16 @@ use serde_json::Value;
const UPSTREAM: &str = "https://api.anthropic.com";
/// Extract the session UUID from `metadata.user_id`. Claude Code ≥2.1.x
/// sends a JSON-ish blob containing `"session_id":"<uuid>"`; older builds
/// used `user_<hash>_account_<uuid>_session_<uuid>`.
fn session_key(u: &str) -> Option<&str> {
if let Some(rest) = u.split(r#"session_id":""#).nth(1) {
return rest.split('"').next();
}
u.split("session_").nth(1)
}
#[derive(Clone)]
struct Ctx {
client: reqwest::Client,
@@ -66,7 +76,7 @@ async fn forward_inner(ctx: Ctx, req: Request) -> anyhow::Result<Response> {
let key = v
.pointer("/metadata/user_id")
.and_then(Value::as_str)
.and_then(|u| u.split("session_").nth(1))
.and_then(session_key)
.unwrap_or("unknown")
.to_string();
// Tool results ride along in the request body; surface them
@@ -127,3 +137,23 @@ async fn forward_inner(ctx: Ctx, req: Request) -> anyhow::Result<Response> {
};
Ok(builder.body(body)?)
}
#[cfg(test)]
mod tests {
use super::session_key;
#[test]
fn session_key_handles_both_user_id_formats() {
// Claude Code ≥2.1.x: JSON blob
assert_eq!(
session_key(r#"{"device_id":"d","account_uuid":"a","session_id":"a78d91b6-1234-5678-9abc-def012345678"}"#),
Some("a78d91b6-1234-5678-9abc-def012345678")
);
// Legacy underscore format
assert_eq!(
session_key("user_abc123_account_acc-uuid_session_29bd3436-aaaa-bbbb-cccc-111122223333"),
Some("29bd3436-aaaa-bbbb-cccc-111122223333")
);
assert_eq!(session_key("no session here"), None);
}
}