ur-agent 1.27.6 → 1.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/dist/cli.js +1862 -1686
- package/docs/providers.md +6 -3
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -51195,13 +51195,1480 @@ var init_configs = __esm(() => {
|
|
|
51195
51195
|
CANONICAL_ID_TO_KEY = Object.fromEntries(Object.entries(ALL_MODEL_CONFIGS).map(([key, cfg]) => [cfg.firstParty, key]));
|
|
51196
51196
|
});
|
|
51197
51197
|
|
|
51198
|
+
// src/services/providers/providerRegistry.ts
|
|
51199
|
+
var exports_providerRegistry = {};
|
|
51200
|
+
__export(exports_providerRegistry, {
|
|
51201
|
+
validateProviderModelPair: () => validateProviderModelPair,
|
|
51202
|
+
validateProviderModelCompatibility: () => validateProviderModelCompatibility,
|
|
51203
|
+
setSafeProviderConfig: () => setSafeProviderConfig,
|
|
51204
|
+
setProviderModel: () => setProviderModel,
|
|
51205
|
+
resolveProviderId: () => resolveProviderId,
|
|
51206
|
+
providerForAuthAlias: () => providerForAuthAlias,
|
|
51207
|
+
providerAliasesFor: () => providerAliasesFor,
|
|
51208
|
+
listProviders: () => listProviders,
|
|
51209
|
+
listModelsForProviderWithSource: () => listModelsForProviderWithSource,
|
|
51210
|
+
listModelsForProvider: () => listModelsForProvider,
|
|
51211
|
+
launchProviderAuth: () => launchProviderAuth,
|
|
51212
|
+
isProviderId: () => isProviderId,
|
|
51213
|
+
isModelSupportedByProvider: () => isModelSupportedByProvider,
|
|
51214
|
+
getValidModelIdsForProvider: () => getValidModelIdsForProvider,
|
|
51215
|
+
getRuntimeProviderId: () => getRuntimeProviderId,
|
|
51216
|
+
getProviderStatus: () => getProviderStatus,
|
|
51217
|
+
getProviderRuntimeInfo: () => getProviderRuntimeInfo,
|
|
51218
|
+
getProviderRuntimeBackend: () => getProviderRuntimeBackend,
|
|
51219
|
+
getProviderFamily: () => getProviderFamily,
|
|
51220
|
+
getProviderDefinition: () => getProviderDefinition,
|
|
51221
|
+
getProviderAccessTypeLabel: () => getProviderAccessTypeLabel,
|
|
51222
|
+
getDefaultModelForProvider: () => getDefaultModelForProvider,
|
|
51223
|
+
getConnectionStatusFromDoctorResult: () => getConnectionStatusFromDoctorResult,
|
|
51224
|
+
getActiveProviderSettings: () => getActiveProviderSettings,
|
|
51225
|
+
formatProviderStatusLabel: () => formatProviderStatusLabel,
|
|
51226
|
+
formatProviderStatus: () => formatProviderStatus,
|
|
51227
|
+
formatProviderList: () => formatProviderList,
|
|
51228
|
+
formatProviderDoctor: () => formatProviderDoctor,
|
|
51229
|
+
formatInvalidProviderModelMessage: () => formatInvalidProviderModelMessage,
|
|
51230
|
+
doctorProvider: () => doctorProvider,
|
|
51231
|
+
doctorActiveProvider: () => doctorActiveProvider,
|
|
51232
|
+
credentialTypeLabel: () => credentialTypeLabel,
|
|
51233
|
+
clearProviderModelCacheForTests: () => clearProviderModelCacheForTests,
|
|
51234
|
+
classifyGeminiAccountSupport: () => classifyGeminiAccountSupport,
|
|
51235
|
+
cacheProviderModelsForProvider: () => cacheProviderModelsForProvider,
|
|
51236
|
+
buildProviderAuthCommand: () => buildProviderAuthCommand,
|
|
51237
|
+
authModeLabel: () => authModeLabel,
|
|
51238
|
+
authAliasForProvider: () => authAliasForProvider,
|
|
51239
|
+
PROVIDER_MODELS: () => PROVIDER_MODELS,
|
|
51240
|
+
PROVIDER_IDS: () => PROVIDER_IDS,
|
|
51241
|
+
PROVIDERS: () => PROVIDERS,
|
|
51242
|
+
DEFAULT_PROVIDER_ID: () => DEFAULT_PROVIDER_ID
|
|
51243
|
+
});
|
|
51244
|
+
import { spawn as spawn2 } from "child_process";
|
|
51245
|
+
function normalizeProviderInput(value) {
|
|
51246
|
+
return value.trim().toLowerCase().replace(/[_\s]+/g, "-");
|
|
51247
|
+
}
|
|
51248
|
+
function isProviderId(value) {
|
|
51249
|
+
return PROVIDER_IDS.includes(value);
|
|
51250
|
+
}
|
|
51251
|
+
function resolveProviderId(value) {
|
|
51252
|
+
const normalized = normalizeProviderInput(value);
|
|
51253
|
+
if (isProviderId(normalized)) {
|
|
51254
|
+
return normalized;
|
|
51255
|
+
}
|
|
51256
|
+
return PROVIDER_ALIASES[normalized] ?? null;
|
|
51257
|
+
}
|
|
51258
|
+
function providerAliasesFor(id) {
|
|
51259
|
+
return PROVIDER_ALIAS_ENTRIES.find((entry) => entry.canonical === id)?.aliases ?? [];
|
|
51260
|
+
}
|
|
51261
|
+
function getProviderDefinition(id) {
|
|
51262
|
+
return PROVIDERS[id];
|
|
51263
|
+
}
|
|
51264
|
+
function getActiveProviderSettings(settings = getInitialSettings()) {
|
|
51265
|
+
const configured = settings.provider ?? {};
|
|
51266
|
+
const active = configured.active ? resolveProviderId(configured.active) ?? DEFAULT_PROVIDER_ID : DEFAULT_PROVIDER_ID;
|
|
51267
|
+
const fallback = configured.fallback === "disabled" ? "disabled" : configured.fallback ? resolveProviderId(configured.fallback) ?? undefined : undefined;
|
|
51268
|
+
return {
|
|
51269
|
+
active,
|
|
51270
|
+
model: configured.model ?? (configured.active ? undefined : settings.model),
|
|
51271
|
+
baseUrl: configured.baseUrl,
|
|
51272
|
+
commandPath: configured.commandPath,
|
|
51273
|
+
fallback
|
|
51274
|
+
};
|
|
51275
|
+
}
|
|
51276
|
+
function getProviderRuntimeInfo(settings = getInitialSettings()) {
|
|
51277
|
+
const providerSettings = getActiveProviderSettings(settings);
|
|
51278
|
+
const provider = providerSettings.active ?? DEFAULT_PROVIDER_ID;
|
|
51279
|
+
const definition = getProviderDefinition(provider);
|
|
51280
|
+
return {
|
|
51281
|
+
provider,
|
|
51282
|
+
providerLabel: definition.statusBarName,
|
|
51283
|
+
accessType: definition.accessType,
|
|
51284
|
+
accessTypeLabel: getProviderAccessTypeLabel(definition),
|
|
51285
|
+
credentialType: definition.credentialType,
|
|
51286
|
+
runtimeBackend: getProviderRuntimeBackend(provider),
|
|
51287
|
+
authMode: definition.authMode,
|
|
51288
|
+
authLabel: authModeLabel(definition.authMode),
|
|
51289
|
+
model: providerSettings.model,
|
|
51290
|
+
baseUrl: providerSettings.baseUrl ?? definition.defaultBaseUrl,
|
|
51291
|
+
fallback: providerSettings.fallback
|
|
51292
|
+
};
|
|
51293
|
+
}
|
|
51294
|
+
function getProviderRuntimeBackend(providerId) {
|
|
51295
|
+
const provider = resolveProviderId(providerId);
|
|
51296
|
+
switch (provider) {
|
|
51297
|
+
case "ollama":
|
|
51298
|
+
return "ollama";
|
|
51299
|
+
case "lmstudio":
|
|
51300
|
+
return "openai-compatible:lmstudio";
|
|
51301
|
+
case "llama.cpp":
|
|
51302
|
+
return "openai-compatible:llama.cpp";
|
|
51303
|
+
case "vllm":
|
|
51304
|
+
return "openai-compatible:vllm";
|
|
51305
|
+
case "openai-compatible":
|
|
51306
|
+
return "openai-compatible";
|
|
51307
|
+
case "codex-cli":
|
|
51308
|
+
return "subscription-cli:codex";
|
|
51309
|
+
case "claude-code-cli":
|
|
51310
|
+
return "subscription-cli:claude-code";
|
|
51311
|
+
case "gemini-cli":
|
|
51312
|
+
return "subscription-cli:gemini";
|
|
51313
|
+
case "antigravity-cli":
|
|
51314
|
+
return "subscription-cli:antigravity";
|
|
51315
|
+
case "openai-api":
|
|
51316
|
+
return "api:openai";
|
|
51317
|
+
case "anthropic-api":
|
|
51318
|
+
return "api:anthropic";
|
|
51319
|
+
case "gemini-api":
|
|
51320
|
+
return "api:gemini";
|
|
51321
|
+
case "openrouter":
|
|
51322
|
+
return "api:openrouter";
|
|
51323
|
+
default:
|
|
51324
|
+
return `unknown:${providerId}`;
|
|
51325
|
+
}
|
|
51326
|
+
}
|
|
51327
|
+
function getProviderFamily(providerId) {
|
|
51328
|
+
const provider = resolveProviderId(providerId);
|
|
51329
|
+
return provider ? PROVIDER_FAMILIES[provider] : "openai-compatible";
|
|
51330
|
+
}
|
|
51331
|
+
function getRuntimeProviderId(settings = getInitialSettings()) {
|
|
51332
|
+
return getActiveProviderSettings(settings).active ?? DEFAULT_PROVIDER_ID;
|
|
51333
|
+
}
|
|
51334
|
+
function authModeLabel(mode) {
|
|
51335
|
+
switch (mode) {
|
|
51336
|
+
case "subscription":
|
|
51337
|
+
return "subscription";
|
|
51338
|
+
case "enterprise-login":
|
|
51339
|
+
return "enterprise-login";
|
|
51340
|
+
case "personal-login":
|
|
51341
|
+
return "personal-login";
|
|
51342
|
+
case "api":
|
|
51343
|
+
return "API";
|
|
51344
|
+
case "local":
|
|
51345
|
+
return "local";
|
|
51346
|
+
}
|
|
51347
|
+
}
|
|
51348
|
+
function getProviderAccessTypeLabel(provider) {
|
|
51349
|
+
return provider.accessTypeLabel ?? provider.accessType;
|
|
51350
|
+
}
|
|
51351
|
+
function credentialTypeLabel(type) {
|
|
51352
|
+
switch (type) {
|
|
51353
|
+
case "cli-login":
|
|
51354
|
+
return "subscription login";
|
|
51355
|
+
case "api-key":
|
|
51356
|
+
return "API key";
|
|
51357
|
+
case "local-runtime":
|
|
51358
|
+
return "local runtime";
|
|
51359
|
+
case "openai-compatible-endpoint":
|
|
51360
|
+
return "OpenAI-compatible endpoint";
|
|
51361
|
+
}
|
|
51362
|
+
}
|
|
51363
|
+
function listProviders() {
|
|
51364
|
+
return PROVIDER_IDS.map((id) => PROVIDERS[id]);
|
|
51365
|
+
}
|
|
51366
|
+
function hasSecretLikeValue(value) {
|
|
51367
|
+
const trimmed = value.trim();
|
|
51368
|
+
if (/^(sk-|sk_|sk-proj-|sk-ant-|xox[baprs]-|gh[pousr]_|AIza)/i.test(trimmed)) {
|
|
51369
|
+
return true;
|
|
51370
|
+
}
|
|
51371
|
+
if (/token|refresh|oauth|secret|api[_-]?key/i.test(trimmed)) {
|
|
51372
|
+
return true;
|
|
51373
|
+
}
|
|
51374
|
+
try {
|
|
51375
|
+
const url3 = new URL(trimmed);
|
|
51376
|
+
return Boolean(url3.username || url3.password);
|
|
51377
|
+
} catch {
|
|
51378
|
+
return false;
|
|
51379
|
+
}
|
|
51380
|
+
}
|
|
51381
|
+
function normalizeBaseUrl(value) {
|
|
51382
|
+
const trimmed = value.trim();
|
|
51383
|
+
const withScheme = /^https?:\/\//i.test(trimmed) ? trimmed : `http://${trimmed}`;
|
|
51384
|
+
const url3 = new URL(withScheme);
|
|
51385
|
+
if (url3.username || url3.password) {
|
|
51386
|
+
throw new Error("base_url must not contain embedded credentials");
|
|
51387
|
+
}
|
|
51388
|
+
return withScheme.replace(/\/$/, "");
|
|
51389
|
+
}
|
|
51390
|
+
function setSafeProviderConfig(key, value) {
|
|
51391
|
+
const trimmed = value.trim();
|
|
51392
|
+
if (!trimmed) {
|
|
51393
|
+
return { ok: false, message: `Missing value for ${key}.` };
|
|
51394
|
+
}
|
|
51395
|
+
if (hasSecretLikeValue(trimmed)) {
|
|
51396
|
+
return {
|
|
51397
|
+
ok: false,
|
|
51398
|
+
message: "Refusing to store credential-like data. Put API keys in environment variables and select API mode explicitly."
|
|
51399
|
+
};
|
|
51400
|
+
}
|
|
51401
|
+
let settings;
|
|
51402
|
+
let providerModelInvalidated = false;
|
|
51403
|
+
try {
|
|
51404
|
+
if (key === "provider") {
|
|
51405
|
+
const provider = resolveProviderId(trimmed);
|
|
51406
|
+
if (!provider) {
|
|
51407
|
+
return {
|
|
51408
|
+
ok: false,
|
|
51409
|
+
message: `Unknown provider "${trimmed}". Run: ur provider list`
|
|
51410
|
+
};
|
|
51411
|
+
}
|
|
51412
|
+
const currentSettings = getInitialSettings();
|
|
51413
|
+
const currentModel = getActiveProviderSettings(currentSettings).model;
|
|
51414
|
+
const nextProviderSettings = { active: provider };
|
|
51415
|
+
let invalidated = false;
|
|
51416
|
+
if (currentModel) {
|
|
51417
|
+
const validation = validateProviderModelPair(provider, currentModel);
|
|
51418
|
+
if (validation.valid === false) {
|
|
51419
|
+
nextProviderSettings.model = undefined;
|
|
51420
|
+
invalidated = true;
|
|
51421
|
+
providerModelInvalidated = true;
|
|
51422
|
+
}
|
|
51423
|
+
}
|
|
51424
|
+
settings = {
|
|
51425
|
+
provider: nextProviderSettings,
|
|
51426
|
+
...invalidated ? { model: undefined } : {}
|
|
51427
|
+
};
|
|
51428
|
+
} else if (key === "provider.fallback") {
|
|
51429
|
+
const fallback = trimmed === "disabled" ? "disabled" : resolveProviderId(trimmed);
|
|
51430
|
+
if (!fallback) {
|
|
51431
|
+
return {
|
|
51432
|
+
ok: false,
|
|
51433
|
+
message: `Unknown fallback provider "${trimmed}". Run: ur provider list`
|
|
51434
|
+
};
|
|
51435
|
+
}
|
|
51436
|
+
settings = { provider: { fallback } };
|
|
51437
|
+
} else if (key === "provider.command_path") {
|
|
51438
|
+
settings = { provider: { commandPath: trimmed } };
|
|
51439
|
+
} else if (key === "model") {
|
|
51440
|
+
const currentSettings = getInitialSettings();
|
|
51441
|
+
const currentProvider = getActiveProviderSettings(currentSettings).active ?? "ollama";
|
|
51442
|
+
const validation = validateProviderModelPair(currentProvider, trimmed);
|
|
51443
|
+
if (validation.valid === false) {
|
|
51444
|
+
return {
|
|
51445
|
+
ok: false,
|
|
51446
|
+
message: validation.error
|
|
51447
|
+
};
|
|
51448
|
+
}
|
|
51449
|
+
settings = { provider: { model: trimmed }, model: trimmed };
|
|
51450
|
+
} else {
|
|
51451
|
+
settings = { provider: { baseUrl: normalizeBaseUrl(trimmed) } };
|
|
51452
|
+
}
|
|
51453
|
+
} catch (error40) {
|
|
51454
|
+
return {
|
|
51455
|
+
ok: false,
|
|
51456
|
+
message: error40 instanceof Error ? error40.message : String(error40)
|
|
51457
|
+
};
|
|
51458
|
+
}
|
|
51459
|
+
const result = updateSettingsForSource("userSettings", settings);
|
|
51460
|
+
if (result.error) {
|
|
51461
|
+
return {
|
|
51462
|
+
ok: false,
|
|
51463
|
+
message: `Failed to write UR-AGENT settings: ${result.error.message}`
|
|
51464
|
+
};
|
|
51465
|
+
}
|
|
51466
|
+
const savedValue = key === "provider" || key === "provider.fallback" ? key === "provider.fallback" && trimmed === "disabled" ? "disabled" : resolveProviderId(trimmed) ?? trimmed : trimmed;
|
|
51467
|
+
return {
|
|
51468
|
+
ok: true,
|
|
51469
|
+
message: `Set ${key} to ${savedValue}.${providerModelInvalidated ? " Cleared incompatible model for the new provider; run /model to choose a scoped model." : ""}`
|
|
51470
|
+
};
|
|
51471
|
+
}
|
|
51472
|
+
function outputText(result) {
|
|
51473
|
+
return `${result.stdout}
|
|
51474
|
+
${result.stderr}
|
|
51475
|
+
${result.error ?? ""}`.trim();
|
|
51476
|
+
}
|
|
51477
|
+
function classifiesAsLoggedIn(text) {
|
|
51478
|
+
return /logged in|authenticated|signed in|active account|using chatgpt/i.test(text);
|
|
51479
|
+
}
|
|
51480
|
+
function classifiesAsNotLoggedIn(text) {
|
|
51481
|
+
return /not logged in|not authenticated|not signed in|login required|unauthenticated/i.test(text);
|
|
51482
|
+
}
|
|
51483
|
+
function classifyGeminiAccountSupport(text) {
|
|
51484
|
+
if (/personal.*unsupported|unsupported.*personal|consumer.*unsupported/i.test(text)) {
|
|
51485
|
+
return "personal-unsupported";
|
|
51486
|
+
}
|
|
51487
|
+
if (/enterprise|standard|code assist|workspace/i.test(text)) {
|
|
51488
|
+
return "enterprise-supported";
|
|
51489
|
+
}
|
|
51490
|
+
return "unknown";
|
|
51491
|
+
}
|
|
51492
|
+
async function resolveCommand(definition, settings, adapters) {
|
|
51493
|
+
if (settings.commandPath) {
|
|
51494
|
+
return settings.commandPath;
|
|
51495
|
+
}
|
|
51496
|
+
for (const candidate of definition.commandCandidates ?? []) {
|
|
51497
|
+
const found = await (adapters.which ?? which)(candidate);
|
|
51498
|
+
if (found)
|
|
51499
|
+
return found;
|
|
51500
|
+
}
|
|
51501
|
+
return null;
|
|
51502
|
+
}
|
|
51503
|
+
async function runCommand(file2, args, adapters) {
|
|
51504
|
+
if (adapters.run) {
|
|
51505
|
+
return adapters.run(file2, args);
|
|
51506
|
+
}
|
|
51507
|
+
return execFileNoThrow(file2, args, {
|
|
51508
|
+
timeout: 15000,
|
|
51509
|
+
preserveOutputOnError: true,
|
|
51510
|
+
audit: false
|
|
51511
|
+
});
|
|
51512
|
+
}
|
|
51513
|
+
function addFailure(result, reason, fix) {
|
|
51514
|
+
result.ok = false;
|
|
51515
|
+
result.failureReason ??= reason;
|
|
51516
|
+
result.suggestedFix ??= fix;
|
|
51517
|
+
}
|
|
51518
|
+
function endpointUrl(baseUrl, kind) {
|
|
51519
|
+
const trimmed = baseUrl.replace(/\/$/, "");
|
|
51520
|
+
if (kind === "ollama") {
|
|
51521
|
+
return `${trimmed}/api/tags`;
|
|
51522
|
+
}
|
|
51523
|
+
return `${trimmed}/models`;
|
|
51524
|
+
}
|
|
51525
|
+
function isLocalBaseUrl(value) {
|
|
51526
|
+
return LOCALHOST_RE.test(value);
|
|
51527
|
+
}
|
|
51528
|
+
async function checkEndpoint(definition, settings, adapters, result) {
|
|
51529
|
+
if (!definition.endpointKind)
|
|
51530
|
+
return;
|
|
51531
|
+
const baseUrl = settings.baseUrl ?? (definition.id === "ollama" ? getOllamaBaseUrl() : definition.defaultBaseUrl);
|
|
51532
|
+
if (!baseUrl) {
|
|
51533
|
+
result.checks.push({
|
|
51534
|
+
name: "base_url",
|
|
51535
|
+
status: "fail",
|
|
51536
|
+
message: "No base_url configured."
|
|
51537
|
+
});
|
|
51538
|
+
addFailure(result, "missing base_url", "Run: ur config set base_url <url>");
|
|
51539
|
+
return;
|
|
51540
|
+
}
|
|
51541
|
+
const url3 = endpointUrl(baseUrl, definition.endpointKind);
|
|
51542
|
+
try {
|
|
51543
|
+
const response = await (adapters.fetch ?? fetch)(url3, {
|
|
51544
|
+
method: "GET",
|
|
51545
|
+
headers: definition.accessType === "api" && (adapters.env ?? process.env)[definition.envKey ?? ""] ? { Authorization: `Bearer ${(adapters.env ?? process.env)[definition.envKey ?? ""]}` } : undefined
|
|
51546
|
+
});
|
|
51547
|
+
if (!response.ok) {
|
|
51548
|
+
result.checks.push({
|
|
51549
|
+
name: "endpoint",
|
|
51550
|
+
status: "fail",
|
|
51551
|
+
message: `${url3} returned HTTP ${response.status}.`
|
|
51552
|
+
});
|
|
51553
|
+
addFailure(result, `endpoint returned HTTP ${response.status}`, `Start the provider server or update base_url: ur config set base_url ${baseUrl}`);
|
|
51554
|
+
return;
|
|
51555
|
+
}
|
|
51556
|
+
result.checks.push({
|
|
51557
|
+
name: "endpoint",
|
|
51558
|
+
status: "pass",
|
|
51559
|
+
message: `${url3} is reachable.`
|
|
51560
|
+
});
|
|
51561
|
+
if (settings.model) {
|
|
51562
|
+
const body = await response.text().catch(() => "");
|
|
51563
|
+
if (body && !body.includes(settings.model)) {
|
|
51564
|
+
result.checks.push({
|
|
51565
|
+
name: "model",
|
|
51566
|
+
status: "warn",
|
|
51567
|
+
message: `Model "${settings.model}" was not found in the detectable model list.`
|
|
51568
|
+
});
|
|
51569
|
+
} else {
|
|
51570
|
+
result.checks.push({
|
|
51571
|
+
name: "model",
|
|
51572
|
+
status: "pass",
|
|
51573
|
+
message: `Model "${settings.model}" is detectable.`
|
|
51574
|
+
});
|
|
51575
|
+
}
|
|
51576
|
+
}
|
|
51577
|
+
} catch (error40) {
|
|
51578
|
+
result.checks.push({
|
|
51579
|
+
name: "endpoint",
|
|
51580
|
+
status: "fail",
|
|
51581
|
+
message: `${url3} is not reachable.`
|
|
51582
|
+
});
|
|
51583
|
+
addFailure(result, error40 instanceof Error ? error40.message : "endpoint unavailable", `Start the provider server or update base_url: ur config set base_url ${baseUrl}`);
|
|
51584
|
+
}
|
|
51585
|
+
}
|
|
51586
|
+
async function checkSubscriptionProvider(definition, settings, adapters, result) {
|
|
51587
|
+
const commandPath = await resolveCommand(definition, settings, adapters);
|
|
51588
|
+
if (!commandPath) {
|
|
51589
|
+
const commands = definition.commandCandidates?.join(", ") ?? definition.id;
|
|
51590
|
+
result.checks.push({
|
|
51591
|
+
name: "cli",
|
|
51592
|
+
status: "fail",
|
|
51593
|
+
message: `No official CLI command found on PATH. Tried: ${commands}.`
|
|
51594
|
+
});
|
|
51595
|
+
addFailure(result, "CLI missing", `Install the official ${definition.displayName} CLI, then run ur auth ${authAliasForProvider(definition.id)}.`);
|
|
51596
|
+
return;
|
|
51597
|
+
}
|
|
51598
|
+
result.checks.push({
|
|
51599
|
+
name: "cli",
|
|
51600
|
+
status: "pass",
|
|
51601
|
+
message: `${commandPath} found.`
|
|
51602
|
+
});
|
|
51603
|
+
if (definition.versionArgs) {
|
|
51604
|
+
const version2 = await runCommand(commandPath, definition.versionArgs, adapters);
|
|
51605
|
+
result.checks.push({
|
|
51606
|
+
name: "version",
|
|
51607
|
+
status: version2.code === 0 ? "pass" : "warn",
|
|
51608
|
+
message: outputText(version2) || `${definition.displayName} version check exited ${version2.code}.`
|
|
51609
|
+
});
|
|
51610
|
+
}
|
|
51611
|
+
if (definition.id === "claude-code-cli" && (adapters.env ?? process.env).ANTHROPIC_API_KEY) {
|
|
51612
|
+
result.checks.push({
|
|
51613
|
+
name: "api_key_override",
|
|
51614
|
+
status: "warn",
|
|
51615
|
+
message: "ANTHROPIC_API_KEY is set and may override Claude Code subscription login. Unset it to test subscription auth."
|
|
51616
|
+
});
|
|
51617
|
+
}
|
|
51618
|
+
if (definition.id === "gemini-cli") {
|
|
51619
|
+
const versionText = result.checks.find((check3) => check3.name === "version")?.message ?? "";
|
|
51620
|
+
const support = classifyGeminiAccountSupport(versionText);
|
|
51621
|
+
if (support === "personal-unsupported") {
|
|
51622
|
+
result.checks.push({
|
|
51623
|
+
name: "account_type",
|
|
51624
|
+
status: "fail",
|
|
51625
|
+
message: definition.unsupportedPersonalAccountMessage ?? "Unsupported account type."
|
|
51626
|
+
});
|
|
51627
|
+
addFailure(result, "unsupported account type", "Use an official Gemini Code Assist Standard/Enterprise login path.");
|
|
51628
|
+
} else if (support === "enterprise-supported") {
|
|
51629
|
+
result.checks.push({
|
|
51630
|
+
name: "account_type",
|
|
51631
|
+
status: "pass",
|
|
51632
|
+
message: "Gemini Code Assist Standard/Enterprise path is supported by the detected CLI output."
|
|
51633
|
+
});
|
|
51634
|
+
} else {
|
|
51635
|
+
result.checks.push({
|
|
51636
|
+
name: "account_type",
|
|
51637
|
+
status: "warn",
|
|
51638
|
+
message: "Gemini CLI status is not exposed by this CLI. UR-AGENT will only use the official Gemini CLI flow and will not support personal-account bypasses."
|
|
51639
|
+
});
|
|
51640
|
+
}
|
|
51641
|
+
}
|
|
51642
|
+
if (!definition.statusArgs) {
|
|
51643
|
+
result.checks.push({
|
|
51644
|
+
name: "login_status",
|
|
51645
|
+
status: "skip",
|
|
51646
|
+
message: "No stable official status command is configured for this provider."
|
|
51647
|
+
});
|
|
51648
|
+
return;
|
|
51649
|
+
}
|
|
51650
|
+
const status = await runCommand(commandPath, definition.statusArgs, adapters);
|
|
51651
|
+
const text = outputText(status);
|
|
51652
|
+
if (status.code === 0 && !classifiesAsNotLoggedIn(text)) {
|
|
51653
|
+
result.checks.push({
|
|
51654
|
+
name: "login_status",
|
|
51655
|
+
status: classifiesAsLoggedIn(text) ? "pass" : "warn",
|
|
51656
|
+
message: text || "Status command succeeded."
|
|
51657
|
+
});
|
|
51658
|
+
return;
|
|
51659
|
+
}
|
|
51660
|
+
result.checks.push({
|
|
51661
|
+
name: "login_status",
|
|
51662
|
+
status: "fail",
|
|
51663
|
+
message: text || `${definition.displayName} is not logged in.`
|
|
51664
|
+
});
|
|
51665
|
+
addFailure(result, "not logged in", `Run: ur auth ${authAliasForProvider(definition.id)}`);
|
|
51666
|
+
}
|
|
51667
|
+
async function checkApiProvider(definition, settings, adapters, result) {
|
|
51668
|
+
const env4 = adapters.env ?? process.env;
|
|
51669
|
+
const baseUrl = settings.baseUrl ?? definition.defaultBaseUrl;
|
|
51670
|
+
const requiresKey = definition.id !== "openai-compatible" || !baseUrl || !isLocalBaseUrl(baseUrl);
|
|
51671
|
+
if (definition.envKey && requiresKey) {
|
|
51672
|
+
if (env4[definition.envKey]) {
|
|
51673
|
+
result.checks.push({
|
|
51674
|
+
name: "api_key",
|
|
51675
|
+
status: "pass",
|
|
51676
|
+
message: `${definition.envKey} is present.`
|
|
51677
|
+
});
|
|
51678
|
+
} else {
|
|
51679
|
+
result.checks.push({
|
|
51680
|
+
name: "api_key",
|
|
51681
|
+
status: "fail",
|
|
51682
|
+
message: `${definition.envKey} is not set.`
|
|
51683
|
+
});
|
|
51684
|
+
addFailure(result, "API key missing", `Set ${definition.envKey} in your environment or choose a subscription/local provider.`);
|
|
51685
|
+
}
|
|
51686
|
+
}
|
|
51687
|
+
await checkEndpoint(definition, settings, adapters, result);
|
|
51688
|
+
}
|
|
51689
|
+
function fallbackResult(settings, active, ok) {
|
|
51690
|
+
if (ok)
|
|
51691
|
+
return;
|
|
51692
|
+
if (!settings.fallback || settings.fallback === "disabled") {
|
|
51693
|
+
return {
|
|
51694
|
+
enabled: false,
|
|
51695
|
+
message: "Fallback is disabled. UR-AGENT will not silently switch providers. Optional: ur config set provider.fallback ollama"
|
|
51696
|
+
};
|
|
51697
|
+
}
|
|
51698
|
+
if (settings.fallback === active) {
|
|
51699
|
+
return {
|
|
51700
|
+
enabled: false,
|
|
51701
|
+
message: "Fallback points at the selected provider and will not be used."
|
|
51702
|
+
};
|
|
51703
|
+
}
|
|
51704
|
+
return {
|
|
51705
|
+
enabled: true,
|
|
51706
|
+
provider: settings.fallback,
|
|
51707
|
+
message: `Fallback is configured as ${settings.fallback}, but UR-AGENT will ask before using it.`
|
|
51708
|
+
};
|
|
51709
|
+
}
|
|
51710
|
+
async function doctorProvider(provider, options = {}) {
|
|
51711
|
+
const allSettings = options.settings ?? getInitialSettings();
|
|
51712
|
+
const providerSettings = getActiveProviderSettings(allSettings);
|
|
51713
|
+
const active = provider ?? providerSettings.active ?? DEFAULT_PROVIDER_ID;
|
|
51714
|
+
const definition = getProviderDefinition(active);
|
|
51715
|
+
const settingsForProvider = {
|
|
51716
|
+
...providerSettings,
|
|
51717
|
+
active
|
|
51718
|
+
};
|
|
51719
|
+
const result = {
|
|
51720
|
+
provider: active,
|
|
51721
|
+
displayName: definition.displayName,
|
|
51722
|
+
accessType: definition.accessType,
|
|
51723
|
+
authMode: definition.authMode,
|
|
51724
|
+
selected: active === providerSettings.active,
|
|
51725
|
+
ok: true,
|
|
51726
|
+
checks: [
|
|
51727
|
+
{
|
|
51728
|
+
name: "legal_path",
|
|
51729
|
+
status: "pass",
|
|
51730
|
+
message: definition.legalPath
|
|
51731
|
+
}
|
|
51732
|
+
]
|
|
51733
|
+
};
|
|
51734
|
+
if (definition.accessType === "subscription") {
|
|
51735
|
+
await checkSubscriptionProvider(definition, settingsForProvider, options.adapters ?? {}, result);
|
|
51736
|
+
} else if (definition.accessType === "api") {
|
|
51737
|
+
await checkApiProvider(definition, settingsForProvider, options.adapters ?? {}, result);
|
|
51738
|
+
} else if (definition.accessType === "local" || definition.accessType === "server") {
|
|
51739
|
+
await checkEndpoint(definition, settingsForProvider, options.adapters ?? {}, result);
|
|
51740
|
+
}
|
|
51741
|
+
result.fallback = fallbackResult(providerSettings, active, result.ok);
|
|
51742
|
+
return result;
|
|
51743
|
+
}
|
|
51744
|
+
async function doctorActiveProvider(options = {}) {
|
|
51745
|
+
const settings = options.settings ?? getInitialSettings();
|
|
51746
|
+
const active = getActiveProviderSettings(settings).active ?? DEFAULT_PROVIDER_ID;
|
|
51747
|
+
return doctorProvider(active, options);
|
|
51748
|
+
}
|
|
51749
|
+
function getConnectionStatusFromDoctorResult(result) {
|
|
51750
|
+
if (result.ok) {
|
|
51751
|
+
return "connected";
|
|
51752
|
+
}
|
|
51753
|
+
if (result.failureReason?.includes("CLI missing") || result.failureReason?.includes("not found")) {
|
|
51754
|
+
return "missing";
|
|
51755
|
+
}
|
|
51756
|
+
if (result.failureReason?.includes("not logged in") || result.failureReason?.includes("not authenticated") || result.failureReason?.includes("API key missing") || result.failureReason?.includes("endpoint") || result.failureReason?.includes("HTTP")) {
|
|
51757
|
+
return "unavailable";
|
|
51758
|
+
}
|
|
51759
|
+
return "unknown";
|
|
51760
|
+
}
|
|
51761
|
+
function formatProviderStatusLabel(status, provider, checks3) {
|
|
51762
|
+
switch (status) {
|
|
51763
|
+
case "connected":
|
|
51764
|
+
if (provider.credentialType === "api-key" && provider.envKey) {
|
|
51765
|
+
return `${provider.envKey} found`;
|
|
51766
|
+
}
|
|
51767
|
+
if (provider.id === "ollama") {
|
|
51768
|
+
return "localhost reachable";
|
|
51769
|
+
}
|
|
51770
|
+
if (provider.credentialType === "openai-compatible-endpoint") {
|
|
51771
|
+
return "OpenAI-compatible endpoint reachable";
|
|
51772
|
+
}
|
|
51773
|
+
if (provider.credentialType === "cli-login") {
|
|
51774
|
+
return "subscription login connected";
|
|
51775
|
+
}
|
|
51776
|
+
return "connected";
|
|
51777
|
+
case "missing":
|
|
51778
|
+
if (provider.commandCandidates) {
|
|
51779
|
+
return `CLI not found (tried: ${provider.commandCandidates.join(", ")})`;
|
|
51780
|
+
}
|
|
51781
|
+
return "missing";
|
|
51782
|
+
case "unavailable": {
|
|
51783
|
+
const failCheck = checks3.find((check3) => check3.status === "fail" || check3.status === "warn");
|
|
51784
|
+
return failCheck?.message ?? "unavailable";
|
|
51785
|
+
}
|
|
51786
|
+
case "unknown":
|
|
51787
|
+
return "status unknown";
|
|
51788
|
+
}
|
|
51789
|
+
}
|
|
51790
|
+
async function getProviderStatus(providerId, options = {}) {
|
|
51791
|
+
const provider = resolveProviderId(providerId);
|
|
51792
|
+
if (!provider) {
|
|
51793
|
+
throw new Error(`Unknown provider "${providerId}". Run: ur provider list`);
|
|
51794
|
+
}
|
|
51795
|
+
const definition = getProviderDefinition(provider);
|
|
51796
|
+
const doctor = await doctorProvider(provider, options);
|
|
51797
|
+
const status = getConnectionStatusFromDoctorResult(doctor);
|
|
51798
|
+
return {
|
|
51799
|
+
provider,
|
|
51800
|
+
displayName: definition.displayName,
|
|
51801
|
+
accessType: definition.accessType,
|
|
51802
|
+
accessTypeLabel: getProviderAccessTypeLabel(definition),
|
|
51803
|
+
credentialType: definition.credentialType,
|
|
51804
|
+
status,
|
|
51805
|
+
label: formatProviderStatusLabel(status, definition, doctor.checks),
|
|
51806
|
+
checks: doctor.checks,
|
|
51807
|
+
doctor
|
|
51808
|
+
};
|
|
51809
|
+
}
|
|
51810
|
+
function authAliasForProvider(provider) {
|
|
51811
|
+
switch (provider) {
|
|
51812
|
+
case "codex-cli":
|
|
51813
|
+
return "chatgpt";
|
|
51814
|
+
case "claude-code-cli":
|
|
51815
|
+
return "claude";
|
|
51816
|
+
case "gemini-cli":
|
|
51817
|
+
return "gemini";
|
|
51818
|
+
case "antigravity-cli":
|
|
51819
|
+
return "antigravity";
|
|
51820
|
+
default:
|
|
51821
|
+
return "provider";
|
|
51822
|
+
}
|
|
51823
|
+
}
|
|
51824
|
+
function providerForAuthAlias(alias) {
|
|
51825
|
+
switch (alias) {
|
|
51826
|
+
case "chatgpt":
|
|
51827
|
+
return "codex-cli";
|
|
51828
|
+
case "claude":
|
|
51829
|
+
return "claude-code-cli";
|
|
51830
|
+
case "gemini":
|
|
51831
|
+
return "gemini-cli";
|
|
51832
|
+
case "antigravity":
|
|
51833
|
+
return "antigravity-cli";
|
|
51834
|
+
default:
|
|
51835
|
+
return null;
|
|
51836
|
+
}
|
|
51837
|
+
}
|
|
51838
|
+
function buildProviderAuthCommand(provider, options = {}) {
|
|
51839
|
+
const definition = getProviderDefinition(provider);
|
|
51840
|
+
const command = definition.commandCandidates?.[0];
|
|
51841
|
+
if (!command)
|
|
51842
|
+
return null;
|
|
51843
|
+
const args = options.deviceAuth && definition.deviceLoginArgs ? definition.deviceLoginArgs : definition.loginArgs;
|
|
51844
|
+
if (!args)
|
|
51845
|
+
return null;
|
|
51846
|
+
if (provider === "gemini-cli") {
|
|
51847
|
+
return {
|
|
51848
|
+
command,
|
|
51849
|
+
args,
|
|
51850
|
+
instructions: "The detected Gemini CLI does not expose a stable non-interactive login subcommand. Launching the official Gemini CLI is the only supported path; complete the Gemini Code Assist login flow if prompted."
|
|
51851
|
+
};
|
|
51852
|
+
}
|
|
51853
|
+
if (provider === "antigravity-cli") {
|
|
51854
|
+
return {
|
|
51855
|
+
command,
|
|
51856
|
+
args,
|
|
51857
|
+
instructions: "UR-AGENT will only launch the official Antigravity CLI. Use its documented login flow where supported; UR-AGENT will not invent flags or reuse browser sessions."
|
|
51858
|
+
};
|
|
51859
|
+
}
|
|
51860
|
+
return {
|
|
51861
|
+
command,
|
|
51862
|
+
args,
|
|
51863
|
+
instructions: `Launching ${definition.legalPath}.`
|
|
51864
|
+
};
|
|
51865
|
+
}
|
|
51866
|
+
async function launchProviderAuth(alias, options = {}) {
|
|
51867
|
+
const provider = providerForAuthAlias(alias);
|
|
51868
|
+
if (!provider) {
|
|
51869
|
+
return { ok: false, message: `Unknown auth provider "${alias}".` };
|
|
51870
|
+
}
|
|
51871
|
+
const authCommand = buildProviderAuthCommand(provider, options);
|
|
51872
|
+
if (!authCommand) {
|
|
51873
|
+
return {
|
|
51874
|
+
ok: false,
|
|
51875
|
+
message: `No official login command is configured for ${provider}.`
|
|
51876
|
+
};
|
|
51877
|
+
}
|
|
51878
|
+
const commandPath = await resolveCommand(getProviderDefinition(provider), {}, {});
|
|
51879
|
+
if (!commandPath) {
|
|
51880
|
+
const commands = getProviderDefinition(provider).commandCandidates?.join(", ") ?? provider;
|
|
51881
|
+
return {
|
|
51882
|
+
ok: false,
|
|
51883
|
+
message: `No official ${getProviderDefinition(provider).displayName} CLI command found. Tried: ${commands}. Install the official CLI first.`
|
|
51884
|
+
};
|
|
51885
|
+
}
|
|
51886
|
+
const printableCommand = commandPath.split(/[\\/]/).pop() ?? authCommand.command;
|
|
51887
|
+
const printable = [printableCommand, ...authCommand.args].join(" ");
|
|
51888
|
+
if (options.dryRun || !process.stdin.isTTY || !process.stdout.isTTY) {
|
|
51889
|
+
return {
|
|
51890
|
+
ok: true,
|
|
51891
|
+
message: `${authCommand.instructions}
|
|
51892
|
+
Run: ${printable}`,
|
|
51893
|
+
command: printable
|
|
51894
|
+
};
|
|
51895
|
+
}
|
|
51896
|
+
await new Promise((resolve8, reject) => {
|
|
51897
|
+
const child = spawn2(commandPath, authCommand.args, {
|
|
51898
|
+
stdio: "inherit",
|
|
51899
|
+
env: process.env
|
|
51900
|
+
});
|
|
51901
|
+
child.on("error", reject);
|
|
51902
|
+
child.on("exit", (code) => {
|
|
51903
|
+
if (code === 0)
|
|
51904
|
+
resolve8();
|
|
51905
|
+
else
|
|
51906
|
+
reject(new Error(`${printable} exited with code ${code ?? 1}`));
|
|
51907
|
+
});
|
|
51908
|
+
});
|
|
51909
|
+
return { ok: true, message: `Completed: ${printable}`, command: printable };
|
|
51910
|
+
}
|
|
51911
|
+
function formatProviderList(json2 = false) {
|
|
51912
|
+
const providers = listProviders().map((provider) => ({
|
|
51913
|
+
id: provider.id,
|
|
51914
|
+
name: provider.displayName,
|
|
51915
|
+
aliases: providerAliasesFor(provider.id),
|
|
51916
|
+
accessType: provider.accessType,
|
|
51917
|
+
accessTypeLabel: getProviderAccessTypeLabel(provider),
|
|
51918
|
+
credentialType: provider.credentialType,
|
|
51919
|
+
modelDiscoveryType: provider.modelDiscoveryType,
|
|
51920
|
+
runtimeBackend: getProviderRuntimeBackend(provider.id),
|
|
51921
|
+
authMode: provider.authMode,
|
|
51922
|
+
accessPath: provider.accessPathLabel,
|
|
51923
|
+
legalPath: provider.legalPath
|
|
51924
|
+
}));
|
|
51925
|
+
if (json2) {
|
|
51926
|
+
return JSON.stringify(providers, null, 2);
|
|
51927
|
+
}
|
|
51928
|
+
return [
|
|
51929
|
+
"Provider | ID | Aliases | Access type | Credential | Model discovery | Runtime backend | Access path",
|
|
51930
|
+
"--- | --- | --- | --- | --- | --- | --- | ---",
|
|
51931
|
+
...providers.map((provider) => `${provider.name} | ${provider.id} | ${provider.aliases.slice(0, 3).join(", ") || "-"} | ${provider.accessTypeLabel} | ${provider.credentialType} | ${provider.modelDiscoveryType} | ${provider.runtimeBackend} | ${provider.accessPath}`)
|
|
51932
|
+
].join(`
|
|
51933
|
+
`);
|
|
51934
|
+
}
|
|
51935
|
+
function formatProviderDoctor(result, json2 = false) {
|
|
51936
|
+
if (json2) {
|
|
51937
|
+
return JSON.stringify(result, null, 2);
|
|
51938
|
+
}
|
|
51939
|
+
const lines = [
|
|
51940
|
+
`Provider: ${result.displayName} (${result.provider})`,
|
|
51941
|
+
`Access: ${getProviderAccessTypeLabel(getProviderDefinition(result.provider))}`,
|
|
51942
|
+
`Credential: ${getProviderDefinition(result.provider).credentialType}`,
|
|
51943
|
+
`Runtime backend: ${getProviderRuntimeBackend(result.provider)}`,
|
|
51944
|
+
`Auth: ${authModeLabel(result.authMode)}`,
|
|
51945
|
+
`Status: ${result.ok ? "ready" : "not ready"}`
|
|
51946
|
+
];
|
|
51947
|
+
for (const check3 of result.checks) {
|
|
51948
|
+
lines.push(`- ${check3.status.toUpperCase()} ${check3.name}: ${check3.message}`);
|
|
51949
|
+
}
|
|
51950
|
+
if (result.failureReason) {
|
|
51951
|
+
lines.push(`Failure reason: ${result.failureReason}`);
|
|
51952
|
+
}
|
|
51953
|
+
if (result.suggestedFix) {
|
|
51954
|
+
lines.push(`Suggested fix: ${result.suggestedFix}`);
|
|
51955
|
+
}
|
|
51956
|
+
if (result.fallback) {
|
|
51957
|
+
lines.push(`Fallback: ${result.fallback.message}`);
|
|
51958
|
+
}
|
|
51959
|
+
return lines.join(`
|
|
51960
|
+
`);
|
|
51961
|
+
}
|
|
51962
|
+
function formatProviderStatus(result, json2 = false) {
|
|
51963
|
+
if (json2) {
|
|
51964
|
+
return JSON.stringify(result, null, 2);
|
|
51965
|
+
}
|
|
51966
|
+
const failure = result.failureReason ? `
|
|
51967
|
+
Failure reason: ${result.failureReason}` : "";
|
|
51968
|
+
const fix = result.suggestedFix ? `
|
|
51969
|
+
Suggested fix: ${result.suggestedFix}` : "";
|
|
51970
|
+
const definition = getProviderDefinition(result.provider);
|
|
51971
|
+
const settings = getActiveProviderSettings(getInitialSettings());
|
|
51972
|
+
const model = settings.model ? `
|
|
51973
|
+
Active model: ${settings.model}` : "";
|
|
51974
|
+
return `Selected provider: ${result.displayName} (${result.provider})
|
|
51975
|
+
Access type: ${getProviderAccessTypeLabel(definition)}
|
|
51976
|
+
Credential: ${definition.credentialType}
|
|
51977
|
+
Runtime backend: ${getProviderRuntimeBackend(result.provider)}${model}
|
|
51978
|
+
Auth mode: ${authModeLabel(result.authMode)}
|
|
51979
|
+
Ready: ${result.ok ? "yes" : "no"}${failure}${fix}`;
|
|
51980
|
+
}
|
|
51981
|
+
function clearProviderModelCacheForTests() {
|
|
51982
|
+
cachedModelsByProvider.clear();
|
|
51983
|
+
}
|
|
51984
|
+
function providerBaseUrl(provider, definition, settings) {
|
|
51985
|
+
const providerSettings = getActiveProviderSettings(settings);
|
|
51986
|
+
if (providerSettings.baseUrl) {
|
|
51987
|
+
return providerSettings.baseUrl;
|
|
51988
|
+
}
|
|
51989
|
+
if (provider === "ollama") {
|
|
51990
|
+
return getOllamaBaseUrl(process.env, settings);
|
|
51991
|
+
}
|
|
51992
|
+
return definition.defaultBaseUrl;
|
|
51993
|
+
}
|
|
51994
|
+
function parseOpenAICompatibleModelNames(value) {
|
|
51995
|
+
if (!value || typeof value !== "object") {
|
|
51996
|
+
return [];
|
|
51997
|
+
}
|
|
51998
|
+
const data = value.data ?? value.models;
|
|
51999
|
+
if (!Array.isArray(data)) {
|
|
52000
|
+
return [];
|
|
52001
|
+
}
|
|
52002
|
+
const names = data.flatMap((model) => {
|
|
52003
|
+
if (typeof model === "string") {
|
|
52004
|
+
const trimmed2 = model.trim();
|
|
52005
|
+
return trimmed2 ? [trimmed2] : [];
|
|
52006
|
+
}
|
|
52007
|
+
if (!model || typeof model !== "object") {
|
|
52008
|
+
return [];
|
|
52009
|
+
}
|
|
52010
|
+
const entry = model;
|
|
52011
|
+
const name = entry.id ?? entry.name ?? entry.model;
|
|
52012
|
+
if (typeof name !== "string") {
|
|
52013
|
+
return [];
|
|
52014
|
+
}
|
|
52015
|
+
const trimmed = name.trim();
|
|
52016
|
+
return trimmed ? [trimmed] : [];
|
|
52017
|
+
});
|
|
52018
|
+
return [...new Set(names)].sort((a2, b) => a2.localeCompare(b));
|
|
52019
|
+
}
|
|
52020
|
+
function parseOllamaModelNamesFromTags(value) {
|
|
52021
|
+
if (!value || typeof value !== "object" || !("models" in value)) {
|
|
52022
|
+
return [];
|
|
52023
|
+
}
|
|
52024
|
+
const models = value.models;
|
|
52025
|
+
if (!Array.isArray(models)) {
|
|
52026
|
+
return [];
|
|
52027
|
+
}
|
|
52028
|
+
const names = models.flatMap((model) => {
|
|
52029
|
+
if (!model || typeof model !== "object") {
|
|
52030
|
+
return [];
|
|
52031
|
+
}
|
|
52032
|
+
const entry = model;
|
|
52033
|
+
const name = entry.name ?? entry.model;
|
|
52034
|
+
if (typeof name !== "string") {
|
|
52035
|
+
return [];
|
|
52036
|
+
}
|
|
52037
|
+
const trimmed = name.trim();
|
|
52038
|
+
return trimmed ? [trimmed] : [];
|
|
52039
|
+
});
|
|
52040
|
+
return [...new Set(names)].sort((a2, b) => a2.localeCompare(b));
|
|
52041
|
+
}
|
|
52042
|
+
function modelDefinitionsFromNames(provider, names, source) {
|
|
52043
|
+
const providerName = getProviderDefinition(provider).displayName;
|
|
52044
|
+
return names.map((name) => ({
|
|
52045
|
+
id: name,
|
|
52046
|
+
displayName: name,
|
|
52047
|
+
description: source === "cache" ? `Cached ${providerName} model` : `Discovered from ${providerName}`
|
|
52048
|
+
}));
|
|
52049
|
+
}
|
|
52050
|
+
function getCachedProviderModels(provider) {
|
|
52051
|
+
return cachedModelsByProvider.get(provider) ?? [];
|
|
52052
|
+
}
|
|
52053
|
+
function cacheProviderModelsForProvider(providerId, models) {
|
|
52054
|
+
const provider = resolveProviderId(providerId);
|
|
52055
|
+
if (!provider) {
|
|
52056
|
+
return;
|
|
52057
|
+
}
|
|
52058
|
+
const definitions = typeof models[0] === "string" ? modelDefinitionsFromNames(provider, models, "cache") : models;
|
|
52059
|
+
if (definitions.length > 0) {
|
|
52060
|
+
cachedModelsByProvider.set(provider, definitions);
|
|
52061
|
+
}
|
|
52062
|
+
}
|
|
52063
|
+
function staticModelsForProvider(provider) {
|
|
52064
|
+
return (PROVIDER_MODELS[provider] ?? []).filter((model) => !model.isDynamic);
|
|
52065
|
+
}
|
|
52066
|
+
async function discoverLiveModelsForProvider(provider, options = {}) {
|
|
52067
|
+
const definition = getProviderDefinition(provider);
|
|
52068
|
+
if (!definition.endpointKind) {
|
|
52069
|
+
return [];
|
|
52070
|
+
}
|
|
52071
|
+
const settings = options.settings ?? getInitialSettings();
|
|
52072
|
+
const baseUrl = providerBaseUrl(provider, definition, settings);
|
|
52073
|
+
if (!baseUrl) {
|
|
52074
|
+
throw new Error(`No base_url configured for provider "${provider}".`);
|
|
52075
|
+
}
|
|
52076
|
+
const url3 = endpointUrl(baseUrl, definition.endpointKind);
|
|
52077
|
+
const env4 = options.adapters?.env ?? process.env;
|
|
52078
|
+
const response = await (options.adapters?.fetch ?? fetch)(url3, {
|
|
52079
|
+
method: "GET",
|
|
52080
|
+
signal: options.signal,
|
|
52081
|
+
headers: definition.accessType === "api" && definition.envKey && env4[definition.envKey] ? { Authorization: `Bearer ${env4[definition.envKey]}` } : undefined
|
|
52082
|
+
});
|
|
52083
|
+
if (!response.ok) {
|
|
52084
|
+
throw new Error(`${url3} returned HTTP ${response.status}.`);
|
|
52085
|
+
}
|
|
52086
|
+
const body = await response.json();
|
|
52087
|
+
const names = definition.endpointKind === "ollama" ? parseOllamaModelNamesFromTags(body) : parseOpenAICompatibleModelNames(body);
|
|
52088
|
+
return modelDefinitionsFromNames(provider, names, "live");
|
|
52089
|
+
}
|
|
52090
|
+
async function listModelsForProviderWithSource(providerId, options = {}) {
|
|
52091
|
+
const provider = resolveProviderId(providerId);
|
|
52092
|
+
if (!provider) {
|
|
52093
|
+
return {
|
|
52094
|
+
provider: "ollama",
|
|
52095
|
+
models: [],
|
|
52096
|
+
source: "static",
|
|
52097
|
+
warning: `Unknown provider "${providerId}". Run: ur provider list`
|
|
52098
|
+
};
|
|
52099
|
+
}
|
|
52100
|
+
const definition = getProviderDefinition(provider);
|
|
52101
|
+
if (definition.modelDiscoveryType === "static") {
|
|
52102
|
+
return {
|
|
52103
|
+
provider,
|
|
52104
|
+
models: staticModelsForProvider(provider),
|
|
52105
|
+
source: "static"
|
|
52106
|
+
};
|
|
52107
|
+
}
|
|
52108
|
+
try {
|
|
52109
|
+
const liveModels = await discoverLiveModelsForProvider(provider, options);
|
|
52110
|
+
if (liveModels.length > 0) {
|
|
52111
|
+
cachedModelsByProvider.set(provider, liveModels);
|
|
52112
|
+
return {
|
|
52113
|
+
provider,
|
|
52114
|
+
models: liveModels,
|
|
52115
|
+
source: "live"
|
|
52116
|
+
};
|
|
52117
|
+
}
|
|
52118
|
+
const cachedModels = getCachedProviderModels(provider);
|
|
52119
|
+
if (cachedModels.length > 0) {
|
|
52120
|
+
return {
|
|
52121
|
+
provider,
|
|
52122
|
+
models: cachedModels,
|
|
52123
|
+
source: "cache",
|
|
52124
|
+
warning: `Live model discovery for "${provider}" returned no models. Showing cached ${provider} models only.`
|
|
52125
|
+
};
|
|
52126
|
+
}
|
|
52127
|
+
const staticModels = staticModelsForProvider(provider);
|
|
52128
|
+
return {
|
|
52129
|
+
provider,
|
|
52130
|
+
models: staticModels,
|
|
52131
|
+
source: staticModels.length > 0 ? "static" : "live",
|
|
52132
|
+
warning: `Live model discovery for "${provider}" returned no models.`
|
|
52133
|
+
};
|
|
52134
|
+
} catch (error40) {
|
|
52135
|
+
const cachedModels = getCachedProviderModels(provider);
|
|
52136
|
+
if (cachedModels.length > 0) {
|
|
52137
|
+
return {
|
|
52138
|
+
provider,
|
|
52139
|
+
models: cachedModels,
|
|
52140
|
+
source: "cache",
|
|
52141
|
+
warning: `Live model discovery for "${provider}" failed: ${error40 instanceof Error ? error40.message : String(error40)}. Showing cached ${provider} models only.`
|
|
52142
|
+
};
|
|
52143
|
+
}
|
|
52144
|
+
const staticModels = staticModelsForProvider(provider);
|
|
52145
|
+
return {
|
|
52146
|
+
provider,
|
|
52147
|
+
models: staticModels,
|
|
52148
|
+
source: staticModels.length > 0 ? "static" : "live",
|
|
52149
|
+
warning: `Live model discovery for "${provider}" failed: ${error40 instanceof Error ? error40.message : String(error40)}.`
|
|
52150
|
+
};
|
|
52151
|
+
}
|
|
52152
|
+
}
|
|
52153
|
+
function listModelsForProvider(providerId) {
|
|
52154
|
+
const provider = resolveProviderId(providerId);
|
|
52155
|
+
if (!provider) {
|
|
52156
|
+
return [];
|
|
52157
|
+
}
|
|
52158
|
+
return PROVIDER_MODELS[provider] ?? [];
|
|
52159
|
+
}
|
|
52160
|
+
function isModelSupportedByProvider(providerId, modelId) {
|
|
52161
|
+
return validateProviderModelPair(providerId, modelId).valid;
|
|
52162
|
+
}
|
|
52163
|
+
function getDefaultModelForProvider(providerId) {
|
|
52164
|
+
const provider = resolveProviderId(providerId);
|
|
52165
|
+
if (!provider) {
|
|
52166
|
+
return;
|
|
52167
|
+
}
|
|
52168
|
+
const models = PROVIDER_MODELS[provider];
|
|
52169
|
+
if (!models) {
|
|
52170
|
+
return;
|
|
52171
|
+
}
|
|
52172
|
+
const defaultModel = models.find((m) => m.isDefault && !m.isDynamic) ?? models.find((m) => !m.isDynamic);
|
|
52173
|
+
return defaultModel?.id;
|
|
52174
|
+
}
|
|
52175
|
+
function getValidModelIdsForProvider(providerId) {
|
|
52176
|
+
const provider = resolveProviderId(providerId);
|
|
52177
|
+
if (!provider) {
|
|
52178
|
+
return [];
|
|
52179
|
+
}
|
|
52180
|
+
const cached2 = getCachedProviderModels(provider);
|
|
52181
|
+
if (cached2.length > 0) {
|
|
52182
|
+
return cached2.map((model) => model.id);
|
|
52183
|
+
}
|
|
52184
|
+
return staticModelsForProvider(provider).map((model) => model.id);
|
|
52185
|
+
}
|
|
52186
|
+
function formatInvalidProviderModelMessage(providerId, modelId, validModels, suggestedModel) {
|
|
52187
|
+
const provider = resolveProviderId(providerId) ?? String(providerId);
|
|
52188
|
+
const validList = validModels.length > 0 ? validModels.join(", ") : "(no models discovered)";
|
|
52189
|
+
const suggested = suggestedModel ?? validModels[0] ?? "<valid-model>";
|
|
52190
|
+
return `Model "${modelId}" is not available for provider "${provider}". Valid models for ${provider}: ${validList}. Run /model and choose a model from ${provider}, or run: ur config set model ${suggested}`;
|
|
52191
|
+
}
|
|
52192
|
+
function validateProviderModelPair(providerId, modelId, options = {}) {
|
|
52193
|
+
const provider = resolveProviderId(providerId);
|
|
52194
|
+
if (!provider) {
|
|
52195
|
+
return {
|
|
52196
|
+
valid: false,
|
|
52197
|
+
error: `Unknown provider "${providerId}". Run: ur provider list`,
|
|
52198
|
+
validModels: []
|
|
52199
|
+
};
|
|
52200
|
+
}
|
|
52201
|
+
const models = PROVIDER_MODELS[provider];
|
|
52202
|
+
if (!models) {
|
|
52203
|
+
return {
|
|
52204
|
+
valid: false,
|
|
52205
|
+
error: `No models defined for provider "${provider}".`,
|
|
52206
|
+
validModels: []
|
|
52207
|
+
};
|
|
52208
|
+
}
|
|
52209
|
+
const suppliedModels = (options.availableModels ?? []).map((model) => typeof model === "string" ? model : model.id);
|
|
52210
|
+
const cachedModels = getCachedProviderModels(provider).map((model) => model.id);
|
|
52211
|
+
const staticModelIds = staticModelsForProvider(provider).map((model) => model.id);
|
|
52212
|
+
const hasDynamicModels = models.some((model) => model.isDynamic);
|
|
52213
|
+
const validModelIds = suppliedModels.length > 0 ? suppliedModels : hasDynamicModels ? cachedModels.length > 0 ? cachedModels : staticModelIds : Array.from(new Set([...staticModelIds, ...cachedModels]));
|
|
52214
|
+
if (validModelIds.includes(modelId)) {
|
|
52215
|
+
return { valid: true };
|
|
52216
|
+
}
|
|
52217
|
+
if (hasDynamicModels && options.allowUncachedDynamic && validModelIds.length === 0) {
|
|
52218
|
+
return { valid: true };
|
|
52219
|
+
}
|
|
52220
|
+
const defaultModel = getDefaultModelForProvider(provider);
|
|
52221
|
+
return {
|
|
52222
|
+
valid: false,
|
|
52223
|
+
error: formatInvalidProviderModelMessage(provider, modelId, validModelIds, defaultModel),
|
|
52224
|
+
validModels: validModelIds,
|
|
52225
|
+
suggestedModel: defaultModel
|
|
52226
|
+
};
|
|
52227
|
+
}
|
|
52228
|
+
function setProviderModel(providerId, modelId, options = {}) {
|
|
52229
|
+
const provider = resolveProviderId(providerId);
|
|
52230
|
+
if (!provider) {
|
|
52231
|
+
return {
|
|
52232
|
+
ok: false,
|
|
52233
|
+
message: `Unknown provider "${providerId}". Run: ur provider list`
|
|
52234
|
+
};
|
|
52235
|
+
}
|
|
52236
|
+
const validation = validateProviderModelPair(provider, modelId, {
|
|
52237
|
+
availableModels: options.availableModels
|
|
52238
|
+
});
|
|
52239
|
+
if (validation.valid === false) {
|
|
52240
|
+
return {
|
|
52241
|
+
ok: false,
|
|
52242
|
+
message: validation.error
|
|
52243
|
+
};
|
|
52244
|
+
}
|
|
52245
|
+
const result = updateSettingsForSource("userSettings", {
|
|
52246
|
+
provider: {
|
|
52247
|
+
active: provider,
|
|
52248
|
+
model: modelId
|
|
52249
|
+
},
|
|
52250
|
+
model: modelId
|
|
52251
|
+
});
|
|
52252
|
+
if (result.error) {
|
|
52253
|
+
return {
|
|
52254
|
+
ok: false,
|
|
52255
|
+
message: `Failed to write UR-AGENT settings: ${result.error.message}`
|
|
52256
|
+
};
|
|
52257
|
+
}
|
|
52258
|
+
return {
|
|
52259
|
+
ok: true,
|
|
52260
|
+
message: `Selected provider ${provider} (${getProviderAccessTypeLabel(getProviderDefinition(provider))}) with model ${modelId} (${options.modelSource ?? "static"}).`,
|
|
52261
|
+
provider,
|
|
52262
|
+
model: modelId,
|
|
52263
|
+
modelSource: options.modelSource ?? "static"
|
|
52264
|
+
};
|
|
52265
|
+
}
|
|
52266
|
+
var PROVIDER_IDS, DEFAULT_PROVIDER_ID = "ollama", LOCALHOST_RE, PROVIDERS, PROVIDER_ALIAS_ENTRIES, PROVIDER_ALIASES, PROVIDER_FAMILIES, PROVIDER_MODELS, cachedModelsByProvider, validateProviderModelCompatibility;
|
|
52267
|
+
var init_providerRegistry = __esm(() => {
|
|
52268
|
+
init_execFileNoThrow();
|
|
52269
|
+
init_ollamaConfig();
|
|
52270
|
+
init_settings2();
|
|
52271
|
+
init_which();
|
|
52272
|
+
PROVIDER_IDS = [
|
|
52273
|
+
"codex-cli",
|
|
52274
|
+
"claude-code-cli",
|
|
52275
|
+
"gemini-cli",
|
|
52276
|
+
"antigravity-cli",
|
|
52277
|
+
"openai-api",
|
|
52278
|
+
"anthropic-api",
|
|
52279
|
+
"gemini-api",
|
|
52280
|
+
"openrouter",
|
|
52281
|
+
"openai-compatible",
|
|
52282
|
+
"ollama",
|
|
52283
|
+
"lmstudio",
|
|
52284
|
+
"llama.cpp",
|
|
52285
|
+
"vllm"
|
|
52286
|
+
];
|
|
52287
|
+
LOCALHOST_RE = /^(https?:\/\/)?(localhost|127\.0\.0\.1|\[::1\]|::1)(:\d+)?(\/|$)/i;
|
|
52288
|
+
PROVIDERS = {
|
|
52289
|
+
"codex-cli": {
|
|
52290
|
+
id: "codex-cli",
|
|
52291
|
+
displayName: "Codex CLI",
|
|
52292
|
+
statusBarName: "Codex CLI",
|
|
52293
|
+
accessType: "subscription",
|
|
52294
|
+
credentialType: "cli-login",
|
|
52295
|
+
modelDiscoveryType: "static",
|
|
52296
|
+
statusCheck: "cli-login",
|
|
52297
|
+
listModels: "static",
|
|
52298
|
+
validateModel: "static-list",
|
|
52299
|
+
authMode: "subscription",
|
|
52300
|
+
legalPath: "official Codex CLI login",
|
|
52301
|
+
accessPathLabel: "subscription login via official Codex CLI",
|
|
52302
|
+
commandCandidates: ["codex"],
|
|
52303
|
+
versionArgs: ["--version"],
|
|
52304
|
+
statusArgs: ["login", "status"],
|
|
52305
|
+
loginArgs: ["login"],
|
|
52306
|
+
deviceLoginArgs: ["login", "--device-auth"]
|
|
52307
|
+
},
|
|
52308
|
+
"claude-code-cli": {
|
|
52309
|
+
id: "claude-code-cli",
|
|
52310
|
+
displayName: "Claude Code",
|
|
52311
|
+
statusBarName: "Claude Code",
|
|
52312
|
+
accessType: "subscription",
|
|
52313
|
+
credentialType: "cli-login",
|
|
52314
|
+
modelDiscoveryType: "static",
|
|
52315
|
+
statusCheck: "cli-login",
|
|
52316
|
+
listModels: "static",
|
|
52317
|
+
validateModel: "static-list",
|
|
52318
|
+
authMode: "subscription",
|
|
52319
|
+
legalPath: "official Claude Code CLI login",
|
|
52320
|
+
accessPathLabel: "subscription login via official Claude Code CLI",
|
|
52321
|
+
commandCandidates: ["claude"],
|
|
52322
|
+
versionArgs: ["--version"],
|
|
52323
|
+
statusArgs: ["auth", "status"],
|
|
52324
|
+
loginArgs: ["auth", "login"]
|
|
52325
|
+
},
|
|
52326
|
+
"gemini-cli": {
|
|
52327
|
+
id: "gemini-cli",
|
|
52328
|
+
displayName: "Gemini CLI",
|
|
52329
|
+
statusBarName: "Gemini CLI",
|
|
52330
|
+
accessType: "subscription",
|
|
52331
|
+
credentialType: "cli-login",
|
|
52332
|
+
modelDiscoveryType: "static",
|
|
52333
|
+
statusCheck: "cli-login",
|
|
52334
|
+
listModels: "static",
|
|
52335
|
+
validateModel: "static-list",
|
|
52336
|
+
authMode: "enterprise-login",
|
|
52337
|
+
legalPath: "official Gemini Code Assist login",
|
|
52338
|
+
accessPathLabel: "subscription login via official Gemini CLI",
|
|
52339
|
+
commandCandidates: ["gemini"],
|
|
52340
|
+
versionArgs: ["--version"],
|
|
52341
|
+
loginArgs: [],
|
|
52342
|
+
unsupportedPersonalAccountMessage: "Personal Google account login is not enabled by UR-AGENT. Use an official Gemini Code Assist Standard/Enterprise path if your Gemini CLI supports it."
|
|
52343
|
+
},
|
|
52344
|
+
"antigravity-cli": {
|
|
52345
|
+
id: "antigravity-cli",
|
|
52346
|
+
displayName: "Antigravity",
|
|
52347
|
+
statusBarName: "Antigravity",
|
|
52348
|
+
accessType: "subscription",
|
|
52349
|
+
credentialType: "cli-login",
|
|
52350
|
+
modelDiscoveryType: "static",
|
|
52351
|
+
statusCheck: "cli-login",
|
|
52352
|
+
listModels: "static",
|
|
52353
|
+
validateModel: "static-list",
|
|
52354
|
+
authMode: "personal-login",
|
|
52355
|
+
legalPath: "official Antigravity CLI login, where supported",
|
|
52356
|
+
accessPathLabel: "subscription login via official Antigravity CLI",
|
|
52357
|
+
commandCandidates: ["agy", "antigravity", "google-antigravity", "ag"],
|
|
52358
|
+
versionArgs: ["--version"],
|
|
52359
|
+
loginArgs: []
|
|
52360
|
+
},
|
|
52361
|
+
"openai-api": {
|
|
52362
|
+
id: "openai-api",
|
|
52363
|
+
displayName: "OpenAI API",
|
|
52364
|
+
statusBarName: "OpenAI",
|
|
52365
|
+
accessType: "api",
|
|
52366
|
+
credentialType: "api-key",
|
|
52367
|
+
modelDiscoveryType: "static",
|
|
52368
|
+
statusCheck: "api-key",
|
|
52369
|
+
listModels: "static",
|
|
52370
|
+
validateModel: "static-list",
|
|
52371
|
+
authMode: "api",
|
|
52372
|
+
legalPath: "OPENAI_API_KEY",
|
|
52373
|
+
accessPathLabel: "API key from OPENAI_API_KEY",
|
|
52374
|
+
envKey: "OPENAI_API_KEY"
|
|
52375
|
+
},
|
|
52376
|
+
"anthropic-api": {
|
|
52377
|
+
id: "anthropic-api",
|
|
52378
|
+
displayName: "Claude API",
|
|
52379
|
+
statusBarName: "Claude API",
|
|
52380
|
+
accessType: "api",
|
|
52381
|
+
credentialType: "api-key",
|
|
52382
|
+
modelDiscoveryType: "static",
|
|
52383
|
+
statusCheck: "api-key",
|
|
52384
|
+
listModels: "static",
|
|
52385
|
+
validateModel: "static-list",
|
|
52386
|
+
authMode: "api",
|
|
52387
|
+
legalPath: "ANTHROPIC_API_KEY",
|
|
52388
|
+
accessPathLabel: "API key from ANTHROPIC_API_KEY",
|
|
52389
|
+
envKey: "ANTHROPIC_API_KEY"
|
|
52390
|
+
},
|
|
52391
|
+
"gemini-api": {
|
|
52392
|
+
id: "gemini-api",
|
|
52393
|
+
displayName: "Gemini API",
|
|
52394
|
+
statusBarName: "Gemini API",
|
|
52395
|
+
accessType: "api",
|
|
52396
|
+
credentialType: "api-key",
|
|
52397
|
+
modelDiscoveryType: "static",
|
|
52398
|
+
statusCheck: "api-key",
|
|
52399
|
+
listModels: "static",
|
|
52400
|
+
validateModel: "static-list",
|
|
52401
|
+
authMode: "api",
|
|
52402
|
+
legalPath: "GEMINI_API_KEY",
|
|
52403
|
+
accessPathLabel: "API key from GEMINI_API_KEY",
|
|
52404
|
+
envKey: "GEMINI_API_KEY"
|
|
52405
|
+
},
|
|
52406
|
+
openrouter: {
|
|
52407
|
+
id: "openrouter",
|
|
52408
|
+
displayName: "OpenRouter",
|
|
52409
|
+
statusBarName: "OpenRouter",
|
|
52410
|
+
accessType: "api",
|
|
52411
|
+
credentialType: "api-key",
|
|
52412
|
+
modelDiscoveryType: "static",
|
|
52413
|
+
statusCheck: "api-key",
|
|
52414
|
+
listModels: "static",
|
|
52415
|
+
validateModel: "static-list",
|
|
52416
|
+
authMode: "api",
|
|
52417
|
+
legalPath: "OPENROUTER_API_KEY",
|
|
52418
|
+
accessPathLabel: "API key from OPENROUTER_API_KEY",
|
|
52419
|
+
envKey: "OPENROUTER_API_KEY"
|
|
52420
|
+
},
|
|
52421
|
+
"openai-compatible": {
|
|
52422
|
+
id: "openai-compatible",
|
|
52423
|
+
displayName: "OpenAI-compatible",
|
|
52424
|
+
statusBarName: "OpenAI-compatible",
|
|
52425
|
+
accessType: "api",
|
|
52426
|
+
accessTypeLabel: "server/api",
|
|
52427
|
+
credentialType: "openai-compatible-endpoint",
|
|
52428
|
+
modelDiscoveryType: "live",
|
|
52429
|
+
statusCheck: "endpoint",
|
|
52430
|
+
listModels: "openai-compatible-models",
|
|
52431
|
+
validateModel: "discovered-list",
|
|
52432
|
+
authMode: "api",
|
|
52433
|
+
legalPath: "user-selected OpenAI-compatible base URL with API key only when required by that endpoint",
|
|
52434
|
+
accessPathLabel: "OpenAI-compatible endpoint",
|
|
52435
|
+
envKey: "OPENAI_API_KEY",
|
|
52436
|
+
endpointKind: "openai-compatible"
|
|
52437
|
+
},
|
|
52438
|
+
ollama: {
|
|
52439
|
+
id: "ollama",
|
|
52440
|
+
displayName: "Ollama",
|
|
52441
|
+
statusBarName: "Ollama",
|
|
52442
|
+
accessType: "local",
|
|
52443
|
+
credentialType: "local-runtime",
|
|
52444
|
+
modelDiscoveryType: "live",
|
|
52445
|
+
statusCheck: "endpoint",
|
|
52446
|
+
listModels: "ollama-tags",
|
|
52447
|
+
validateModel: "discovered-list",
|
|
52448
|
+
authMode: "local",
|
|
52449
|
+
legalPath: "localhost Ollama runtime",
|
|
52450
|
+
accessPathLabel: "local Ollama runtime",
|
|
52451
|
+
defaultBaseUrl: "http://localhost:11434",
|
|
52452
|
+
endpointKind: "ollama"
|
|
52453
|
+
},
|
|
52454
|
+
lmstudio: {
|
|
52455
|
+
id: "lmstudio",
|
|
52456
|
+
displayName: "LM Studio",
|
|
52457
|
+
statusBarName: "LM Studio",
|
|
52458
|
+
accessType: "server",
|
|
52459
|
+
accessTypeLabel: "local/server",
|
|
52460
|
+
credentialType: "openai-compatible-endpoint",
|
|
52461
|
+
modelDiscoveryType: "live",
|
|
52462
|
+
statusCheck: "endpoint",
|
|
52463
|
+
listModels: "openai-compatible-models",
|
|
52464
|
+
validateModel: "discovered-list",
|
|
52465
|
+
authMode: "local",
|
|
52466
|
+
legalPath: "local OpenAI-compatible server",
|
|
52467
|
+
accessPathLabel: "local OpenAI-compatible endpoint",
|
|
52468
|
+
defaultBaseUrl: "http://localhost:1234/v1",
|
|
52469
|
+
endpointKind: "openai-compatible"
|
|
52470
|
+
},
|
|
52471
|
+
"llama.cpp": {
|
|
52472
|
+
id: "llama.cpp",
|
|
52473
|
+
displayName: "llama.cpp",
|
|
52474
|
+
statusBarName: "llama.cpp",
|
|
52475
|
+
accessType: "server",
|
|
52476
|
+
accessTypeLabel: "local/server",
|
|
52477
|
+
credentialType: "openai-compatible-endpoint",
|
|
52478
|
+
modelDiscoveryType: "live",
|
|
52479
|
+
statusCheck: "endpoint",
|
|
52480
|
+
listModels: "openai-compatible-models",
|
|
52481
|
+
validateModel: "discovered-list",
|
|
52482
|
+
authMode: "local",
|
|
52483
|
+
legalPath: "local OpenAI-compatible server",
|
|
52484
|
+
accessPathLabel: "local OpenAI-compatible endpoint",
|
|
52485
|
+
defaultBaseUrl: "http://localhost:8080/v1",
|
|
52486
|
+
endpointKind: "openai-compatible"
|
|
52487
|
+
},
|
|
52488
|
+
vllm: {
|
|
52489
|
+
id: "vllm",
|
|
52490
|
+
displayName: "vLLM",
|
|
52491
|
+
statusBarName: "vLLM",
|
|
52492
|
+
accessType: "server",
|
|
52493
|
+
accessTypeLabel: "local/server",
|
|
52494
|
+
credentialType: "openai-compatible-endpoint",
|
|
52495
|
+
modelDiscoveryType: "live",
|
|
52496
|
+
statusCheck: "endpoint",
|
|
52497
|
+
listModels: "openai-compatible-models",
|
|
52498
|
+
validateModel: "discovered-list",
|
|
52499
|
+
authMode: "local",
|
|
52500
|
+
legalPath: "OpenAI-compatible server",
|
|
52501
|
+
accessPathLabel: "OpenAI-compatible endpoint runtime",
|
|
52502
|
+
defaultBaseUrl: "http://localhost:8000/v1",
|
|
52503
|
+
endpointKind: "openai-compatible"
|
|
52504
|
+
}
|
|
52505
|
+
};
|
|
52506
|
+
PROVIDER_ALIAS_ENTRIES = [
|
|
52507
|
+
{
|
|
52508
|
+
canonical: "codex-cli",
|
|
52509
|
+
aliases: ["chatgpt", "codex", "codex cli", "openai codex", "chatgpt codex"]
|
|
52510
|
+
},
|
|
52511
|
+
{
|
|
52512
|
+
canonical: "claude-code-cli",
|
|
52513
|
+
aliases: ["claude", "claude code", "claude cli", "anthropic claude"]
|
|
52514
|
+
},
|
|
52515
|
+
{
|
|
52516
|
+
canonical: "gemini-cli",
|
|
52517
|
+
aliases: ["gemini", "gemini cli", "gemini code assist", "google gemini cli"]
|
|
52518
|
+
},
|
|
52519
|
+
{
|
|
52520
|
+
canonical: "antigravity-cli",
|
|
52521
|
+
aliases: ["antigravity", "antigravity cli", "agy", "ag", "google antigravity"]
|
|
52522
|
+
},
|
|
52523
|
+
{
|
|
52524
|
+
canonical: "openai-api",
|
|
52525
|
+
aliases: ["openai", "openai api"]
|
|
52526
|
+
},
|
|
52527
|
+
{
|
|
52528
|
+
canonical: "anthropic-api",
|
|
52529
|
+
aliases: ["anthropic", "anthropic claude api", "claude api"]
|
|
52530
|
+
},
|
|
52531
|
+
{
|
|
52532
|
+
canonical: "gemini-api",
|
|
52533
|
+
aliases: ["gemini api", "google gemini api"]
|
|
52534
|
+
},
|
|
52535
|
+
{
|
|
52536
|
+
canonical: "openrouter",
|
|
52537
|
+
aliases: ["openrouter api"]
|
|
52538
|
+
},
|
|
52539
|
+
{
|
|
52540
|
+
canonical: "openai-compatible",
|
|
52541
|
+
aliases: ["compatible", "openai compatible", "openai compatible api"]
|
|
52542
|
+
},
|
|
52543
|
+
{
|
|
52544
|
+
canonical: "ollama",
|
|
52545
|
+
aliases: ["ollama local"]
|
|
52546
|
+
},
|
|
52547
|
+
{
|
|
52548
|
+
canonical: "lmstudio",
|
|
52549
|
+
aliases: ["lm studio", "lm-studio"]
|
|
52550
|
+
},
|
|
52551
|
+
{
|
|
52552
|
+
canonical: "llama.cpp",
|
|
52553
|
+
aliases: ["llama cpp", "llamacpp", "llama-cpp"]
|
|
52554
|
+
},
|
|
52555
|
+
{
|
|
52556
|
+
canonical: "vllm",
|
|
52557
|
+
aliases: ["vllm server"]
|
|
52558
|
+
}
|
|
52559
|
+
];
|
|
52560
|
+
PROVIDER_ALIASES = Object.fromEntries(PROVIDER_ALIAS_ENTRIES.flatMap((entry) => [
|
|
52561
|
+
[normalizeProviderInput(entry.canonical), entry.canonical],
|
|
52562
|
+
[entry.canonical, entry.canonical],
|
|
52563
|
+
...entry.aliases.map((alias) => [normalizeProviderInput(alias), entry.canonical])
|
|
52564
|
+
]));
|
|
52565
|
+
PROVIDER_FAMILIES = {
|
|
52566
|
+
"anthropic-api": "anthropic",
|
|
52567
|
+
"claude-code-cli": "anthropic",
|
|
52568
|
+
"openai-api": "openai",
|
|
52569
|
+
"codex-cli": "openai",
|
|
52570
|
+
"gemini-api": "google",
|
|
52571
|
+
"gemini-cli": "google",
|
|
52572
|
+
"antigravity-cli": "google",
|
|
52573
|
+
openrouter: "openai-compatible",
|
|
52574
|
+
"openai-compatible": "openai-compatible",
|
|
52575
|
+
lmstudio: "openai-compatible",
|
|
52576
|
+
"llama.cpp": "openai-compatible",
|
|
52577
|
+
vllm: "openai-compatible",
|
|
52578
|
+
ollama: "ollama"
|
|
52579
|
+
};
|
|
52580
|
+
PROVIDER_MODELS = {
|
|
52581
|
+
"codex-cli": [
|
|
52582
|
+
{ id: "codex/gpt-5.5", displayName: "GPT-5.5 (Codex CLI)", description: "Subscription model through official Codex CLI login", isDefault: true },
|
|
52583
|
+
{ id: "codex/gpt-5.4", displayName: "GPT-5.4 (Codex CLI)", description: "Subscription model through official Codex CLI login" },
|
|
52584
|
+
{ id: "codex/gpt-5.4-mini", displayName: "GPT-5.4 Mini (Codex CLI)", description: "Fast subscription model through official Codex CLI login" },
|
|
52585
|
+
{ id: "codex/gpt-4o", displayName: "GPT-4o (Codex CLI)", description: "Subscription model through official Codex CLI login" },
|
|
52586
|
+
{ id: "codex/gpt-4o-mini", displayName: "GPT-4o Mini (Codex CLI)", description: "Fast subscription model through official Codex CLI login" },
|
|
52587
|
+
{ id: "codex/o1", displayName: "o1 (Codex CLI)", description: "Reasoning model through official Codex CLI login" },
|
|
52588
|
+
{ id: "codex/o3-mini", displayName: "o3-mini (Codex CLI)", description: "Fast reasoning model through official Codex CLI login" }
|
|
52589
|
+
],
|
|
52590
|
+
"claude-code-cli": [
|
|
52591
|
+
{ id: "claude-code/sonnet-5", displayName: "Claude Sonnet 5 (Claude Code)", description: "Subscription model through official Claude Code login", isDefault: true },
|
|
52592
|
+
{ id: "claude-code/opus-4-8", displayName: "Claude Opus 4.8 (Claude Code)", description: "Subscription model through official Claude Code login" },
|
|
52593
|
+
{ id: "claude-code/opus-4-7", displayName: "Claude Opus 4.7 (Claude Code)", description: "Subscription model through official Claude Code login" },
|
|
52594
|
+
{ id: "claude-code/opus-4-6", displayName: "Claude Opus 4.6 (Claude Code)", description: "Subscription model through official Claude Code login" },
|
|
52595
|
+
{ id: "claude-code/opus-4-5", displayName: "Claude Opus 4.5 (Claude Code)", description: "Subscription model through official Claude Code login" },
|
|
52596
|
+
{ id: "claude-code/sonnet-4-6", displayName: "Claude Sonnet 4.6 (Claude Code)", description: "Subscription model through official Claude Code login" },
|
|
52597
|
+
{ id: "claude-code/sonnet-4-5", displayName: "Claude Sonnet 4.5 (Claude Code)", description: "Subscription model through official Claude Code login" },
|
|
52598
|
+
{ id: "claude-code/haiku-4-5", displayName: "Claude Haiku 4.5 (Claude Code)", description: "Subscription model through official Claude Code login" }
|
|
52599
|
+
],
|
|
52600
|
+
"gemini-cli": [
|
|
52601
|
+
{ id: "gemini-cli/gemini-3.5-flash", displayName: "Gemini 3.5 Flash (Gemini CLI)", description: "Subscription model through official Gemini CLI login", isDefault: true },
|
|
52602
|
+
{ id: "gemini-cli/gemini-3.1-pro", displayName: "Gemini 3.1 Pro (Gemini CLI)", description: "Subscription model through official Gemini CLI login" },
|
|
52603
|
+
{ id: "gemini-cli/gemini-3.1-flash-lite", displayName: "Gemini 3.1 Flash Lite (Gemini CLI)", description: "Subscription model through official Gemini CLI login" },
|
|
52604
|
+
{ id: "gemini-cli/gemini-2.5-pro", displayName: "Gemini 2.5 Pro (Gemini CLI)", description: "Subscription model through official Gemini CLI login" },
|
|
52605
|
+
{ id: "gemini-cli/gemini-2.5-flash", displayName: "Gemini 2.5 Flash (Gemini CLI)", description: "Subscription model through official Gemini CLI login" },
|
|
52606
|
+
{ id: "gemini-cli/gemini-2.5-flash-lite", displayName: "Gemini 2.5 Flash Lite (Gemini CLI)", description: "Subscription model through official Gemini CLI login" }
|
|
52607
|
+
],
|
|
52608
|
+
"antigravity-cli": [
|
|
52609
|
+
{ id: "antigravity/gemini-3.5-flash", displayName: "Gemini 3.5 Flash (Antigravity)", description: "Subscription model through official Antigravity login", isDefault: true },
|
|
52610
|
+
{ id: "antigravity/gemini-2.5-pro", displayName: "Gemini 2.5 Pro (Antigravity)", description: "Subscription model through official Antigravity login" },
|
|
52611
|
+
{ id: "antigravity/gemini-2.5-flash", displayName: "Gemini 2.5 Flash (Antigravity)", description: "Subscription model through official Antigravity login" }
|
|
52612
|
+
],
|
|
52613
|
+
"openai-api": [
|
|
52614
|
+
{ id: "gpt-5.5", displayName: "GPT-5.5", description: "Latest OpenAI model", isDefault: true },
|
|
52615
|
+
{ id: "gpt-5.4", displayName: "GPT-5.4", description: "Advanced reasoning and coding" },
|
|
52616
|
+
{ id: "gpt-5.4-mini", displayName: "GPT-5.4 Mini", description: "Fast, efficient variant" },
|
|
52617
|
+
{ id: "gpt-4o", displayName: "GPT-4o", description: "Previous generation flagship" },
|
|
52618
|
+
{ id: "gpt-4o-mini", displayName: "GPT-4o Mini", description: "Fast GPT-4o variant" },
|
|
52619
|
+
{ id: "o1", displayName: "o1", description: "Deep reasoning model" },
|
|
52620
|
+
{ id: "o3-mini", displayName: "o3-mini", description: "Fast reasoning model" }
|
|
52621
|
+
],
|
|
52622
|
+
"anthropic-api": [
|
|
52623
|
+
{ id: "claude-sonnet-5", displayName: "Claude Sonnet 5", description: "Balanced performance and speed", isDefault: true },
|
|
52624
|
+
{ id: "claude-opus-4-8", displayName: "Claude Opus 4.8", description: "Most powerful Claude model" },
|
|
52625
|
+
{ id: "claude-opus-4-7", displayName: "Claude Opus 4.7", description: "High-end reasoning" },
|
|
52626
|
+
{ id: "claude-opus-4-6", displayName: "Claude Opus 4.6", description: "Advanced problem solving" },
|
|
52627
|
+
{ id: "claude-opus-4-5", displayName: "Claude Opus 4.5", description: "Previous Opus generation" },
|
|
52628
|
+
{ id: "claude-sonnet-4-6", displayName: "Claude Sonnet 4.6", description: "Fast Sonnet variant" },
|
|
52629
|
+
{ id: "claude-sonnet-4-5", displayName: "Claude Sonnet 4.5", description: "Previous Sonnet generation" },
|
|
52630
|
+
{ id: "claude-haiku-4-5", displayName: "Claude Haiku 4.5", description: "Fastest Claude model" }
|
|
52631
|
+
],
|
|
52632
|
+
"gemini-api": [
|
|
52633
|
+
{ id: "gemini-3.5-flash", displayName: "Gemini 3.5 Flash", description: "Most intelligent for agentic tasks", isDefault: true },
|
|
52634
|
+
{ id: "gemini-3.1-pro", displayName: "Gemini 3.1 Pro", description: "Advanced problem solving (preview)" },
|
|
52635
|
+
{ id: "gemini-3.1-flash-lite", displayName: "Gemini 3.1 Flash Lite", description: "Budget-friendly performance" },
|
|
52636
|
+
{ id: "gemini-2.5-pro", displayName: "Gemini 2.5 Pro", description: "Complex reasoning and coding" },
|
|
52637
|
+
{ id: "gemini-2.5-flash", displayName: "Gemini 2.5 Flash", description: "Low-latency tasks" },
|
|
52638
|
+
{ id: "gemini-2.5-flash-lite", displayName: "Gemini 2.5 Flash Lite", description: "Fastest Gemini model" }
|
|
52639
|
+
],
|
|
52640
|
+
openrouter: [
|
|
52641
|
+
{ id: "openai/gpt-5.5", displayName: "GPT-5.5", description: "OpenAI GPT-5.5 via OpenRouter", isDefault: true },
|
|
52642
|
+
{ id: "openai/gpt-5.4", displayName: "GPT-5.4", description: "OpenAI GPT-5.4 via OpenRouter" },
|
|
52643
|
+
{ id: "openai/gpt-4o", displayName: "GPT-4o", description: "OpenAI GPT-4o via OpenRouter" },
|
|
52644
|
+
{ id: "anthropic/claude-sonnet-5", displayName: "Claude Sonnet 5", description: "Anthropic Claude via OpenRouter" },
|
|
52645
|
+
{ id: "anthropic/claude-opus-4-8", displayName: "Claude Opus 4.8", description: "Anthropic Claude via OpenRouter" },
|
|
52646
|
+
{ id: "google/gemini-3.5-flash", displayName: "Gemini 3.5 Flash", description: "Google Gemini via OpenRouter" },
|
|
52647
|
+
{ id: "google/gemini-2.5-pro", displayName: "Gemini 2.5 Pro", description: "Google Gemini via OpenRouter" }
|
|
52648
|
+
],
|
|
52649
|
+
"openai-compatible": [
|
|
52650
|
+
{ id: "custom", displayName: "Custom Model", description: "Model name from provider endpoint", isDynamic: true }
|
|
52651
|
+
],
|
|
52652
|
+
ollama: [
|
|
52653
|
+
{ id: "dynamic", displayName: "Discovered Models", description: "Models discovered from Ollama server", isDynamic: true, isDefault: true }
|
|
52654
|
+
],
|
|
52655
|
+
lmstudio: [
|
|
52656
|
+
{ id: "dynamic", displayName: "Discovered Models", description: "Models discovered from LM Studio server", isDynamic: true, isDefault: true }
|
|
52657
|
+
],
|
|
52658
|
+
"llama.cpp": [
|
|
52659
|
+
{ id: "dynamic", displayName: "Discovered Models", description: "Models discovered from llama.cpp server", isDynamic: true, isDefault: true }
|
|
52660
|
+
],
|
|
52661
|
+
vllm: [
|
|
52662
|
+
{ id: "dynamic", displayName: "Discovered Models", description: "Models discovered from vLLM server", isDynamic: true, isDefault: true }
|
|
52663
|
+
]
|
|
52664
|
+
};
|
|
52665
|
+
cachedModelsByProvider = new Map;
|
|
52666
|
+
validateProviderModelCompatibility = validateProviderModelPair;
|
|
52667
|
+
});
|
|
52668
|
+
|
|
51198
52669
|
// src/utils/model/providers.ts
|
|
51199
52670
|
function getAPIProvider() {
|
|
51200
|
-
|
|
51201
|
-
if (!activeProvider || activeProvider === "ollama") {
|
|
51202
|
-
return "ollama";
|
|
51203
|
-
}
|
|
51204
|
-
return "foundry";
|
|
52671
|
+
return getRuntimeProviderId() === "ollama" ? "ollama" : "foundry";
|
|
51205
52672
|
}
|
|
51206
52673
|
function getAPIProviderForStatsig() {
|
|
51207
52674
|
return getAPIProvider();
|
|
@@ -51210,7 +52677,7 @@ function isFirstPartyURHQBaseUrl() {
|
|
|
51210
52677
|
return true;
|
|
51211
52678
|
}
|
|
51212
52679
|
var init_providers = __esm(() => {
|
|
51213
|
-
|
|
52680
|
+
init_providerRegistry();
|
|
51214
52681
|
});
|
|
51215
52682
|
|
|
51216
52683
|
// src/utils/model/modelStrings.ts
|
|
@@ -53024,1452 +54491,6 @@ var init_ollamaModels = __esm(() => {
|
|
|
53024
54491
|
cachedOllamaModelNames = [];
|
|
53025
54492
|
});
|
|
53026
54493
|
|
|
53027
|
-
// src/services/providers/providerRegistry.ts
|
|
53028
|
-
var exports_providerRegistry = {};
|
|
53029
|
-
__export(exports_providerRegistry, {
|
|
53030
|
-
validateProviderModelPair: () => validateProviderModelPair,
|
|
53031
|
-
validateProviderModelCompatibility: () => validateProviderModelCompatibility,
|
|
53032
|
-
setSafeProviderConfig: () => setSafeProviderConfig,
|
|
53033
|
-
setProviderModel: () => setProviderModel,
|
|
53034
|
-
resolveProviderId: () => resolveProviderId,
|
|
53035
|
-
providerForAuthAlias: () => providerForAuthAlias,
|
|
53036
|
-
providerAliasesFor: () => providerAliasesFor,
|
|
53037
|
-
listProviders: () => listProviders,
|
|
53038
|
-
listModelsForProviderWithSource: () => listModelsForProviderWithSource,
|
|
53039
|
-
listModelsForProvider: () => listModelsForProvider,
|
|
53040
|
-
launchProviderAuth: () => launchProviderAuth,
|
|
53041
|
-
isProviderId: () => isProviderId,
|
|
53042
|
-
isModelSupportedByProvider: () => isModelSupportedByProvider,
|
|
53043
|
-
getValidModelIdsForProvider: () => getValidModelIdsForProvider,
|
|
53044
|
-
getProviderStatus: () => getProviderStatus,
|
|
53045
|
-
getProviderRuntimeInfo: () => getProviderRuntimeInfo,
|
|
53046
|
-
getProviderRuntimeBackend: () => getProviderRuntimeBackend,
|
|
53047
|
-
getProviderDefinition: () => getProviderDefinition,
|
|
53048
|
-
getProviderAccessTypeLabel: () => getProviderAccessTypeLabel,
|
|
53049
|
-
getDefaultModelForProvider: () => getDefaultModelForProvider,
|
|
53050
|
-
getConnectionStatusFromDoctorResult: () => getConnectionStatusFromDoctorResult,
|
|
53051
|
-
getActiveProviderSettings: () => getActiveProviderSettings,
|
|
53052
|
-
formatProviderStatusLabel: () => formatProviderStatusLabel,
|
|
53053
|
-
formatProviderStatus: () => formatProviderStatus,
|
|
53054
|
-
formatProviderList: () => formatProviderList,
|
|
53055
|
-
formatProviderDoctor: () => formatProviderDoctor,
|
|
53056
|
-
formatInvalidProviderModelMessage: () => formatInvalidProviderModelMessage,
|
|
53057
|
-
doctorProvider: () => doctorProvider,
|
|
53058
|
-
doctorActiveProvider: () => doctorActiveProvider,
|
|
53059
|
-
credentialTypeLabel: () => credentialTypeLabel,
|
|
53060
|
-
clearProviderModelCacheForTests: () => clearProviderModelCacheForTests,
|
|
53061
|
-
classifyGeminiAccountSupport: () => classifyGeminiAccountSupport,
|
|
53062
|
-
cacheProviderModelsForProvider: () => cacheProviderModelsForProvider,
|
|
53063
|
-
buildProviderAuthCommand: () => buildProviderAuthCommand,
|
|
53064
|
-
authModeLabel: () => authModeLabel,
|
|
53065
|
-
authAliasForProvider: () => authAliasForProvider,
|
|
53066
|
-
PROVIDER_MODELS: () => PROVIDER_MODELS,
|
|
53067
|
-
PROVIDER_IDS: () => PROVIDER_IDS,
|
|
53068
|
-
PROVIDERS: () => PROVIDERS
|
|
53069
|
-
});
|
|
53070
|
-
import { spawn as spawn2 } from "child_process";
|
|
53071
|
-
function normalizeProviderInput(value) {
|
|
53072
|
-
return value.trim().toLowerCase().replace(/[_\s]+/g, "-");
|
|
53073
|
-
}
|
|
53074
|
-
function isProviderId(value) {
|
|
53075
|
-
return PROVIDER_IDS.includes(value);
|
|
53076
|
-
}
|
|
53077
|
-
function resolveProviderId(value) {
|
|
53078
|
-
const normalized = normalizeProviderInput(value);
|
|
53079
|
-
if (isProviderId(normalized)) {
|
|
53080
|
-
return normalized;
|
|
53081
|
-
}
|
|
53082
|
-
return PROVIDER_ALIASES[normalized] ?? null;
|
|
53083
|
-
}
|
|
53084
|
-
function providerAliasesFor(id) {
|
|
53085
|
-
return PROVIDER_ALIAS_ENTRIES.find((entry) => entry.canonical === id)?.aliases ?? [];
|
|
53086
|
-
}
|
|
53087
|
-
function getProviderDefinition(id) {
|
|
53088
|
-
return PROVIDERS[id];
|
|
53089
|
-
}
|
|
53090
|
-
function getActiveProviderSettings(settings = getInitialSettings()) {
|
|
53091
|
-
const configured = settings.provider ?? {};
|
|
53092
|
-
const active = configured.active ? resolveProviderId(configured.active) ?? "ollama" : "ollama";
|
|
53093
|
-
const fallback = configured.fallback === "disabled" ? "disabled" : configured.fallback ? resolveProviderId(configured.fallback) ?? undefined : undefined;
|
|
53094
|
-
return {
|
|
53095
|
-
active,
|
|
53096
|
-
model: configured.model ?? (configured.active ? undefined : settings.model),
|
|
53097
|
-
baseUrl: configured.baseUrl,
|
|
53098
|
-
commandPath: configured.commandPath,
|
|
53099
|
-
fallback
|
|
53100
|
-
};
|
|
53101
|
-
}
|
|
53102
|
-
function getProviderRuntimeInfo(settings = getInitialSettings()) {
|
|
53103
|
-
const providerSettings = getActiveProviderSettings(settings);
|
|
53104
|
-
const provider = providerSettings.active ?? "ollama";
|
|
53105
|
-
const definition = getProviderDefinition(provider);
|
|
53106
|
-
return {
|
|
53107
|
-
provider,
|
|
53108
|
-
providerLabel: definition.statusBarName,
|
|
53109
|
-
accessType: definition.accessType,
|
|
53110
|
-
accessTypeLabel: getProviderAccessTypeLabel(definition),
|
|
53111
|
-
credentialType: definition.credentialType,
|
|
53112
|
-
runtimeBackend: getProviderRuntimeBackend(provider),
|
|
53113
|
-
authMode: definition.authMode,
|
|
53114
|
-
authLabel: authModeLabel(definition.authMode),
|
|
53115
|
-
model: providerSettings.model,
|
|
53116
|
-
baseUrl: providerSettings.baseUrl ?? definition.defaultBaseUrl,
|
|
53117
|
-
fallback: providerSettings.fallback
|
|
53118
|
-
};
|
|
53119
|
-
}
|
|
53120
|
-
function getProviderRuntimeBackend(providerId) {
|
|
53121
|
-
const provider = resolveProviderId(providerId);
|
|
53122
|
-
switch (provider) {
|
|
53123
|
-
case "ollama":
|
|
53124
|
-
return "ollama";
|
|
53125
|
-
case "lmstudio":
|
|
53126
|
-
return "openai-compatible:lmstudio";
|
|
53127
|
-
case "llama.cpp":
|
|
53128
|
-
return "openai-compatible:llama.cpp";
|
|
53129
|
-
case "vllm":
|
|
53130
|
-
return "openai-compatible:vllm";
|
|
53131
|
-
case "openai-compatible":
|
|
53132
|
-
return "openai-compatible";
|
|
53133
|
-
case "codex-cli":
|
|
53134
|
-
return "subscription-cli:codex";
|
|
53135
|
-
case "claude-code-cli":
|
|
53136
|
-
return "subscription-cli:claude-code";
|
|
53137
|
-
case "gemini-cli":
|
|
53138
|
-
return "subscription-cli:gemini";
|
|
53139
|
-
case "antigravity-cli":
|
|
53140
|
-
return "subscription-cli:antigravity";
|
|
53141
|
-
case "openai-api":
|
|
53142
|
-
return "api:openai";
|
|
53143
|
-
case "anthropic-api":
|
|
53144
|
-
return "api:anthropic";
|
|
53145
|
-
case "gemini-api":
|
|
53146
|
-
return "api:gemini";
|
|
53147
|
-
case "openrouter":
|
|
53148
|
-
return "api:openrouter";
|
|
53149
|
-
default:
|
|
53150
|
-
return `unknown:${providerId}`;
|
|
53151
|
-
}
|
|
53152
|
-
}
|
|
53153
|
-
function authModeLabel(mode) {
|
|
53154
|
-
switch (mode) {
|
|
53155
|
-
case "subscription":
|
|
53156
|
-
return "subscription";
|
|
53157
|
-
case "enterprise-login":
|
|
53158
|
-
return "enterprise-login";
|
|
53159
|
-
case "personal-login":
|
|
53160
|
-
return "personal-login";
|
|
53161
|
-
case "api":
|
|
53162
|
-
return "API";
|
|
53163
|
-
case "local":
|
|
53164
|
-
return "local";
|
|
53165
|
-
}
|
|
53166
|
-
}
|
|
53167
|
-
function getProviderAccessTypeLabel(provider) {
|
|
53168
|
-
return provider.accessTypeLabel ?? provider.accessType;
|
|
53169
|
-
}
|
|
53170
|
-
function credentialTypeLabel(type) {
|
|
53171
|
-
switch (type) {
|
|
53172
|
-
case "cli-login":
|
|
53173
|
-
return "subscription login";
|
|
53174
|
-
case "api-key":
|
|
53175
|
-
return "API key";
|
|
53176
|
-
case "local-runtime":
|
|
53177
|
-
return "local runtime";
|
|
53178
|
-
case "openai-compatible-endpoint":
|
|
53179
|
-
return "OpenAI-compatible endpoint";
|
|
53180
|
-
}
|
|
53181
|
-
}
|
|
53182
|
-
function listProviders() {
|
|
53183
|
-
return PROVIDER_IDS.map((id) => PROVIDERS[id]);
|
|
53184
|
-
}
|
|
53185
|
-
function hasSecretLikeValue(value) {
|
|
53186
|
-
const trimmed = value.trim();
|
|
53187
|
-
if (/^(sk-|sk_|sk-proj-|sk-ant-|xox[baprs]-|gh[pousr]_|AIza)/i.test(trimmed)) {
|
|
53188
|
-
return true;
|
|
53189
|
-
}
|
|
53190
|
-
if (/token|refresh|oauth|secret|api[_-]?key/i.test(trimmed)) {
|
|
53191
|
-
return true;
|
|
53192
|
-
}
|
|
53193
|
-
try {
|
|
53194
|
-
const url3 = new URL(trimmed);
|
|
53195
|
-
return Boolean(url3.username || url3.password);
|
|
53196
|
-
} catch {
|
|
53197
|
-
return false;
|
|
53198
|
-
}
|
|
53199
|
-
}
|
|
53200
|
-
function normalizeBaseUrl(value) {
|
|
53201
|
-
const trimmed = value.trim();
|
|
53202
|
-
const withScheme = /^https?:\/\//i.test(trimmed) ? trimmed : `http://${trimmed}`;
|
|
53203
|
-
const url3 = new URL(withScheme);
|
|
53204
|
-
if (url3.username || url3.password) {
|
|
53205
|
-
throw new Error("base_url must not contain embedded credentials");
|
|
53206
|
-
}
|
|
53207
|
-
return withScheme.replace(/\/$/, "");
|
|
53208
|
-
}
|
|
53209
|
-
function setSafeProviderConfig(key, value) {
|
|
53210
|
-
const trimmed = value.trim();
|
|
53211
|
-
if (!trimmed) {
|
|
53212
|
-
return { ok: false, message: `Missing value for ${key}.` };
|
|
53213
|
-
}
|
|
53214
|
-
if (hasSecretLikeValue(trimmed)) {
|
|
53215
|
-
return {
|
|
53216
|
-
ok: false,
|
|
53217
|
-
message: "Refusing to store credential-like data. Put API keys in environment variables and select API mode explicitly."
|
|
53218
|
-
};
|
|
53219
|
-
}
|
|
53220
|
-
let settings;
|
|
53221
|
-
let providerModelInvalidated = false;
|
|
53222
|
-
try {
|
|
53223
|
-
if (key === "provider") {
|
|
53224
|
-
const provider = resolveProviderId(trimmed);
|
|
53225
|
-
if (!provider) {
|
|
53226
|
-
return {
|
|
53227
|
-
ok: false,
|
|
53228
|
-
message: `Unknown provider "${trimmed}". Run: ur provider list`
|
|
53229
|
-
};
|
|
53230
|
-
}
|
|
53231
|
-
const currentSettings = getInitialSettings();
|
|
53232
|
-
const currentModel = getActiveProviderSettings(currentSettings).model;
|
|
53233
|
-
const nextProviderSettings = { active: provider };
|
|
53234
|
-
let invalidated = false;
|
|
53235
|
-
if (currentModel) {
|
|
53236
|
-
const validation = validateProviderModelPair(provider, currentModel);
|
|
53237
|
-
if (validation.valid === false) {
|
|
53238
|
-
nextProviderSettings.model = undefined;
|
|
53239
|
-
invalidated = true;
|
|
53240
|
-
providerModelInvalidated = true;
|
|
53241
|
-
}
|
|
53242
|
-
}
|
|
53243
|
-
settings = {
|
|
53244
|
-
provider: nextProviderSettings,
|
|
53245
|
-
...invalidated ? { model: undefined } : {}
|
|
53246
|
-
};
|
|
53247
|
-
} else if (key === "provider.fallback") {
|
|
53248
|
-
const fallback = trimmed === "disabled" ? "disabled" : resolveProviderId(trimmed);
|
|
53249
|
-
if (!fallback) {
|
|
53250
|
-
return {
|
|
53251
|
-
ok: false,
|
|
53252
|
-
message: `Unknown fallback provider "${trimmed}". Run: ur provider list`
|
|
53253
|
-
};
|
|
53254
|
-
}
|
|
53255
|
-
settings = { provider: { fallback } };
|
|
53256
|
-
} else if (key === "provider.command_path") {
|
|
53257
|
-
settings = { provider: { commandPath: trimmed } };
|
|
53258
|
-
} else if (key === "model") {
|
|
53259
|
-
const currentSettings = getInitialSettings();
|
|
53260
|
-
const currentProvider = getActiveProviderSettings(currentSettings).active ?? "ollama";
|
|
53261
|
-
const validation = validateProviderModelPair(currentProvider, trimmed);
|
|
53262
|
-
if (validation.valid === false) {
|
|
53263
|
-
return {
|
|
53264
|
-
ok: false,
|
|
53265
|
-
message: validation.error
|
|
53266
|
-
};
|
|
53267
|
-
}
|
|
53268
|
-
settings = { provider: { model: trimmed }, model: trimmed };
|
|
53269
|
-
} else {
|
|
53270
|
-
settings = { provider: { baseUrl: normalizeBaseUrl(trimmed) } };
|
|
53271
|
-
}
|
|
53272
|
-
} catch (error40) {
|
|
53273
|
-
return {
|
|
53274
|
-
ok: false,
|
|
53275
|
-
message: error40 instanceof Error ? error40.message : String(error40)
|
|
53276
|
-
};
|
|
53277
|
-
}
|
|
53278
|
-
const result = updateSettingsForSource("userSettings", settings);
|
|
53279
|
-
if (result.error) {
|
|
53280
|
-
return {
|
|
53281
|
-
ok: false,
|
|
53282
|
-
message: `Failed to write UR-AGENT settings: ${result.error.message}`
|
|
53283
|
-
};
|
|
53284
|
-
}
|
|
53285
|
-
const savedValue = key === "provider" || key === "provider.fallback" ? key === "provider.fallback" && trimmed === "disabled" ? "disabled" : resolveProviderId(trimmed) ?? trimmed : trimmed;
|
|
53286
|
-
return {
|
|
53287
|
-
ok: true,
|
|
53288
|
-
message: `Set ${key} to ${savedValue}.${providerModelInvalidated ? " Cleared incompatible model for the new provider; run /model to choose a scoped model." : ""}`
|
|
53289
|
-
};
|
|
53290
|
-
}
|
|
53291
|
-
function outputText(result) {
|
|
53292
|
-
return `${result.stdout}
|
|
53293
|
-
${result.stderr}
|
|
53294
|
-
${result.error ?? ""}`.trim();
|
|
53295
|
-
}
|
|
53296
|
-
function classifiesAsLoggedIn(text) {
|
|
53297
|
-
return /logged in|authenticated|signed in|active account|using chatgpt/i.test(text);
|
|
53298
|
-
}
|
|
53299
|
-
function classifiesAsNotLoggedIn(text) {
|
|
53300
|
-
return /not logged in|not authenticated|not signed in|login required|unauthenticated/i.test(text);
|
|
53301
|
-
}
|
|
53302
|
-
function classifyGeminiAccountSupport(text) {
|
|
53303
|
-
if (/personal.*unsupported|unsupported.*personal|consumer.*unsupported/i.test(text)) {
|
|
53304
|
-
return "personal-unsupported";
|
|
53305
|
-
}
|
|
53306
|
-
if (/enterprise|standard|code assist|workspace/i.test(text)) {
|
|
53307
|
-
return "enterprise-supported";
|
|
53308
|
-
}
|
|
53309
|
-
return "unknown";
|
|
53310
|
-
}
|
|
53311
|
-
async function resolveCommand(definition, settings, adapters) {
|
|
53312
|
-
if (settings.commandPath) {
|
|
53313
|
-
return settings.commandPath;
|
|
53314
|
-
}
|
|
53315
|
-
for (const candidate of definition.commandCandidates ?? []) {
|
|
53316
|
-
const found = await (adapters.which ?? which)(candidate);
|
|
53317
|
-
if (found)
|
|
53318
|
-
return found;
|
|
53319
|
-
}
|
|
53320
|
-
return null;
|
|
53321
|
-
}
|
|
53322
|
-
async function runCommand(file2, args, adapters) {
|
|
53323
|
-
if (adapters.run) {
|
|
53324
|
-
return adapters.run(file2, args);
|
|
53325
|
-
}
|
|
53326
|
-
return execFileNoThrow(file2, args, {
|
|
53327
|
-
timeout: 15000,
|
|
53328
|
-
preserveOutputOnError: true,
|
|
53329
|
-
audit: false
|
|
53330
|
-
});
|
|
53331
|
-
}
|
|
53332
|
-
function addFailure(result, reason, fix) {
|
|
53333
|
-
result.ok = false;
|
|
53334
|
-
result.failureReason ??= reason;
|
|
53335
|
-
result.suggestedFix ??= fix;
|
|
53336
|
-
}
|
|
53337
|
-
function endpointUrl(baseUrl, kind) {
|
|
53338
|
-
const trimmed = baseUrl.replace(/\/$/, "");
|
|
53339
|
-
if (kind === "ollama") {
|
|
53340
|
-
return `${trimmed}/api/tags`;
|
|
53341
|
-
}
|
|
53342
|
-
return `${trimmed}/models`;
|
|
53343
|
-
}
|
|
53344
|
-
function isLocalBaseUrl(value) {
|
|
53345
|
-
return LOCALHOST_RE.test(value);
|
|
53346
|
-
}
|
|
53347
|
-
async function checkEndpoint(definition, settings, adapters, result) {
|
|
53348
|
-
if (!definition.endpointKind)
|
|
53349
|
-
return;
|
|
53350
|
-
const baseUrl = settings.baseUrl ?? (definition.id === "ollama" ? getOllamaBaseUrl() : definition.defaultBaseUrl);
|
|
53351
|
-
if (!baseUrl) {
|
|
53352
|
-
result.checks.push({
|
|
53353
|
-
name: "base_url",
|
|
53354
|
-
status: "fail",
|
|
53355
|
-
message: "No base_url configured."
|
|
53356
|
-
});
|
|
53357
|
-
addFailure(result, "missing base_url", "Run: ur config set base_url <url>");
|
|
53358
|
-
return;
|
|
53359
|
-
}
|
|
53360
|
-
const url3 = endpointUrl(baseUrl, definition.endpointKind);
|
|
53361
|
-
try {
|
|
53362
|
-
const response = await (adapters.fetch ?? fetch)(url3, {
|
|
53363
|
-
method: "GET",
|
|
53364
|
-
headers: definition.accessType === "api" && (adapters.env ?? process.env)[definition.envKey ?? ""] ? { Authorization: `Bearer ${(adapters.env ?? process.env)[definition.envKey ?? ""]}` } : undefined
|
|
53365
|
-
});
|
|
53366
|
-
if (!response.ok) {
|
|
53367
|
-
result.checks.push({
|
|
53368
|
-
name: "endpoint",
|
|
53369
|
-
status: "fail",
|
|
53370
|
-
message: `${url3} returned HTTP ${response.status}.`
|
|
53371
|
-
});
|
|
53372
|
-
addFailure(result, `endpoint returned HTTP ${response.status}`, `Start the provider server or update base_url: ur config set base_url ${baseUrl}`);
|
|
53373
|
-
return;
|
|
53374
|
-
}
|
|
53375
|
-
result.checks.push({
|
|
53376
|
-
name: "endpoint",
|
|
53377
|
-
status: "pass",
|
|
53378
|
-
message: `${url3} is reachable.`
|
|
53379
|
-
});
|
|
53380
|
-
if (settings.model) {
|
|
53381
|
-
const body = await response.text().catch(() => "");
|
|
53382
|
-
if (body && !body.includes(settings.model)) {
|
|
53383
|
-
result.checks.push({
|
|
53384
|
-
name: "model",
|
|
53385
|
-
status: "warn",
|
|
53386
|
-
message: `Model "${settings.model}" was not found in the detectable model list.`
|
|
53387
|
-
});
|
|
53388
|
-
} else {
|
|
53389
|
-
result.checks.push({
|
|
53390
|
-
name: "model",
|
|
53391
|
-
status: "pass",
|
|
53392
|
-
message: `Model "${settings.model}" is detectable.`
|
|
53393
|
-
});
|
|
53394
|
-
}
|
|
53395
|
-
}
|
|
53396
|
-
} catch (error40) {
|
|
53397
|
-
result.checks.push({
|
|
53398
|
-
name: "endpoint",
|
|
53399
|
-
status: "fail",
|
|
53400
|
-
message: `${url3} is not reachable.`
|
|
53401
|
-
});
|
|
53402
|
-
addFailure(result, error40 instanceof Error ? error40.message : "endpoint unavailable", `Start the provider server or update base_url: ur config set base_url ${baseUrl}`);
|
|
53403
|
-
}
|
|
53404
|
-
}
|
|
53405
|
-
async function checkSubscriptionProvider(definition, settings, adapters, result) {
|
|
53406
|
-
const commandPath = await resolveCommand(definition, settings, adapters);
|
|
53407
|
-
if (!commandPath) {
|
|
53408
|
-
const commands = definition.commandCandidates?.join(", ") ?? definition.id;
|
|
53409
|
-
result.checks.push({
|
|
53410
|
-
name: "cli",
|
|
53411
|
-
status: "fail",
|
|
53412
|
-
message: `No official CLI command found on PATH. Tried: ${commands}.`
|
|
53413
|
-
});
|
|
53414
|
-
addFailure(result, "CLI missing", `Install the official ${definition.displayName} CLI, then run ur auth ${authAliasForProvider(definition.id)}.`);
|
|
53415
|
-
return;
|
|
53416
|
-
}
|
|
53417
|
-
result.checks.push({
|
|
53418
|
-
name: "cli",
|
|
53419
|
-
status: "pass",
|
|
53420
|
-
message: `${commandPath} found.`
|
|
53421
|
-
});
|
|
53422
|
-
if (definition.versionArgs) {
|
|
53423
|
-
const version2 = await runCommand(commandPath, definition.versionArgs, adapters);
|
|
53424
|
-
result.checks.push({
|
|
53425
|
-
name: "version",
|
|
53426
|
-
status: version2.code === 0 ? "pass" : "warn",
|
|
53427
|
-
message: outputText(version2) || `${definition.displayName} version check exited ${version2.code}.`
|
|
53428
|
-
});
|
|
53429
|
-
}
|
|
53430
|
-
if (definition.id === "claude-code-cli" && (adapters.env ?? process.env).ANTHROPIC_API_KEY) {
|
|
53431
|
-
result.checks.push({
|
|
53432
|
-
name: "api_key_override",
|
|
53433
|
-
status: "warn",
|
|
53434
|
-
message: "ANTHROPIC_API_KEY is set and may override Claude Code subscription login. Unset it to test subscription auth."
|
|
53435
|
-
});
|
|
53436
|
-
}
|
|
53437
|
-
if (definition.id === "gemini-cli") {
|
|
53438
|
-
const versionText = result.checks.find((check3) => check3.name === "version")?.message ?? "";
|
|
53439
|
-
const support = classifyGeminiAccountSupport(versionText);
|
|
53440
|
-
if (support === "personal-unsupported") {
|
|
53441
|
-
result.checks.push({
|
|
53442
|
-
name: "account_type",
|
|
53443
|
-
status: "fail",
|
|
53444
|
-
message: definition.unsupportedPersonalAccountMessage ?? "Unsupported account type."
|
|
53445
|
-
});
|
|
53446
|
-
addFailure(result, "unsupported account type", "Use an official Gemini Code Assist Standard/Enterprise login path.");
|
|
53447
|
-
} else if (support === "enterprise-supported") {
|
|
53448
|
-
result.checks.push({
|
|
53449
|
-
name: "account_type",
|
|
53450
|
-
status: "pass",
|
|
53451
|
-
message: "Gemini Code Assist Standard/Enterprise path is supported by the detected CLI output."
|
|
53452
|
-
});
|
|
53453
|
-
} else {
|
|
53454
|
-
result.checks.push({
|
|
53455
|
-
name: "account_type",
|
|
53456
|
-
status: "warn",
|
|
53457
|
-
message: "Gemini CLI status is not exposed by this CLI. UR-AGENT will only use the official Gemini CLI flow and will not support personal-account bypasses."
|
|
53458
|
-
});
|
|
53459
|
-
}
|
|
53460
|
-
}
|
|
53461
|
-
if (!definition.statusArgs) {
|
|
53462
|
-
result.checks.push({
|
|
53463
|
-
name: "login_status",
|
|
53464
|
-
status: "skip",
|
|
53465
|
-
message: "No stable official status command is configured for this provider."
|
|
53466
|
-
});
|
|
53467
|
-
return;
|
|
53468
|
-
}
|
|
53469
|
-
const status = await runCommand(commandPath, definition.statusArgs, adapters);
|
|
53470
|
-
const text = outputText(status);
|
|
53471
|
-
if (status.code === 0 && !classifiesAsNotLoggedIn(text)) {
|
|
53472
|
-
result.checks.push({
|
|
53473
|
-
name: "login_status",
|
|
53474
|
-
status: classifiesAsLoggedIn(text) ? "pass" : "warn",
|
|
53475
|
-
message: text || "Status command succeeded."
|
|
53476
|
-
});
|
|
53477
|
-
return;
|
|
53478
|
-
}
|
|
53479
|
-
result.checks.push({
|
|
53480
|
-
name: "login_status",
|
|
53481
|
-
status: "fail",
|
|
53482
|
-
message: text || `${definition.displayName} is not logged in.`
|
|
53483
|
-
});
|
|
53484
|
-
addFailure(result, "not logged in", `Run: ur auth ${authAliasForProvider(definition.id)}`);
|
|
53485
|
-
}
|
|
53486
|
-
async function checkApiProvider(definition, settings, adapters, result) {
|
|
53487
|
-
const env4 = adapters.env ?? process.env;
|
|
53488
|
-
const baseUrl = settings.baseUrl ?? definition.defaultBaseUrl;
|
|
53489
|
-
const requiresKey = definition.id !== "openai-compatible" || !baseUrl || !isLocalBaseUrl(baseUrl);
|
|
53490
|
-
if (definition.envKey && requiresKey) {
|
|
53491
|
-
if (env4[definition.envKey]) {
|
|
53492
|
-
result.checks.push({
|
|
53493
|
-
name: "api_key",
|
|
53494
|
-
status: "pass",
|
|
53495
|
-
message: `${definition.envKey} is present.`
|
|
53496
|
-
});
|
|
53497
|
-
} else {
|
|
53498
|
-
result.checks.push({
|
|
53499
|
-
name: "api_key",
|
|
53500
|
-
status: "fail",
|
|
53501
|
-
message: `${definition.envKey} is not set.`
|
|
53502
|
-
});
|
|
53503
|
-
addFailure(result, "API key missing", `Set ${definition.envKey} in your environment or choose a subscription/local provider.`);
|
|
53504
|
-
}
|
|
53505
|
-
}
|
|
53506
|
-
await checkEndpoint(definition, settings, adapters, result);
|
|
53507
|
-
}
|
|
53508
|
-
function fallbackResult(settings, active, ok) {
|
|
53509
|
-
if (ok)
|
|
53510
|
-
return;
|
|
53511
|
-
if (!settings.fallback || settings.fallback === "disabled") {
|
|
53512
|
-
return {
|
|
53513
|
-
enabled: false,
|
|
53514
|
-
message: "Fallback is disabled. UR-AGENT will not silently switch providers. Optional: ur config set provider.fallback ollama"
|
|
53515
|
-
};
|
|
53516
|
-
}
|
|
53517
|
-
if (settings.fallback === active) {
|
|
53518
|
-
return {
|
|
53519
|
-
enabled: false,
|
|
53520
|
-
message: "Fallback points at the selected provider and will not be used."
|
|
53521
|
-
};
|
|
53522
|
-
}
|
|
53523
|
-
return {
|
|
53524
|
-
enabled: true,
|
|
53525
|
-
provider: settings.fallback,
|
|
53526
|
-
message: `Fallback is configured as ${settings.fallback}, but UR-AGENT will ask before using it.`
|
|
53527
|
-
};
|
|
53528
|
-
}
|
|
53529
|
-
async function doctorProvider(provider, options = {}) {
|
|
53530
|
-
const allSettings = options.settings ?? getInitialSettings();
|
|
53531
|
-
const providerSettings = getActiveProviderSettings(allSettings);
|
|
53532
|
-
const active = provider ?? providerSettings.active ?? "ollama";
|
|
53533
|
-
const definition = getProviderDefinition(active);
|
|
53534
|
-
const settingsForProvider = {
|
|
53535
|
-
...providerSettings,
|
|
53536
|
-
active
|
|
53537
|
-
};
|
|
53538
|
-
const result = {
|
|
53539
|
-
provider: active,
|
|
53540
|
-
displayName: definition.displayName,
|
|
53541
|
-
accessType: definition.accessType,
|
|
53542
|
-
authMode: definition.authMode,
|
|
53543
|
-
selected: active === providerSettings.active,
|
|
53544
|
-
ok: true,
|
|
53545
|
-
checks: [
|
|
53546
|
-
{
|
|
53547
|
-
name: "legal_path",
|
|
53548
|
-
status: "pass",
|
|
53549
|
-
message: definition.legalPath
|
|
53550
|
-
}
|
|
53551
|
-
]
|
|
53552
|
-
};
|
|
53553
|
-
if (definition.accessType === "subscription") {
|
|
53554
|
-
await checkSubscriptionProvider(definition, settingsForProvider, options.adapters ?? {}, result);
|
|
53555
|
-
} else if (definition.accessType === "api") {
|
|
53556
|
-
await checkApiProvider(definition, settingsForProvider, options.adapters ?? {}, result);
|
|
53557
|
-
} else if (definition.accessType === "local" || definition.accessType === "server") {
|
|
53558
|
-
await checkEndpoint(definition, settingsForProvider, options.adapters ?? {}, result);
|
|
53559
|
-
}
|
|
53560
|
-
result.fallback = fallbackResult(providerSettings, active, result.ok);
|
|
53561
|
-
return result;
|
|
53562
|
-
}
|
|
53563
|
-
async function doctorActiveProvider(options = {}) {
|
|
53564
|
-
const settings = options.settings ?? getInitialSettings();
|
|
53565
|
-
const active = getActiveProviderSettings(settings).active ?? "ollama";
|
|
53566
|
-
return doctorProvider(active, options);
|
|
53567
|
-
}
|
|
53568
|
-
function getConnectionStatusFromDoctorResult(result) {
|
|
53569
|
-
if (result.ok) {
|
|
53570
|
-
return "connected";
|
|
53571
|
-
}
|
|
53572
|
-
if (result.failureReason?.includes("CLI missing") || result.failureReason?.includes("not found")) {
|
|
53573
|
-
return "missing";
|
|
53574
|
-
}
|
|
53575
|
-
if (result.failureReason?.includes("not logged in") || result.failureReason?.includes("not authenticated") || result.failureReason?.includes("API key missing") || result.failureReason?.includes("endpoint") || result.failureReason?.includes("HTTP")) {
|
|
53576
|
-
return "unavailable";
|
|
53577
|
-
}
|
|
53578
|
-
return "unknown";
|
|
53579
|
-
}
|
|
53580
|
-
function formatProviderStatusLabel(status, provider, checks3) {
|
|
53581
|
-
switch (status) {
|
|
53582
|
-
case "connected":
|
|
53583
|
-
if (provider.credentialType === "api-key" && provider.envKey) {
|
|
53584
|
-
return `${provider.envKey} found`;
|
|
53585
|
-
}
|
|
53586
|
-
if (provider.id === "ollama") {
|
|
53587
|
-
return "localhost reachable";
|
|
53588
|
-
}
|
|
53589
|
-
if (provider.credentialType === "openai-compatible-endpoint") {
|
|
53590
|
-
return "OpenAI-compatible endpoint reachable";
|
|
53591
|
-
}
|
|
53592
|
-
if (provider.credentialType === "cli-login") {
|
|
53593
|
-
return "subscription login connected";
|
|
53594
|
-
}
|
|
53595
|
-
return "connected";
|
|
53596
|
-
case "missing":
|
|
53597
|
-
if (provider.commandCandidates) {
|
|
53598
|
-
return `CLI not found (tried: ${provider.commandCandidates.join(", ")})`;
|
|
53599
|
-
}
|
|
53600
|
-
return "missing";
|
|
53601
|
-
case "unavailable": {
|
|
53602
|
-
const failCheck = checks3.find((check3) => check3.status === "fail" || check3.status === "warn");
|
|
53603
|
-
return failCheck?.message ?? "unavailable";
|
|
53604
|
-
}
|
|
53605
|
-
case "unknown":
|
|
53606
|
-
return "status unknown";
|
|
53607
|
-
}
|
|
53608
|
-
}
|
|
53609
|
-
async function getProviderStatus(providerId, options = {}) {
|
|
53610
|
-
const provider = resolveProviderId(providerId);
|
|
53611
|
-
if (!provider) {
|
|
53612
|
-
throw new Error(`Unknown provider "${providerId}". Run: ur provider list`);
|
|
53613
|
-
}
|
|
53614
|
-
const definition = getProviderDefinition(provider);
|
|
53615
|
-
const doctor = await doctorProvider(provider, options);
|
|
53616
|
-
const status = getConnectionStatusFromDoctorResult(doctor);
|
|
53617
|
-
return {
|
|
53618
|
-
provider,
|
|
53619
|
-
displayName: definition.displayName,
|
|
53620
|
-
accessType: definition.accessType,
|
|
53621
|
-
accessTypeLabel: getProviderAccessTypeLabel(definition),
|
|
53622
|
-
credentialType: definition.credentialType,
|
|
53623
|
-
status,
|
|
53624
|
-
label: formatProviderStatusLabel(status, definition, doctor.checks),
|
|
53625
|
-
checks: doctor.checks,
|
|
53626
|
-
doctor
|
|
53627
|
-
};
|
|
53628
|
-
}
|
|
53629
|
-
function authAliasForProvider(provider) {
|
|
53630
|
-
switch (provider) {
|
|
53631
|
-
case "codex-cli":
|
|
53632
|
-
return "chatgpt";
|
|
53633
|
-
case "claude-code-cli":
|
|
53634
|
-
return "claude";
|
|
53635
|
-
case "gemini-cli":
|
|
53636
|
-
return "gemini";
|
|
53637
|
-
case "antigravity-cli":
|
|
53638
|
-
return "antigravity";
|
|
53639
|
-
default:
|
|
53640
|
-
return "provider";
|
|
53641
|
-
}
|
|
53642
|
-
}
|
|
53643
|
-
function providerForAuthAlias(alias) {
|
|
53644
|
-
switch (alias) {
|
|
53645
|
-
case "chatgpt":
|
|
53646
|
-
return "codex-cli";
|
|
53647
|
-
case "claude":
|
|
53648
|
-
return "claude-code-cli";
|
|
53649
|
-
case "gemini":
|
|
53650
|
-
return "gemini-cli";
|
|
53651
|
-
case "antigravity":
|
|
53652
|
-
return "antigravity-cli";
|
|
53653
|
-
default:
|
|
53654
|
-
return null;
|
|
53655
|
-
}
|
|
53656
|
-
}
|
|
53657
|
-
function buildProviderAuthCommand(provider, options = {}) {
|
|
53658
|
-
const definition = getProviderDefinition(provider);
|
|
53659
|
-
const command = definition.commandCandidates?.[0];
|
|
53660
|
-
if (!command)
|
|
53661
|
-
return null;
|
|
53662
|
-
const args = options.deviceAuth && definition.deviceLoginArgs ? definition.deviceLoginArgs : definition.loginArgs;
|
|
53663
|
-
if (!args)
|
|
53664
|
-
return null;
|
|
53665
|
-
if (provider === "gemini-cli") {
|
|
53666
|
-
return {
|
|
53667
|
-
command,
|
|
53668
|
-
args,
|
|
53669
|
-
instructions: "The detected Gemini CLI does not expose a stable non-interactive login subcommand. Launching the official Gemini CLI is the only supported path; complete the Gemini Code Assist login flow if prompted."
|
|
53670
|
-
};
|
|
53671
|
-
}
|
|
53672
|
-
if (provider === "antigravity-cli") {
|
|
53673
|
-
return {
|
|
53674
|
-
command,
|
|
53675
|
-
args,
|
|
53676
|
-
instructions: "UR-AGENT will only launch the official Antigravity CLI. Use its documented login flow where supported; UR-AGENT will not invent flags or reuse browser sessions."
|
|
53677
|
-
};
|
|
53678
|
-
}
|
|
53679
|
-
return {
|
|
53680
|
-
command,
|
|
53681
|
-
args,
|
|
53682
|
-
instructions: `Launching ${definition.legalPath}.`
|
|
53683
|
-
};
|
|
53684
|
-
}
|
|
53685
|
-
async function launchProviderAuth(alias, options = {}) {
|
|
53686
|
-
const provider = providerForAuthAlias(alias);
|
|
53687
|
-
if (!provider) {
|
|
53688
|
-
return { ok: false, message: `Unknown auth provider "${alias}".` };
|
|
53689
|
-
}
|
|
53690
|
-
const authCommand = buildProviderAuthCommand(provider, options);
|
|
53691
|
-
if (!authCommand) {
|
|
53692
|
-
return {
|
|
53693
|
-
ok: false,
|
|
53694
|
-
message: `No official login command is configured for ${provider}.`
|
|
53695
|
-
};
|
|
53696
|
-
}
|
|
53697
|
-
const commandPath = await resolveCommand(getProviderDefinition(provider), {}, {});
|
|
53698
|
-
if (!commandPath) {
|
|
53699
|
-
const commands = getProviderDefinition(provider).commandCandidates?.join(", ") ?? provider;
|
|
53700
|
-
return {
|
|
53701
|
-
ok: false,
|
|
53702
|
-
message: `No official ${getProviderDefinition(provider).displayName} CLI command found. Tried: ${commands}. Install the official CLI first.`
|
|
53703
|
-
};
|
|
53704
|
-
}
|
|
53705
|
-
const printableCommand = commandPath.split(/[\\/]/).pop() ?? authCommand.command;
|
|
53706
|
-
const printable = [printableCommand, ...authCommand.args].join(" ");
|
|
53707
|
-
if (options.dryRun || !process.stdin.isTTY || !process.stdout.isTTY) {
|
|
53708
|
-
return {
|
|
53709
|
-
ok: true,
|
|
53710
|
-
message: `${authCommand.instructions}
|
|
53711
|
-
Run: ${printable}`,
|
|
53712
|
-
command: printable
|
|
53713
|
-
};
|
|
53714
|
-
}
|
|
53715
|
-
await new Promise((resolve8, reject) => {
|
|
53716
|
-
const child = spawn2(commandPath, authCommand.args, {
|
|
53717
|
-
stdio: "inherit",
|
|
53718
|
-
env: process.env
|
|
53719
|
-
});
|
|
53720
|
-
child.on("error", reject);
|
|
53721
|
-
child.on("exit", (code) => {
|
|
53722
|
-
if (code === 0)
|
|
53723
|
-
resolve8();
|
|
53724
|
-
else
|
|
53725
|
-
reject(new Error(`${printable} exited with code ${code ?? 1}`));
|
|
53726
|
-
});
|
|
53727
|
-
});
|
|
53728
|
-
return { ok: true, message: `Completed: ${printable}`, command: printable };
|
|
53729
|
-
}
|
|
53730
|
-
function formatProviderList(json2 = false) {
|
|
53731
|
-
const providers = listProviders().map((provider) => ({
|
|
53732
|
-
id: provider.id,
|
|
53733
|
-
name: provider.displayName,
|
|
53734
|
-
aliases: providerAliasesFor(provider.id),
|
|
53735
|
-
accessType: provider.accessType,
|
|
53736
|
-
accessTypeLabel: getProviderAccessTypeLabel(provider),
|
|
53737
|
-
credentialType: provider.credentialType,
|
|
53738
|
-
modelDiscoveryType: provider.modelDiscoveryType,
|
|
53739
|
-
runtimeBackend: getProviderRuntimeBackend(provider.id),
|
|
53740
|
-
authMode: provider.authMode,
|
|
53741
|
-
accessPath: provider.accessPathLabel,
|
|
53742
|
-
legalPath: provider.legalPath
|
|
53743
|
-
}));
|
|
53744
|
-
if (json2) {
|
|
53745
|
-
return JSON.stringify(providers, null, 2);
|
|
53746
|
-
}
|
|
53747
|
-
return [
|
|
53748
|
-
"Provider | ID | Aliases | Access type | Credential | Model discovery | Runtime backend | Access path",
|
|
53749
|
-
"--- | --- | --- | --- | --- | --- | --- | ---",
|
|
53750
|
-
...providers.map((provider) => `${provider.name} | ${provider.id} | ${provider.aliases.slice(0, 3).join(", ") || "-"} | ${provider.accessTypeLabel} | ${provider.credentialType} | ${provider.modelDiscoveryType} | ${provider.runtimeBackend} | ${provider.accessPath}`)
|
|
53751
|
-
].join(`
|
|
53752
|
-
`);
|
|
53753
|
-
}
|
|
53754
|
-
function formatProviderDoctor(result, json2 = false) {
|
|
53755
|
-
if (json2) {
|
|
53756
|
-
return JSON.stringify(result, null, 2);
|
|
53757
|
-
}
|
|
53758
|
-
const lines = [
|
|
53759
|
-
`Provider: ${result.displayName} (${result.provider})`,
|
|
53760
|
-
`Access: ${getProviderAccessTypeLabel(getProviderDefinition(result.provider))}`,
|
|
53761
|
-
`Credential: ${getProviderDefinition(result.provider).credentialType}`,
|
|
53762
|
-
`Runtime backend: ${getProviderRuntimeBackend(result.provider)}`,
|
|
53763
|
-
`Auth: ${authModeLabel(result.authMode)}`,
|
|
53764
|
-
`Status: ${result.ok ? "ready" : "not ready"}`
|
|
53765
|
-
];
|
|
53766
|
-
for (const check3 of result.checks) {
|
|
53767
|
-
lines.push(`- ${check3.status.toUpperCase()} ${check3.name}: ${check3.message}`);
|
|
53768
|
-
}
|
|
53769
|
-
if (result.failureReason) {
|
|
53770
|
-
lines.push(`Failure reason: ${result.failureReason}`);
|
|
53771
|
-
}
|
|
53772
|
-
if (result.suggestedFix) {
|
|
53773
|
-
lines.push(`Suggested fix: ${result.suggestedFix}`);
|
|
53774
|
-
}
|
|
53775
|
-
if (result.fallback) {
|
|
53776
|
-
lines.push(`Fallback: ${result.fallback.message}`);
|
|
53777
|
-
}
|
|
53778
|
-
return lines.join(`
|
|
53779
|
-
`);
|
|
53780
|
-
}
|
|
53781
|
-
function formatProviderStatus(result, json2 = false) {
|
|
53782
|
-
if (json2) {
|
|
53783
|
-
return JSON.stringify(result, null, 2);
|
|
53784
|
-
}
|
|
53785
|
-
const failure = result.failureReason ? `
|
|
53786
|
-
Failure reason: ${result.failureReason}` : "";
|
|
53787
|
-
const fix = result.suggestedFix ? `
|
|
53788
|
-
Suggested fix: ${result.suggestedFix}` : "";
|
|
53789
|
-
const definition = getProviderDefinition(result.provider);
|
|
53790
|
-
const settings = getActiveProviderSettings(getInitialSettings());
|
|
53791
|
-
const model = settings.model ? `
|
|
53792
|
-
Active model: ${settings.model}` : "";
|
|
53793
|
-
return `Selected provider: ${result.displayName} (${result.provider})
|
|
53794
|
-
Access type: ${getProviderAccessTypeLabel(definition)}
|
|
53795
|
-
Credential: ${definition.credentialType}
|
|
53796
|
-
Runtime backend: ${getProviderRuntimeBackend(result.provider)}${model}
|
|
53797
|
-
Auth mode: ${authModeLabel(result.authMode)}
|
|
53798
|
-
Ready: ${result.ok ? "yes" : "no"}${failure}${fix}`;
|
|
53799
|
-
}
|
|
53800
|
-
function clearProviderModelCacheForTests() {
|
|
53801
|
-
cachedModelsByProvider.clear();
|
|
53802
|
-
}
|
|
53803
|
-
function providerBaseUrl(provider, definition, settings) {
|
|
53804
|
-
const providerSettings = getActiveProviderSettings(settings);
|
|
53805
|
-
if (providerSettings.baseUrl) {
|
|
53806
|
-
return providerSettings.baseUrl;
|
|
53807
|
-
}
|
|
53808
|
-
if (provider === "ollama") {
|
|
53809
|
-
return getOllamaBaseUrl(process.env, settings);
|
|
53810
|
-
}
|
|
53811
|
-
return definition.defaultBaseUrl;
|
|
53812
|
-
}
|
|
53813
|
-
function parseOpenAICompatibleModelNames(value) {
|
|
53814
|
-
if (!value || typeof value !== "object") {
|
|
53815
|
-
return [];
|
|
53816
|
-
}
|
|
53817
|
-
const data = value.data ?? value.models;
|
|
53818
|
-
if (!Array.isArray(data)) {
|
|
53819
|
-
return [];
|
|
53820
|
-
}
|
|
53821
|
-
const names = data.flatMap((model) => {
|
|
53822
|
-
if (typeof model === "string") {
|
|
53823
|
-
const trimmed2 = model.trim();
|
|
53824
|
-
return trimmed2 ? [trimmed2] : [];
|
|
53825
|
-
}
|
|
53826
|
-
if (!model || typeof model !== "object") {
|
|
53827
|
-
return [];
|
|
53828
|
-
}
|
|
53829
|
-
const entry = model;
|
|
53830
|
-
const name = entry.id ?? entry.name ?? entry.model;
|
|
53831
|
-
if (typeof name !== "string") {
|
|
53832
|
-
return [];
|
|
53833
|
-
}
|
|
53834
|
-
const trimmed = name.trim();
|
|
53835
|
-
return trimmed ? [trimmed] : [];
|
|
53836
|
-
});
|
|
53837
|
-
return [...new Set(names)].sort((a2, b) => a2.localeCompare(b));
|
|
53838
|
-
}
|
|
53839
|
-
function parseOllamaModelNamesFromTags(value) {
|
|
53840
|
-
if (!value || typeof value !== "object" || !("models" in value)) {
|
|
53841
|
-
return [];
|
|
53842
|
-
}
|
|
53843
|
-
const models = value.models;
|
|
53844
|
-
if (!Array.isArray(models)) {
|
|
53845
|
-
return [];
|
|
53846
|
-
}
|
|
53847
|
-
const names = models.flatMap((model) => {
|
|
53848
|
-
if (!model || typeof model !== "object") {
|
|
53849
|
-
return [];
|
|
53850
|
-
}
|
|
53851
|
-
const entry = model;
|
|
53852
|
-
const name = entry.name ?? entry.model;
|
|
53853
|
-
if (typeof name !== "string") {
|
|
53854
|
-
return [];
|
|
53855
|
-
}
|
|
53856
|
-
const trimmed = name.trim();
|
|
53857
|
-
return trimmed ? [trimmed] : [];
|
|
53858
|
-
});
|
|
53859
|
-
return [...new Set(names)].sort((a2, b) => a2.localeCompare(b));
|
|
53860
|
-
}
|
|
53861
|
-
function modelDefinitionsFromNames(provider, names, source) {
|
|
53862
|
-
const providerName = getProviderDefinition(provider).displayName;
|
|
53863
|
-
return names.map((name) => ({
|
|
53864
|
-
id: name,
|
|
53865
|
-
displayName: name,
|
|
53866
|
-
description: source === "cache" ? `Cached ${providerName} model` : `Discovered from ${providerName}`
|
|
53867
|
-
}));
|
|
53868
|
-
}
|
|
53869
|
-
function getCachedProviderModels(provider) {
|
|
53870
|
-
return cachedModelsByProvider.get(provider) ?? [];
|
|
53871
|
-
}
|
|
53872
|
-
function cacheProviderModelsForProvider(providerId, models) {
|
|
53873
|
-
const provider = resolveProviderId(providerId);
|
|
53874
|
-
if (!provider) {
|
|
53875
|
-
return;
|
|
53876
|
-
}
|
|
53877
|
-
const definitions = typeof models[0] === "string" ? modelDefinitionsFromNames(provider, models, "cache") : models;
|
|
53878
|
-
if (definitions.length > 0) {
|
|
53879
|
-
cachedModelsByProvider.set(provider, definitions);
|
|
53880
|
-
}
|
|
53881
|
-
}
|
|
53882
|
-
function staticModelsForProvider(provider) {
|
|
53883
|
-
return (PROVIDER_MODELS[provider] ?? []).filter((model) => !model.isDynamic);
|
|
53884
|
-
}
|
|
53885
|
-
async function discoverLiveModelsForProvider(provider, options = {}) {
|
|
53886
|
-
const definition = getProviderDefinition(provider);
|
|
53887
|
-
if (!definition.endpointKind) {
|
|
53888
|
-
return [];
|
|
53889
|
-
}
|
|
53890
|
-
const settings = options.settings ?? getInitialSettings();
|
|
53891
|
-
const baseUrl = providerBaseUrl(provider, definition, settings);
|
|
53892
|
-
if (!baseUrl) {
|
|
53893
|
-
throw new Error(`No base_url configured for provider "${provider}".`);
|
|
53894
|
-
}
|
|
53895
|
-
const url3 = endpointUrl(baseUrl, definition.endpointKind);
|
|
53896
|
-
const env4 = options.adapters?.env ?? process.env;
|
|
53897
|
-
const response = await (options.adapters?.fetch ?? fetch)(url3, {
|
|
53898
|
-
method: "GET",
|
|
53899
|
-
signal: options.signal,
|
|
53900
|
-
headers: definition.accessType === "api" && definition.envKey && env4[definition.envKey] ? { Authorization: `Bearer ${env4[definition.envKey]}` } : undefined
|
|
53901
|
-
});
|
|
53902
|
-
if (!response.ok) {
|
|
53903
|
-
throw new Error(`${url3} returned HTTP ${response.status}.`);
|
|
53904
|
-
}
|
|
53905
|
-
const body = await response.json();
|
|
53906
|
-
const names = definition.endpointKind === "ollama" ? parseOllamaModelNamesFromTags(body) : parseOpenAICompatibleModelNames(body);
|
|
53907
|
-
return modelDefinitionsFromNames(provider, names, "live");
|
|
53908
|
-
}
|
|
53909
|
-
async function listModelsForProviderWithSource(providerId, options = {}) {
|
|
53910
|
-
const provider = resolveProviderId(providerId);
|
|
53911
|
-
if (!provider) {
|
|
53912
|
-
return {
|
|
53913
|
-
provider: "ollama",
|
|
53914
|
-
models: [],
|
|
53915
|
-
source: "static",
|
|
53916
|
-
warning: `Unknown provider "${providerId}". Run: ur provider list`
|
|
53917
|
-
};
|
|
53918
|
-
}
|
|
53919
|
-
const definition = getProviderDefinition(provider);
|
|
53920
|
-
if (definition.modelDiscoveryType === "static") {
|
|
53921
|
-
return {
|
|
53922
|
-
provider,
|
|
53923
|
-
models: staticModelsForProvider(provider),
|
|
53924
|
-
source: "static"
|
|
53925
|
-
};
|
|
53926
|
-
}
|
|
53927
|
-
try {
|
|
53928
|
-
const liveModels = await discoverLiveModelsForProvider(provider, options);
|
|
53929
|
-
if (liveModels.length > 0) {
|
|
53930
|
-
cachedModelsByProvider.set(provider, liveModels);
|
|
53931
|
-
return {
|
|
53932
|
-
provider,
|
|
53933
|
-
models: liveModels,
|
|
53934
|
-
source: "live"
|
|
53935
|
-
};
|
|
53936
|
-
}
|
|
53937
|
-
const cachedModels = getCachedProviderModels(provider);
|
|
53938
|
-
if (cachedModels.length > 0) {
|
|
53939
|
-
return {
|
|
53940
|
-
provider,
|
|
53941
|
-
models: cachedModels,
|
|
53942
|
-
source: "cache",
|
|
53943
|
-
warning: `Live model discovery for "${provider}" returned no models. Showing cached ${provider} models only.`
|
|
53944
|
-
};
|
|
53945
|
-
}
|
|
53946
|
-
const staticModels = staticModelsForProvider(provider);
|
|
53947
|
-
return {
|
|
53948
|
-
provider,
|
|
53949
|
-
models: staticModels,
|
|
53950
|
-
source: staticModels.length > 0 ? "static" : "live",
|
|
53951
|
-
warning: `Live model discovery for "${provider}" returned no models.`
|
|
53952
|
-
};
|
|
53953
|
-
} catch (error40) {
|
|
53954
|
-
const cachedModels = getCachedProviderModels(provider);
|
|
53955
|
-
if (cachedModels.length > 0) {
|
|
53956
|
-
return {
|
|
53957
|
-
provider,
|
|
53958
|
-
models: cachedModels,
|
|
53959
|
-
source: "cache",
|
|
53960
|
-
warning: `Live model discovery for "${provider}" failed: ${error40 instanceof Error ? error40.message : String(error40)}. Showing cached ${provider} models only.`
|
|
53961
|
-
};
|
|
53962
|
-
}
|
|
53963
|
-
const staticModels = staticModelsForProvider(provider);
|
|
53964
|
-
return {
|
|
53965
|
-
provider,
|
|
53966
|
-
models: staticModels,
|
|
53967
|
-
source: staticModels.length > 0 ? "static" : "live",
|
|
53968
|
-
warning: `Live model discovery for "${provider}" failed: ${error40 instanceof Error ? error40.message : String(error40)}.`
|
|
53969
|
-
};
|
|
53970
|
-
}
|
|
53971
|
-
}
|
|
53972
|
-
function listModelsForProvider(providerId) {
|
|
53973
|
-
const provider = resolveProviderId(providerId);
|
|
53974
|
-
if (!provider) {
|
|
53975
|
-
return [];
|
|
53976
|
-
}
|
|
53977
|
-
return PROVIDER_MODELS[provider] ?? [];
|
|
53978
|
-
}
|
|
53979
|
-
function isModelSupportedByProvider(providerId, modelId) {
|
|
53980
|
-
return validateProviderModelPair(providerId, modelId).valid;
|
|
53981
|
-
}
|
|
53982
|
-
function getDefaultModelForProvider(providerId) {
|
|
53983
|
-
const provider = resolveProviderId(providerId);
|
|
53984
|
-
if (!provider) {
|
|
53985
|
-
return;
|
|
53986
|
-
}
|
|
53987
|
-
const models = PROVIDER_MODELS[provider];
|
|
53988
|
-
if (!models) {
|
|
53989
|
-
return;
|
|
53990
|
-
}
|
|
53991
|
-
const defaultModel = models.find((m) => m.isDefault && !m.isDynamic) ?? models.find((m) => !m.isDynamic);
|
|
53992
|
-
return defaultModel?.id;
|
|
53993
|
-
}
|
|
53994
|
-
function getValidModelIdsForProvider(providerId) {
|
|
53995
|
-
const provider = resolveProviderId(providerId);
|
|
53996
|
-
if (!provider) {
|
|
53997
|
-
return [];
|
|
53998
|
-
}
|
|
53999
|
-
const cached2 = getCachedProviderModels(provider);
|
|
54000
|
-
if (cached2.length > 0) {
|
|
54001
|
-
return cached2.map((model) => model.id);
|
|
54002
|
-
}
|
|
54003
|
-
return staticModelsForProvider(provider).map((model) => model.id);
|
|
54004
|
-
}
|
|
54005
|
-
function formatInvalidProviderModelMessage(providerId, modelId, validModels, suggestedModel) {
|
|
54006
|
-
const provider = resolveProviderId(providerId) ?? String(providerId);
|
|
54007
|
-
const validList = validModels.length > 0 ? validModels.join(", ") : "(no models discovered)";
|
|
54008
|
-
const suggested = suggestedModel ?? validModels[0] ?? "<valid-model>";
|
|
54009
|
-
return `Model "${modelId}" is not available for provider "${provider}". Valid models for ${provider}: ${validList}. Run /model and choose a model from ${provider}, or run: ur config set model ${suggested}`;
|
|
54010
|
-
}
|
|
54011
|
-
function validateProviderModelPair(providerId, modelId, options = {}) {
|
|
54012
|
-
const provider = resolveProviderId(providerId);
|
|
54013
|
-
if (!provider) {
|
|
54014
|
-
return {
|
|
54015
|
-
valid: false,
|
|
54016
|
-
error: `Unknown provider "${providerId}". Run: ur provider list`,
|
|
54017
|
-
validModels: []
|
|
54018
|
-
};
|
|
54019
|
-
}
|
|
54020
|
-
const models = PROVIDER_MODELS[provider];
|
|
54021
|
-
if (!models) {
|
|
54022
|
-
return {
|
|
54023
|
-
valid: false,
|
|
54024
|
-
error: `No models defined for provider "${provider}".`,
|
|
54025
|
-
validModels: []
|
|
54026
|
-
};
|
|
54027
|
-
}
|
|
54028
|
-
const suppliedModels = (options.availableModels ?? []).map((model) => typeof model === "string" ? model : model.id);
|
|
54029
|
-
const cachedModels = getCachedProviderModels(provider).map((model) => model.id);
|
|
54030
|
-
const staticModelIds = staticModelsForProvider(provider).map((model) => model.id);
|
|
54031
|
-
const hasDynamicModels = models.some((model) => model.isDynamic);
|
|
54032
|
-
const validModelIds = suppliedModels.length > 0 ? suppliedModels : hasDynamicModels ? cachedModels.length > 0 ? cachedModels : staticModelIds : Array.from(new Set([...staticModelIds, ...cachedModels]));
|
|
54033
|
-
if (validModelIds.includes(modelId)) {
|
|
54034
|
-
return { valid: true };
|
|
54035
|
-
}
|
|
54036
|
-
if (hasDynamicModels && options.allowUncachedDynamic && validModelIds.length === 0) {
|
|
54037
|
-
return { valid: true };
|
|
54038
|
-
}
|
|
54039
|
-
const defaultModel = getDefaultModelForProvider(provider);
|
|
54040
|
-
return {
|
|
54041
|
-
valid: false,
|
|
54042
|
-
error: formatInvalidProviderModelMessage(provider, modelId, validModelIds, defaultModel),
|
|
54043
|
-
validModels: validModelIds,
|
|
54044
|
-
suggestedModel: defaultModel
|
|
54045
|
-
};
|
|
54046
|
-
}
|
|
54047
|
-
function setProviderModel(providerId, modelId, options = {}) {
|
|
54048
|
-
const provider = resolveProviderId(providerId);
|
|
54049
|
-
if (!provider) {
|
|
54050
|
-
return {
|
|
54051
|
-
ok: false,
|
|
54052
|
-
message: `Unknown provider "${providerId}". Run: ur provider list`
|
|
54053
|
-
};
|
|
54054
|
-
}
|
|
54055
|
-
const validation = validateProviderModelPair(provider, modelId, {
|
|
54056
|
-
availableModels: options.availableModels
|
|
54057
|
-
});
|
|
54058
|
-
if (validation.valid === false) {
|
|
54059
|
-
return {
|
|
54060
|
-
ok: false,
|
|
54061
|
-
message: validation.error
|
|
54062
|
-
};
|
|
54063
|
-
}
|
|
54064
|
-
const result = updateSettingsForSource("userSettings", {
|
|
54065
|
-
provider: {
|
|
54066
|
-
active: provider,
|
|
54067
|
-
model: modelId
|
|
54068
|
-
},
|
|
54069
|
-
model: modelId
|
|
54070
|
-
});
|
|
54071
|
-
if (result.error) {
|
|
54072
|
-
return {
|
|
54073
|
-
ok: false,
|
|
54074
|
-
message: `Failed to write UR-AGENT settings: ${result.error.message}`
|
|
54075
|
-
};
|
|
54076
|
-
}
|
|
54077
|
-
return {
|
|
54078
|
-
ok: true,
|
|
54079
|
-
message: `Selected provider ${provider} (${getProviderAccessTypeLabel(getProviderDefinition(provider))}) with model ${modelId} (${options.modelSource ?? "static"}).`,
|
|
54080
|
-
provider,
|
|
54081
|
-
model: modelId,
|
|
54082
|
-
modelSource: options.modelSource ?? "static"
|
|
54083
|
-
};
|
|
54084
|
-
}
|
|
54085
|
-
var PROVIDER_IDS, LOCALHOST_RE, PROVIDERS, PROVIDER_ALIAS_ENTRIES, PROVIDER_ALIASES, PROVIDER_MODELS, cachedModelsByProvider, validateProviderModelCompatibility;
|
|
54086
|
-
var init_providerRegistry = __esm(() => {
|
|
54087
|
-
init_execFileNoThrow();
|
|
54088
|
-
init_ollamaConfig();
|
|
54089
|
-
init_settings2();
|
|
54090
|
-
init_which();
|
|
54091
|
-
PROVIDER_IDS = [
|
|
54092
|
-
"codex-cli",
|
|
54093
|
-
"claude-code-cli",
|
|
54094
|
-
"gemini-cli",
|
|
54095
|
-
"antigravity-cli",
|
|
54096
|
-
"openai-api",
|
|
54097
|
-
"anthropic-api",
|
|
54098
|
-
"gemini-api",
|
|
54099
|
-
"openrouter",
|
|
54100
|
-
"openai-compatible",
|
|
54101
|
-
"ollama",
|
|
54102
|
-
"lmstudio",
|
|
54103
|
-
"llama.cpp",
|
|
54104
|
-
"vllm"
|
|
54105
|
-
];
|
|
54106
|
-
LOCALHOST_RE = /^(https?:\/\/)?(localhost|127\.0\.0\.1|\[::1\]|::1)(:\d+)?(\/|$)/i;
|
|
54107
|
-
PROVIDERS = {
|
|
54108
|
-
"codex-cli": {
|
|
54109
|
-
id: "codex-cli",
|
|
54110
|
-
displayName: "Codex CLI",
|
|
54111
|
-
statusBarName: "Codex CLI",
|
|
54112
|
-
accessType: "subscription",
|
|
54113
|
-
credentialType: "cli-login",
|
|
54114
|
-
modelDiscoveryType: "static",
|
|
54115
|
-
statusCheck: "cli-login",
|
|
54116
|
-
listModels: "static",
|
|
54117
|
-
validateModel: "static-list",
|
|
54118
|
-
authMode: "subscription",
|
|
54119
|
-
legalPath: "official Codex CLI login",
|
|
54120
|
-
accessPathLabel: "subscription login via official Codex CLI",
|
|
54121
|
-
commandCandidates: ["codex"],
|
|
54122
|
-
versionArgs: ["--version"],
|
|
54123
|
-
statusArgs: ["login", "status"],
|
|
54124
|
-
loginArgs: ["login"],
|
|
54125
|
-
deviceLoginArgs: ["login", "--device-auth"]
|
|
54126
|
-
},
|
|
54127
|
-
"claude-code-cli": {
|
|
54128
|
-
id: "claude-code-cli",
|
|
54129
|
-
displayName: "Claude Code",
|
|
54130
|
-
statusBarName: "Claude Code",
|
|
54131
|
-
accessType: "subscription",
|
|
54132
|
-
credentialType: "cli-login",
|
|
54133
|
-
modelDiscoveryType: "static",
|
|
54134
|
-
statusCheck: "cli-login",
|
|
54135
|
-
listModels: "static",
|
|
54136
|
-
validateModel: "static-list",
|
|
54137
|
-
authMode: "subscription",
|
|
54138
|
-
legalPath: "official Claude Code CLI login",
|
|
54139
|
-
accessPathLabel: "subscription login via official Claude Code CLI",
|
|
54140
|
-
commandCandidates: ["claude"],
|
|
54141
|
-
versionArgs: ["--version"],
|
|
54142
|
-
statusArgs: ["auth", "status"],
|
|
54143
|
-
loginArgs: ["auth", "login"]
|
|
54144
|
-
},
|
|
54145
|
-
"gemini-cli": {
|
|
54146
|
-
id: "gemini-cli",
|
|
54147
|
-
displayName: "Gemini CLI",
|
|
54148
|
-
statusBarName: "Gemini CLI",
|
|
54149
|
-
accessType: "subscription",
|
|
54150
|
-
credentialType: "cli-login",
|
|
54151
|
-
modelDiscoveryType: "static",
|
|
54152
|
-
statusCheck: "cli-login",
|
|
54153
|
-
listModels: "static",
|
|
54154
|
-
validateModel: "static-list",
|
|
54155
|
-
authMode: "enterprise-login",
|
|
54156
|
-
legalPath: "official Gemini Code Assist login",
|
|
54157
|
-
accessPathLabel: "subscription login via official Gemini CLI",
|
|
54158
|
-
commandCandidates: ["gemini"],
|
|
54159
|
-
versionArgs: ["--version"],
|
|
54160
|
-
loginArgs: [],
|
|
54161
|
-
unsupportedPersonalAccountMessage: "Personal Google account login is not enabled by UR-AGENT. Use an official Gemini Code Assist Standard/Enterprise path if your Gemini CLI supports it."
|
|
54162
|
-
},
|
|
54163
|
-
"antigravity-cli": {
|
|
54164
|
-
id: "antigravity-cli",
|
|
54165
|
-
displayName: "Antigravity",
|
|
54166
|
-
statusBarName: "Antigravity",
|
|
54167
|
-
accessType: "subscription",
|
|
54168
|
-
credentialType: "cli-login",
|
|
54169
|
-
modelDiscoveryType: "static",
|
|
54170
|
-
statusCheck: "cli-login",
|
|
54171
|
-
listModels: "static",
|
|
54172
|
-
validateModel: "static-list",
|
|
54173
|
-
authMode: "personal-login",
|
|
54174
|
-
legalPath: "official Antigravity CLI login, where supported",
|
|
54175
|
-
accessPathLabel: "subscription login via official Antigravity CLI",
|
|
54176
|
-
commandCandidates: ["agy", "antigravity", "google-antigravity", "ag"],
|
|
54177
|
-
versionArgs: ["--version"],
|
|
54178
|
-
loginArgs: []
|
|
54179
|
-
},
|
|
54180
|
-
"openai-api": {
|
|
54181
|
-
id: "openai-api",
|
|
54182
|
-
displayName: "OpenAI API",
|
|
54183
|
-
statusBarName: "OpenAI",
|
|
54184
|
-
accessType: "api",
|
|
54185
|
-
credentialType: "api-key",
|
|
54186
|
-
modelDiscoveryType: "static",
|
|
54187
|
-
statusCheck: "api-key",
|
|
54188
|
-
listModels: "static",
|
|
54189
|
-
validateModel: "static-list",
|
|
54190
|
-
authMode: "api",
|
|
54191
|
-
legalPath: "OPENAI_API_KEY",
|
|
54192
|
-
accessPathLabel: "API key from OPENAI_API_KEY",
|
|
54193
|
-
envKey: "OPENAI_API_KEY"
|
|
54194
|
-
},
|
|
54195
|
-
"anthropic-api": {
|
|
54196
|
-
id: "anthropic-api",
|
|
54197
|
-
displayName: "Claude API",
|
|
54198
|
-
statusBarName: "Claude API",
|
|
54199
|
-
accessType: "api",
|
|
54200
|
-
credentialType: "api-key",
|
|
54201
|
-
modelDiscoveryType: "static",
|
|
54202
|
-
statusCheck: "api-key",
|
|
54203
|
-
listModels: "static",
|
|
54204
|
-
validateModel: "static-list",
|
|
54205
|
-
authMode: "api",
|
|
54206
|
-
legalPath: "ANTHROPIC_API_KEY",
|
|
54207
|
-
accessPathLabel: "API key from ANTHROPIC_API_KEY",
|
|
54208
|
-
envKey: "ANTHROPIC_API_KEY"
|
|
54209
|
-
},
|
|
54210
|
-
"gemini-api": {
|
|
54211
|
-
id: "gemini-api",
|
|
54212
|
-
displayName: "Gemini API",
|
|
54213
|
-
statusBarName: "Gemini API",
|
|
54214
|
-
accessType: "api",
|
|
54215
|
-
credentialType: "api-key",
|
|
54216
|
-
modelDiscoveryType: "static",
|
|
54217
|
-
statusCheck: "api-key",
|
|
54218
|
-
listModels: "static",
|
|
54219
|
-
validateModel: "static-list",
|
|
54220
|
-
authMode: "api",
|
|
54221
|
-
legalPath: "GEMINI_API_KEY",
|
|
54222
|
-
accessPathLabel: "API key from GEMINI_API_KEY",
|
|
54223
|
-
envKey: "GEMINI_API_KEY"
|
|
54224
|
-
},
|
|
54225
|
-
openrouter: {
|
|
54226
|
-
id: "openrouter",
|
|
54227
|
-
displayName: "OpenRouter",
|
|
54228
|
-
statusBarName: "OpenRouter",
|
|
54229
|
-
accessType: "api",
|
|
54230
|
-
credentialType: "api-key",
|
|
54231
|
-
modelDiscoveryType: "static",
|
|
54232
|
-
statusCheck: "api-key",
|
|
54233
|
-
listModels: "static",
|
|
54234
|
-
validateModel: "static-list",
|
|
54235
|
-
authMode: "api",
|
|
54236
|
-
legalPath: "OPENROUTER_API_KEY",
|
|
54237
|
-
accessPathLabel: "API key from OPENROUTER_API_KEY",
|
|
54238
|
-
envKey: "OPENROUTER_API_KEY"
|
|
54239
|
-
},
|
|
54240
|
-
"openai-compatible": {
|
|
54241
|
-
id: "openai-compatible",
|
|
54242
|
-
displayName: "OpenAI-compatible",
|
|
54243
|
-
statusBarName: "OpenAI-compatible",
|
|
54244
|
-
accessType: "api",
|
|
54245
|
-
accessTypeLabel: "server/api",
|
|
54246
|
-
credentialType: "openai-compatible-endpoint",
|
|
54247
|
-
modelDiscoveryType: "live",
|
|
54248
|
-
statusCheck: "endpoint",
|
|
54249
|
-
listModels: "openai-compatible-models",
|
|
54250
|
-
validateModel: "discovered-list",
|
|
54251
|
-
authMode: "api",
|
|
54252
|
-
legalPath: "user-selected OpenAI-compatible base URL with API key only when required by that endpoint",
|
|
54253
|
-
accessPathLabel: "OpenAI-compatible endpoint",
|
|
54254
|
-
envKey: "OPENAI_API_KEY",
|
|
54255
|
-
endpointKind: "openai-compatible"
|
|
54256
|
-
},
|
|
54257
|
-
ollama: {
|
|
54258
|
-
id: "ollama",
|
|
54259
|
-
displayName: "Ollama",
|
|
54260
|
-
statusBarName: "Ollama",
|
|
54261
|
-
accessType: "local",
|
|
54262
|
-
credentialType: "local-runtime",
|
|
54263
|
-
modelDiscoveryType: "live",
|
|
54264
|
-
statusCheck: "endpoint",
|
|
54265
|
-
listModels: "ollama-tags",
|
|
54266
|
-
validateModel: "discovered-list",
|
|
54267
|
-
authMode: "local",
|
|
54268
|
-
legalPath: "localhost Ollama runtime",
|
|
54269
|
-
accessPathLabel: "local Ollama runtime",
|
|
54270
|
-
defaultBaseUrl: "http://localhost:11434",
|
|
54271
|
-
endpointKind: "ollama"
|
|
54272
|
-
},
|
|
54273
|
-
lmstudio: {
|
|
54274
|
-
id: "lmstudio",
|
|
54275
|
-
displayName: "LM Studio",
|
|
54276
|
-
statusBarName: "LM Studio",
|
|
54277
|
-
accessType: "server",
|
|
54278
|
-
accessTypeLabel: "local/server",
|
|
54279
|
-
credentialType: "openai-compatible-endpoint",
|
|
54280
|
-
modelDiscoveryType: "live",
|
|
54281
|
-
statusCheck: "endpoint",
|
|
54282
|
-
listModels: "openai-compatible-models",
|
|
54283
|
-
validateModel: "discovered-list",
|
|
54284
|
-
authMode: "local",
|
|
54285
|
-
legalPath: "local OpenAI-compatible server",
|
|
54286
|
-
accessPathLabel: "local OpenAI-compatible endpoint",
|
|
54287
|
-
defaultBaseUrl: "http://localhost:1234/v1",
|
|
54288
|
-
endpointKind: "openai-compatible"
|
|
54289
|
-
},
|
|
54290
|
-
"llama.cpp": {
|
|
54291
|
-
id: "llama.cpp",
|
|
54292
|
-
displayName: "llama.cpp",
|
|
54293
|
-
statusBarName: "llama.cpp",
|
|
54294
|
-
accessType: "server",
|
|
54295
|
-
accessTypeLabel: "local/server",
|
|
54296
|
-
credentialType: "openai-compatible-endpoint",
|
|
54297
|
-
modelDiscoveryType: "live",
|
|
54298
|
-
statusCheck: "endpoint",
|
|
54299
|
-
listModels: "openai-compatible-models",
|
|
54300
|
-
validateModel: "discovered-list",
|
|
54301
|
-
authMode: "local",
|
|
54302
|
-
legalPath: "local OpenAI-compatible server",
|
|
54303
|
-
accessPathLabel: "local OpenAI-compatible endpoint",
|
|
54304
|
-
defaultBaseUrl: "http://localhost:8080/v1",
|
|
54305
|
-
endpointKind: "openai-compatible"
|
|
54306
|
-
},
|
|
54307
|
-
vllm: {
|
|
54308
|
-
id: "vllm",
|
|
54309
|
-
displayName: "vLLM",
|
|
54310
|
-
statusBarName: "vLLM",
|
|
54311
|
-
accessType: "server",
|
|
54312
|
-
accessTypeLabel: "local/server",
|
|
54313
|
-
credentialType: "openai-compatible-endpoint",
|
|
54314
|
-
modelDiscoveryType: "live",
|
|
54315
|
-
statusCheck: "endpoint",
|
|
54316
|
-
listModels: "openai-compatible-models",
|
|
54317
|
-
validateModel: "discovered-list",
|
|
54318
|
-
authMode: "local",
|
|
54319
|
-
legalPath: "OpenAI-compatible server",
|
|
54320
|
-
accessPathLabel: "OpenAI-compatible endpoint runtime",
|
|
54321
|
-
defaultBaseUrl: "http://localhost:8000/v1",
|
|
54322
|
-
endpointKind: "openai-compatible"
|
|
54323
|
-
}
|
|
54324
|
-
};
|
|
54325
|
-
PROVIDER_ALIAS_ENTRIES = [
|
|
54326
|
-
{
|
|
54327
|
-
canonical: "codex-cli",
|
|
54328
|
-
aliases: ["chatgpt", "codex", "codex cli", "openai codex", "chatgpt codex"]
|
|
54329
|
-
},
|
|
54330
|
-
{
|
|
54331
|
-
canonical: "claude-code-cli",
|
|
54332
|
-
aliases: ["claude", "claude code", "claude cli", "anthropic claude"]
|
|
54333
|
-
},
|
|
54334
|
-
{
|
|
54335
|
-
canonical: "gemini-cli",
|
|
54336
|
-
aliases: ["gemini", "gemini cli", "gemini code assist", "google gemini cli"]
|
|
54337
|
-
},
|
|
54338
|
-
{
|
|
54339
|
-
canonical: "antigravity-cli",
|
|
54340
|
-
aliases: ["antigravity", "antigravity cli", "agy", "ag", "google antigravity"]
|
|
54341
|
-
},
|
|
54342
|
-
{
|
|
54343
|
-
canonical: "openai-api",
|
|
54344
|
-
aliases: ["openai", "openai api"]
|
|
54345
|
-
},
|
|
54346
|
-
{
|
|
54347
|
-
canonical: "anthropic-api",
|
|
54348
|
-
aliases: ["anthropic", "anthropic claude api", "claude api"]
|
|
54349
|
-
},
|
|
54350
|
-
{
|
|
54351
|
-
canonical: "gemini-api",
|
|
54352
|
-
aliases: ["gemini api", "google gemini api"]
|
|
54353
|
-
},
|
|
54354
|
-
{
|
|
54355
|
-
canonical: "openrouter",
|
|
54356
|
-
aliases: ["openrouter api"]
|
|
54357
|
-
},
|
|
54358
|
-
{
|
|
54359
|
-
canonical: "openai-compatible",
|
|
54360
|
-
aliases: ["compatible", "openai compatible", "openai compatible api"]
|
|
54361
|
-
},
|
|
54362
|
-
{
|
|
54363
|
-
canonical: "ollama",
|
|
54364
|
-
aliases: ["ollama local"]
|
|
54365
|
-
},
|
|
54366
|
-
{
|
|
54367
|
-
canonical: "lmstudio",
|
|
54368
|
-
aliases: ["lm studio", "lm-studio"]
|
|
54369
|
-
},
|
|
54370
|
-
{
|
|
54371
|
-
canonical: "llama.cpp",
|
|
54372
|
-
aliases: ["llama cpp", "llamacpp", "llama-cpp"]
|
|
54373
|
-
},
|
|
54374
|
-
{
|
|
54375
|
-
canonical: "vllm",
|
|
54376
|
-
aliases: ["vllm server"]
|
|
54377
|
-
}
|
|
54378
|
-
];
|
|
54379
|
-
PROVIDER_ALIASES = Object.fromEntries(PROVIDER_ALIAS_ENTRIES.flatMap((entry) => [
|
|
54380
|
-
[normalizeProviderInput(entry.canonical), entry.canonical],
|
|
54381
|
-
[entry.canonical, entry.canonical],
|
|
54382
|
-
...entry.aliases.map((alias) => [normalizeProviderInput(alias), entry.canonical])
|
|
54383
|
-
]));
|
|
54384
|
-
PROVIDER_MODELS = {
|
|
54385
|
-
"codex-cli": [
|
|
54386
|
-
{ id: "codex/gpt-5.5", displayName: "GPT-5.5 (Codex CLI)", description: "Subscription model through official Codex CLI login", isDefault: true },
|
|
54387
|
-
{ id: "codex/gpt-5.4", displayName: "GPT-5.4 (Codex CLI)", description: "Subscription model through official Codex CLI login" },
|
|
54388
|
-
{ id: "codex/gpt-5.4-mini", displayName: "GPT-5.4 Mini (Codex CLI)", description: "Fast subscription model through official Codex CLI login" },
|
|
54389
|
-
{ id: "codex/gpt-4o", displayName: "GPT-4o (Codex CLI)", description: "Subscription model through official Codex CLI login" },
|
|
54390
|
-
{ id: "codex/gpt-4o-mini", displayName: "GPT-4o Mini (Codex CLI)", description: "Fast subscription model through official Codex CLI login" },
|
|
54391
|
-
{ id: "codex/o1", displayName: "o1 (Codex CLI)", description: "Reasoning model through official Codex CLI login" },
|
|
54392
|
-
{ id: "codex/o3-mini", displayName: "o3-mini (Codex CLI)", description: "Fast reasoning model through official Codex CLI login" }
|
|
54393
|
-
],
|
|
54394
|
-
"claude-code-cli": [
|
|
54395
|
-
{ id: "claude-code/sonnet-5", displayName: "Claude Sonnet 5 (Claude Code)", description: "Subscription model through official Claude Code login", isDefault: true },
|
|
54396
|
-
{ id: "claude-code/opus-4-8", displayName: "Claude Opus 4.8 (Claude Code)", description: "Subscription model through official Claude Code login" },
|
|
54397
|
-
{ id: "claude-code/opus-4-7", displayName: "Claude Opus 4.7 (Claude Code)", description: "Subscription model through official Claude Code login" },
|
|
54398
|
-
{ id: "claude-code/opus-4-6", displayName: "Claude Opus 4.6 (Claude Code)", description: "Subscription model through official Claude Code login" },
|
|
54399
|
-
{ id: "claude-code/opus-4-5", displayName: "Claude Opus 4.5 (Claude Code)", description: "Subscription model through official Claude Code login" },
|
|
54400
|
-
{ id: "claude-code/sonnet-4-6", displayName: "Claude Sonnet 4.6 (Claude Code)", description: "Subscription model through official Claude Code login" },
|
|
54401
|
-
{ id: "claude-code/sonnet-4-5", displayName: "Claude Sonnet 4.5 (Claude Code)", description: "Subscription model through official Claude Code login" },
|
|
54402
|
-
{ id: "claude-code/haiku-4-5", displayName: "Claude Haiku 4.5 (Claude Code)", description: "Subscription model through official Claude Code login" }
|
|
54403
|
-
],
|
|
54404
|
-
"gemini-cli": [
|
|
54405
|
-
{ id: "gemini-cli/gemini-3.5-flash", displayName: "Gemini 3.5 Flash (Gemini CLI)", description: "Subscription model through official Gemini CLI login", isDefault: true },
|
|
54406
|
-
{ id: "gemini-cli/gemini-3.1-pro", displayName: "Gemini 3.1 Pro (Gemini CLI)", description: "Subscription model through official Gemini CLI login" },
|
|
54407
|
-
{ id: "gemini-cli/gemini-3.1-flash-lite", displayName: "Gemini 3.1 Flash Lite (Gemini CLI)", description: "Subscription model through official Gemini CLI login" },
|
|
54408
|
-
{ id: "gemini-cli/gemini-2.5-pro", displayName: "Gemini 2.5 Pro (Gemini CLI)", description: "Subscription model through official Gemini CLI login" },
|
|
54409
|
-
{ id: "gemini-cli/gemini-2.5-flash", displayName: "Gemini 2.5 Flash (Gemini CLI)", description: "Subscription model through official Gemini CLI login" },
|
|
54410
|
-
{ id: "gemini-cli/gemini-2.5-flash-lite", displayName: "Gemini 2.5 Flash Lite (Gemini CLI)", description: "Subscription model through official Gemini CLI login" }
|
|
54411
|
-
],
|
|
54412
|
-
"antigravity-cli": [
|
|
54413
|
-
{ id: "antigravity/gemini-3.5-flash", displayName: "Gemini 3.5 Flash (Antigravity)", description: "Subscription model through official Antigravity login", isDefault: true },
|
|
54414
|
-
{ id: "antigravity/gemini-2.5-pro", displayName: "Gemini 2.5 Pro (Antigravity)", description: "Subscription model through official Antigravity login" },
|
|
54415
|
-
{ id: "antigravity/gemini-2.5-flash", displayName: "Gemini 2.5 Flash (Antigravity)", description: "Subscription model through official Antigravity login" }
|
|
54416
|
-
],
|
|
54417
|
-
"openai-api": [
|
|
54418
|
-
{ id: "gpt-5.5", displayName: "GPT-5.5", description: "Latest OpenAI model", isDefault: true },
|
|
54419
|
-
{ id: "gpt-5.4", displayName: "GPT-5.4", description: "Advanced reasoning and coding" },
|
|
54420
|
-
{ id: "gpt-5.4-mini", displayName: "GPT-5.4 Mini", description: "Fast, efficient variant" },
|
|
54421
|
-
{ id: "gpt-4o", displayName: "GPT-4o", description: "Previous generation flagship" },
|
|
54422
|
-
{ id: "gpt-4o-mini", displayName: "GPT-4o Mini", description: "Fast GPT-4o variant" },
|
|
54423
|
-
{ id: "o1", displayName: "o1", description: "Deep reasoning model" },
|
|
54424
|
-
{ id: "o3-mini", displayName: "o3-mini", description: "Fast reasoning model" }
|
|
54425
|
-
],
|
|
54426
|
-
"anthropic-api": [
|
|
54427
|
-
{ id: "claude-sonnet-5", displayName: "Claude Sonnet 5", description: "Balanced performance and speed", isDefault: true },
|
|
54428
|
-
{ id: "claude-opus-4-8", displayName: "Claude Opus 4.8", description: "Most powerful Claude model" },
|
|
54429
|
-
{ id: "claude-opus-4-7", displayName: "Claude Opus 4.7", description: "High-end reasoning" },
|
|
54430
|
-
{ id: "claude-opus-4-6", displayName: "Claude Opus 4.6", description: "Advanced problem solving" },
|
|
54431
|
-
{ id: "claude-opus-4-5", displayName: "Claude Opus 4.5", description: "Previous Opus generation" },
|
|
54432
|
-
{ id: "claude-sonnet-4-6", displayName: "Claude Sonnet 4.6", description: "Fast Sonnet variant" },
|
|
54433
|
-
{ id: "claude-sonnet-4-5", displayName: "Claude Sonnet 4.5", description: "Previous Sonnet generation" },
|
|
54434
|
-
{ id: "claude-haiku-4-5", displayName: "Claude Haiku 4.5", description: "Fastest Claude model" }
|
|
54435
|
-
],
|
|
54436
|
-
"gemini-api": [
|
|
54437
|
-
{ id: "gemini-3.5-flash", displayName: "Gemini 3.5 Flash", description: "Most intelligent for agentic tasks", isDefault: true },
|
|
54438
|
-
{ id: "gemini-3.1-pro", displayName: "Gemini 3.1 Pro", description: "Advanced problem solving (preview)" },
|
|
54439
|
-
{ id: "gemini-3.1-flash-lite", displayName: "Gemini 3.1 Flash Lite", description: "Budget-friendly performance" },
|
|
54440
|
-
{ id: "gemini-2.5-pro", displayName: "Gemini 2.5 Pro", description: "Complex reasoning and coding" },
|
|
54441
|
-
{ id: "gemini-2.5-flash", displayName: "Gemini 2.5 Flash", description: "Low-latency tasks" },
|
|
54442
|
-
{ id: "gemini-2.5-flash-lite", displayName: "Gemini 2.5 Flash Lite", description: "Fastest Gemini model" }
|
|
54443
|
-
],
|
|
54444
|
-
openrouter: [
|
|
54445
|
-
{ id: "openai/gpt-5.5", displayName: "GPT-5.5", description: "OpenAI GPT-5.5 via OpenRouter", isDefault: true },
|
|
54446
|
-
{ id: "openai/gpt-5.4", displayName: "GPT-5.4", description: "OpenAI GPT-5.4 via OpenRouter" },
|
|
54447
|
-
{ id: "openai/gpt-4o", displayName: "GPT-4o", description: "OpenAI GPT-4o via OpenRouter" },
|
|
54448
|
-
{ id: "anthropic/claude-sonnet-5", displayName: "Claude Sonnet 5", description: "Anthropic Claude via OpenRouter" },
|
|
54449
|
-
{ id: "anthropic/claude-opus-4-8", displayName: "Claude Opus 4.8", description: "Anthropic Claude via OpenRouter" },
|
|
54450
|
-
{ id: "google/gemini-3.5-flash", displayName: "Gemini 3.5 Flash", description: "Google Gemini via OpenRouter" },
|
|
54451
|
-
{ id: "google/gemini-2.5-pro", displayName: "Gemini 2.5 Pro", description: "Google Gemini via OpenRouter" }
|
|
54452
|
-
],
|
|
54453
|
-
"openai-compatible": [
|
|
54454
|
-
{ id: "custom", displayName: "Custom Model", description: "Model name from provider endpoint", isDynamic: true }
|
|
54455
|
-
],
|
|
54456
|
-
ollama: [
|
|
54457
|
-
{ id: "dynamic", displayName: "Discovered Models", description: "Models discovered from Ollama server", isDynamic: true, isDefault: true }
|
|
54458
|
-
],
|
|
54459
|
-
lmstudio: [
|
|
54460
|
-
{ id: "dynamic", displayName: "Discovered Models", description: "Models discovered from LM Studio server", isDynamic: true, isDefault: true }
|
|
54461
|
-
],
|
|
54462
|
-
"llama.cpp": [
|
|
54463
|
-
{ id: "dynamic", displayName: "Discovered Models", description: "Models discovered from llama.cpp server", isDynamic: true, isDefault: true }
|
|
54464
|
-
],
|
|
54465
|
-
vllm: [
|
|
54466
|
-
{ id: "dynamic", displayName: "Discovered Models", description: "Models discovered from vLLM server", isDynamic: true, isDefault: true }
|
|
54467
|
-
]
|
|
54468
|
-
};
|
|
54469
|
-
cachedModelsByProvider = new Map;
|
|
54470
|
-
validateProviderModelCompatibility = validateProviderModelPair;
|
|
54471
|
-
});
|
|
54472
|
-
|
|
54473
54494
|
// src/utils/model/model.ts
|
|
54474
54495
|
var exports_model = {};
|
|
54475
54496
|
__export(exports_model, {
|
|
@@ -56794,40 +56815,59 @@ var exports_urhqSubscription = {};
|
|
|
56794
56815
|
__export(exports_urhqSubscription, {
|
|
56795
56816
|
createURHQSubscriptionClient: () => createURHQSubscriptionClient
|
|
56796
56817
|
});
|
|
56818
|
+
import { spawn as spawn3 } from "child_process";
|
|
56797
56819
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
56798
|
-
|
|
56799
|
-
|
|
56800
|
-
|
|
56820
|
+
function createURHQSubscriptionClient(providerId, options) {
|
|
56821
|
+
const spec = CLI_SPECS[providerId];
|
|
56822
|
+
if (!spec) {
|
|
56823
|
+
throw new Error(`No subscription CLI dispatch is configured for provider "${providerId}".`);
|
|
56824
|
+
}
|
|
56825
|
+
const run = options.runner ?? defaultRunner;
|
|
56826
|
+
async function doRequest(params, requestOptions) {
|
|
56827
|
+
const model = cliModelName(params.model ?? options.model ?? "");
|
|
56828
|
+
if (!model) {
|
|
56829
|
+
throw new Error(`Provider "${providerId}" requires a model to dispatch to its CLI.`);
|
|
56830
|
+
}
|
|
56831
|
+
const prompt = messagesToPrompt(params);
|
|
56832
|
+
const result = await run(options.commandPath, spec.args(model, prompt), {
|
|
56833
|
+
signal: requestOptions?.signal,
|
|
56834
|
+
timeoutMs: options.timeoutMs ?? 120000
|
|
56835
|
+
});
|
|
56836
|
+
if (result.code !== 0) {
|
|
56837
|
+
throw new Error(`Subscription CLI "${options.commandPath}" for ${providerId} exited ${result.code}: ${result.stderr.trim() || result.stdout.trim() || "no output"}`);
|
|
56838
|
+
}
|
|
56839
|
+
const text = extractText(result.stdout);
|
|
56840
|
+
if (!text) {
|
|
56841
|
+
throw new Error(`Subscription CLI "${options.commandPath}" for ${providerId} produced no output.`);
|
|
56842
|
+
}
|
|
56801
56843
|
const data = {
|
|
56802
56844
|
id: `${providerId}-${randomUUID5()}`,
|
|
56803
56845
|
type: "message",
|
|
56804
56846
|
role: "assistant",
|
|
56805
|
-
model: params.model,
|
|
56806
|
-
content: [{ type: "text", text
|
|
56847
|
+
model: params.model ?? options.model,
|
|
56848
|
+
content: [{ type: "text", text }],
|
|
56807
56849
|
stop_reason: "end_turn",
|
|
56808
56850
|
stop_sequence: null,
|
|
56809
56851
|
usage: {
|
|
56810
|
-
input_tokens:
|
|
56811
|
-
output_tokens:
|
|
56852
|
+
input_tokens: estimateTokens(prompt),
|
|
56853
|
+
output_tokens: estimateTokens(text),
|
|
56812
56854
|
cache_creation_input_tokens: 0,
|
|
56813
56855
|
cache_read_input_tokens: 0
|
|
56814
56856
|
}
|
|
56815
56857
|
};
|
|
56858
|
+
const clientRequestId = params?.headers?.["x-client-request-id"];
|
|
56816
56859
|
return {
|
|
56817
56860
|
data,
|
|
56818
|
-
response: {
|
|
56819
|
-
headers: clientRequestId ? { "x-client-request-id": clientRequestId } : {},
|
|
56820
|
-
...extraHeaders
|
|
56821
|
-
}
|
|
56861
|
+
response: { headers: clientRequestId ? { "x-client-request-id": clientRequestId } : {} }
|
|
56822
56862
|
};
|
|
56823
56863
|
}
|
|
56824
56864
|
const messagesAPI = {
|
|
56825
|
-
create(params,
|
|
56865
|
+
create(params, requestOptions) {
|
|
56826
56866
|
if (params.stream) {
|
|
56827
|
-
const
|
|
56867
|
+
const pending = doRequest(params, requestOptions);
|
|
56828
56868
|
return {
|
|
56829
56869
|
async withResponse() {
|
|
56830
|
-
const { response, data } = await
|
|
56870
|
+
const { response, data } = await pending;
|
|
56831
56871
|
return {
|
|
56832
56872
|
data: createOneShotMessageStream(data),
|
|
56833
56873
|
response,
|
|
@@ -56836,33 +56876,121 @@ async function createURHQSubscriptionClient(providerId, options) {
|
|
|
56836
56876
|
}
|
|
56837
56877
|
};
|
|
56838
56878
|
}
|
|
56839
|
-
return doRequest(params,
|
|
56879
|
+
return doRequest(params, requestOptions).then(({ response, data }) => ({
|
|
56840
56880
|
...data,
|
|
56841
|
-
withResponse: () => ({
|
|
56842
|
-
data,
|
|
56843
|
-
response,
|
|
56844
|
-
request_id: data.id
|
|
56845
|
-
})
|
|
56881
|
+
withResponse: () => ({ data, response, request_id: data.id })
|
|
56846
56882
|
}));
|
|
56847
56883
|
},
|
|
56848
56884
|
async countTokens(params) {
|
|
56849
|
-
return {
|
|
56850
|
-
input_tokens: estimateTokenCount(params)
|
|
56851
|
-
};
|
|
56852
|
-
}
|
|
56853
|
-
};
|
|
56854
|
-
return {
|
|
56855
|
-
beta: {
|
|
56856
|
-
messages: messagesAPI
|
|
56885
|
+
return { input_tokens: estimateTokens(messagesToPrompt(params)) };
|
|
56857
56886
|
}
|
|
56858
56887
|
};
|
|
56888
|
+
return { beta: { messages: messagesAPI } };
|
|
56859
56889
|
}
|
|
56860
|
-
function
|
|
56861
|
-
const
|
|
56862
|
-
return
|
|
56890
|
+
function cliModelName(model) {
|
|
56891
|
+
const slash = model.indexOf("/");
|
|
56892
|
+
return slash >= 0 ? model.slice(slash + 1) : model;
|
|
56863
56893
|
}
|
|
56894
|
+
function messagesToPrompt(params) {
|
|
56895
|
+
const parts = [];
|
|
56896
|
+
const system = systemToText3(params.system);
|
|
56897
|
+
if (system)
|
|
56898
|
+
parts.push(system);
|
|
56899
|
+
const messages = params.messages ?? [];
|
|
56900
|
+
const label = messages.length > 1;
|
|
56901
|
+
for (const message of messages) {
|
|
56902
|
+
const text = contentToText2(message.content);
|
|
56903
|
+
if (!text)
|
|
56904
|
+
continue;
|
|
56905
|
+
parts.push(label ? `${capitalize2(message.role)}: ${text}` : text);
|
|
56906
|
+
}
|
|
56907
|
+
return parts.join(`
|
|
56908
|
+
|
|
56909
|
+
`);
|
|
56910
|
+
}
|
|
56911
|
+
function extractText(stdout) {
|
|
56912
|
+
const raw = stdout.trim();
|
|
56913
|
+
if (!raw)
|
|
56914
|
+
return "";
|
|
56915
|
+
try {
|
|
56916
|
+
const parsed = JSON.parse(raw);
|
|
56917
|
+
if (typeof parsed === "string")
|
|
56918
|
+
return parsed;
|
|
56919
|
+
const candidate = parsed.result ?? parsed.response ?? parsed.text ?? parsed.output ?? parsed.message?.content ?? parsed.choices?.[0]?.message?.content ?? (Array.isArray(parsed.content) ? parsed.content.map((block) => block?.text ?? "").join("") : undefined);
|
|
56920
|
+
if (typeof candidate === "string" && candidate.trim())
|
|
56921
|
+
return candidate;
|
|
56922
|
+
} catch {}
|
|
56923
|
+
return raw;
|
|
56924
|
+
}
|
|
56925
|
+
function systemToText3(system) {
|
|
56926
|
+
if (!system)
|
|
56927
|
+
return "";
|
|
56928
|
+
if (typeof system === "string")
|
|
56929
|
+
return system;
|
|
56930
|
+
if (Array.isArray(system))
|
|
56931
|
+
return system.map((block) => block?.text ?? "").join(`
|
|
56932
|
+
|
|
56933
|
+
`);
|
|
56934
|
+
return "";
|
|
56935
|
+
}
|
|
56936
|
+
function contentToText2(content) {
|
|
56937
|
+
if (typeof content === "string")
|
|
56938
|
+
return content;
|
|
56939
|
+
if (!Array.isArray(content))
|
|
56940
|
+
return "";
|
|
56941
|
+
return content.map((block) => {
|
|
56942
|
+
if (typeof block === "string")
|
|
56943
|
+
return block;
|
|
56944
|
+
if (block?.type === "text")
|
|
56945
|
+
return block.text ?? "";
|
|
56946
|
+
if (block?.type === "tool_result")
|
|
56947
|
+
return contentToText2(block.content);
|
|
56948
|
+
return "";
|
|
56949
|
+
}).join(`
|
|
56950
|
+
`);
|
|
56951
|
+
}
|
|
56952
|
+
function capitalize2(value) {
|
|
56953
|
+
return value ? value[0].toUpperCase() + value.slice(1) : value;
|
|
56954
|
+
}
|
|
56955
|
+
function estimateTokens(text) {
|
|
56956
|
+
return Math.ceil((text?.length ?? 0) / 4);
|
|
56957
|
+
}
|
|
56958
|
+
var CLI_SPECS, defaultRunner = (command, args, options) => new Promise((resolve8, reject) => {
|
|
56959
|
+
const child = spawn3(command, args, { stdio: ["pipe", "pipe", "pipe"], signal: options.signal });
|
|
56960
|
+
let stdout = "";
|
|
56961
|
+
let stderr = "";
|
|
56962
|
+
const timer = options.timeoutMs ? setTimeout(() => child.kill("SIGKILL"), options.timeoutMs) : undefined;
|
|
56963
|
+
child.stdout?.on("data", (chunk) => {
|
|
56964
|
+
stdout += chunk;
|
|
56965
|
+
});
|
|
56966
|
+
child.stderr?.on("data", (chunk) => {
|
|
56967
|
+
stderr += chunk;
|
|
56968
|
+
});
|
|
56969
|
+
child.on("error", (error40) => {
|
|
56970
|
+
if (timer)
|
|
56971
|
+
clearTimeout(timer);
|
|
56972
|
+
reject(error40);
|
|
56973
|
+
});
|
|
56974
|
+
child.on("close", (code) => {
|
|
56975
|
+
if (timer)
|
|
56976
|
+
clearTimeout(timer);
|
|
56977
|
+
resolve8({ code: code ?? 1, stdout, stderr });
|
|
56978
|
+
});
|
|
56979
|
+
if (options.input) {
|
|
56980
|
+
child.stdin?.write(options.input);
|
|
56981
|
+
}
|
|
56982
|
+
child.stdin?.end();
|
|
56983
|
+
});
|
|
56864
56984
|
var init_urhqSubscription = __esm(() => {
|
|
56865
56985
|
init_streamingAdapters();
|
|
56986
|
+
CLI_SPECS = {
|
|
56987
|
+
"codex-cli": { args: (model, prompt) => ["exec", "--model", model, prompt] },
|
|
56988
|
+
"claude-code-cli": {
|
|
56989
|
+
args: (model, prompt) => ["-p", prompt, "--model", model, "--output-format", "json"]
|
|
56990
|
+
},
|
|
56991
|
+
"gemini-cli": { args: (model, prompt) => ["-p", prompt, "-m", model] },
|
|
56992
|
+
"antigravity-cli": { args: (model, prompt) => ["-p", prompt, "--model", model] }
|
|
56993
|
+
};
|
|
56866
56994
|
});
|
|
56867
56995
|
|
|
56868
56996
|
// src/services/api/openrouter.ts
|
|
@@ -56938,7 +57066,7 @@ async function createOpenRouterClient(options) {
|
|
|
56938
57066
|
},
|
|
56939
57067
|
async countTokens(params) {
|
|
56940
57068
|
return {
|
|
56941
|
-
input_tokens:
|
|
57069
|
+
input_tokens: estimateTokenCount(params)
|
|
56942
57070
|
};
|
|
56943
57071
|
}
|
|
56944
57072
|
};
|
|
@@ -56948,7 +57076,7 @@ async function createOpenRouterClient(options) {
|
|
|
56948
57076
|
}
|
|
56949
57077
|
};
|
|
56950
57078
|
}
|
|
56951
|
-
function
|
|
57079
|
+
function estimateTokenCount(params) {
|
|
56952
57080
|
const text = JSON.stringify(params.messages ?? []);
|
|
56953
57081
|
return Math.ceil(text.length / 4);
|
|
56954
57082
|
}
|
|
@@ -56964,116 +57092,219 @@ __export(exports_standardAPI, {
|
|
|
56964
57092
|
});
|
|
56965
57093
|
import { randomUUID as randomUUID7 } from "crypto";
|
|
56966
57094
|
async function createStandardAPIClient(options) {
|
|
56967
|
-
const { providerId, apiKey, baseUrl
|
|
57095
|
+
const { providerId, apiKey, baseUrl } = options;
|
|
57096
|
+
const family = getProviderFamily(providerId);
|
|
56968
57097
|
async function doRequest(params, extraHeaders) {
|
|
56969
|
-
const endpoint = getAPIEndpoint(
|
|
57098
|
+
const endpoint = getAPIEndpoint(family, baseUrl, params.model);
|
|
56970
57099
|
const clientRequestId = params?.headers?.["x-client-request-id"];
|
|
56971
|
-
const response = await axios_default.post(endpoint, buildAPIRequest(
|
|
57100
|
+
const response = await axios_default.post(endpoint, buildAPIRequest(family, params), {
|
|
56972
57101
|
headers: {
|
|
56973
57102
|
"Content-Type": "application/json",
|
|
56974
|
-
|
|
57103
|
+
...buildAuthHeaders(family, apiKey, params),
|
|
56975
57104
|
...clientRequestId && { "x-client-request-id": clientRequestId },
|
|
56976
57105
|
...extraHeaders
|
|
56977
57106
|
},
|
|
56978
57107
|
timeout: 60000
|
|
56979
57108
|
});
|
|
56980
|
-
return { response, data: parseAPIResponse(
|
|
57109
|
+
return { response, data: parseAPIResponse(family, response.data, params.model) };
|
|
56981
57110
|
}
|
|
56982
57111
|
const messagesAPI = {
|
|
56983
|
-
create(params,
|
|
57112
|
+
create(params, requestOptions) {
|
|
56984
57113
|
if (params.stream) {
|
|
56985
|
-
const
|
|
57114
|
+
const pending = doRequest(params, requestOptions?.headers);
|
|
56986
57115
|
return {
|
|
56987
57116
|
async withResponse() {
|
|
56988
|
-
const { response, data } = await
|
|
57117
|
+
const { response, data } = await pending;
|
|
56989
57118
|
return {
|
|
56990
57119
|
data: createOneShotMessageStream(data),
|
|
56991
57120
|
response,
|
|
56992
|
-
request_id:
|
|
57121
|
+
request_id: data.id ?? response.headers?.["x-request-id"] ?? randomUUID7()
|
|
56993
57122
|
};
|
|
56994
57123
|
}
|
|
56995
57124
|
};
|
|
56996
57125
|
}
|
|
56997
|
-
return doRequest(params,
|
|
57126
|
+
return doRequest(params, requestOptions?.headers).then(({ response, data }) => ({
|
|
56998
57127
|
...data,
|
|
56999
57128
|
withResponse: () => ({
|
|
57000
57129
|
data,
|
|
57001
57130
|
response,
|
|
57002
|
-
request_id:
|
|
57131
|
+
request_id: data.id ?? response.headers?.["x-request-id"] ?? randomUUID7()
|
|
57003
57132
|
})
|
|
57004
57133
|
}));
|
|
57005
57134
|
},
|
|
57006
57135
|
async countTokens(params) {
|
|
57007
|
-
return {
|
|
57008
|
-
input_tokens: estimateTokenCount3(params)
|
|
57009
|
-
};
|
|
57010
|
-
}
|
|
57011
|
-
};
|
|
57012
|
-
return {
|
|
57013
|
-
beta: {
|
|
57014
|
-
messages: messagesAPI
|
|
57136
|
+
return { input_tokens: estimateTokenCount2(params) };
|
|
57015
57137
|
}
|
|
57016
57138
|
};
|
|
57139
|
+
return { beta: { messages: messagesAPI } };
|
|
57017
57140
|
}
|
|
57018
|
-
function getAPIEndpoint(
|
|
57019
|
-
switch (
|
|
57020
|
-
case "openai
|
|
57141
|
+
function getAPIEndpoint(family, baseUrl, model) {
|
|
57142
|
+
switch (family) {
|
|
57143
|
+
case "openai":
|
|
57021
57144
|
return baseUrl ?? "https://api.openai.com/v1/chat/completions";
|
|
57022
|
-
case "anthropic
|
|
57145
|
+
case "anthropic":
|
|
57023
57146
|
return baseUrl ?? "https://api.anthropic.com/v1/messages";
|
|
57024
|
-
case "
|
|
57025
|
-
|
|
57147
|
+
case "google": {
|
|
57148
|
+
const root2 = baseUrl ?? "https://generativelanguage.googleapis.com/v1beta";
|
|
57149
|
+
return `${root2.replace(/\/$/, "")}/models/${model}:generateContent`;
|
|
57150
|
+
}
|
|
57026
57151
|
default:
|
|
57027
57152
|
return baseUrl ?? "";
|
|
57028
57153
|
}
|
|
57029
57154
|
}
|
|
57030
|
-
function
|
|
57031
|
-
switch (
|
|
57032
|
-
case "
|
|
57155
|
+
function buildAuthHeaders(family, apiKey, params) {
|
|
57156
|
+
switch (family) {
|
|
57157
|
+
case "anthropic": {
|
|
57158
|
+
const headers = {
|
|
57159
|
+
"x-api-key": apiKey ?? "",
|
|
57160
|
+
"anthropic-version": ANTHROPIC_VERSION
|
|
57161
|
+
};
|
|
57162
|
+
if (Array.isArray(params.betas) && params.betas.length > 0) {
|
|
57163
|
+
headers["anthropic-beta"] = params.betas.join(",");
|
|
57164
|
+
}
|
|
57165
|
+
return headers;
|
|
57166
|
+
}
|
|
57167
|
+
case "google":
|
|
57168
|
+
return { "x-goog-api-key": apiKey ?? "" };
|
|
57169
|
+
default:
|
|
57170
|
+
return { Authorization: `Bearer ${apiKey ?? ""}` };
|
|
57171
|
+
}
|
|
57172
|
+
}
|
|
57173
|
+
function buildAPIRequest(family, params) {
|
|
57174
|
+
switch (family) {
|
|
57175
|
+
case "openai":
|
|
57033
57176
|
return {
|
|
57034
57177
|
model: params.model,
|
|
57035
57178
|
messages: toOpenAIMessages2(params),
|
|
57036
57179
|
max_tokens: params.max_tokens,
|
|
57180
|
+
...params.temperature !== undefined && { temperature: params.temperature },
|
|
57037
57181
|
stream: false
|
|
57038
57182
|
};
|
|
57039
|
-
case "anthropic
|
|
57183
|
+
case "anthropic":
|
|
57040
57184
|
return {
|
|
57041
57185
|
model: params.model,
|
|
57186
|
+
...params.system && { system: params.system },
|
|
57042
57187
|
messages: params.messages,
|
|
57043
|
-
max_tokens: params.max_tokens
|
|
57188
|
+
max_tokens: params.max_tokens ?? 4096,
|
|
57189
|
+
...params.temperature !== undefined && { temperature: params.temperature },
|
|
57044
57190
|
stream: false
|
|
57045
57191
|
};
|
|
57192
|
+
case "google":
|
|
57193
|
+
return {
|
|
57194
|
+
contents: toGeminiContents(params),
|
|
57195
|
+
...geminiSystemInstruction(params) && {
|
|
57196
|
+
systemInstruction: geminiSystemInstruction(params)
|
|
57197
|
+
},
|
|
57198
|
+
generationConfig: {
|
|
57199
|
+
...params.max_tokens && { maxOutputTokens: params.max_tokens },
|
|
57200
|
+
...params.temperature !== undefined && { temperature: params.temperature }
|
|
57201
|
+
}
|
|
57202
|
+
};
|
|
57046
57203
|
default:
|
|
57047
57204
|
return params;
|
|
57048
57205
|
}
|
|
57049
57206
|
}
|
|
57207
|
+
function parseAPIResponse(family, data, fallbackModel) {
|
|
57208
|
+
switch (family) {
|
|
57209
|
+
case "openai":
|
|
57210
|
+
return {
|
|
57211
|
+
id: data.id ?? `openai-${randomUUID7()}`,
|
|
57212
|
+
type: "message",
|
|
57213
|
+
role: "assistant",
|
|
57214
|
+
model: data.model ?? fallbackModel,
|
|
57215
|
+
content: [{ type: "text", text: data.choices?.[0]?.message?.content ?? "" }],
|
|
57216
|
+
stop_reason: mapStopReason(data.choices?.[0]?.finish_reason),
|
|
57217
|
+
stop_sequence: null,
|
|
57218
|
+
usage: {
|
|
57219
|
+
input_tokens: data.usage?.prompt_tokens ?? 0,
|
|
57220
|
+
output_tokens: data.usage?.completion_tokens ?? 0,
|
|
57221
|
+
cache_creation_input_tokens: 0,
|
|
57222
|
+
cache_read_input_tokens: 0
|
|
57223
|
+
}
|
|
57224
|
+
};
|
|
57225
|
+
case "anthropic":
|
|
57226
|
+
return {
|
|
57227
|
+
id: data.id ?? `anthropic-${randomUUID7()}`,
|
|
57228
|
+
type: "message",
|
|
57229
|
+
role: "assistant",
|
|
57230
|
+
model: data.model ?? fallbackModel,
|
|
57231
|
+
content: Array.isArray(data.content) ? data.content.map((block) => ({ type: block.type, text: block.text })) : [{ type: "text", text: "" }],
|
|
57232
|
+
stop_reason: data.stop_reason ?? "end_turn",
|
|
57233
|
+
stop_sequence: data.stop_sequence ?? null,
|
|
57234
|
+
usage: {
|
|
57235
|
+
input_tokens: data.usage?.input_tokens ?? 0,
|
|
57236
|
+
output_tokens: data.usage?.output_tokens ?? 0,
|
|
57237
|
+
cache_creation_input_tokens: data.usage?.cache_creation_input_tokens ?? 0,
|
|
57238
|
+
cache_read_input_tokens: data.usage?.cache_read_input_tokens ?? 0
|
|
57239
|
+
}
|
|
57240
|
+
};
|
|
57241
|
+
case "google": {
|
|
57242
|
+
const parts = data.candidates?.[0]?.content?.parts ?? [];
|
|
57243
|
+
return {
|
|
57244
|
+
id: `gemini-${randomUUID7()}`,
|
|
57245
|
+
type: "message",
|
|
57246
|
+
role: "assistant",
|
|
57247
|
+
model: fallbackModel,
|
|
57248
|
+
content: [{ type: "text", text: parts.map((part) => part?.text ?? "").join("") }],
|
|
57249
|
+
stop_reason: mapStopReason(data.candidates?.[0]?.finishReason),
|
|
57250
|
+
stop_sequence: null,
|
|
57251
|
+
usage: {
|
|
57252
|
+
input_tokens: data.usageMetadata?.promptTokenCount ?? 0,
|
|
57253
|
+
output_tokens: data.usageMetadata?.candidatesTokenCount ?? 0,
|
|
57254
|
+
cache_creation_input_tokens: 0,
|
|
57255
|
+
cache_read_input_tokens: 0
|
|
57256
|
+
}
|
|
57257
|
+
};
|
|
57258
|
+
}
|
|
57259
|
+
default:
|
|
57260
|
+
return data;
|
|
57261
|
+
}
|
|
57262
|
+
}
|
|
57263
|
+
function mapStopReason(reason) {
|
|
57264
|
+
switch (reason) {
|
|
57265
|
+
case "length":
|
|
57266
|
+
case "MAX_TOKENS":
|
|
57267
|
+
return "max_tokens";
|
|
57268
|
+
case "stop":
|
|
57269
|
+
case "STOP":
|
|
57270
|
+
case undefined:
|
|
57271
|
+
return "end_turn";
|
|
57272
|
+
default:
|
|
57273
|
+
return "end_turn";
|
|
57274
|
+
}
|
|
57275
|
+
}
|
|
57050
57276
|
function toOpenAIMessages2(params) {
|
|
57051
57277
|
const messages = [];
|
|
57052
|
-
const system =
|
|
57053
|
-
if (system)
|
|
57278
|
+
const system = systemToText4(params.system);
|
|
57279
|
+
if (system)
|
|
57054
57280
|
messages.push({ role: "system", content: system });
|
|
57055
|
-
}
|
|
57056
57281
|
for (const message of params.messages ?? []) {
|
|
57057
|
-
messages.push({
|
|
57058
|
-
role: message.role,
|
|
57059
|
-
content: contentToText2(message.content)
|
|
57060
|
-
});
|
|
57282
|
+
messages.push({ role: message.role, content: contentToText3(message.content) });
|
|
57061
57283
|
}
|
|
57062
57284
|
return messages;
|
|
57063
57285
|
}
|
|
57064
|
-
function
|
|
57286
|
+
function toGeminiContents(params) {
|
|
57287
|
+
return (params.messages ?? []).map((message) => ({
|
|
57288
|
+
role: message.role === "assistant" ? "model" : "user",
|
|
57289
|
+
parts: [{ text: contentToText3(message.content) }]
|
|
57290
|
+
}));
|
|
57291
|
+
}
|
|
57292
|
+
function geminiSystemInstruction(params) {
|
|
57293
|
+
const system = systemToText4(params.system);
|
|
57294
|
+
return system ? { parts: [{ text: system }] } : undefined;
|
|
57295
|
+
}
|
|
57296
|
+
function systemToText4(system) {
|
|
57065
57297
|
if (!system)
|
|
57066
57298
|
return "";
|
|
57067
57299
|
if (typeof system === "string")
|
|
57068
57300
|
return system;
|
|
57069
|
-
if (Array.isArray(system))
|
|
57301
|
+
if (Array.isArray(system))
|
|
57070
57302
|
return system.map((block) => block?.text ?? "").join(`
|
|
57071
57303
|
|
|
57072
57304
|
`);
|
|
57073
|
-
}
|
|
57074
57305
|
return "";
|
|
57075
57306
|
}
|
|
57076
|
-
function
|
|
57307
|
+
function contentToText3(content) {
|
|
57077
57308
|
if (typeof content === "string")
|
|
57078
57309
|
return content;
|
|
57079
57310
|
if (!Array.isArray(content))
|
|
@@ -57084,55 +57315,18 @@ function contentToText2(content) {
|
|
|
57084
57315
|
if (block?.type === "text")
|
|
57085
57316
|
return block.text ?? "";
|
|
57086
57317
|
if (block?.type === "tool_result")
|
|
57087
|
-
return block.content
|
|
57318
|
+
return contentToText3(block.content);
|
|
57088
57319
|
return "";
|
|
57089
57320
|
}).join(`
|
|
57090
57321
|
`);
|
|
57091
57322
|
}
|
|
57092
|
-
function
|
|
57093
|
-
|
|
57094
|
-
case "openai-api":
|
|
57095
|
-
return {
|
|
57096
|
-
id: `openai-${randomUUID7()}`,
|
|
57097
|
-
type: "message",
|
|
57098
|
-
role: "assistant",
|
|
57099
|
-
model: data.model,
|
|
57100
|
-
content: [{ type: "text", text: data.choices?.[0]?.message?.content ?? "" }],
|
|
57101
|
-
stop_reason: data.choices?.[0]?.finish_reason ?? "end_turn",
|
|
57102
|
-
stop_sequence: null,
|
|
57103
|
-
usage: {
|
|
57104
|
-
input_tokens: data.usage?.prompt_tokens ?? 0,
|
|
57105
|
-
output_tokens: data.usage?.completion_tokens ?? 0,
|
|
57106
|
-
cache_creation_input_tokens: 0,
|
|
57107
|
-
cache_read_input_tokens: 0
|
|
57108
|
-
}
|
|
57109
|
-
};
|
|
57110
|
-
case "anthropic-api":
|
|
57111
|
-
return {
|
|
57112
|
-
id: data.id,
|
|
57113
|
-
type: "message",
|
|
57114
|
-
role: "assistant",
|
|
57115
|
-
model: data.model,
|
|
57116
|
-
content: data.content?.map((c3) => ({ type: c3.type, text: c3.text })),
|
|
57117
|
-
stop_reason: data.stop_reason ?? "end_turn",
|
|
57118
|
-
stop_sequence: null,
|
|
57119
|
-
usage: {
|
|
57120
|
-
input_tokens: data.usage?.input_tokens ?? 0,
|
|
57121
|
-
output_tokens: data.usage?.output_tokens ?? 0,
|
|
57122
|
-
cache_creation_input_tokens: 0,
|
|
57123
|
-
cache_read_input_tokens: 0
|
|
57124
|
-
}
|
|
57125
|
-
};
|
|
57126
|
-
default:
|
|
57127
|
-
return data;
|
|
57128
|
-
}
|
|
57129
|
-
}
|
|
57130
|
-
function estimateTokenCount3(params) {
|
|
57131
|
-
const text = JSON.stringify(params.messages ?? []);
|
|
57132
|
-
return Math.ceil(text.length / 4);
|
|
57323
|
+
function estimateTokenCount2(params) {
|
|
57324
|
+
return Math.ceil(JSON.stringify(params.messages ?? []).length / 4);
|
|
57133
57325
|
}
|
|
57326
|
+
var ANTHROPIC_VERSION = "2023-06-01";
|
|
57134
57327
|
var init_standardAPI = __esm(() => {
|
|
57135
57328
|
init_axios2();
|
|
57329
|
+
init_providerRegistry();
|
|
57136
57330
|
init_streamingAdapters();
|
|
57137
57331
|
});
|
|
57138
57332
|
|
|
@@ -57140,7 +57334,7 @@ var init_standardAPI = __esm(() => {
|
|
|
57140
57334
|
function resolveActiveProviderModel(options = {}) {
|
|
57141
57335
|
const settings = options.settings ?? getInitialSettings();
|
|
57142
57336
|
const providerSettings = getActiveProviderSettings(settings);
|
|
57143
|
-
const providerId = providerSettings.active ??
|
|
57337
|
+
const providerId = providerSettings.active ?? DEFAULT_PROVIDER_ID;
|
|
57144
57338
|
const provider = getProviderDefinition(providerId);
|
|
57145
57339
|
if (!provider) {
|
|
57146
57340
|
throw new Error(`Provider "${providerId}" is selected, but no runtime provider is registered. Run: ur provider list`);
|
|
@@ -57153,7 +57347,7 @@ function resolveActiveProviderModel(options = {}) {
|
|
|
57153
57347
|
throw new Error(`Provider "${providerId}" is selected, but no model is selected or discoverable. Run /model and choose a model from ${providerId}.`);
|
|
57154
57348
|
}
|
|
57155
57349
|
const validation = validateProviderModelPair(providerId, model, {
|
|
57156
|
-
allowUncachedDynamic:
|
|
57350
|
+
allowUncachedDynamic: provider.modelDiscoveryType === "live"
|
|
57157
57351
|
});
|
|
57158
57352
|
if (validation.valid === false) {
|
|
57159
57353
|
throw new Error(formatRuntimeDispatchError({
|
|
@@ -69063,7 +69257,7 @@ var init_auth = __esm(() => {
|
|
|
69063
69257
|
|
|
69064
69258
|
// src/utils/userAgent.ts
|
|
69065
69259
|
function getURCodeUserAgent() {
|
|
69066
|
-
return `ur/${"1.
|
|
69260
|
+
return `ur/${"1.28.0"}`;
|
|
69067
69261
|
}
|
|
69068
69262
|
|
|
69069
69263
|
// src/utils/workloadContext.ts
|
|
@@ -69085,7 +69279,7 @@ function getUserAgent() {
|
|
|
69085
69279
|
const clientApp = process.env.UR_AGENT_SDK_CLIENT_APP ? `, client-app/${process.env.UR_AGENT_SDK_CLIENT_APP}` : "";
|
|
69086
69280
|
const workload = getWorkload();
|
|
69087
69281
|
const workloadSuffix = workload ? `, workload/${workload}` : "";
|
|
69088
|
-
return `ur-cli/${"1.
|
|
69282
|
+
return `ur-cli/${"1.28.0"} (${process.env.USER_TYPE}, ${process.env.UR_CODE_ENTRYPOINT ?? "cli"}${agentSdkVersion}${clientApp}${workloadSuffix})`;
|
|
69089
69283
|
}
|
|
69090
69284
|
function getMCPUserAgent() {
|
|
69091
69285
|
const parts = [];
|
|
@@ -69099,7 +69293,7 @@ function getMCPUserAgent() {
|
|
|
69099
69293
|
parts.push(`client-app/${process.env.UR_AGENT_SDK_CLIENT_APP}`);
|
|
69100
69294
|
}
|
|
69101
69295
|
const suffix = parts.length > 0 ? ` (${parts.join(", ")})` : "";
|
|
69102
|
-
return `ur/${"1.
|
|
69296
|
+
return `ur/${"1.28.0"}${suffix}`;
|
|
69103
69297
|
}
|
|
69104
69298
|
function getWebFetchUserAgent() {
|
|
69105
69299
|
return `UR-User (${getURCodeUserAgent()})`;
|
|
@@ -69237,7 +69431,7 @@ var init_user = __esm(() => {
|
|
|
69237
69431
|
deviceId,
|
|
69238
69432
|
sessionId: getSessionId(),
|
|
69239
69433
|
email: getEmail(),
|
|
69240
|
-
appVersion: "1.
|
|
69434
|
+
appVersion: "1.28.0",
|
|
69241
69435
|
platform: getHostPlatformForAnalytics(),
|
|
69242
69436
|
organizationUuid,
|
|
69243
69437
|
accountUuid,
|
|
@@ -75754,7 +75948,7 @@ var init_metadata = __esm(() => {
|
|
|
75754
75948
|
COMPOUND_OPERATOR_REGEX = /\s*(?:&&|\|\||[;|])\s*/;
|
|
75755
75949
|
WHITESPACE_REGEX = /\s+/;
|
|
75756
75950
|
getVersionBase = memoize_default(() => {
|
|
75757
|
-
const match = "1.
|
|
75951
|
+
const match = "1.28.0".match(/^\d+\.\d+\.\d+(?:-[a-z]+)?/);
|
|
75758
75952
|
return match ? match[0] : undefined;
|
|
75759
75953
|
});
|
|
75760
75954
|
buildEnvContext = memoize_default(async () => {
|
|
@@ -75794,7 +75988,7 @@ var init_metadata = __esm(() => {
|
|
|
75794
75988
|
isGithubAction: isEnvTruthy(process.env.GITHUB_ACTIONS),
|
|
75795
75989
|
isURCodeAction: isEnvTruthy(process.env.UR_CODE_ACTION),
|
|
75796
75990
|
isURAiAuth: isURAISubscriber2(),
|
|
75797
|
-
version: "1.
|
|
75991
|
+
version: "1.28.0",
|
|
75798
75992
|
versionBase: getVersionBase(),
|
|
75799
75993
|
buildTime: "",
|
|
75800
75994
|
deploymentEnvironment: env2.detectDeploymentEnvironment(),
|
|
@@ -76464,7 +76658,7 @@ function initialize1PEventLogging() {
|
|
|
76464
76658
|
const platform2 = getPlatform();
|
|
76465
76659
|
const attributes = {
|
|
76466
76660
|
[import_semantic_conventions4.ATTR_SERVICE_NAME]: "ur",
|
|
76467
|
-
[import_semantic_conventions4.ATTR_SERVICE_VERSION]: "1.
|
|
76661
|
+
[import_semantic_conventions4.ATTR_SERVICE_VERSION]: "1.28.0"
|
|
76468
76662
|
};
|
|
76469
76663
|
if (platform2 === "wsl") {
|
|
76470
76664
|
const wslVersion = getWslVersion();
|
|
@@ -76491,7 +76685,7 @@ function initialize1PEventLogging() {
|
|
|
76491
76685
|
})
|
|
76492
76686
|
]
|
|
76493
76687
|
});
|
|
76494
|
-
firstPartyEventLogger = firstPartyEventLoggerProvider.getLogger("com.urhq.ur.events", "1.
|
|
76688
|
+
firstPartyEventLogger = firstPartyEventLoggerProvider.getLogger("com.urhq.ur.events", "1.28.0");
|
|
76495
76689
|
}
|
|
76496
76690
|
async function reinitialize1PEventLoggingIfConfigChanged() {
|
|
76497
76691
|
if (!is1PEventLoggingEnabled() || !firstPartyEventLoggerProvider) {
|
|
@@ -80807,7 +81001,7 @@ __export(exports_backgroundRunner, {
|
|
|
80807
81001
|
backgroundDir: () => backgroundDir,
|
|
80808
81002
|
appendBackgroundFeedback: () => appendBackgroundFeedback
|
|
80809
81003
|
});
|
|
80810
|
-
import { spawn as
|
|
81004
|
+
import { spawn as spawn4 } from "child_process";
|
|
80811
81005
|
import {
|
|
80812
81006
|
closeSync as closeSync3,
|
|
80813
81007
|
existsSync as existsSync5,
|
|
@@ -81021,7 +81215,7 @@ async function spawnBackgroundWorker(task, bin) {
|
|
|
81021
81215
|
const err = openSync3(task.logFile, "a");
|
|
81022
81216
|
try {
|
|
81023
81217
|
const env4 = await resolveTaskEnv(task);
|
|
81024
|
-
const child =
|
|
81218
|
+
const child = spawn4(entry.file, command, {
|
|
81025
81219
|
cwd: task.cwd,
|
|
81026
81220
|
detached: true,
|
|
81027
81221
|
stdio: ["ignore", out, err],
|
|
@@ -81237,7 +81431,7 @@ async function runHeadlessAgent(task, cwd2) {
|
|
|
81237
81431
|
if (sawResult)
|
|
81238
81432
|
closeInputSoon();
|
|
81239
81433
|
};
|
|
81240
|
-
const child =
|
|
81434
|
+
const child = spawn4(entry.file, args, {
|
|
81241
81435
|
cwd: cwd2,
|
|
81242
81436
|
stdio: ["pipe", "pipe", "pipe"],
|
|
81243
81437
|
env: env4
|
|
@@ -81788,7 +81982,7 @@ function formatAgentTrendReport(report = buildAgentTrendReport()) {
|
|
|
81788
81982
|
function formatA2AAgentCard(options = {}, pretty = true) {
|
|
81789
81983
|
return JSON.stringify(buildA2AAgentCard(options), null, pretty ? 2 : 0);
|
|
81790
81984
|
}
|
|
81791
|
-
var urVersion = "1.
|
|
81985
|
+
var urVersion = "1.28.0", coverage, priorityRoadmap;
|
|
81792
81986
|
var init_trends = __esm(() => {
|
|
81793
81987
|
coverage = [
|
|
81794
81988
|
{
|
|
@@ -83781,7 +83975,7 @@ function getAttributionHeader(fingerprint) {
|
|
|
83781
83975
|
if (!isAttributionHeaderEnabled()) {
|
|
83782
83976
|
return "";
|
|
83783
83977
|
}
|
|
83784
|
-
const version2 = `${"1.
|
|
83978
|
+
const version2 = `${"1.28.0"}.${fingerprint}`;
|
|
83785
83979
|
const entrypoint = process.env.UR_CODE_ENTRYPOINT ?? "unknown";
|
|
83786
83980
|
const cch = "";
|
|
83787
83981
|
const workload = getWorkload();
|
|
@@ -84104,7 +84298,7 @@ var require_ignore = __commonJS((exports, module) => {
|
|
|
84104
84298
|
// node_modules/tree-kill/index.js
|
|
84105
84299
|
var require_tree_kill = __commonJS((exports, module) => {
|
|
84106
84300
|
var childProcess = __require("child_process");
|
|
84107
|
-
var
|
|
84301
|
+
var spawn5 = childProcess.spawn;
|
|
84108
84302
|
var exec2 = childProcess.exec;
|
|
84109
84303
|
module.exports = function(pid, signal, callback) {
|
|
84110
84304
|
if (typeof signal === "function" && callback === undefined) {
|
|
@@ -84129,14 +84323,14 @@ var require_tree_kill = __commonJS((exports, module) => {
|
|
|
84129
84323
|
break;
|
|
84130
84324
|
case "darwin":
|
|
84131
84325
|
buildProcessTree(pid, tree, pidsToProcess, function(parentPid) {
|
|
84132
|
-
return
|
|
84326
|
+
return spawn5("pgrep", ["-P", parentPid]);
|
|
84133
84327
|
}, function() {
|
|
84134
84328
|
killAll(tree, signal, callback);
|
|
84135
84329
|
});
|
|
84136
84330
|
break;
|
|
84137
84331
|
default:
|
|
84138
84332
|
buildProcessTree(pid, tree, pidsToProcess, function(parentPid) {
|
|
84139
|
-
return
|
|
84333
|
+
return spawn5("ps", ["-o", "pid", "--no-headers", "--ppid", parentPid]);
|
|
84140
84334
|
}, function() {
|
|
84141
84335
|
killAll(tree, signal, callback);
|
|
84142
84336
|
});
|
|
@@ -123458,7 +123652,7 @@ var init_frontmatterParser = __esm(() => {
|
|
|
123458
123652
|
});
|
|
123459
123653
|
|
|
123460
123654
|
// src/utils/ripgrep.ts
|
|
123461
|
-
import { execFile as execFile3, spawn as
|
|
123655
|
+
import { execFile as execFile3, spawn as spawn5 } from "child_process";
|
|
123462
123656
|
import { existsSync as existsSync8 } from "fs";
|
|
123463
123657
|
import { homedir as homedir10 } from "os";
|
|
123464
123658
|
import * as path9 from "path";
|
|
@@ -123482,7 +123676,7 @@ function ripGrepRaw(args, target, abortSignal, callback, singleThread = false) {
|
|
|
123482
123676
|
const parsedSeconds = parseInt(process.env.UR_CODE_GLOB_TIMEOUT_SECONDS || "", 10) || 0;
|
|
123483
123677
|
const timeout = parsedSeconds > 0 ? parsedSeconds * 1000 : defaultTimeout;
|
|
123484
123678
|
if (argv0) {
|
|
123485
|
-
const child =
|
|
123679
|
+
const child = spawn5(rgPath, fullArgs, {
|
|
123486
123680
|
argv0,
|
|
123487
123681
|
signal: abortSignal,
|
|
123488
123682
|
windowsHide: true
|
|
@@ -123556,7 +123750,7 @@ async function ripGrepFileCount(args, target, abortSignal) {
|
|
|
123556
123750
|
await codesignRipgrepIfNecessary();
|
|
123557
123751
|
const { rgPath, rgArgs, argv0 } = ripgrepCommand();
|
|
123558
123752
|
return new Promise((resolve15, reject) => {
|
|
123559
|
-
const child =
|
|
123753
|
+
const child = spawn5(rgPath, [...rgArgs, ...args, target], {
|
|
123560
123754
|
argv0,
|
|
123561
123755
|
signal: abortSignal,
|
|
123562
123756
|
windowsHide: true,
|
|
@@ -141740,7 +141934,7 @@ var DEFAULT_REPEAT_THRESHOLD = 3;
|
|
|
141740
141934
|
var init_loopDetector = () => {};
|
|
141741
141935
|
|
|
141742
141936
|
// src/services/verifier/projectGates.ts
|
|
141743
|
-
import { spawn as
|
|
141937
|
+
import { spawn as spawn6 } from "child_process";
|
|
141744
141938
|
import { readFile as readFile9 } from "fs/promises";
|
|
141745
141939
|
import { isAbsolute as isAbsolute9, join as join50, relative as relative8 } from "path";
|
|
141746
141940
|
async function loadVerifyConfig(cwd2) {
|
|
@@ -141821,7 +142015,7 @@ async function runGateCommands(commands, cwd2, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
|
141821
142015
|
}
|
|
141822
142016
|
function runSingleCommand(command, cwd2, timeoutMs) {
|
|
141823
142017
|
return new Promise((resolve18) => {
|
|
141824
|
-
const child =
|
|
142018
|
+
const child = spawn6(command, {
|
|
141825
142019
|
cwd: cwd2,
|
|
141826
142020
|
shell: true,
|
|
141827
142021
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -191454,7 +191648,7 @@ function getTelemetryAttributes() {
|
|
|
191454
191648
|
attributes["session.id"] = sessionId;
|
|
191455
191649
|
}
|
|
191456
191650
|
if (shouldIncludeAttribute("OTEL_METRICS_INCLUDE_VERSION")) {
|
|
191457
|
-
attributes["app.version"] = "1.
|
|
191651
|
+
attributes["app.version"] = "1.28.0";
|
|
191458
191652
|
}
|
|
191459
191653
|
const oauthAccount = getOauthAccountInfo();
|
|
191460
191654
|
if (oauthAccount) {
|
|
@@ -225425,14 +225619,14 @@ var init_upperFirst = __esm(() => {
|
|
|
225425
225619
|
});
|
|
225426
225620
|
|
|
225427
225621
|
// node_modules/lodash-es/capitalize.js
|
|
225428
|
-
function
|
|
225622
|
+
function capitalize3(string5) {
|
|
225429
225623
|
return upperFirst_default(toString_default(string5).toLowerCase());
|
|
225430
225624
|
}
|
|
225431
225625
|
var capitalize_default;
|
|
225432
225626
|
var init_capitalize = __esm(() => {
|
|
225433
225627
|
init_toString();
|
|
225434
225628
|
init_upperFirst();
|
|
225435
|
-
capitalize_default =
|
|
225629
|
+
capitalize_default = capitalize3;
|
|
225436
225630
|
});
|
|
225437
225631
|
|
|
225438
225632
|
// src/utils/jetbrains.ts
|
|
@@ -226856,7 +227050,7 @@ function getInstallationEnv() {
|
|
|
226856
227050
|
return;
|
|
226857
227051
|
}
|
|
226858
227052
|
function getURCodeVersion() {
|
|
226859
|
-
return "1.
|
|
227053
|
+
return "1.28.0";
|
|
226860
227054
|
}
|
|
226861
227055
|
async function getInstalledVSCodeExtensionVersion(command) {
|
|
226862
227056
|
const { stdout } = await execFileNoThrow(command, ["--list-extensions", "--show-versions"], {
|
|
@@ -229695,7 +229889,7 @@ async function setupSdkMcpClients(sdkMcpConfigs, sendMcpMessage) {
|
|
|
229695
229889
|
const client2 = new Client({
|
|
229696
229890
|
name: "ur",
|
|
229697
229891
|
title: "UR",
|
|
229698
|
-
version: "1.
|
|
229892
|
+
version: "1.28.0",
|
|
229699
229893
|
description: "UR-AGENT autonomous engineering workflow engine",
|
|
229700
229894
|
websiteUrl: PRODUCT_URL
|
|
229701
229895
|
}, {
|
|
@@ -230049,7 +230243,7 @@ var init_client5 = __esm(() => {
|
|
|
230049
230243
|
const client2 = new Client({
|
|
230050
230244
|
name: "ur",
|
|
230051
230245
|
title: "UR",
|
|
230052
|
-
version: "1.
|
|
230246
|
+
version: "1.28.0",
|
|
230053
230247
|
description: "UR-AGENT autonomous engineering workflow engine",
|
|
230054
230248
|
websiteUrl: PRODUCT_URL
|
|
230055
230249
|
}, {
|
|
@@ -239865,9 +240059,9 @@ async function assertMinVersion() {
|
|
|
239865
240059
|
if (false) {}
|
|
239866
240060
|
try {
|
|
239867
240061
|
const versionConfig = await getDynamicConfig_BLOCKS_ON_INIT("tengu_version_config", { minVersion: "0.0.0" });
|
|
239868
|
-
if (versionConfig.minVersion && lt("1.
|
|
240062
|
+
if (versionConfig.minVersion && lt("1.28.0", versionConfig.minVersion)) {
|
|
239869
240063
|
console.error(`
|
|
239870
|
-
It looks like your version of UR (${"1.
|
|
240064
|
+
It looks like your version of UR (${"1.28.0"}) needs an update.
|
|
239871
240065
|
A newer version (${versionConfig.minVersion} or higher) is required to continue.
|
|
239872
240066
|
|
|
239873
240067
|
To update, please run:
|
|
@@ -240083,7 +240277,7 @@ async function installGlobalPackage(specificVersion) {
|
|
|
240083
240277
|
logError2(new AutoUpdaterError("Another process is currently installing an update"));
|
|
240084
240278
|
logEvent("tengu_auto_updater_lock_contention", {
|
|
240085
240279
|
pid: process.pid,
|
|
240086
|
-
currentVersion: "1.
|
|
240280
|
+
currentVersion: "1.28.0"
|
|
240087
240281
|
});
|
|
240088
240282
|
return "in_progress";
|
|
240089
240283
|
}
|
|
@@ -240092,7 +240286,7 @@ async function installGlobalPackage(specificVersion) {
|
|
|
240092
240286
|
if (!env2.isRunningWithBun() && env2.isNpmFromWindowsPath()) {
|
|
240093
240287
|
logError2(new Error("Windows NPM detected in WSL environment"));
|
|
240094
240288
|
logEvent("tengu_auto_updater_windows_npm_in_wsl", {
|
|
240095
|
-
currentVersion: "1.
|
|
240289
|
+
currentVersion: "1.28.0"
|
|
240096
240290
|
});
|
|
240097
240291
|
console.error(`
|
|
240098
240292
|
Error: Windows NPM detected in WSL
|
|
@@ -240627,7 +240821,7 @@ function detectLinuxGlobPatternWarnings() {
|
|
|
240627
240821
|
}
|
|
240628
240822
|
async function getDoctorDiagnostic() {
|
|
240629
240823
|
const installationType = await getCurrentInstallationType();
|
|
240630
|
-
const version2 = typeof MACRO !== "undefined" ? "1.
|
|
240824
|
+
const version2 = typeof MACRO !== "undefined" ? "1.28.0" : "unknown";
|
|
240631
240825
|
const installationPath = await getInstallationPath();
|
|
240632
240826
|
const invokedBinary = getInvokedBinary();
|
|
240633
240827
|
const multipleInstallations = await detectMultipleInstallations();
|
|
@@ -241562,8 +241756,8 @@ async function updateLatest(channelOrVersion, forceReinstall = false) {
|
|
|
241562
241756
|
const maxVersion = await getMaxVersion();
|
|
241563
241757
|
if (maxVersion && gt(version2, maxVersion)) {
|
|
241564
241758
|
logForDebugging(`Native installer: maxVersion ${maxVersion} is set, capping update from ${version2} to ${maxVersion}`);
|
|
241565
|
-
if (gte("1.
|
|
241566
|
-
logForDebugging(`Native installer: current version ${"1.
|
|
241759
|
+
if (gte("1.28.0", maxVersion)) {
|
|
241760
|
+
logForDebugging(`Native installer: current version ${"1.28.0"} is already at or above maxVersion ${maxVersion}, skipping update`);
|
|
241567
241761
|
logEvent("tengu_native_update_skipped_max_version", {
|
|
241568
241762
|
latency_ms: Date.now() - startTime,
|
|
241569
241763
|
max_version: maxVersion,
|
|
@@ -241574,7 +241768,7 @@ async function updateLatest(channelOrVersion, forceReinstall = false) {
|
|
|
241574
241768
|
version2 = maxVersion;
|
|
241575
241769
|
}
|
|
241576
241770
|
}
|
|
241577
|
-
if (!forceReinstall && version2 === "1.
|
|
241771
|
+
if (!forceReinstall && version2 === "1.28.0" && await versionIsAvailable(version2) && await isPossibleURBinary(executablePath)) {
|
|
241578
241772
|
logForDebugging(`Found ${version2} at ${executablePath}, skipping install`);
|
|
241579
241773
|
logEvent("tengu_native_update_complete", {
|
|
241580
241774
|
latency_ms: Date.now() - startTime,
|
|
@@ -273959,7 +274153,7 @@ var exports_LSPClient = {};
|
|
|
273959
274153
|
__export(exports_LSPClient, {
|
|
273960
274154
|
createLSPClient: () => createLSPClient
|
|
273961
274155
|
});
|
|
273962
|
-
import { spawn as
|
|
274156
|
+
import { spawn as spawn8 } from "child_process";
|
|
273963
274157
|
function createLSPClient(serverName, onCrash) {
|
|
273964
274158
|
let process14;
|
|
273965
274159
|
let connection;
|
|
@@ -273984,7 +274178,7 @@ function createLSPClient(serverName, onCrash) {
|
|
|
273984
274178
|
},
|
|
273985
274179
|
async start(command, args, options2) {
|
|
273986
274180
|
try {
|
|
273987
|
-
process14 =
|
|
274181
|
+
process14 = spawn8(command, args, {
|
|
273988
274182
|
stdio: ["pipe", "pipe", "pipe"],
|
|
273989
274183
|
env: { ...subprocessEnv(), ...options2?.env },
|
|
273990
274184
|
cwd: options2?.cwd,
|
|
@@ -276448,7 +276642,7 @@ var init_powershellProvider = __esm(() => {
|
|
|
276448
276642
|
});
|
|
276449
276643
|
|
|
276450
276644
|
// src/utils/Shell.ts
|
|
276451
|
-
import { execFileSync as execFileSync2, spawn as
|
|
276645
|
+
import { execFileSync as execFileSync2, spawn as spawn9 } from "child_process";
|
|
276452
276646
|
import { constants as fsConstants4, readFileSync as readFileSync19, unlinkSync as unlinkSync2 } from "fs";
|
|
276453
276647
|
import { mkdir as mkdir19, open as open9, realpath as realpath9 } from "fs/promises";
|
|
276454
276648
|
import { isAbsolute as isAbsolute16, resolve as resolve25 } from "path";
|
|
@@ -276576,7 +276770,7 @@ async function exec3(command, abortSignal, shellType, options2) {
|
|
|
276576
276770
|
outputHandle = await open9(taskOutput.path, process.platform === "win32" ? "w" : fsConstants4.O_WRONLY | fsConstants4.O_CREAT | fsConstants4.O_APPEND | O_NOFOLLOW);
|
|
276577
276771
|
}
|
|
276578
276772
|
try {
|
|
276579
|
-
const childProcess =
|
|
276773
|
+
const childProcess = spawn9(spawnBinary, shellArgs, {
|
|
276580
276774
|
env: {
|
|
276581
276775
|
...subprocessEnv(),
|
|
276582
276776
|
SHELL: shellType === "bash" ? binShell : undefined,
|
|
@@ -338499,7 +338693,7 @@ function Feedback({
|
|
|
338499
338693
|
platform: env2.platform,
|
|
338500
338694
|
gitRepo: envInfo.isGit,
|
|
338501
338695
|
terminal: env2.terminal,
|
|
338502
|
-
version: "1.
|
|
338696
|
+
version: "1.28.0",
|
|
338503
338697
|
transcript: normalizeMessagesForAPI(messages),
|
|
338504
338698
|
errors: sanitizedErrors,
|
|
338505
338699
|
lastApiRequest: getLastAPIRequest(),
|
|
@@ -338691,7 +338885,7 @@ function Feedback({
|
|
|
338691
338885
|
", ",
|
|
338692
338886
|
env2.terminal,
|
|
338693
338887
|
", v",
|
|
338694
|
-
"1.
|
|
338888
|
+
"1.28.0"
|
|
338695
338889
|
]
|
|
338696
338890
|
}, undefined, true, undefined, this)
|
|
338697
338891
|
]
|
|
@@ -338797,7 +338991,7 @@ ${sanitizedDescription}
|
|
|
338797
338991
|
` + `**Environment Info**
|
|
338798
338992
|
` + `- Platform: ${env2.platform}
|
|
338799
338993
|
` + `- Terminal: ${env2.terminal}
|
|
338800
|
-
` + `- Version: ${"1.
|
|
338994
|
+
` + `- Version: ${"1.28.0"}
|
|
338801
338995
|
` + `- Feedback ID: ${feedbackId}
|
|
338802
338996
|
` + `
|
|
338803
338997
|
**Errors**
|
|
@@ -341908,7 +342102,7 @@ function buildPrimarySection() {
|
|
|
341908
342102
|
}, undefined, false, undefined, this);
|
|
341909
342103
|
return [{
|
|
341910
342104
|
label: "Version",
|
|
341911
|
-
value: "1.
|
|
342105
|
+
value: "1.28.0"
|
|
341912
342106
|
}, {
|
|
341913
342107
|
label: "Session name",
|
|
341914
342108
|
value: nameValue
|
|
@@ -345208,7 +345402,7 @@ function Config({
|
|
|
345208
345402
|
}
|
|
345209
345403
|
}, undefined, false, undefined, this)
|
|
345210
345404
|
}, undefined, false, undefined, this) : showSubmenu === "ChannelDowngrade" ? /* @__PURE__ */ jsx_dev_runtime177.jsxDEV(ChannelDowngradeDialog, {
|
|
345211
|
-
currentVersion: "1.
|
|
345405
|
+
currentVersion: "1.28.0",
|
|
345212
345406
|
onChoice: (choice) => {
|
|
345213
345407
|
setShowSubmenu(null);
|
|
345214
345408
|
setTabsHidden(false);
|
|
@@ -345220,7 +345414,7 @@ function Config({
|
|
|
345220
345414
|
autoUpdatesChannel: "stable"
|
|
345221
345415
|
};
|
|
345222
345416
|
if (choice === "stay") {
|
|
345223
|
-
newSettings.minimumVersion = "1.
|
|
345417
|
+
newSettings.minimumVersion = "1.28.0";
|
|
345224
345418
|
}
|
|
345225
345419
|
updateSettingsForSource("userSettings", newSettings);
|
|
345226
345420
|
setSettingsData((prev_27) => ({
|
|
@@ -352123,7 +352317,7 @@ var init_MemoryUpdateNotification = __esm(() => {
|
|
|
352123
352317
|
|
|
352124
352318
|
// src/utils/editor.ts
|
|
352125
352319
|
import {
|
|
352126
|
-
spawn as
|
|
352320
|
+
spawn as spawn10,
|
|
352127
352321
|
spawnSync as spawnSync3
|
|
352128
352322
|
} from "child_process";
|
|
352129
352323
|
import { basename as basename37 } from "path";
|
|
@@ -352157,9 +352351,9 @@ function openFileInExternalEditor(filePath, line) {
|
|
|
352157
352351
|
let child;
|
|
352158
352352
|
if (process.platform === "win32") {
|
|
352159
352353
|
const gotoStr = gotoArgv.map((a2) => `"${a2}"`).join(" ");
|
|
352160
|
-
child =
|
|
352354
|
+
child = spawn10(`${editor} ${gotoStr}`, { ...detachedOpts, shell: true });
|
|
352161
352355
|
} else {
|
|
352162
|
-
child =
|
|
352356
|
+
child = spawn10(base2, [...editorArgs, ...gotoArgv], detachedOpts);
|
|
352163
352357
|
}
|
|
352164
352358
|
child.on("error", (e) => logForDebugging(`editor spawn failed: ${e}`, { level: "error" }));
|
|
352165
352359
|
child.unref();
|
|
@@ -353290,7 +353484,7 @@ function HelpV2(t0) {
|
|
|
353290
353484
|
let t6;
|
|
353291
353485
|
if ($3[31] !== tabs) {
|
|
353292
353486
|
t6 = /* @__PURE__ */ jsx_dev_runtime204.jsxDEV(Tabs, {
|
|
353293
|
-
title: `UR v${"1.
|
|
353487
|
+
title: `UR v${"1.28.0"}`,
|
|
353294
353488
|
color: "professionalBlue",
|
|
353295
353489
|
defaultTab: "general",
|
|
353296
353490
|
children: tabs
|
|
@@ -373392,7 +373586,7 @@ function getAllReleaseNotes(changelogContent = getStoredChangelogFromMemory()) {
|
|
|
373392
373586
|
return [];
|
|
373393
373587
|
}
|
|
373394
373588
|
}
|
|
373395
|
-
async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.
|
|
373589
|
+
async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.28.0") {
|
|
373396
373590
|
if (process.env.USER_TYPE === "ant") {
|
|
373397
373591
|
const changelog = "";
|
|
373398
373592
|
if (changelog) {
|
|
@@ -373419,7 +373613,7 @@ async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.27.6")
|
|
|
373419
373613
|
releaseNotes
|
|
373420
373614
|
};
|
|
373421
373615
|
}
|
|
373422
|
-
function checkForReleaseNotesSync(lastSeenVersion, currentVersion = "1.
|
|
373616
|
+
function checkForReleaseNotesSync(lastSeenVersion, currentVersion = "1.28.0") {
|
|
373423
373617
|
if (process.env.USER_TYPE === "ant") {
|
|
373424
373618
|
const changelog = "";
|
|
373425
373619
|
if (changelog) {
|
|
@@ -374589,7 +374783,7 @@ function getRecentActivitySync() {
|
|
|
374589
374783
|
return cachedActivity;
|
|
374590
374784
|
}
|
|
374591
374785
|
function getLogoDisplayData() {
|
|
374592
|
-
const version2 = process.env.DEMO_VERSION ?? "1.
|
|
374786
|
+
const version2 = process.env.DEMO_VERSION ?? "1.28.0";
|
|
374593
374787
|
const serverUrl = getDirectConnectServerUrl();
|
|
374594
374788
|
const displayPath = process.env.DEMO_VERSION ? "/code/ur" : getDisplayPath(getCwd2());
|
|
374595
374789
|
const cwd2 = serverUrl ? `${displayPath} in ${serverUrl.replace(/^https?:\/\//, "")}` : displayPath;
|
|
@@ -375378,7 +375572,7 @@ function LogoV2() {
|
|
|
375378
375572
|
if ($3[2] === Symbol.for("react.memo_cache_sentinel")) {
|
|
375379
375573
|
t2 = () => {
|
|
375380
375574
|
const currentConfig = getGlobalConfig();
|
|
375381
|
-
if (currentConfig.lastReleaseNotesSeen === "1.
|
|
375575
|
+
if (currentConfig.lastReleaseNotesSeen === "1.28.0") {
|
|
375382
375576
|
return;
|
|
375383
375577
|
}
|
|
375384
375578
|
saveGlobalConfig(_temp326);
|
|
@@ -376063,12 +376257,12 @@ function LogoV2() {
|
|
|
376063
376257
|
return t41;
|
|
376064
376258
|
}
|
|
376065
376259
|
function _temp326(current) {
|
|
376066
|
-
if (current.lastReleaseNotesSeen === "1.
|
|
376260
|
+
if (current.lastReleaseNotesSeen === "1.28.0") {
|
|
376067
376261
|
return current;
|
|
376068
376262
|
}
|
|
376069
376263
|
return {
|
|
376070
376264
|
...current,
|
|
376071
|
-
lastReleaseNotesSeen: "1.
|
|
376265
|
+
lastReleaseNotesSeen: "1.28.0"
|
|
376072
376266
|
};
|
|
376073
376267
|
}
|
|
376074
376268
|
function _temp243(s_0) {
|
|
@@ -383539,11 +383733,11 @@ async function pollForApprovedExitPlanMode(sessionId, timeoutMs, onPhaseChange,
|
|
|
383539
383733
|
}
|
|
383540
383734
|
throw new UltraplanPollError(scanner.everSeenPending ? `no approval after ${timeoutMs / 1000}s` : `ExitPlanMode never reached after ${timeoutMs / 1000}s (the remote container failed to start, or session ID mismatch?)`, scanner.everSeenPending ? "timeout_pending" : "timeout_no_plan", scanner.rejectCount);
|
|
383541
383735
|
}
|
|
383542
|
-
function
|
|
383736
|
+
function contentToText4(content) {
|
|
383543
383737
|
return typeof content === "string" ? content : Array.isArray(content) ? content.map((b) => ("text" in b) ? b.text : "").join("") : "";
|
|
383544
383738
|
}
|
|
383545
383739
|
function extractTeleportPlan(content) {
|
|
383546
|
-
const text =
|
|
383740
|
+
const text = contentToText4(content);
|
|
383547
383741
|
const marker = `${ULTRAPLAN_TELEPORT_SENTINEL}
|
|
383548
383742
|
`;
|
|
383549
383743
|
const idx = text.indexOf(marker);
|
|
@@ -383552,7 +383746,7 @@ function extractTeleportPlan(content) {
|
|
|
383552
383746
|
return text.slice(idx + marker.length).trimEnd();
|
|
383553
383747
|
}
|
|
383554
383748
|
function extractApprovedPlan(content) {
|
|
383555
|
-
const text =
|
|
383749
|
+
const text = contentToText4(content);
|
|
383556
383750
|
const markers = [
|
|
383557
383751
|
`## Approved Plan (edited by user):
|
|
383558
383752
|
`,
|
|
@@ -389593,9 +389787,9 @@ var init_reports = __esm(() => {
|
|
|
389593
389787
|
});
|
|
389594
389788
|
|
|
389595
389789
|
// src/security/exec.ts
|
|
389596
|
-
import { spawn as
|
|
389790
|
+
import { spawn as spawn11 } from "child_process";
|
|
389597
389791
|
var MAX = 400000, spawnExec = (bin, args, opts = {}) => new Promise((resolve43) => {
|
|
389598
|
-
const child =
|
|
389792
|
+
const child = spawn11(bin, args, { cwd: opts.cwd });
|
|
389599
389793
|
let stdout = "";
|
|
389600
389794
|
let stderr = "";
|
|
389601
389795
|
child.stdout.on("data", (d) => {
|
|
@@ -393057,7 +393251,7 @@ function buildToolUseContext(tools, readFileStateCache) {
|
|
|
393057
393251
|
async function handleInitialize() {
|
|
393058
393252
|
return {
|
|
393059
393253
|
name: "ur-agent",
|
|
393060
|
-
version: "1.
|
|
393254
|
+
version: "1.28.0",
|
|
393061
393255
|
protocolVersion: "0.1.0"
|
|
393062
393256
|
};
|
|
393063
393257
|
}
|
|
@@ -406518,7 +406712,7 @@ var init_code_index2 = __esm(() => {
|
|
|
406518
406712
|
|
|
406519
406713
|
// node_modules/typescript/lib/typescript.js
|
|
406520
406714
|
var require_typescript2 = __commonJS((exports, module) => {
|
|
406521
|
-
var __dirname = "/
|
|
406715
|
+
var __dirname = "/sessions/confident-pensive-edison/mnt/UR-1.19.0/node_modules/typescript/lib", __filename = "/sessions/confident-pensive-edison/mnt/UR-1.19.0/node_modules/typescript/lib/typescript.js";
|
|
406522
406716
|
/*! *****************************************************************************
|
|
406523
406717
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
406524
406718
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
@@ -592052,7 +592246,7 @@ async function captureMemoryDiagnostics(trigger2, dumpNumber = 0) {
|
|
|
592052
592246
|
smapsRollup,
|
|
592053
592247
|
platform: process.platform,
|
|
592054
592248
|
nodeVersion: process.version,
|
|
592055
|
-
ccVersion: "1.
|
|
592249
|
+
ccVersion: "1.28.0"
|
|
592056
592250
|
};
|
|
592057
592251
|
}
|
|
592058
592252
|
async function performHeapDump(trigger2 = "manual", dumpNumber = 0) {
|
|
@@ -592638,7 +592832,7 @@ var init_bridge_kick = __esm(() => {
|
|
|
592638
592832
|
var call136 = async () => {
|
|
592639
592833
|
return {
|
|
592640
592834
|
type: "text",
|
|
592641
|
-
value: "1.
|
|
592835
|
+
value: "1.28.0"
|
|
592642
592836
|
};
|
|
592643
592837
|
}, version2, version_default;
|
|
592644
592838
|
var init_version = __esm(() => {
|
|
@@ -596149,23 +596343,6 @@ function SetModelAndClose({
|
|
|
596149
596343
|
}
|
|
596150
596344
|
setModel(model);
|
|
596151
596345
|
return;
|
|
596152
|
-
try {
|
|
596153
|
-
const {
|
|
596154
|
-
valid,
|
|
596155
|
-
error: error_0
|
|
596156
|
-
} = await validateModel(model);
|
|
596157
|
-
if (valid) {
|
|
596158
|
-
setModel(model);
|
|
596159
|
-
} else {
|
|
596160
|
-
onDone(error_0 || `Model '${model}' not found`, {
|
|
596161
|
-
display: "system"
|
|
596162
|
-
});
|
|
596163
|
-
}
|
|
596164
|
-
} catch (error40) {
|
|
596165
|
-
onDone(`Failed to validate model: ${error40.message}`, {
|
|
596166
|
-
display: "system"
|
|
596167
|
-
});
|
|
596168
|
-
}
|
|
596169
596346
|
}
|
|
596170
596347
|
function setModel(modelValue) {
|
|
596171
596348
|
setAppState((prev) => ({
|
|
@@ -596279,7 +596456,6 @@ var init_model2 = __esm(() => {
|
|
|
596279
596456
|
init_check1mAccess();
|
|
596280
596457
|
init_model();
|
|
596281
596458
|
init_modelAllowlist();
|
|
596282
|
-
init_validateModel();
|
|
596283
596459
|
init_providerRegistry();
|
|
596284
596460
|
init_settings2();
|
|
596285
596461
|
import_compiler_runtime263 = __toESM(require_compiler_runtime(), 1);
|
|
@@ -602541,7 +602717,7 @@ function generateHtmlReport(data, insights) {
|
|
|
602541
602717
|
</html>`;
|
|
602542
602718
|
}
|
|
602543
602719
|
function buildExportData(data, insights, facets, remoteStats) {
|
|
602544
|
-
const version3 = typeof MACRO !== "undefined" ? "1.
|
|
602720
|
+
const version3 = typeof MACRO !== "undefined" ? "1.28.0" : "unknown";
|
|
602545
602721
|
const remote_hosts_collected = remoteStats?.hosts.filter((h2) => h2.sessionCount > 0).map((h2) => h2.name);
|
|
602546
602722
|
const facets_summary = {
|
|
602547
602723
|
total: facets.size,
|
|
@@ -606819,7 +606995,7 @@ var init_sessionStorage = __esm(() => {
|
|
|
606819
606995
|
init_settings2();
|
|
606820
606996
|
init_slowOperations();
|
|
606821
606997
|
init_uuid();
|
|
606822
|
-
VERSION5 = typeof MACRO !== "undefined" ? "1.
|
|
606998
|
+
VERSION5 = typeof MACRO !== "undefined" ? "1.28.0" : "unknown";
|
|
606823
606999
|
MAX_TOMBSTONE_REWRITE_BYTES = 50 * 1024 * 1024;
|
|
606824
607000
|
SKIP_FIRST_PROMPT_PATTERN = /^(?:\s*<[a-z][\w-]*[\s>]|\[Request interrupted by user[^\]]*\])/;
|
|
606825
607001
|
EPHEMERAL_PROGRESS_TYPES = new Set([
|
|
@@ -608024,7 +608200,7 @@ var init_filesystem = __esm(() => {
|
|
|
608024
608200
|
});
|
|
608025
608201
|
getBundledSkillsRoot = memoize_default(function getBundledSkillsRoot2() {
|
|
608026
608202
|
const nonce = randomBytes18(16).toString("hex");
|
|
608027
|
-
return join200(getURTempDir(), "bundled-skills", "1.
|
|
608203
|
+
return join200(getURTempDir(), "bundled-skills", "1.28.0", nonce);
|
|
608028
608204
|
});
|
|
608029
608205
|
getResolvedWorkingDirPaths = memoize_default(getPathsForPermissionCheck);
|
|
608030
608206
|
});
|
|
@@ -609462,7 +609638,7 @@ __export(exports_hooks2, {
|
|
|
609462
609638
|
createBaseHookInput: () => createBaseHookInput
|
|
609463
609639
|
});
|
|
609464
609640
|
import { basename as basename45 } from "path";
|
|
609465
|
-
import { spawn as
|
|
609641
|
+
import { spawn as spawn12 } from "child_process";
|
|
609466
609642
|
import { randomUUID as randomUUID39 } from "crypto";
|
|
609467
609643
|
function getSessionEndHookTimeoutMs() {
|
|
609468
609644
|
const raw = process.env.UR_CODE_SESSIONEND_HOOKS_TIMEOUT_MS;
|
|
@@ -609875,14 +610051,14 @@ async function execCommandHook(hook, hookEvent, hookName, jsonInput, signal, hoo
|
|
|
609875
610051
|
if (!pwshPath) {
|
|
609876
610052
|
throw new Error(`Hook "${hook.command}" has shell: 'powershell' but no PowerShell ` + `executable (pwsh or powershell) was found on PATH. Install ` + `PowerShell, or remove "shell": "powershell" to use bash.`);
|
|
609877
610053
|
}
|
|
609878
|
-
child =
|
|
610054
|
+
child = spawn12(pwshPath, buildPowerShellArgs(finalCommand), {
|
|
609879
610055
|
env: envVars,
|
|
609880
610056
|
cwd: safeCwd,
|
|
609881
610057
|
windowsHide: true
|
|
609882
610058
|
});
|
|
609883
610059
|
} else {
|
|
609884
610060
|
const shell = isWindows2 ? findGitBashPath() : true;
|
|
609885
|
-
child =
|
|
610061
|
+
child = spawn12(finalCommand, [], {
|
|
609886
610062
|
env: envVars,
|
|
609887
610063
|
cwd: safeCwd,
|
|
609888
610064
|
shell,
|
|
@@ -614316,7 +614492,7 @@ function computeFingerprint(messageText2, version3) {
|
|
|
614316
614492
|
}
|
|
614317
614493
|
function computeFingerprintFromMessages(messages) {
|
|
614318
614494
|
const firstMessageText = extractFirstMessageText(messages);
|
|
614319
|
-
return computeFingerprint(firstMessageText, "1.
|
|
614495
|
+
return computeFingerprint(firstMessageText, "1.28.0");
|
|
614320
614496
|
}
|
|
614321
614497
|
var FINGERPRINT_SALT = "59cf53e54c78";
|
|
614322
614498
|
var init_fingerprint = () => {};
|
|
@@ -616183,7 +616359,7 @@ async function sideQuery(opts) {
|
|
|
616183
616359
|
betas.push(STRUCTURED_OUTPUTS_BETA_HEADER);
|
|
616184
616360
|
}
|
|
616185
616361
|
const messageText2 = extractFirstUserMessageText(messages);
|
|
616186
|
-
const fingerprint = computeFingerprint(messageText2, "1.
|
|
616362
|
+
const fingerprint = computeFingerprint(messageText2, "1.28.0");
|
|
616187
616363
|
const attributionHeader = getAttributionHeader(fingerprint);
|
|
616188
616364
|
const systemBlocks = [
|
|
616189
616365
|
attributionHeader ? { type: "text", text: attributionHeader } : null,
|
|
@@ -620428,7 +620604,7 @@ var init_IdleReturnDialog = __esm(() => {
|
|
|
620428
620604
|
});
|
|
620429
620605
|
|
|
620430
620606
|
// src/services/preventSleep.ts
|
|
620431
|
-
import { spawn as
|
|
620607
|
+
import { spawn as spawn13 } from "child_process";
|
|
620432
620608
|
function startPreventSleep() {
|
|
620433
620609
|
refCount++;
|
|
620434
620610
|
if (refCount === 1) {
|
|
@@ -620486,7 +620662,7 @@ function spawnCaffeinate() {
|
|
|
620486
620662
|
});
|
|
620487
620663
|
}
|
|
620488
620664
|
try {
|
|
620489
|
-
caffeinateProcess =
|
|
620665
|
+
caffeinateProcess = spawn13("caffeinate", ["-i", "-t", String(CAFFEINATE_TIMEOUT_SECONDS)], {
|
|
620490
620666
|
stdio: "ignore"
|
|
620491
620667
|
});
|
|
620492
620668
|
caffeinateProcess.unref();
|
|
@@ -620920,7 +621096,7 @@ function buildSystemInitMessage(inputs) {
|
|
|
620920
621096
|
slash_commands: inputs.commands.filter((c4) => c4.userInvocable !== false).map((c4) => c4.name),
|
|
620921
621097
|
apiKeySource: getURHQApiKeyWithSource().source,
|
|
620922
621098
|
betas: getSdkBetas(),
|
|
620923
|
-
ur_version: "1.
|
|
621099
|
+
ur_version: "1.28.0",
|
|
620924
621100
|
output_style: outputStyle2,
|
|
620925
621101
|
agents: inputs.agents.map((agent) => agent.agentType),
|
|
620926
621102
|
skills: inputs.skills.filter((s) => s.userInvocable !== false).map((skill2) => skill2.name),
|
|
@@ -635548,7 +635724,7 @@ var init_useVoiceEnabled = __esm(() => {
|
|
|
635548
635724
|
function getSemverPart(version3) {
|
|
635549
635725
|
return `${import_semver13.major(version3, { loose: true })}.${import_semver13.minor(version3, { loose: true })}.${import_semver13.patch(version3, { loose: true })}`;
|
|
635550
635726
|
}
|
|
635551
|
-
function useUpdateNotification(updatedVersion, initialVersion = "1.
|
|
635727
|
+
function useUpdateNotification(updatedVersion, initialVersion = "1.28.0") {
|
|
635552
635728
|
const [lastNotifiedSemver, setLastNotifiedSemver] = import_react226.useState(() => getSemverPart(initialVersion));
|
|
635553
635729
|
if (!updatedVersion) {
|
|
635554
635730
|
return null;
|
|
@@ -635597,7 +635773,7 @@ function AutoUpdater({
|
|
|
635597
635773
|
return;
|
|
635598
635774
|
}
|
|
635599
635775
|
if (false) {}
|
|
635600
|
-
const currentVersion = "1.
|
|
635776
|
+
const currentVersion = "1.28.0";
|
|
635601
635777
|
const channel = getInitialSettings()?.autoUpdatesChannel ?? "latest";
|
|
635602
635778
|
let latestVersion = await getLatestVersion(channel);
|
|
635603
635779
|
const isDisabled = isAutoUpdaterDisabled();
|
|
@@ -635826,12 +636002,12 @@ function NativeAutoUpdater({
|
|
|
635826
636002
|
logEvent("tengu_native_auto_updater_start", {});
|
|
635827
636003
|
try {
|
|
635828
636004
|
const maxVersion = await getMaxVersion();
|
|
635829
|
-
if (maxVersion && gt("1.
|
|
636005
|
+
if (maxVersion && gt("1.28.0", maxVersion)) {
|
|
635830
636006
|
const msg = await getMaxVersionMessage();
|
|
635831
636007
|
setMaxVersionIssue(msg ?? "affects your version");
|
|
635832
636008
|
}
|
|
635833
636009
|
const result = await installLatest(channel);
|
|
635834
|
-
const currentVersion = "1.
|
|
636010
|
+
const currentVersion = "1.28.0";
|
|
635835
636011
|
const latencyMs = Date.now() - startTime;
|
|
635836
636012
|
if (result.lockFailed) {
|
|
635837
636013
|
logEvent("tengu_native_auto_updater_lock_contention", {
|
|
@@ -635968,17 +636144,17 @@ function PackageManagerAutoUpdater(t0) {
|
|
|
635968
636144
|
const maxVersion = await getMaxVersion();
|
|
635969
636145
|
if (maxVersion && latest && gt(latest, maxVersion)) {
|
|
635970
636146
|
logForDebugging(`PackageManagerAutoUpdater: maxVersion ${maxVersion} is set, capping update from ${latest} to ${maxVersion}`);
|
|
635971
|
-
if (gte("1.
|
|
635972
|
-
logForDebugging(`PackageManagerAutoUpdater: current version ${"1.
|
|
636147
|
+
if (gte("1.28.0", maxVersion)) {
|
|
636148
|
+
logForDebugging(`PackageManagerAutoUpdater: current version ${"1.28.0"} is already at or above maxVersion ${maxVersion}, skipping update`);
|
|
635973
636149
|
setUpdateAvailable(false);
|
|
635974
636150
|
return;
|
|
635975
636151
|
}
|
|
635976
636152
|
latest = maxVersion;
|
|
635977
636153
|
}
|
|
635978
|
-
const hasUpdate = latest && !gte("1.
|
|
636154
|
+
const hasUpdate = latest && !gte("1.28.0", latest) && !shouldSkipVersion(latest);
|
|
635979
636155
|
setUpdateAvailable(!!hasUpdate);
|
|
635980
636156
|
if (hasUpdate) {
|
|
635981
|
-
logForDebugging(`PackageManagerAutoUpdater: Update available ${"1.
|
|
636157
|
+
logForDebugging(`PackageManagerAutoUpdater: Update available ${"1.28.0"} -> ${latest}`);
|
|
635982
636158
|
}
|
|
635983
636159
|
};
|
|
635984
636160
|
$3[0] = t1;
|
|
@@ -636012,7 +636188,7 @@ function PackageManagerAutoUpdater(t0) {
|
|
|
636012
636188
|
wrap: "truncate",
|
|
636013
636189
|
children: [
|
|
636014
636190
|
"currentVersion: ",
|
|
636015
|
-
"1.
|
|
636191
|
+
"1.28.0"
|
|
636016
636192
|
]
|
|
636017
636193
|
}, undefined, true, undefined, this);
|
|
636018
636194
|
$3[3] = verbose;
|
|
@@ -648458,7 +648634,7 @@ function buildStatusLineCommandInput(permissionMode, exceeds200kTokens, settings
|
|
|
648458
648634
|
project_dir: getOriginalCwd(),
|
|
648459
648635
|
added_dirs: addedDirs
|
|
648460
648636
|
},
|
|
648461
|
-
version: "1.
|
|
648637
|
+
version: "1.28.0",
|
|
648462
648638
|
output_style: {
|
|
648463
648639
|
name: outputStyleName
|
|
648464
648640
|
},
|
|
@@ -648533,7 +648709,7 @@ function StatusLineInner({
|
|
|
648533
648709
|
const taskValues = Object.values(tasks2);
|
|
648534
648710
|
const taskRunningCount = taskValues.filter((task2) => task2.status === "running" || task2.status === "pending").length;
|
|
648535
648711
|
const defaultStatusLineText = buildDefaultStatusBar({
|
|
648536
|
-
version: "1.
|
|
648712
|
+
version: "1.28.0",
|
|
648537
648713
|
providerLabel: providerRuntime.providerLabel,
|
|
648538
648714
|
authMode: providerRuntime.authLabel,
|
|
648539
648715
|
model: providerRuntime.model ?? renderModelName(mainLoopModel),
|
|
@@ -660019,7 +660195,7 @@ async function submitTranscriptShare(messages, trigger2, appearanceId) {
|
|
|
660019
660195
|
} catch {}
|
|
660020
660196
|
const data = {
|
|
660021
660197
|
trigger: trigger2,
|
|
660022
|
-
version: "1.
|
|
660198
|
+
version: "1.28.0",
|
|
660023
660199
|
platform: process.platform,
|
|
660024
660200
|
transcript,
|
|
660025
660201
|
subagentTranscripts: Object.keys(subagentTranscripts).length > 0 ? subagentTranscripts : undefined,
|
|
@@ -671903,7 +672079,7 @@ function WelcomeV2() {
|
|
|
671903
672079
|
dimColor: true,
|
|
671904
672080
|
children: [
|
|
671905
672081
|
"v",
|
|
671906
|
-
"1.
|
|
672082
|
+
"1.28.0"
|
|
671907
672083
|
]
|
|
671908
672084
|
}, undefined, true, undefined, this)
|
|
671909
672085
|
]
|
|
@@ -673163,7 +673339,7 @@ function completeOnboarding() {
|
|
|
673163
673339
|
saveGlobalConfig((current) => ({
|
|
673164
673340
|
...current,
|
|
673165
673341
|
hasCompletedOnboarding: true,
|
|
673166
|
-
lastOnboardingVersion: "1.
|
|
673342
|
+
lastOnboardingVersion: "1.28.0"
|
|
673167
673343
|
}));
|
|
673168
673344
|
}
|
|
673169
673345
|
function showDialog(root2, renderer) {
|
|
@@ -678267,7 +678443,7 @@ function appendToLog(path24, message) {
|
|
|
678267
678443
|
cwd: getFsImplementation().cwd(),
|
|
678268
678444
|
userType: process.env.USER_TYPE,
|
|
678269
678445
|
sessionId: getSessionId(),
|
|
678270
|
-
version: "1.
|
|
678446
|
+
version: "1.28.0"
|
|
678271
678447
|
};
|
|
678272
678448
|
getLogWriter(path24).write(messageWithTimestamp);
|
|
678273
678449
|
}
|
|
@@ -682361,8 +682537,8 @@ async function getEnvLessBridgeConfig() {
|
|
|
682361
682537
|
}
|
|
682362
682538
|
async function checkEnvLessBridgeMinVersion() {
|
|
682363
682539
|
const cfg = await getEnvLessBridgeConfig();
|
|
682364
|
-
if (cfg.min_version && lt("1.
|
|
682365
|
-
return `Your version of UR (${"1.
|
|
682540
|
+
if (cfg.min_version && lt("1.28.0", cfg.min_version)) {
|
|
682541
|
+
return `Your version of UR (${"1.28.0"}) is too old for Remote Control.
|
|
682366
682542
|
Version ${cfg.min_version} or higher is required. Run \`ur update\` to update.`;
|
|
682367
682543
|
}
|
|
682368
682544
|
return null;
|
|
@@ -682836,7 +683012,7 @@ async function initBridgeCore(params) {
|
|
|
682836
683012
|
const rawApi = createBridgeApiClient({
|
|
682837
683013
|
baseUrl,
|
|
682838
683014
|
getAccessToken,
|
|
682839
|
-
runnerVersion: "1.
|
|
683015
|
+
runnerVersion: "1.28.0",
|
|
682840
683016
|
onDebug: logForDebugging,
|
|
682841
683017
|
onAuth401,
|
|
682842
683018
|
getTrustedDeviceToken
|
|
@@ -688518,7 +688694,7 @@ async function startMCPServer(cwd3, debug2, verbose) {
|
|
|
688518
688694
|
setCwd(cwd3);
|
|
688519
688695
|
const server2 = new Server({
|
|
688520
688696
|
name: "ur/tengu",
|
|
688521
|
-
version: "1.
|
|
688697
|
+
version: "1.28.0"
|
|
688522
688698
|
}, {
|
|
688523
688699
|
capabilities: {
|
|
688524
688700
|
tools: {}
|
|
@@ -690331,7 +690507,7 @@ async function update() {
|
|
|
690331
690507
|
logEvent("tengu_update_check", {});
|
|
690332
690508
|
const diagnostic = await getDoctorDiagnostic();
|
|
690333
690509
|
const result = await checkUpgradeStatus({
|
|
690334
|
-
currentVersion: "1.
|
|
690510
|
+
currentVersion: "1.28.0",
|
|
690335
690511
|
packageName: UR_AGENT_PACKAGE_NAME,
|
|
690336
690512
|
installationType: diagnostic.installationType,
|
|
690337
690513
|
latestVersion: () => getLatestNpmPackageVersion(UR_AGENT_PACKAGE_NAME)
|
|
@@ -691577,7 +691753,7 @@ ${customInstructions}` : customInstructions;
|
|
|
691577
691753
|
}
|
|
691578
691754
|
}
|
|
691579
691755
|
logForDiagnosticsNoPII("info", "started", {
|
|
691580
|
-
version: "1.
|
|
691756
|
+
version: "1.28.0",
|
|
691581
691757
|
is_native_binary: isInBundledMode()
|
|
691582
691758
|
});
|
|
691583
691759
|
registerCleanup(async () => {
|
|
@@ -692361,7 +692537,7 @@ Usage: ur --remote "your task description"`, () => gracefulShutdown(1));
|
|
|
692361
692537
|
pendingHookMessages
|
|
692362
692538
|
}, renderAndRun);
|
|
692363
692539
|
}
|
|
692364
|
-
}).version("1.
|
|
692540
|
+
}).version("1.28.0 (UR-AGENT)", "-v, --version", "Output the version number");
|
|
692365
692541
|
program2.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
|
|
692366
692542
|
program2.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
|
|
692367
692543
|
if (canUserConfigureAdvisor()) {
|
|
@@ -693239,7 +693415,7 @@ if (false) {}
|
|
|
693239
693415
|
async function main2() {
|
|
693240
693416
|
const args = process.argv.slice(2);
|
|
693241
693417
|
if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
|
|
693242
|
-
console.log(`${"1.
|
|
693418
|
+
console.log(`${"1.28.0"} (UR-AGENT)`);
|
|
693243
693419
|
return;
|
|
693244
693420
|
}
|
|
693245
693421
|
if (args[0] === "a2a" && args[1] === "serve" && !args.includes("--help") && !args.includes("-h")) {
|