Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@gitcommit90/rerouted",
"productName": "ReRouted",
"version": "0.5.13",
"version": "0.5.14",
"description": "A local AI router for connected accounts, models, named routes, and automatic fallback.",
"author": "gitcommit90",
"license": "MIT",
Expand Down
16 changes: 7 additions & 9 deletions src/lib/providers/claude.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,21 +109,19 @@ function generateBillingHeader(payload) {
}

/**
* Strip third-party agent structure that can trigger extra-usage or proxy
* detection on OAuth traffic.
* Preserve client system context while moving it into the provider-compatible
* reminder location used for OAuth traffic. Truncating this text is unsafe:
* callers rely on late system blocks for policy, memory, and handoff state.
*/
function sanitizeForwardedSystemPrompt(text) {
if (!String(text || "").trim()) return "";
// Keep a short neutral reminder; full client system prompts look like non-CLI agents.
const forwarded = String(text || "").trim();
if (!forwarded) return "";
return [
"Use the available tools when needed to help with software engineering tasks.",
"Keep responses concise and focused on the user's request.",
"Prefer acting on the user's task over describing product-specific workflows.",
// Preserve a short slice of original context if useful
String(text).trim().slice(0, 400),
]
.filter(Boolean)
.join("\n");
forwarded,
].join("\n");
}

/** Wrap forwarded system context in provider-compatible reminder blocks. */
Expand Down
5 changes: 5 additions & 0 deletions tests/gateway.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -745,10 +745,12 @@ describe("OAuth refresh against mock", () => {

describe("claude oauth request shaping", () => {
it("applyCloaking injects CC system blocks + metadata; moves client system to user", () => {
const lateSystemSentinel = `LATE_SYSTEM_HANDOFF_${"z".repeat(1600)}_END`;
const base = claude.toAnthropicBody(
{
messages: [
{ role: "system", content: "You are a custom app agent with secret tools." },
{ role: "system", content: lateSystemSentinel },
{ role: "user", content: "hi" },
],
max_tokens: 8,
Expand All @@ -774,6 +776,9 @@ describe("claude oauth request shaping", () => {
? userContent.map((b) => b.text || "").join("\n")
: String(userContent);
assert.ok(userText.includes("<system-reminder>"), userText.slice(0, 200));
assert.ok(userText.includes("You are a custom app agent with secret tools."));
assert.ok(userText.includes(lateSystemSentinel), "late and long client system context must survive OAuth request shaping");
assert.ok(userText.includes(`${lateSystemSentinel}\n\nIMPORTANT:`), "the complete sentinel must precede the reminder footer");
const uid = JSON.parse(cloaked.metadata.user_id);
assert.equal(uid.session_id, sessionId);
assert.ok(uid.device_id && uid.account_uuid);
Expand Down
Loading