diff --git a/open-sse/services/comboAgentMiddleware.ts b/open-sse/services/comboAgentMiddleware.ts index 870abf14a7..7017599528 100644 --- a/open-sse/services/comboAgentMiddleware.ts +++ b/open-sse/services/comboAgentMiddleware.ts @@ -123,6 +123,20 @@ export function applyToolFilter( }); } +/** + * Strip all tags from message content before forwarding to the provider. + * The tag is an internal OmniRoute marker; providers must never see it or their + * cache will treat every tagged request as a new session (#454). + */ +export function stripModelTags(messages: Message[]): Message[] { + return messages.map((msg) => { + if (typeof msg.content === "string" && CACHE_TAG_PATTERN.test(msg.content)) { + return { ...msg, content: msg.content.replace(CACHE_TAG_PATTERN, "").trimEnd() }; + } + return msg; + }); +} + // ── Main Middleware ────────────────────────────────────────────────────────── /** @@ -158,6 +172,11 @@ export function applyComboAgentMiddleware( comboConfig.tool_filter_regex ); + // 4. Strip internal tags before forwarding to provider (#454) + // These tags are OmniRoute-internal markers and must never reach the provider + // since providers would treat each tagged request as a new cache session. + messages = stripModelTags(messages); + return { body: { ...body, diff --git a/src/app/(dashboard)/dashboard/combos/page.tsx b/src/app/(dashboard)/dashboard/combos/page.tsx index 26f32a40e4..d60a9688c2 100644 --- a/src/app/(dashboard)/dashboard/combos/page.tsx +++ b/src/app/(dashboard)/dashboard/combos/page.tsx @@ -1181,6 +1181,12 @@ function ComboFormModal({ isOpen, combo, onClose, onSave, activeProviders }) { const [config, setConfig] = useState(combo?.config || {}); const [showStrategyNudge, setShowStrategyNudge] = useState(false); const strategyChangeMountedRef = useRef(false); + // Agent features (#399 / #401 / #454) + const [agentSystemMessage, setAgentSystemMessage] = useState(combo?.system_message || ""); + const [agentToolFilter, setAgentToolFilter] = useState(combo?.tool_filter_regex || ""); + const [agentContextCache, setAgentContextCache] = useState( + !!combo?.context_cache_protection + ); // DnD state const hasPricingForModel = useCallback( @@ -1532,6 +1538,14 @@ function ComboFormModal({ isOpen, combo, onClose, onSave, activeProviders }) { saveData.config = configToSave; } + // Agent features (#399 / #401 / #454) + if (agentSystemMessage.trim()) saveData.system_message = agentSystemMessage.trim(); + else delete saveData.system_message; + if (agentToolFilter.trim()) saveData.tool_filter_regex = agentToolFilter.trim(); + else delete saveData.tool_filter_regex; + if (agentContextCache) saveData.context_cache_protection = true; + else delete saveData.context_cache_protection; + await onSave(saveData); setSaving(false); }; @@ -2052,6 +2066,72 @@ function ComboFormModal({ isOpen, combo, onClose, onSave, activeProviders }) { )} + {/* Agent Features (#399 / #401 / #454) */} +
+
+ smart_toy +

Agent Features

+ + — optional, for agent/tool workflows + +
+ + {/* System Message Override */} +
+ +