diff --git a/open-sse/services/systemTransforms.ts b/open-sse/services/systemTransforms.ts index 4d8f265ef8..5e06dfdd12 100644 --- a/open-sse/services/systemTransforms.ts +++ b/open-sse/services/systemTransforms.ts @@ -188,7 +188,7 @@ export const DEFAULT_CC_BRIDGE_PROVIDER_PIPELINE: TransformOp[] = [ export const DEFAULT_SYSTEM_TRANSFORMS_CONFIG: SystemTransformsConfig = { providers: { [PROVIDER_CLAUDE]: { - enabled: true, + enabled: false, pipeline: DEFAULT_CLAUDE_PIPELINE, }, [PROVIDER_CC_BRIDGE]: { diff --git a/src/app/(dashboard)/dashboard/settings/components/RoutingTab.tsx b/src/app/(dashboard)/dashboard/settings/components/RoutingTab.tsx index 8d2ba72701..63d64a6873 100644 --- a/src/app/(dashboard)/dashboard/settings/components/RoutingTab.tsx +++ b/src/app/(dashboard)/dashboard/settings/components/RoutingTab.tsx @@ -43,7 +43,7 @@ const DEFAULT_OBFUSCATE_WORDS = [ const DEFAULT_SYSTEM_TRANSFORMS_CLIENT = { providers: { [PROVIDER_CLAUDE]: { - enabled: true, + enabled: false, pipeline: [ { kind: "drop_paragraph_if_contains", @@ -118,9 +118,6 @@ const DEFAULT_SYSTEM_TRANSFORMS_CLIENT = { }, } as const; -// Provider display metadata for the per-provider tiles. -// Mirrors the names from CLI_COMPAT_PROVIDER_DISPLAY where applicable so the -// header-fingerprint toggle row stays consistent with the rest of the card. const PROVIDER_TILE_DISPLAY: Record< string, { name: string; description: string; icon: string; tone: string } @@ -128,19 +125,313 @@ const PROVIDER_TILE_DISPLAY: Record< [PROVIDER_CLAUDE]: { name: "Claude (OAuth)", description: - "Native Claude provider — handles OAuth-issued tokens. Header fingerprint is force-applied for account safety; transforms are cosmetic-only (no billing/identity prepend — native code already does that).", + "Native Claude provider — OAuth-issued tokens. Cosmetic transforms only; billing/identity prepend handled by native executor.", icon: "anthropic", tone: "indigo", }, [PROVIDER_CC_BRIDGE]: { name: "Claude-Code Bridge (anthropic-compatible-cc-*)", description: - "Relay endpoints that accept Anthropic-shaped requests on behalf of API-key callers. The full transform pipeline ships here (paragraph anchors + identity prefixes + text replacements + SDK identity + billing header) — that's the T4-200 layout proven on the live OmniRoute deployment.", + "Relay endpoints using API keys. Full transform pipeline (paragraph anchors + identity prefixes + replacements + SDK identity + billing header).", icon: "hub", tone: "purple", }, }; +type TransformOpKind = + | "drop_paragraph_if_contains" + | "drop_paragraph_if_starts_with" + | "replace_text" + | "replace_regex" + | "drop_block_if_contains" + | "prepend_system_block" + | "append_system_block" + | "inject_billing_header" + | "obfuscate_words"; + +const OP_KIND_LABELS: Record = { + drop_paragraph_if_contains: "Drop paragraph (contains)", + drop_paragraph_if_starts_with: "Drop paragraph (starts with)", + replace_text: "Replace text", + replace_regex: "Replace regex", + drop_block_if_contains: "Drop block (contains)", + prepend_system_block: "Prepend system block", + append_system_block: "Append system block", + inject_billing_header: "Inject billing header", + obfuscate_words: "Obfuscate words (ZWJ)", +}; + +function makeDefaultOp(kind: TransformOpKind): any { + switch (kind) { + case "drop_paragraph_if_contains": + return { kind, needles: [""] }; + case "drop_paragraph_if_starts_with": + return { kind, prefixes: [""] }; + case "replace_text": + return { kind, match: "", replacement: "", allOccurrences: true }; + case "replace_regex": + return { kind, pattern: "", flags: "g", replacement: "" }; + case "drop_block_if_contains": + return { kind, needles: [""] }; + case "prepend_system_block": + return { kind, text: "", idempotencyKey: "" }; + case "append_system_block": + return { kind, text: "", idempotencyKey: "" }; + case "inject_billing_header": + return { + kind, + entrypoint: "sdk-cli", + versionFormat: "ex-machina", + cchAlgo: "sha256-first-user", + }; + case "obfuscate_words": + return { kind, words: [""], targets: ["system", "messages", "tools"] }; + } +} + +function OpEditor({ op, onChange }: { op: any; onChange: (next: any) => void }) { + const inputCls = + "w-full rounded border border-border/50 bg-background/40 px-2 py-1 text-xs font-mono text-text"; + const labelCls = "block text-[11px] text-text-muted mb-0.5"; + + const updateField = (field: string, value: any) => onChange({ ...op, [field]: value }); + + const updateListItem = (field: string, idx: number, value: string) => { + const arr = [...(op[field] || [])]; + arr[idx] = value; + onChange({ ...op, [field]: arr }); + }; + + const addListItem = (field: string) => onChange({ ...op, [field]: [...(op[field] || []), ""] }); + + const removeListItem = (field: string, idx: number) => { + const arr = [...(op[field] || [])]; + arr.splice(idx, 1); + onChange({ ...op, [field]: arr }); + }; + + const renderList = (field: string) => ( +
+ {(op[field] || []).map((item: string, idx: number) => ( +
+ updateListItem(field, idx, e.target.value)} + /> + +
+ ))} + +
+ ); + + switch (op?.kind) { + case "drop_paragraph_if_contains": + return ( +
+ + {renderList("needles")} + +
+ ); + case "drop_paragraph_if_starts_with": + return ( +
+ + {renderList("prefixes")} + +
+ ); + case "replace_text": + return ( +
+
+ + updateField("match", e.target.value)} + /> +
+
+ + updateField("replacement", e.target.value)} + /> +
+ +
+ ); + case "replace_regex": + return ( +
+
+ + updateField("pattern", e.target.value)} + /> +
+
+ + updateField("flags", e.target.value)} + /> +
+
+ + updateField("replacement", e.target.value)} + /> +
+
+ ); + case "drop_block_if_contains": + return ( +
+ + {renderList("needles")} +
+ ); + case "prepend_system_block": + case "append_system_block": + return ( +
+
+ +