mirror of
https://github.com/musistudio/claude-code-router.git
synced 2026-07-09 17:18:24 +00:00
Remove deeplink replace and default actions
This commit is contained in:
parent
9119cd8567
commit
0243b408a1
5 changed files with 10 additions and 51 deletions
|
|
@ -20,7 +20,7 @@ The wrapper reads `~/.claude-code-router/config.json`, preserves the old CCR `Pr
|
|||
Supplier websites can open CCR and import a model provider with a custom protocol link:
|
||||
|
||||
```text
|
||||
ccr://provider?name=Example%20AI&base_url=https%3A%2F%2Fapi.example.com%2Fv1&api_key=sk-example&models=example-chat%2Cexample-coder&protocol=openai_chat_completions&set_default=1
|
||||
ccr://provider?name=Example%20AI&base_url=https%3A%2F%2Fapi.example.com%2Fv1&api_key=sk-example&models=example-chat%2Cexample-coder&protocol=openai_chat_completions
|
||||
```
|
||||
|
||||
Supported query parameters:
|
||||
|
|
@ -30,8 +30,6 @@ Supported query parameters:
|
|||
- `api_key`: optional provider API key. Aliases: `apiKey`, `apikey`, `key`, `token`.
|
||||
- `models`: comma-separated or newline-separated model list. You can also repeat `model=...`.
|
||||
- `protocol`: one of `openai_chat_completions`, `openai_responses`, `anthropic_messages`, or `gemini_generate_content`. Aliases such as `openai`, `responses`, `anthropic`, and `gemini` are accepted.
|
||||
- `set_default=1`: make the imported provider the preferred provider.
|
||||
- `replace=1`: replace an existing provider with the same name or normalized base URL.
|
||||
|
||||
For larger payloads, pass `payload` as URL-encoded JSON or base64url JSON with the same fields:
|
||||
|
||||
|
|
@ -41,8 +39,7 @@ For larger payloads, pass `payload` as URL-encoded JSON or base64url JSON with t
|
|||
"baseUrl": "https://api.example.com/v1",
|
||||
"apiKey": "sk-example",
|
||||
"models": ["example-chat", "example-coder"],
|
||||
"protocol": "openai_chat_completions",
|
||||
"setDefault": true
|
||||
"protocol": "openai_chat_completions"
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import {
|
|||
enforceSingleEnabledGlobalProfilePerAgent,
|
||||
ExtensionConfigTarget, ExtensionDeleteTarget, ExtensionInstallDraft, ExtensionSource, fallbackAgentAnalysis, fallbackConfig,
|
||||
fallbackGatewayStatus, fallbackInfo, fallbackProxyCertificateStatus, fallbackProxyNetworkSnapshot, fallbackProxyStatus, fallbackRequestLogPage,
|
||||
fallbackUpdateStatus, fallbackUsageStats, findProviderDeepLinkReplacementIndex, formatJson, formatProxyCertificateInstallMessage, GatewayProviderConfig,
|
||||
fallbackUpdateStatus, fallbackUsageStats, formatJson, formatProxyCertificateInstallMessage, GatewayProviderConfig,
|
||||
fusionCustomMcpServerFromDraft, fusionCustomToolConfigFromProfile,
|
||||
GatewayProviderProbeResult, gatewayServiceMessage, GatewayStatus, getDefaultOnboardingStep, isClaudeDesignPluginConfig, isClaudeDesignRoutingDraftValid,
|
||||
isCursorProxyPluginConfig, isMacPlatform, isPlainRecord, isProfileDraftSubmittable, isProviderNameDuplicate, isProviderProbeCandidateReady,
|
||||
|
|
@ -1231,17 +1231,10 @@ function App() {
|
|||
const probe = await probeProviderDeepLinkPayload(payload);
|
||||
let importedProviderName = payload.name?.trim() || "";
|
||||
const next = buildConfigUpdate((config) => {
|
||||
const replaceIndex = payload.replaceExisting
|
||||
? findProviderDeepLinkReplacementIndex(config.Providers, payload, probe?.normalizedBaseUrl || payload.baseUrl)
|
||||
: -1;
|
||||
const provider = createProviderConfigFromDeepLink(payload, config.Providers, probe, replaceIndex);
|
||||
const provider = createProviderConfigFromDeepLink(payload, config.Providers, probe);
|
||||
importedProviderName = provider.name;
|
||||
if (replaceIndex >= 0) {
|
||||
config.Providers[replaceIndex] = provider;
|
||||
} else {
|
||||
config.Providers.push(provider);
|
||||
}
|
||||
if (payload.setDefault || !config.preferredProvider) {
|
||||
config.Providers.push(provider);
|
||||
if (!config.preferredProvider) {
|
||||
config.preferredProvider = provider.name;
|
||||
}
|
||||
return config;
|
||||
|
|
|
|||
|
|
@ -790,8 +790,7 @@ export async function resolveProviderDeepLinkIcon(payload: ProviderDeepLinkPaylo
|
|||
export function createProviderConfigFromDeepLink(
|
||||
payload: ProviderDeepLinkPayload,
|
||||
providers: GatewayProviderConfig[],
|
||||
probe: GatewayProviderProbeResult | undefined,
|
||||
replaceIndex: number
|
||||
probe: GatewayProviderProbeResult | undefined
|
||||
): GatewayProviderConfig {
|
||||
const protocol = probe?.detectedProtocol ?? payload.protocol ?? "openai_chat_completions";
|
||||
const baseUrl = probe?.normalizedBaseUrl || payload.baseUrl;
|
||||
|
|
@ -802,9 +801,8 @@ export function createProviderConfigFromDeepLink(
|
|||
throw new Error("Models are required. Ask the provider to include models=... in the link.");
|
||||
}
|
||||
|
||||
const existingName = replaceIndex >= 0 ? providers[replaceIndex]?.name : undefined;
|
||||
const baseName = payload.name?.trim() || existingName || inferProviderNameFromBaseUrl(baseUrl);
|
||||
const name = replaceIndex >= 0 ? baseName : uniqueProviderName(providers, baseName);
|
||||
const baseName = payload.name?.trim() || inferProviderNameFromBaseUrl(baseUrl);
|
||||
const name = uniqueProviderName(providers, baseName);
|
||||
const keySafetyIssue = providerApiKeySafetyIssue({ apiKey: payload.apiKey, baseUrl, name });
|
||||
if (keySafetyIssue) {
|
||||
throw new Error(keySafetyIssue.message);
|
||||
|
|
@ -839,23 +837,6 @@ export function createProviderConfigFromDeepLink(
|
|||
};
|
||||
}
|
||||
|
||||
export function findProviderDeepLinkReplacementIndex(
|
||||
providers: GatewayProviderConfig[],
|
||||
payload: ProviderDeepLinkPayload,
|
||||
baseUrl: string
|
||||
): number {
|
||||
const name = payload.name?.trim();
|
||||
if (name) {
|
||||
const namedIndex = providers.findIndex((provider) => provider.name === name);
|
||||
if (namedIndex >= 0) {
|
||||
return namedIndex;
|
||||
}
|
||||
}
|
||||
|
||||
const normalizedBaseUrl = normalizeProviderBaseUrl(baseUrl).toLowerCase();
|
||||
return providers.findIndex((provider) => normalizeProviderBaseUrl(providerBaseUrl(provider)).toLowerCase() === normalizedBaseUrl);
|
||||
}
|
||||
|
||||
export function inferProviderNameFromBaseUrl(baseUrl: string): string {
|
||||
try {
|
||||
const url = new URL(providerUrlWithDefaultScheme(baseUrl));
|
||||
|
|
@ -1445,9 +1426,7 @@ export function createProviderInstallLinkFromDraft(draft: AddProviderDraft, prob
|
|||
...(draft.icon.trim() ? { icon: draft.icon.trim() } : {}),
|
||||
models,
|
||||
name: providerName,
|
||||
protocol,
|
||||
replaceExisting: false,
|
||||
setDefault: false
|
||||
protocol
|
||||
};
|
||||
return `ccr://provider?payload=${base64UrlEncodeText(JSON.stringify(payload))}`;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -215,8 +215,6 @@ export type ProviderDeepLinkPayload = {
|
|||
models: string[];
|
||||
name?: string;
|
||||
protocol?: GatewayProviderProtocol;
|
||||
replaceExisting: boolean;
|
||||
setDefault: boolean;
|
||||
source?: string;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -160,8 +160,6 @@ export function parseProviderDeepLinkPayload(rawUrl: string): ProviderDeepLinkPa
|
|||
firstStringParam(params, ["protocol", "type"]) ?? firstPayloadString(payload, ["protocol", "type"])
|
||||
);
|
||||
const models = readDeepLinkModels(params, payload);
|
||||
const setDefault = readDeepLinkBoolean(params, payload, ["set_default", "setDefault", "default", "preferred"]);
|
||||
const replaceExisting = readDeepLinkBoolean(params, payload, ["replace", "replace_existing", "replaceExisting", "update"]);
|
||||
const account = readDeepLinkAccount(params, payload);
|
||||
const source = boundedString(
|
||||
firstStringParam(params, ["source", "source_url", "sourceUrl"]) ??
|
||||
|
|
@ -176,8 +174,6 @@ export function parseProviderDeepLinkPayload(rawUrl: string): ProviderDeepLinkPa
|
|||
models,
|
||||
...(name ? { name } : {}),
|
||||
...(protocol ? { protocol } : {}),
|
||||
replaceExisting,
|
||||
setDefault,
|
||||
...(source ? { source } : {})
|
||||
};
|
||||
}
|
||||
|
|
@ -232,8 +228,6 @@ function parseProviderPayloadFields(
|
|||
firstStringParam(params, ["protocol", "type"]) ?? firstPayloadString(payload, ["protocol", "type"])
|
||||
);
|
||||
const models = readDeepLinkModels(params, payload);
|
||||
const setDefault = readDeepLinkBoolean(params, payload, ["set_default", "setDefault", "default", "preferred"]);
|
||||
const replaceExisting = readDeepLinkBoolean(params, payload, ["replace", "replace_existing", "replaceExisting", "update"]);
|
||||
const account = readDeepLinkAccount(params, payload);
|
||||
const source = boundedString(
|
||||
firstStringParam(params, ["source", "source_url", "sourceUrl"]) ??
|
||||
|
|
@ -251,8 +245,6 @@ function parseProviderPayloadFields(
|
|||
models,
|
||||
...(name ? { name } : {}),
|
||||
...(protocol ? { protocol } : {}),
|
||||
replaceExisting,
|
||||
setDefault,
|
||||
...(source ? { source } : {})
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue