mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-04 06:12:10 +03:00
fix(settings): restore CLI fingerprint toggles (#1863)
Integrated into release/v3.7.8
This commit is contained in:
64
package-lock.json
generated
64
package-lock.json
generated
@@ -33,7 +33,7 @@
|
||||
"lowdb": "^7.0.1",
|
||||
"monaco-editor": "^0.55.1",
|
||||
"next": "^16.2.3",
|
||||
"next-intl": "^4.8.3",
|
||||
"next-intl": "^4.11.0",
|
||||
"node-machine-id": "^1.1.12",
|
||||
"open": "^11.0.0",
|
||||
"ora": "^9.1.0",
|
||||
@@ -1409,18 +1409,18 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@formatjs/icu-messageformat-parser": {
|
||||
"version": "3.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-3.5.5.tgz",
|
||||
"integrity": "sha512-ASMon8BNlKHgQQpZx84xI80EXRS90GlsEU4wEulCKCzrMtUdrfEvFc9UEYmRbvEvtFQLZ4qHXnisUy6PuFjwyA==",
|
||||
"version": "3.5.6",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-3.5.6.tgz",
|
||||
"integrity": "sha512-04ZjRIeQCnR/h32wBP9/S7rkyy1hLAs2fXJcNwc7hseJd//K9TMBqK0ukb4dXqnALKQ9m5ruZeOD2qqEkK9ixg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@formatjs/icu-skeleton-parser": "2.1.5"
|
||||
"@formatjs/icu-skeleton-parser": "2.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@formatjs/icu-skeleton-parser": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-2.1.5.tgz",
|
||||
"integrity": "sha512-9Kc6tMaAPZKTGevdfcvx5zT3v4BTfamo+djJE29wF6ds1QLhoA09MZNDpWMZaebWzuoOTIXhDvgmqmjSlUOGlw==",
|
||||
"version": "2.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-2.1.6.tgz",
|
||||
"integrity": "sha512-9f1VQ2kaaLHK0WPU1OrAmiNKCKJwyoDmwNzQXbUa6XtFBOgHZ4YZURE8sSedHmMr0kvpB75OtplB0hMYkfdwfg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@formatjs/intl-localematcher": {
|
||||
@@ -8634,9 +8634,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/icu-minify": {
|
||||
"version": "4.9.2",
|
||||
"resolved": "https://registry.npmjs.org/icu-minify/-/icu-minify-4.9.2.tgz",
|
||||
"integrity": "sha512-MYt1aKn6Hrag6KO1gns+2XUjguLnL4lUxnHZXCStB2hdml+ooYzMW1VnOkrwKg5aTh5fGjvfZsgJ9DYC21lTmg==",
|
||||
"version": "4.11.0",
|
||||
"resolved": "https://registry.npmjs.org/icu-minify/-/icu-minify-4.11.0.tgz",
|
||||
"integrity": "sha512-XRvblCwLqWXio5ZLcmDqXvJv7alSACK6UjXuuMOdQWB//d25AQX6xlVlI1FEbc3Q6iPLXXo6HaVLn8LcAFhn1Q==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
@@ -8767,15 +8767,21 @@
|
||||
}
|
||||
},
|
||||
"node_modules/intl-messageformat": {
|
||||
"version": "11.2.2",
|
||||
"resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-11.2.2.tgz",
|
||||
"integrity": "sha512-yUfyIkPGqMvvk2onw2xBJeLsjXdiYUYebR8mmZVQYBuZUJsFGVht48Ftm1khgu8EZ0n+izX4rAEj3fLAilkh9g==",
|
||||
"version": "11.2.3",
|
||||
"resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-11.2.3.tgz",
|
||||
"integrity": "sha512-kZthTU+3WLcoWoRg5j6LOkN1TeUBtmkX0OIwSAbcHVIfQAEbGVdmANM8u6GL3eUDOqLwheYoXMUshAh1UdeXlQ==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"@formatjs/fast-memoize": "3.1.2",
|
||||
"@formatjs/icu-messageformat-parser": "3.5.5"
|
||||
"@formatjs/fast-memoize": "3.1.3",
|
||||
"@formatjs/icu-messageformat-parser": "3.5.6"
|
||||
}
|
||||
},
|
||||
"node_modules/intl-messageformat/node_modules/@formatjs/fast-memoize": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-3.1.3.tgz",
|
||||
"integrity": "sha512-Ocd1vPuD68rW6BJDuAOtnnc1GPeVepY5kZXML1psGVFQ+1Q8CfkftT3Tnam+Mxx97Pz08jIEDCotl/GV+Naccg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ip-address": {
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz",
|
||||
@@ -11160,9 +11166,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/next-intl": {
|
||||
"version": "4.9.2",
|
||||
"resolved": "https://registry.npmjs.org/next-intl/-/next-intl-4.9.2.tgz",
|
||||
"integrity": "sha512-AZoMRsVGLZczB2hisq1OTWmNAYAKwk/jaWH4+9pfl5TCG8kbILZZptZHux9zw7DyN1yzh6X7jmaQvoykHs9Y7Q==",
|
||||
"version": "4.11.0",
|
||||
"resolved": "https://registry.npmjs.org/next-intl/-/next-intl-4.11.0.tgz",
|
||||
"integrity": "sha512-Chp8rgEVUYOX/bCtYy+PXH6lDX3X+GPT9sR9HScHroL283em/4urP9btfdHEMEHJJXdq2W/5wDaDDtWONPdNSA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
@@ -11174,11 +11180,11 @@
|
||||
"@formatjs/intl-localematcher": "^0.8.1",
|
||||
"@parcel/watcher": "^2.4.1",
|
||||
"@swc/core": "^1.15.2",
|
||||
"icu-minify": "^4.9.2",
|
||||
"icu-minify": "^4.11.0",
|
||||
"negotiator": "^1.0.0",
|
||||
"next-intl-swc-plugin-extractor": "^4.9.2",
|
||||
"next-intl-swc-plugin-extractor": "^4.11.0",
|
||||
"po-parser": "^2.1.1",
|
||||
"use-intl": "^4.9.2"
|
||||
"use-intl": "^4.11.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"next": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
|
||||
@@ -11191,9 +11197,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/next-intl-swc-plugin-extractor": {
|
||||
"version": "4.9.2",
|
||||
"resolved": "https://registry.npmjs.org/next-intl-swc-plugin-extractor/-/next-intl-swc-plugin-extractor-4.9.2.tgz",
|
||||
"integrity": "sha512-VMlEe18tvYgl+2Fl+/hOKckm0Z0EZooBLt3nFjDMva+gopFwZYhNeLBDrc/R8rulWvwBxz8LN+uKPFSQ0fFJ4A==",
|
||||
"version": "4.11.0",
|
||||
"resolved": "https://registry.npmjs.org/next-intl-swc-plugin-extractor/-/next-intl-swc-plugin-extractor-4.11.0.tgz",
|
||||
"integrity": "sha512-WUGBSxGNd8eQ0rAsJHFmRw2H7+SZAXQIY/HAnYM57JaUsj5D2vx4KOz4zFtXlyKDtsw9awHfgWVvBae2/RDF9A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/next/node_modules/@swc/helpers": {
|
||||
@@ -14346,9 +14352,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/use-intl": {
|
||||
"version": "4.9.2",
|
||||
"resolved": "https://registry.npmjs.org/use-intl/-/use-intl-4.9.2.tgz",
|
||||
"integrity": "sha512-/FCW/P/wJCv6oGTUOWLNvv+i2uowOg7r/1HAZSBfwbcNoBe5tzXgh9uZaoEKaRl9t7MnZqrDNgEJoYd+1ko1oQ==",
|
||||
"version": "4.11.0",
|
||||
"resolved": "https://registry.npmjs.org/use-intl/-/use-intl-4.11.0.tgz",
|
||||
"integrity": "sha512-7ILhTLuo3fnSKhoTGDk5X9591pjtWr6qB4inrlvGkN9OEyKhoiG73GZFoLSs68wz3BsSGtoWa62iWvrYEYU+iA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
@@ -14359,7 +14365,7 @@
|
||||
"dependencies": {
|
||||
"@formatjs/fast-memoize": "^3.1.0",
|
||||
"@schummar/icu-type-parser": "1.21.5",
|
||||
"icu-minify": "^4.9.2",
|
||||
"icu-minify": "^4.11.0",
|
||||
"intl-messageformat": "^11.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
"lowdb": "^7.0.1",
|
||||
"monaco-editor": "^0.55.1",
|
||||
"next": "^16.2.3",
|
||||
"next-intl": "^4.8.3",
|
||||
"next-intl": "^4.11.0",
|
||||
"node-machine-id": "^1.1.12",
|
||||
"open": "^11.0.0",
|
||||
"ora": "^9.1.0",
|
||||
|
||||
@@ -403,8 +403,8 @@ export default function AgentsPage() {
|
||||
<span className="material-symbols-outlined text-[14px] text-text-muted">fingerprint</span>
|
||||
<p className="text-xs text-text-muted">
|
||||
{t("fingerprintSettingsHint")}{" "}
|
||||
<Link href="/dashboard/settings" className="text-primary hover:underline">
|
||||
{t("openSettings")}
|
||||
<Link href="/dashboard/settings?tab=routing" className="text-primary hover:underline">
|
||||
{t("settingsRoutingLink")}
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { Button, Card } from "@/shared/components";
|
||||
import { useTranslations } from "next-intl";
|
||||
import FallbackChainsEditor from "./FallbackChainsEditor";
|
||||
import {
|
||||
CLI_COMPAT_PROVIDER_DISPLAY,
|
||||
CLI_COMPAT_TOGGLE_IDS,
|
||||
normalizeCliCompatProviderId,
|
||||
} from "@/shared/constants/cliCompatProviders";
|
||||
|
||||
export default function RoutingTab() {
|
||||
const [settings, setSettings] = useState<any>({
|
||||
@@ -40,6 +45,26 @@ export default function RoutingTab() {
|
||||
}
|
||||
};
|
||||
|
||||
const cliCompatProviders = useMemo(
|
||||
() =>
|
||||
Array.isArray(settings.cliCompatProviders)
|
||||
? settings.cliCompatProviders.map((providerId: string) => normalizeCliCompatProviderId(providerId))
|
||||
: [],
|
||||
[settings.cliCompatProviders]
|
||||
);
|
||||
const cliCompatProviderSet = useMemo(() => new Set(cliCompatProviders), [cliCompatProviders]);
|
||||
|
||||
const toggleCliCompatProvider = (providerId: string, enabled: boolean) => {
|
||||
const normalizedProviderId = normalizeCliCompatProviderId(providerId);
|
||||
const nextProviders = new Set(cliCompatProviders);
|
||||
if (enabled) {
|
||||
nextProviders.add(normalizedProviderId);
|
||||
} else {
|
||||
nextProviders.delete(normalizedProviderId);
|
||||
}
|
||||
updateSetting({ cliCompatProviders: Array.from(nextProviders) });
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-6">
|
||||
<Card>
|
||||
@@ -224,6 +249,62 @@ export default function RoutingTab() {
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<div className="p-2 rounded-lg bg-indigo-500/10 text-indigo-500">
|
||||
<span className="material-symbols-outlined text-[20px]" aria-hidden="true">
|
||||
fingerprint
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold">{t("cliFingerprint")}</h3>
|
||||
<p className="text-sm text-text-muted">{t("cliFingerprintDesc")}</p>
|
||||
<p className="mt-1 text-xs text-text-muted">
|
||||
{t("cliFingerprintEnabled", { count: cliCompatProviderSet.size })}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-3 md:grid-cols-2">
|
||||
{CLI_COMPAT_TOGGLE_IDS.map((providerId) => {
|
||||
const normalizedProviderId = normalizeCliCompatProviderId(providerId);
|
||||
const providerDisplay = CLI_COMPAT_PROVIDER_DISPLAY[providerId];
|
||||
const checked = cliCompatProviderSet.has(normalizedProviderId);
|
||||
const label = providerDisplay?.name || providerId;
|
||||
const description = providerDisplay?.description || providerId;
|
||||
|
||||
return (
|
||||
<button
|
||||
key={providerId}
|
||||
type="button"
|
||||
onClick={() => toggleCliCompatProvider(providerId, !checked)}
|
||||
disabled={loading}
|
||||
aria-pressed={checked}
|
||||
title={checked ? t("disableFingerprintTitle", { provider: label }) : t("enableFingerprintTitle", { provider: label })}
|
||||
className={`flex items-start gap-3 rounded-lg border p-3 text-left transition-all ${
|
||||
checked
|
||||
? "border-indigo-500/50 bg-indigo-500/5 ring-1 ring-indigo-500/20"
|
||||
: "border-border/50 hover:border-border hover:bg-surface/30"
|
||||
} ${loading ? "cursor-not-allowed opacity-60" : ""}`}
|
||||
>
|
||||
<span
|
||||
className={`material-symbols-outlined mt-0.5 text-[18px] ${checked ? "text-indigo-400" : "text-text-muted"}`}
|
||||
aria-hidden="true"
|
||||
>
|
||||
{checked ? "check_circle" : "radio_button_unchecked"}
|
||||
</span>
|
||||
<span className="min-w-0 flex-1">
|
||||
<span className={`block text-sm font-medium ${checked ? "text-indigo-400" : ""}`}>
|
||||
{label}
|
||||
</span>
|
||||
<span className="mt-1 block text-xs text-text-muted">{description}</span>
|
||||
</span>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<div className="p-2 rounded-lg bg-green-500/10 text-green-500">
|
||||
|
||||
@@ -4669,6 +4669,7 @@
|
||||
"flowDiagramCli": "CLI Agent",
|
||||
"flowDiagramCliDesc": "Processes with own auth/model",
|
||||
"fingerprintSettingsHint": "CLI Fingerprint matching (disguise requests as specific CLI tools) can be configured in",
|
||||
"settingsRoutingLink": "Settings/Routing",
|
||||
"openSettings": "Settings"
|
||||
},
|
||||
"templateNames": {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { CLI_TOOLS } from "./cliTools";
|
||||
import { normalizeCliCompatProviderId } from "../utils/cliCompat";
|
||||
|
||||
export { normalizeCliCompatProviderId };
|
||||
@@ -53,21 +52,37 @@ export const CLI_COMPAT_OMITTED_PROVIDER_IDS = [
|
||||
* Provider IDs toggled in Settings -> CLI Fingerprint.
|
||||
*
|
||||
* Source of truth:
|
||||
* - derive from visible CLI tools when a provider mapping exists
|
||||
* - keep legacy-compatible IDs that are still used by existing setups
|
||||
* - expose only providers with an implemented `CLI_FINGERPRINTS` entry
|
||||
* - keep legacy-compatible display IDs such as `copilot` while persisting normalized provider IDs
|
||||
*/
|
||||
const TOOL_ID_TO_PROVIDER_ID: Record<string, string> = {
|
||||
kilo: "kilocode",
|
||||
copilot: "github",
|
||||
};
|
||||
|
||||
const DERIVED_PROVIDER_IDS = Object.values(CLI_TOOLS)
|
||||
.map((tool: any) => normalizeCliCompatProviderId(TOOL_ID_TO_PROVIDER_ID[tool.id] ?? tool.id))
|
||||
// "continue" currently has no provider id in AI_PROVIDERS
|
||||
.filter((providerId) => IMPLEMENTED_CLI_FINGERPRINT_PROVIDER_IDS.includes(providerId as any));
|
||||
|
||||
export const CLI_COMPAT_PROVIDER_IDS = Array.from(
|
||||
new Set([...DERIVED_PROVIDER_IDS, ...IMPLEMENTED_CLI_FINGERPRINT_PROVIDER_IDS])
|
||||
new Set([...IMPLEMENTED_CLI_FINGERPRINT_PROVIDER_IDS])
|
||||
);
|
||||
|
||||
export const CLI_COMPAT_TOGGLE_IDS = Array.from(new Set(CLI_COMPAT_DISPLAY_PROVIDER_IDS));
|
||||
|
||||
export const CLI_COMPAT_PROVIDER_DISPLAY: Record<
|
||||
(typeof CLI_COMPAT_DISPLAY_PROVIDER_IDS)[number],
|
||||
{ name: string; description: string }
|
||||
> = {
|
||||
claude: {
|
||||
name: "Claude Code",
|
||||
description: "Anthropic Claude Code CLI",
|
||||
},
|
||||
codex: {
|
||||
name: "OpenAI Codex CLI",
|
||||
description: "OpenAI Codex CLI",
|
||||
},
|
||||
copilot: {
|
||||
name: "GitHub Copilot",
|
||||
description: "GitHub Copilot CLI compatibility",
|
||||
},
|
||||
antigravity: {
|
||||
name: "Antigravity",
|
||||
description: "Google Antigravity IDE compatibility",
|
||||
},
|
||||
qwen: {
|
||||
name: "Qwen Code / Qoder",
|
||||
description: "Qwen Code and Qoder CLI compatibility",
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user