opencommit 3.2.11 → 3.2.12
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/README.md +22 -0
- package/out/cli.cjs +646 -123
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -201,6 +201,28 @@ or for as a cheaper option:
|
|
|
201
201
|
oco config set OCO_MODEL=gpt-3.5-turbo
|
|
202
202
|
```
|
|
203
203
|
|
|
204
|
+
### Model Management
|
|
205
|
+
|
|
206
|
+
OpenCommit automatically fetches available models from your provider when you run `oco setup`. Models are cached for 7 days to reduce API calls.
|
|
207
|
+
|
|
208
|
+
To see available models for your current provider:
|
|
209
|
+
|
|
210
|
+
```sh
|
|
211
|
+
oco models
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
To refresh the model list (e.g., after new models are released):
|
|
215
|
+
|
|
216
|
+
```sh
|
|
217
|
+
oco models --refresh
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
To see models for a specific provider:
|
|
221
|
+
|
|
222
|
+
```sh
|
|
223
|
+
oco models --provider anthropic
|
|
224
|
+
```
|
|
225
|
+
|
|
204
226
|
### Switch to other LLM providers with a custom URL
|
|
205
227
|
|
|
206
228
|
By default OpenCommit uses [OpenAI](https://openai.com).
|
package/out/cli.cjs
CHANGED
|
@@ -48509,7 +48509,7 @@ function G3(t2, e3) {
|
|
|
48509
48509
|
// package.json
|
|
48510
48510
|
var package_default = {
|
|
48511
48511
|
name: "opencommit",
|
|
48512
|
-
version: "3.2.
|
|
48512
|
+
version: "3.2.12",
|
|
48513
48513
|
description: "Auto-generate impressive commits in 1 second. Killing lame commits with AI \u{1F92F}\u{1F52B}",
|
|
48514
48514
|
keywords: [
|
|
48515
48515
|
"git",
|
|
@@ -53911,9 +53911,6 @@ var { AnthropicError: AnthropicError2, APIError: APIError2, APIConnectionError:
|
|
|
53911
53911
|
})(Anthropic || (Anthropic = {}));
|
|
53912
53912
|
var sdk_default = Anthropic;
|
|
53913
53913
|
|
|
53914
|
-
// src/engine/anthropic.ts
|
|
53915
|
-
init_dist2();
|
|
53916
|
-
|
|
53917
53914
|
// node_modules/axios/lib/helpers/bind.js
|
|
53918
53915
|
function bind(fn, thisArg) {
|
|
53919
53916
|
return function wrap() {
|
|
@@ -57224,6 +57221,51 @@ var {
|
|
|
57224
57221
|
} = axios_default;
|
|
57225
57222
|
|
|
57226
57223
|
// src/utils/errors.ts
|
|
57224
|
+
var PROVIDER_BILLING_URLS = {
|
|
57225
|
+
["anthropic" /* ANTHROPIC */]: "https://console.anthropic.com/settings/billing",
|
|
57226
|
+
["openai" /* OPENAI */]: "https://platform.openai.com/settings/organization/billing",
|
|
57227
|
+
["gemini" /* GEMINI */]: "https://aistudio.google.com/app/plan",
|
|
57228
|
+
["groq" /* GROQ */]: "https://console.groq.com/settings/billing",
|
|
57229
|
+
["mistral" /* MISTRAL */]: "https://console.mistral.ai/billing/",
|
|
57230
|
+
["deepseek" /* DEEPSEEK */]: "https://platform.deepseek.com/usage",
|
|
57231
|
+
["openrouter" /* OPENROUTER */]: "https://openrouter.ai/credits",
|
|
57232
|
+
["aimlapi" /* AIMLAPI */]: "https://aimlapi.com/app/billing",
|
|
57233
|
+
["azure" /* AZURE */]: "https://portal.azure.com/#view/Microsoft_Azure_CostManagement",
|
|
57234
|
+
["ollama" /* OLLAMA */]: null,
|
|
57235
|
+
["mlx" /* MLX */]: null,
|
|
57236
|
+
["flowise" /* FLOWISE */]: null,
|
|
57237
|
+
["test" /* TEST */]: null
|
|
57238
|
+
};
|
|
57239
|
+
var InsufficientCreditsError = class extends Error {
|
|
57240
|
+
constructor(provider, message) {
|
|
57241
|
+
super(message || `Insufficient credits or quota for provider '${provider}'`);
|
|
57242
|
+
this.name = "InsufficientCreditsError";
|
|
57243
|
+
this.provider = provider;
|
|
57244
|
+
}
|
|
57245
|
+
};
|
|
57246
|
+
var RateLimitError3 = class extends Error {
|
|
57247
|
+
constructor(provider, retryAfter, message) {
|
|
57248
|
+
super(message || `Rate limit exceeded for provider '${provider}'`);
|
|
57249
|
+
this.name = "RateLimitError";
|
|
57250
|
+
this.provider = provider;
|
|
57251
|
+
this.retryAfter = retryAfter;
|
|
57252
|
+
}
|
|
57253
|
+
};
|
|
57254
|
+
var ServiceUnavailableError = class extends Error {
|
|
57255
|
+
constructor(provider, statusCode = 503, message) {
|
|
57256
|
+
super(message || `Service unavailable for provider '${provider}'`);
|
|
57257
|
+
this.name = "ServiceUnavailableError";
|
|
57258
|
+
this.provider = provider;
|
|
57259
|
+
this.statusCode = statusCode;
|
|
57260
|
+
}
|
|
57261
|
+
};
|
|
57262
|
+
var AuthenticationError3 = class extends Error {
|
|
57263
|
+
constructor(provider, message) {
|
|
57264
|
+
super(message || `Authentication failed for provider '${provider}'`);
|
|
57265
|
+
this.name = "AuthenticationError";
|
|
57266
|
+
this.provider = provider;
|
|
57267
|
+
}
|
|
57268
|
+
};
|
|
57227
57269
|
var ModelNotFoundError = class extends Error {
|
|
57228
57270
|
constructor(modelName, provider, statusCode = 404) {
|
|
57229
57271
|
super(`Model '${modelName}' not found for provider '${provider}'`);
|
|
@@ -57233,6 +57275,13 @@ var ModelNotFoundError = class extends Error {
|
|
|
57233
57275
|
this.statusCode = statusCode;
|
|
57234
57276
|
}
|
|
57235
57277
|
};
|
|
57278
|
+
var ApiKeyMissingError = class extends Error {
|
|
57279
|
+
constructor(provider) {
|
|
57280
|
+
super(`API key is missing for provider '${provider}'`);
|
|
57281
|
+
this.name = "ApiKeyMissingError";
|
|
57282
|
+
this.provider = provider;
|
|
57283
|
+
}
|
|
57284
|
+
};
|
|
57236
57285
|
function isModelNotFoundError(error) {
|
|
57237
57286
|
if (error instanceof ModelNotFoundError) {
|
|
57238
57287
|
return true;
|
|
@@ -57257,6 +57306,24 @@ function isModelNotFoundError(error) {
|
|
|
57257
57306
|
}
|
|
57258
57307
|
return false;
|
|
57259
57308
|
}
|
|
57309
|
+
function isApiKeyError(error) {
|
|
57310
|
+
if (error instanceof ApiKeyMissingError) {
|
|
57311
|
+
return true;
|
|
57312
|
+
}
|
|
57313
|
+
if (error instanceof Error) {
|
|
57314
|
+
const message = error.message.toLowerCase();
|
|
57315
|
+
if (message.includes("api key") || message.includes("apikey") || message.includes("authentication") || message.includes("unauthorized") || message.includes("invalid_api_key") || message.includes("incorrect api key")) {
|
|
57316
|
+
return true;
|
|
57317
|
+
}
|
|
57318
|
+
if ("response" in error) {
|
|
57319
|
+
const response = error.response;
|
|
57320
|
+
if (response?.status === 401) {
|
|
57321
|
+
return true;
|
|
57322
|
+
}
|
|
57323
|
+
}
|
|
57324
|
+
}
|
|
57325
|
+
return false;
|
|
57326
|
+
}
|
|
57260
57327
|
function getSuggestedModels(provider, failedModel) {
|
|
57261
57328
|
const providerKey = provider.toLowerCase();
|
|
57262
57329
|
const models = MODEL_LIST[providerKey];
|
|
@@ -57265,6 +57332,276 @@ function getSuggestedModels(provider, failedModel) {
|
|
|
57265
57332
|
}
|
|
57266
57333
|
return models.filter((m5) => m5 !== failedModel).slice(0, 5);
|
|
57267
57334
|
}
|
|
57335
|
+
function isInsufficientCreditsError(error) {
|
|
57336
|
+
if (error instanceof InsufficientCreditsError) {
|
|
57337
|
+
return true;
|
|
57338
|
+
}
|
|
57339
|
+
if (error instanceof Error) {
|
|
57340
|
+
const message = error.message.toLowerCase();
|
|
57341
|
+
if (message.includes("insufficient") || message.includes("credit") || message.includes("quota") || message.includes("balance") || message.includes("billing") || message.includes("payment") || message.includes("exceeded") || message.includes("limit reached") || message.includes("no remaining")) {
|
|
57342
|
+
return true;
|
|
57343
|
+
}
|
|
57344
|
+
if ("status" in error && error.status === 402) {
|
|
57345
|
+
return true;
|
|
57346
|
+
}
|
|
57347
|
+
if ("response" in error) {
|
|
57348
|
+
const response = error.response;
|
|
57349
|
+
if (response?.status === 402) {
|
|
57350
|
+
return true;
|
|
57351
|
+
}
|
|
57352
|
+
}
|
|
57353
|
+
}
|
|
57354
|
+
return false;
|
|
57355
|
+
}
|
|
57356
|
+
function isRateLimitError(error) {
|
|
57357
|
+
if (error instanceof RateLimitError3) {
|
|
57358
|
+
return true;
|
|
57359
|
+
}
|
|
57360
|
+
if (error instanceof Error) {
|
|
57361
|
+
const message = error.message.toLowerCase();
|
|
57362
|
+
if (message.includes("rate limit") || message.includes("rate_limit") || message.includes("too many requests") || message.includes("throttle")) {
|
|
57363
|
+
return true;
|
|
57364
|
+
}
|
|
57365
|
+
if ("status" in error && error.status === 429) {
|
|
57366
|
+
return true;
|
|
57367
|
+
}
|
|
57368
|
+
if ("response" in error) {
|
|
57369
|
+
const response = error.response;
|
|
57370
|
+
if (response?.status === 429) {
|
|
57371
|
+
return true;
|
|
57372
|
+
}
|
|
57373
|
+
}
|
|
57374
|
+
}
|
|
57375
|
+
return false;
|
|
57376
|
+
}
|
|
57377
|
+
function isServiceUnavailableError(error) {
|
|
57378
|
+
if (error instanceof ServiceUnavailableError) {
|
|
57379
|
+
return true;
|
|
57380
|
+
}
|
|
57381
|
+
if (error instanceof Error) {
|
|
57382
|
+
const message = error.message.toLowerCase();
|
|
57383
|
+
if (message.includes("service unavailable") || message.includes("server error") || message.includes("internal error") || message.includes("temporarily unavailable") || message.includes("overloaded")) {
|
|
57384
|
+
return true;
|
|
57385
|
+
}
|
|
57386
|
+
const status = error.status || error.response?.status;
|
|
57387
|
+
if (status && status >= 500 && status < 600) {
|
|
57388
|
+
return true;
|
|
57389
|
+
}
|
|
57390
|
+
}
|
|
57391
|
+
return false;
|
|
57392
|
+
}
|
|
57393
|
+
function formatUserFriendlyError(error, provider) {
|
|
57394
|
+
const billingUrl = PROVIDER_BILLING_URLS[provider] || null;
|
|
57395
|
+
if (error instanceof InsufficientCreditsError) {
|
|
57396
|
+
return {
|
|
57397
|
+
title: "Insufficient Credits",
|
|
57398
|
+
message: `Your ${provider} account has insufficient credits or quota.`,
|
|
57399
|
+
helpUrl: billingUrl,
|
|
57400
|
+
suggestion: "Add credits to your account to continue using the service."
|
|
57401
|
+
};
|
|
57402
|
+
}
|
|
57403
|
+
if (error instanceof RateLimitError3) {
|
|
57404
|
+
const retryMsg = error.retryAfter ? `Please wait ${error.retryAfter} seconds before retrying.` : "Please wait a moment before retrying.";
|
|
57405
|
+
return {
|
|
57406
|
+
title: "Rate Limit Exceeded",
|
|
57407
|
+
message: `You've made too many requests to ${provider}.`,
|
|
57408
|
+
helpUrl: billingUrl,
|
|
57409
|
+
suggestion: retryMsg
|
|
57410
|
+
};
|
|
57411
|
+
}
|
|
57412
|
+
if (error instanceof ServiceUnavailableError) {
|
|
57413
|
+
return {
|
|
57414
|
+
title: "Service Unavailable",
|
|
57415
|
+
message: `The ${provider} service is temporarily unavailable.`,
|
|
57416
|
+
helpUrl: null,
|
|
57417
|
+
suggestion: "Please try again in a few moments."
|
|
57418
|
+
};
|
|
57419
|
+
}
|
|
57420
|
+
if (error instanceof AuthenticationError3) {
|
|
57421
|
+
return {
|
|
57422
|
+
title: "Authentication Failed",
|
|
57423
|
+
message: `Your ${provider} API key is invalid or expired.`,
|
|
57424
|
+
helpUrl: billingUrl,
|
|
57425
|
+
suggestion: "Run `oco setup` to configure a valid API key."
|
|
57426
|
+
};
|
|
57427
|
+
}
|
|
57428
|
+
if (error instanceof ModelNotFoundError) {
|
|
57429
|
+
return {
|
|
57430
|
+
title: "Model Not Found",
|
|
57431
|
+
message: `The model '${error.modelName}' is not available for ${provider}.`,
|
|
57432
|
+
helpUrl: null,
|
|
57433
|
+
suggestion: "Run `oco setup` to select a valid model."
|
|
57434
|
+
};
|
|
57435
|
+
}
|
|
57436
|
+
if (isInsufficientCreditsError(error)) {
|
|
57437
|
+
return {
|
|
57438
|
+
title: "Insufficient Credits",
|
|
57439
|
+
message: `Your ${provider} account has insufficient credits or quota.`,
|
|
57440
|
+
helpUrl: billingUrl,
|
|
57441
|
+
suggestion: "Add credits to your account to continue using the service."
|
|
57442
|
+
};
|
|
57443
|
+
}
|
|
57444
|
+
if (isRateLimitError(error)) {
|
|
57445
|
+
return {
|
|
57446
|
+
title: "Rate Limit Exceeded",
|
|
57447
|
+
message: `You've made too many requests to ${provider}.`,
|
|
57448
|
+
helpUrl: billingUrl,
|
|
57449
|
+
suggestion: "Please wait a moment before retrying."
|
|
57450
|
+
};
|
|
57451
|
+
}
|
|
57452
|
+
if (isServiceUnavailableError(error)) {
|
|
57453
|
+
return {
|
|
57454
|
+
title: "Service Unavailable",
|
|
57455
|
+
message: `The ${provider} service is temporarily unavailable.`,
|
|
57456
|
+
helpUrl: null,
|
|
57457
|
+
suggestion: "Please try again in a few moments."
|
|
57458
|
+
};
|
|
57459
|
+
}
|
|
57460
|
+
if (isApiKeyError(error)) {
|
|
57461
|
+
return {
|
|
57462
|
+
title: "Authentication Failed",
|
|
57463
|
+
message: `Your ${provider} API key is invalid or expired.`,
|
|
57464
|
+
helpUrl: billingUrl,
|
|
57465
|
+
suggestion: "Run `oco setup` to configure a valid API key."
|
|
57466
|
+
};
|
|
57467
|
+
}
|
|
57468
|
+
if (isModelNotFoundError(error)) {
|
|
57469
|
+
const model = error.modelName || error.model || "unknown";
|
|
57470
|
+
return {
|
|
57471
|
+
title: "Model Not Found",
|
|
57472
|
+
message: `The model '${model}' is not available for ${provider}.`,
|
|
57473
|
+
helpUrl: null,
|
|
57474
|
+
suggestion: "Run `oco setup` to select a valid model."
|
|
57475
|
+
};
|
|
57476
|
+
}
|
|
57477
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
57478
|
+
return {
|
|
57479
|
+
title: "Error",
|
|
57480
|
+
message: errorMessage,
|
|
57481
|
+
helpUrl: null,
|
|
57482
|
+
suggestion: "Run `oco setup` to reconfigure or check your settings."
|
|
57483
|
+
};
|
|
57484
|
+
}
|
|
57485
|
+
function printFormattedError(formatted) {
|
|
57486
|
+
let output = `
|
|
57487
|
+
${source_default.red("\u2716")} ${source_default.bold.red(formatted.title)}
|
|
57488
|
+
`;
|
|
57489
|
+
output += ` ${formatted.message}
|
|
57490
|
+
`;
|
|
57491
|
+
if (formatted.helpUrl) {
|
|
57492
|
+
output += `
|
|
57493
|
+
${source_default.cyan("Help:")} ${source_default.underline(formatted.helpUrl)}
|
|
57494
|
+
`;
|
|
57495
|
+
}
|
|
57496
|
+
if (formatted.suggestion) {
|
|
57497
|
+
output += `
|
|
57498
|
+
${source_default.yellow("Suggestion:")} ${formatted.suggestion}
|
|
57499
|
+
`;
|
|
57500
|
+
}
|
|
57501
|
+
return output;
|
|
57502
|
+
}
|
|
57503
|
+
|
|
57504
|
+
// src/utils/engineErrorHandler.ts
|
|
57505
|
+
function getStatusCode(error) {
|
|
57506
|
+
if (typeof error?.status === "number") {
|
|
57507
|
+
return error.status;
|
|
57508
|
+
}
|
|
57509
|
+
if (axios_default.isAxiosError(error)) {
|
|
57510
|
+
return error.response?.status ?? null;
|
|
57511
|
+
}
|
|
57512
|
+
if (typeof error?.response?.status === "number") {
|
|
57513
|
+
return error.response.status;
|
|
57514
|
+
}
|
|
57515
|
+
return null;
|
|
57516
|
+
}
|
|
57517
|
+
function getRetryAfter(error) {
|
|
57518
|
+
const headers = error?.response?.headers;
|
|
57519
|
+
if (headers) {
|
|
57520
|
+
const retryAfter = headers["retry-after"] || headers["Retry-After"];
|
|
57521
|
+
if (retryAfter) {
|
|
57522
|
+
const seconds = parseInt(retryAfter, 10);
|
|
57523
|
+
if (!isNaN(seconds)) {
|
|
57524
|
+
return seconds;
|
|
57525
|
+
}
|
|
57526
|
+
}
|
|
57527
|
+
}
|
|
57528
|
+
return void 0;
|
|
57529
|
+
}
|
|
57530
|
+
function extractErrorMessage(error) {
|
|
57531
|
+
if (error instanceof Error) {
|
|
57532
|
+
return error.message;
|
|
57533
|
+
}
|
|
57534
|
+
const apiError = error?.response?.data?.error;
|
|
57535
|
+
if (apiError) {
|
|
57536
|
+
if (typeof apiError === "string") {
|
|
57537
|
+
return apiError;
|
|
57538
|
+
}
|
|
57539
|
+
if (apiError.message) {
|
|
57540
|
+
return apiError.message;
|
|
57541
|
+
}
|
|
57542
|
+
}
|
|
57543
|
+
const errorData = error?.error;
|
|
57544
|
+
if (errorData) {
|
|
57545
|
+
if (typeof errorData === "string") {
|
|
57546
|
+
return errorData;
|
|
57547
|
+
}
|
|
57548
|
+
if (errorData.message) {
|
|
57549
|
+
return errorData.message;
|
|
57550
|
+
}
|
|
57551
|
+
}
|
|
57552
|
+
if (typeof error === "string") {
|
|
57553
|
+
return error;
|
|
57554
|
+
}
|
|
57555
|
+
return "An unknown error occurred";
|
|
57556
|
+
}
|
|
57557
|
+
function isModelNotFoundMessage(message) {
|
|
57558
|
+
const lowerMessage = message.toLowerCase();
|
|
57559
|
+
return lowerMessage.includes("model") && (lowerMessage.includes("not found") || lowerMessage.includes("does not exist") || lowerMessage.includes("invalid") || lowerMessage.includes("pull")) || lowerMessage.includes("does_not_exist");
|
|
57560
|
+
}
|
|
57561
|
+
function isInsufficientCreditsMessage(message) {
|
|
57562
|
+
const lowerMessage = message.toLowerCase();
|
|
57563
|
+
return lowerMessage.includes("insufficient") || lowerMessage.includes("credit") || lowerMessage.includes("quota") || lowerMessage.includes("balance too low") || lowerMessage.includes("billing") || lowerMessage.includes("payment required") || lowerMessage.includes("exceeded");
|
|
57564
|
+
}
|
|
57565
|
+
function normalizeEngineError(error, provider, model) {
|
|
57566
|
+
if (error instanceof ModelNotFoundError || error instanceof AuthenticationError3 || error instanceof InsufficientCreditsError || error instanceof RateLimitError3 || error instanceof ServiceUnavailableError) {
|
|
57567
|
+
return error;
|
|
57568
|
+
}
|
|
57569
|
+
const statusCode = getStatusCode(error);
|
|
57570
|
+
const message = extractErrorMessage(error);
|
|
57571
|
+
switch (statusCode) {
|
|
57572
|
+
case 401:
|
|
57573
|
+
return new AuthenticationError3(provider, message);
|
|
57574
|
+
case 402:
|
|
57575
|
+
return new InsufficientCreditsError(provider, message);
|
|
57576
|
+
case 404:
|
|
57577
|
+
if (isModelNotFoundMessage(message)) {
|
|
57578
|
+
return new ModelNotFoundError(model, provider, 404);
|
|
57579
|
+
}
|
|
57580
|
+
return error instanceof Error ? error : new Error(message);
|
|
57581
|
+
case 429:
|
|
57582
|
+
const retryAfter = getRetryAfter(error);
|
|
57583
|
+
return new RateLimitError3(provider, retryAfter, message);
|
|
57584
|
+
case 500:
|
|
57585
|
+
case 502:
|
|
57586
|
+
case 503:
|
|
57587
|
+
case 504:
|
|
57588
|
+
return new ServiceUnavailableError(provider, statusCode, message);
|
|
57589
|
+
}
|
|
57590
|
+
if (isModelNotFoundMessage(message)) {
|
|
57591
|
+
return new ModelNotFoundError(model, provider, 404);
|
|
57592
|
+
}
|
|
57593
|
+
if (isInsufficientCreditsMessage(message)) {
|
|
57594
|
+
return new InsufficientCreditsError(provider, message);
|
|
57595
|
+
}
|
|
57596
|
+
const lowerMessage = message.toLowerCase();
|
|
57597
|
+
if (lowerMessage.includes("rate limit") || lowerMessage.includes("rate_limit") || lowerMessage.includes("too many requests")) {
|
|
57598
|
+
return new RateLimitError3(provider, void 0, message);
|
|
57599
|
+
}
|
|
57600
|
+
if (lowerMessage.includes("unauthorized") || lowerMessage.includes("api key") || lowerMessage.includes("apikey") || lowerMessage.includes("authentication") || lowerMessage.includes("invalid_api_key")) {
|
|
57601
|
+
return new AuthenticationError3(provider, message);
|
|
57602
|
+
}
|
|
57603
|
+
return error instanceof Error ? error : new Error(message);
|
|
57604
|
+
}
|
|
57268
57605
|
|
|
57269
57606
|
// src/utils/removeContentTags.ts
|
|
57270
57607
|
function removeContentTags(content, tag) {
|
|
@@ -57342,25 +57679,7 @@ var AnthropicEngine = class {
|
|
|
57342
57679
|
let content = message;
|
|
57343
57680
|
return removeContentTags(content, "think");
|
|
57344
57681
|
} catch (error) {
|
|
57345
|
-
|
|
57346
|
-
if (err.message?.toLowerCase().includes("model") && (err.message?.toLowerCase().includes("not found") || err.message?.toLowerCase().includes("does not exist") || err.message?.toLowerCase().includes("invalid"))) {
|
|
57347
|
-
throw new ModelNotFoundError(this.config.model, "anthropic", 404);
|
|
57348
|
-
}
|
|
57349
|
-
if ("status" in error && error.status === 404) {
|
|
57350
|
-
throw new ModelNotFoundError(this.config.model, "anthropic", 404);
|
|
57351
|
-
}
|
|
57352
|
-
ce(`${source_default.red("\u2716")} ${err?.message || err}`);
|
|
57353
|
-
if (axios_default.isAxiosError(error) && error.response?.status === 401) {
|
|
57354
|
-
const anthropicAiError = error.response.data.error;
|
|
57355
|
-
if (anthropicAiError?.message) ce(anthropicAiError.message);
|
|
57356
|
-
ce(
|
|
57357
|
-
"For help look into README https://github.com/di-sukharev/opencommit#setup"
|
|
57358
|
-
);
|
|
57359
|
-
}
|
|
57360
|
-
if (axios_default.isAxiosError(error) && error.response?.status === 404) {
|
|
57361
|
-
throw new ModelNotFoundError(this.config.model, "anthropic", 404);
|
|
57362
|
-
}
|
|
57363
|
-
throw err;
|
|
57682
|
+
throw normalizeEngineError(error, "anthropic", this.config.model);
|
|
57364
57683
|
}
|
|
57365
57684
|
};
|
|
57366
57685
|
this.config = config7;
|
|
@@ -61176,7 +61495,6 @@ var OpenAIClient = class {
|
|
|
61176
61495
|
};
|
|
61177
61496
|
|
|
61178
61497
|
// src/engine/azure.ts
|
|
61179
|
-
init_dist2();
|
|
61180
61498
|
var AzureEngine = class {
|
|
61181
61499
|
constructor(config7) {
|
|
61182
61500
|
this.generateCommitMessage = async (messages) => {
|
|
@@ -61196,17 +61514,7 @@ var AzureEngine = class {
|
|
|
61196
61514
|
let content = message?.content;
|
|
61197
61515
|
return removeContentTags(content, "think");
|
|
61198
61516
|
} catch (error) {
|
|
61199
|
-
|
|
61200
|
-
const err = error;
|
|
61201
|
-
ce(`${source_default.red("\u2716")} ${JSON.stringify(error)}`);
|
|
61202
|
-
if (axios_default.isAxiosError(error) && error.response?.status === 401) {
|
|
61203
|
-
const openAiError = error.response.data.error;
|
|
61204
|
-
if (openAiError?.message) ce(openAiError.message);
|
|
61205
|
-
ce(
|
|
61206
|
-
"For help look into README https://github.com/di-sukharev/opencommit#setup"
|
|
61207
|
-
);
|
|
61208
|
-
}
|
|
61209
|
-
throw err;
|
|
61517
|
+
throw normalizeEngineError(error, "azure", this.config.model);
|
|
61210
61518
|
}
|
|
61211
61519
|
};
|
|
61212
61520
|
this.config = config7;
|
|
@@ -61240,9 +61548,8 @@ var FlowiseEngine = class {
|
|
|
61240
61548
|
const message = response.data;
|
|
61241
61549
|
let content = message?.text;
|
|
61242
61550
|
return removeContentTags(content, "think");
|
|
61243
|
-
} catch (
|
|
61244
|
-
|
|
61245
|
-
throw new Error("local model issues. details: " + message);
|
|
61551
|
+
} catch (error) {
|
|
61552
|
+
throw normalizeEngineError(error, "flowise", this.config.model);
|
|
61246
61553
|
}
|
|
61247
61554
|
}
|
|
61248
61555
|
};
|
|
@@ -62102,18 +62409,7 @@ var GeminiEngine = class {
|
|
|
62102
62409
|
const content = result.response.text();
|
|
62103
62410
|
return removeContentTags(content, "think");
|
|
62104
62411
|
} catch (error) {
|
|
62105
|
-
|
|
62106
|
-
if (err.message?.toLowerCase().includes("model") && (err.message?.toLowerCase().includes("not found") || err.message?.toLowerCase().includes("does not exist") || err.message?.toLowerCase().includes("invalid"))) {
|
|
62107
|
-
throw new ModelNotFoundError(this.config.model, "gemini", 404);
|
|
62108
|
-
}
|
|
62109
|
-
if (axios_default.isAxiosError(error) && error.response?.status === 401) {
|
|
62110
|
-
const geminiError = error.response.data.error;
|
|
62111
|
-
if (geminiError) throw new Error(geminiError?.message);
|
|
62112
|
-
}
|
|
62113
|
-
if (axios_default.isAxiosError(error) && error.response?.status === 404) {
|
|
62114
|
-
throw new ModelNotFoundError(this.config.model, "gemini", 404);
|
|
62115
|
-
}
|
|
62116
|
-
throw err;
|
|
62412
|
+
throw normalizeEngineError(error, "gemini", this.config.model);
|
|
62117
62413
|
}
|
|
62118
62414
|
}
|
|
62119
62415
|
};
|
|
@@ -62146,15 +62442,8 @@ var OllamaEngine = class {
|
|
|
62146
62442
|
const { message } = response.data;
|
|
62147
62443
|
let content = message?.content;
|
|
62148
62444
|
return removeContentTags(content, "think");
|
|
62149
|
-
} catch (
|
|
62150
|
-
|
|
62151
|
-
if (message?.toLowerCase().includes("model") && (message?.toLowerCase().includes("not found") || message?.toLowerCase().includes("does not exist") || message?.toLowerCase().includes("pull"))) {
|
|
62152
|
-
throw new ModelNotFoundError(this.config.model, "ollama", 404);
|
|
62153
|
-
}
|
|
62154
|
-
if (err.response?.status === 404) {
|
|
62155
|
-
throw new ModelNotFoundError(this.config.model, "ollama", 404);
|
|
62156
|
-
}
|
|
62157
|
-
throw new Error(`Ollama provider error: ${message}`);
|
|
62445
|
+
} catch (error) {
|
|
62446
|
+
throw normalizeEngineError(error, "ollama", this.config.model);
|
|
62158
62447
|
}
|
|
62159
62448
|
}
|
|
62160
62449
|
};
|
|
@@ -62166,7 +62455,7 @@ __export(error_exports2, {
|
|
|
62166
62455
|
APIConnectionTimeoutError: () => APIConnectionTimeoutError3,
|
|
62167
62456
|
APIError: () => APIError3,
|
|
62168
62457
|
APIUserAbortError: () => APIUserAbortError3,
|
|
62169
|
-
AuthenticationError: () =>
|
|
62458
|
+
AuthenticationError: () => AuthenticationError4,
|
|
62170
62459
|
BadRequestError: () => BadRequestError3,
|
|
62171
62460
|
ConflictError: () => ConflictError3,
|
|
62172
62461
|
ContentFilterFinishReasonError: () => ContentFilterFinishReasonError,
|
|
@@ -62175,7 +62464,7 @@ __export(error_exports2, {
|
|
|
62175
62464
|
NotFoundError: () => NotFoundError3,
|
|
62176
62465
|
OpenAIError: () => OpenAIError,
|
|
62177
62466
|
PermissionDeniedError: () => PermissionDeniedError3,
|
|
62178
|
-
RateLimitError: () =>
|
|
62467
|
+
RateLimitError: () => RateLimitError4,
|
|
62179
62468
|
UnprocessableEntityError: () => UnprocessableEntityError3
|
|
62180
62469
|
});
|
|
62181
62470
|
|
|
@@ -63447,7 +63736,7 @@ var APIError3 = class _APIError extends OpenAIError {
|
|
|
63447
63736
|
return new BadRequestError3(status, error, message, headers);
|
|
63448
63737
|
}
|
|
63449
63738
|
if (status === 401) {
|
|
63450
|
-
return new
|
|
63739
|
+
return new AuthenticationError4(status, error, message, headers);
|
|
63451
63740
|
}
|
|
63452
63741
|
if (status === 403) {
|
|
63453
63742
|
return new PermissionDeniedError3(status, error, message, headers);
|
|
@@ -63462,7 +63751,7 @@ var APIError3 = class _APIError extends OpenAIError {
|
|
|
63462
63751
|
return new UnprocessableEntityError3(status, error, message, headers);
|
|
63463
63752
|
}
|
|
63464
63753
|
if (status === 429) {
|
|
63465
|
-
return new
|
|
63754
|
+
return new RateLimitError4(status, error, message, headers);
|
|
63466
63755
|
}
|
|
63467
63756
|
if (status >= 500) {
|
|
63468
63757
|
return new InternalServerError3(status, error, message, headers);
|
|
@@ -63495,7 +63784,7 @@ var BadRequestError3 = class extends APIError3 {
|
|
|
63495
63784
|
this.status = 400;
|
|
63496
63785
|
}
|
|
63497
63786
|
};
|
|
63498
|
-
var
|
|
63787
|
+
var AuthenticationError4 = class extends APIError3 {
|
|
63499
63788
|
constructor() {
|
|
63500
63789
|
super(...arguments);
|
|
63501
63790
|
this.status = 401;
|
|
@@ -63525,7 +63814,7 @@ var UnprocessableEntityError3 = class extends APIError3 {
|
|
|
63525
63814
|
this.status = 422;
|
|
63526
63815
|
}
|
|
63527
63816
|
};
|
|
63528
|
-
var
|
|
63817
|
+
var RateLimitError4 = class extends APIError3 {
|
|
63529
63818
|
constructor() {
|
|
63530
63819
|
super(...arguments);
|
|
63531
63820
|
this.status = 429;
|
|
@@ -66834,15 +67123,15 @@ OpenAI.APIConnectionTimeoutError = APIConnectionTimeoutError3;
|
|
|
66834
67123
|
OpenAI.APIUserAbortError = APIUserAbortError3;
|
|
66835
67124
|
OpenAI.NotFoundError = NotFoundError3;
|
|
66836
67125
|
OpenAI.ConflictError = ConflictError3;
|
|
66837
|
-
OpenAI.RateLimitError =
|
|
67126
|
+
OpenAI.RateLimitError = RateLimitError4;
|
|
66838
67127
|
OpenAI.BadRequestError = BadRequestError3;
|
|
66839
|
-
OpenAI.AuthenticationError =
|
|
67128
|
+
OpenAI.AuthenticationError = AuthenticationError4;
|
|
66840
67129
|
OpenAI.InternalServerError = InternalServerError3;
|
|
66841
67130
|
OpenAI.PermissionDeniedError = PermissionDeniedError3;
|
|
66842
67131
|
OpenAI.UnprocessableEntityError = UnprocessableEntityError3;
|
|
66843
67132
|
OpenAI.toFile = toFile2;
|
|
66844
67133
|
OpenAI.fileFromPath = fileFromPath4;
|
|
66845
|
-
var { OpenAIError: OpenAIError2, APIError: APIError4, APIConnectionError: APIConnectionError4, APIConnectionTimeoutError: APIConnectionTimeoutError4, APIUserAbortError: APIUserAbortError4, NotFoundError: NotFoundError4, ConflictError: ConflictError4, RateLimitError:
|
|
67134
|
+
var { OpenAIError: OpenAIError2, APIError: APIError4, APIConnectionError: APIConnectionError4, APIConnectionTimeoutError: APIConnectionTimeoutError4, APIUserAbortError: APIUserAbortError4, NotFoundError: NotFoundError4, ConflictError: ConflictError4, RateLimitError: RateLimitError5, BadRequestError: BadRequestError4, AuthenticationError: AuthenticationError5, InternalServerError: InternalServerError4, PermissionDeniedError: PermissionDeniedError4, UnprocessableEntityError: UnprocessableEntityError4 } = error_exports2;
|
|
66846
67135
|
(function(OpenAI2) {
|
|
66847
67136
|
OpenAI2.Page = Page;
|
|
66848
67137
|
OpenAI2.CursorPage = CursorPage;
|
|
@@ -66883,21 +67172,7 @@ var OpenAiEngine = class {
|
|
|
66883
67172
|
let content = message?.content;
|
|
66884
67173
|
return removeContentTags(content, "think");
|
|
66885
67174
|
} catch (error) {
|
|
66886
|
-
|
|
66887
|
-
if (err.message?.toLowerCase().includes("model") && (err.message?.toLowerCase().includes("not found") || err.message?.toLowerCase().includes("does not exist") || err.message?.toLowerCase().includes("invalid"))) {
|
|
66888
|
-
throw new ModelNotFoundError(this.config.model, "openai", 404);
|
|
66889
|
-
}
|
|
66890
|
-
if ("status" in error && error.status === 404) {
|
|
66891
|
-
throw new ModelNotFoundError(this.config.model, "openai", 404);
|
|
66892
|
-
}
|
|
66893
|
-
if (axios_default.isAxiosError(error) && error.response?.status === 401) {
|
|
66894
|
-
const openAiError = error.response.data.error;
|
|
66895
|
-
if (openAiError) throw new Error(openAiError.message);
|
|
66896
|
-
}
|
|
66897
|
-
if (axios_default.isAxiosError(error) && error.response?.status === 404) {
|
|
66898
|
-
throw new ModelNotFoundError(this.config.model, "openai", 404);
|
|
66899
|
-
}
|
|
66900
|
-
throw err;
|
|
67175
|
+
throw normalizeEngineError(error, "openai", this.config.model);
|
|
66901
67176
|
}
|
|
66902
67177
|
};
|
|
66903
67178
|
this.config = config7;
|
|
@@ -66941,12 +67216,7 @@ var MistralAiEngine = class {
|
|
|
66941
67216
|
let content = message.content;
|
|
66942
67217
|
return removeContentTags(content, "think");
|
|
66943
67218
|
} catch (error) {
|
|
66944
|
-
|
|
66945
|
-
if (axios_default.isAxiosError(error) && error.response?.status === 401) {
|
|
66946
|
-
const mistralError = error.response.data.error;
|
|
66947
|
-
if (mistralError) throw new Error(mistralError.message);
|
|
66948
|
-
}
|
|
66949
|
-
throw err;
|
|
67219
|
+
throw normalizeEngineError(error, "mistral", this.config.model);
|
|
66950
67220
|
}
|
|
66951
67221
|
};
|
|
66952
67222
|
this.config = config7;
|
|
@@ -66995,9 +67265,8 @@ var MLXEngine = class {
|
|
|
66995
67265
|
const message = choices[0].message;
|
|
66996
67266
|
let content = message?.content;
|
|
66997
67267
|
return removeContentTags(content, "think");
|
|
66998
|
-
} catch (
|
|
66999
|
-
|
|
67000
|
-
throw new Error(`MLX provider error: ${message}`);
|
|
67268
|
+
} catch (error) {
|
|
67269
|
+
throw normalizeEngineError(error, "mlx", this.config.model);
|
|
67001
67270
|
}
|
|
67002
67271
|
}
|
|
67003
67272
|
};
|
|
@@ -67027,12 +67296,7 @@ var DeepseekEngine = class extends OpenAiEngine {
|
|
|
67027
67296
|
let content = message?.content;
|
|
67028
67297
|
return removeContentTags(content, "think");
|
|
67029
67298
|
} catch (error) {
|
|
67030
|
-
|
|
67031
|
-
if (axios_default.isAxiosError(error) && error.response?.status === 401) {
|
|
67032
|
-
const openAiError = error.response.data.error;
|
|
67033
|
-
if (openAiError) throw new Error(openAiError.message);
|
|
67034
|
-
}
|
|
67035
|
-
throw err;
|
|
67299
|
+
throw normalizeEngineError(error, "deepseek", this.config.model);
|
|
67036
67300
|
}
|
|
67037
67301
|
};
|
|
67038
67302
|
}
|
|
@@ -67051,12 +67315,7 @@ var AimlApiEngine = class {
|
|
|
67051
67315
|
const message = response.data.choices?.[0]?.message;
|
|
67052
67316
|
return message?.content ?? null;
|
|
67053
67317
|
} catch (error) {
|
|
67054
|
-
|
|
67055
|
-
if (axios_default.isAxiosError(error) && error.response?.status === 401) {
|
|
67056
|
-
const apiError = error.response.data.error;
|
|
67057
|
-
if (apiError) throw new Error(apiError.message);
|
|
67058
|
-
}
|
|
67059
|
-
throw err;
|
|
67318
|
+
throw normalizeEngineError(error, "aimlapi", this.config.model);
|
|
67060
67319
|
}
|
|
67061
67320
|
};
|
|
67062
67321
|
this.client = axios_default.create({
|
|
@@ -67086,12 +67345,7 @@ var OpenRouterEngine = class {
|
|
|
67086
67345
|
let content = message?.content;
|
|
67087
67346
|
return removeContentTags(content, "think");
|
|
67088
67347
|
} catch (error) {
|
|
67089
|
-
|
|
67090
|
-
if (axios_default.isAxiosError(error) && error.response?.status === 401) {
|
|
67091
|
-
const openRouterError = error.response.data.error;
|
|
67092
|
-
if (openRouterError) throw new Error(openRouterError.message);
|
|
67093
|
-
}
|
|
67094
|
-
throw err;
|
|
67348
|
+
throw normalizeEngineError(error, "openrouter", this.config.model);
|
|
67095
67349
|
}
|
|
67096
67350
|
};
|
|
67097
67351
|
this.client = axios_default.create({
|
|
@@ -68153,9 +68407,10 @@ ${source_default.grey("\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2
|
|
|
68153
68407
|
commitGenerationSpinner.stop(
|
|
68154
68408
|
`${source_default.red("\u2716")} Failed to generate the commit message`
|
|
68155
68409
|
);
|
|
68156
|
-
|
|
68157
|
-
const
|
|
68158
|
-
|
|
68410
|
+
const errorConfig = getConfig();
|
|
68411
|
+
const provider = errorConfig.OCO_AI_PROVIDER || "openai";
|
|
68412
|
+
const formatted = formatUserFriendlyError(error, provider);
|
|
68413
|
+
ce(printFormattedError(formatted));
|
|
68159
68414
|
process.exit(1);
|
|
68160
68415
|
}
|
|
68161
68416
|
};
|
|
@@ -68458,9 +68713,97 @@ async function fetchOllamaModels(baseUrl = "http://localhost:11434") {
|
|
|
68458
68713
|
return [];
|
|
68459
68714
|
}
|
|
68460
68715
|
}
|
|
68461
|
-
async function
|
|
68716
|
+
async function fetchAnthropicModels(apiKey) {
|
|
68717
|
+
try {
|
|
68718
|
+
const response = await fetch("https://api.anthropic.com/v1/models", {
|
|
68719
|
+
headers: {
|
|
68720
|
+
"x-api-key": apiKey,
|
|
68721
|
+
"anthropic-version": "2023-06-01"
|
|
68722
|
+
}
|
|
68723
|
+
});
|
|
68724
|
+
if (!response.ok) {
|
|
68725
|
+
return MODEL_LIST.anthropic;
|
|
68726
|
+
}
|
|
68727
|
+
const data = await response.json();
|
|
68728
|
+
const models = data.data?.map((m5) => m5.id).filter((id) => id.startsWith("claude-")).sort();
|
|
68729
|
+
return models && models.length > 0 ? models : MODEL_LIST.anthropic;
|
|
68730
|
+
} catch {
|
|
68731
|
+
return MODEL_LIST.anthropic;
|
|
68732
|
+
}
|
|
68733
|
+
}
|
|
68734
|
+
async function fetchMistralModels(apiKey) {
|
|
68735
|
+
try {
|
|
68736
|
+
const response = await fetch("https://api.mistral.ai/v1/models", {
|
|
68737
|
+
headers: {
|
|
68738
|
+
Authorization: `Bearer ${apiKey}`
|
|
68739
|
+
}
|
|
68740
|
+
});
|
|
68741
|
+
if (!response.ok) {
|
|
68742
|
+
return MODEL_LIST.mistral;
|
|
68743
|
+
}
|
|
68744
|
+
const data = await response.json();
|
|
68745
|
+
const models = data.data?.map((m5) => m5.id).sort();
|
|
68746
|
+
return models && models.length > 0 ? models : MODEL_LIST.mistral;
|
|
68747
|
+
} catch {
|
|
68748
|
+
return MODEL_LIST.mistral;
|
|
68749
|
+
}
|
|
68750
|
+
}
|
|
68751
|
+
async function fetchGroqModels(apiKey) {
|
|
68752
|
+
try {
|
|
68753
|
+
const response = await fetch("https://api.groq.com/openai/v1/models", {
|
|
68754
|
+
headers: {
|
|
68755
|
+
Authorization: `Bearer ${apiKey}`
|
|
68756
|
+
}
|
|
68757
|
+
});
|
|
68758
|
+
if (!response.ok) {
|
|
68759
|
+
return MODEL_LIST.groq;
|
|
68760
|
+
}
|
|
68761
|
+
const data = await response.json();
|
|
68762
|
+
const models = data.data?.map((m5) => m5.id).sort();
|
|
68763
|
+
return models && models.length > 0 ? models : MODEL_LIST.groq;
|
|
68764
|
+
} catch {
|
|
68765
|
+
return MODEL_LIST.groq;
|
|
68766
|
+
}
|
|
68767
|
+
}
|
|
68768
|
+
async function fetchOpenRouterModels(apiKey) {
|
|
68769
|
+
try {
|
|
68770
|
+
const response = await fetch("https://openrouter.ai/api/v1/models", {
|
|
68771
|
+
headers: {
|
|
68772
|
+
Authorization: `Bearer ${apiKey}`
|
|
68773
|
+
}
|
|
68774
|
+
});
|
|
68775
|
+
if (!response.ok) {
|
|
68776
|
+
return MODEL_LIST.openrouter;
|
|
68777
|
+
}
|
|
68778
|
+
const data = await response.json();
|
|
68779
|
+
const models = data.data?.filter(
|
|
68780
|
+
(m5) => m5.context_length && m5.context_length > 0
|
|
68781
|
+
).map((m5) => m5.id).sort();
|
|
68782
|
+
return models && models.length > 0 ? models : MODEL_LIST.openrouter;
|
|
68783
|
+
} catch {
|
|
68784
|
+
return MODEL_LIST.openrouter;
|
|
68785
|
+
}
|
|
68786
|
+
}
|
|
68787
|
+
async function fetchDeepSeekModels(apiKey) {
|
|
68788
|
+
try {
|
|
68789
|
+
const response = await fetch("https://api.deepseek.com/v1/models", {
|
|
68790
|
+
headers: {
|
|
68791
|
+
Authorization: `Bearer ${apiKey}`
|
|
68792
|
+
}
|
|
68793
|
+
});
|
|
68794
|
+
if (!response.ok) {
|
|
68795
|
+
return MODEL_LIST.deepseek;
|
|
68796
|
+
}
|
|
68797
|
+
const data = await response.json();
|
|
68798
|
+
const models = data.data?.map((m5) => m5.id).sort();
|
|
68799
|
+
return models && models.length > 0 ? models : MODEL_LIST.deepseek;
|
|
68800
|
+
} catch {
|
|
68801
|
+
return MODEL_LIST.deepseek;
|
|
68802
|
+
}
|
|
68803
|
+
}
|
|
68804
|
+
async function fetchModelsForProvider(provider, apiKey, baseUrl, forceRefresh = false) {
|
|
68462
68805
|
const cache = readCache();
|
|
68463
|
-
if (isCacheValid(cache) && cache.models[provider]) {
|
|
68806
|
+
if (!forceRefresh && isCacheValid(cache) && cache.models[provider]) {
|
|
68464
68807
|
return cache.models[provider];
|
|
68465
68808
|
}
|
|
68466
68809
|
let models = [];
|
|
@@ -68476,25 +68819,45 @@ async function fetchModelsForProvider(provider, apiKey, baseUrl) {
|
|
|
68476
68819
|
models = await fetchOllamaModels(baseUrl);
|
|
68477
68820
|
break;
|
|
68478
68821
|
case "anthropic" /* ANTHROPIC */:
|
|
68479
|
-
|
|
68822
|
+
if (apiKey) {
|
|
68823
|
+
models = await fetchAnthropicModels(apiKey);
|
|
68824
|
+
} else {
|
|
68825
|
+
models = MODEL_LIST.anthropic;
|
|
68826
|
+
}
|
|
68480
68827
|
break;
|
|
68481
68828
|
case "gemini" /* GEMINI */:
|
|
68482
68829
|
models = MODEL_LIST.gemini;
|
|
68483
68830
|
break;
|
|
68484
68831
|
case "groq" /* GROQ */:
|
|
68485
|
-
|
|
68832
|
+
if (apiKey) {
|
|
68833
|
+
models = await fetchGroqModels(apiKey);
|
|
68834
|
+
} else {
|
|
68835
|
+
models = MODEL_LIST.groq;
|
|
68836
|
+
}
|
|
68486
68837
|
break;
|
|
68487
68838
|
case "mistral" /* MISTRAL */:
|
|
68488
|
-
|
|
68839
|
+
if (apiKey) {
|
|
68840
|
+
models = await fetchMistralModels(apiKey);
|
|
68841
|
+
} else {
|
|
68842
|
+
models = MODEL_LIST.mistral;
|
|
68843
|
+
}
|
|
68489
68844
|
break;
|
|
68490
68845
|
case "deepseek" /* DEEPSEEK */:
|
|
68491
|
-
|
|
68846
|
+
if (apiKey) {
|
|
68847
|
+
models = await fetchDeepSeekModels(apiKey);
|
|
68848
|
+
} else {
|
|
68849
|
+
models = MODEL_LIST.deepseek;
|
|
68850
|
+
}
|
|
68492
68851
|
break;
|
|
68493
68852
|
case "aimlapi" /* AIMLAPI */:
|
|
68494
68853
|
models = MODEL_LIST.aimlapi;
|
|
68495
68854
|
break;
|
|
68496
68855
|
case "openrouter" /* OPENROUTER */:
|
|
68497
|
-
|
|
68856
|
+
if (apiKey) {
|
|
68857
|
+
models = await fetchOpenRouterModels(apiKey);
|
|
68858
|
+
} else {
|
|
68859
|
+
models = MODEL_LIST.openrouter;
|
|
68860
|
+
}
|
|
68498
68861
|
break;
|
|
68499
68862
|
default:
|
|
68500
68863
|
models = MODEL_LIST.openai;
|
|
@@ -68504,6 +68867,31 @@ async function fetchModelsForProvider(provider, apiKey, baseUrl) {
|
|
|
68504
68867
|
writeCache(existingCache);
|
|
68505
68868
|
return models;
|
|
68506
68869
|
}
|
|
68870
|
+
function clearModelCache() {
|
|
68871
|
+
try {
|
|
68872
|
+
if ((0, import_fs5.existsSync)(MODEL_CACHE_PATH)) {
|
|
68873
|
+
(0, import_fs5.writeFileSync)(MODEL_CACHE_PATH, "{}", "utf8");
|
|
68874
|
+
}
|
|
68875
|
+
} catch {
|
|
68876
|
+
}
|
|
68877
|
+
}
|
|
68878
|
+
function getCacheInfo() {
|
|
68879
|
+
const cache = readCache();
|
|
68880
|
+
if (!cache) {
|
|
68881
|
+
return { timestamp: null, providers: [] };
|
|
68882
|
+
}
|
|
68883
|
+
return {
|
|
68884
|
+
timestamp: cache.timestamp,
|
|
68885
|
+
providers: Object.keys(cache.models || {})
|
|
68886
|
+
};
|
|
68887
|
+
}
|
|
68888
|
+
function getCachedModels(provider) {
|
|
68889
|
+
const cache = readCache();
|
|
68890
|
+
if (!cache || !cache.models[provider]) {
|
|
68891
|
+
return null;
|
|
68892
|
+
}
|
|
68893
|
+
return cache.models[provider];
|
|
68894
|
+
}
|
|
68507
68895
|
|
|
68508
68896
|
// src/commands/setup.ts
|
|
68509
68897
|
var PROVIDER_DISPLAY_NAMES = {
|
|
@@ -68582,17 +68970,42 @@ ${source_default.dim(` Get your key at: ${url2}`)}`;
|
|
|
68582
68970
|
}
|
|
68583
68971
|
});
|
|
68584
68972
|
}
|
|
68973
|
+
function formatCacheAge(timestamp) {
|
|
68974
|
+
if (!timestamp) return "";
|
|
68975
|
+
const ageMs = Date.now() - timestamp;
|
|
68976
|
+
const days = Math.floor(ageMs / (1e3 * 60 * 60 * 24));
|
|
68977
|
+
const hours = Math.floor(ageMs / (1e3 * 60 * 60));
|
|
68978
|
+
if (days > 0) {
|
|
68979
|
+
return `${days} day${days === 1 ? "" : "s"} ago`;
|
|
68980
|
+
} else if (hours > 0) {
|
|
68981
|
+
return `${hours} hour${hours === 1 ? "" : "s"} ago`;
|
|
68982
|
+
}
|
|
68983
|
+
return "just now";
|
|
68984
|
+
}
|
|
68585
68985
|
async function selectModel(provider, apiKey) {
|
|
68986
|
+
const providerDisplayName = PROVIDER_DISPLAY_NAMES[provider]?.split(" (")[0] || provider;
|
|
68586
68987
|
const loadingSpinner = le();
|
|
68587
|
-
loadingSpinner.start(
|
|
68988
|
+
loadingSpinner.start(`Fetching models from ${providerDisplayName}...`);
|
|
68588
68989
|
let models = [];
|
|
68990
|
+
let usedFallback = false;
|
|
68589
68991
|
try {
|
|
68590
68992
|
models = await fetchModelsForProvider(provider, apiKey);
|
|
68591
68993
|
} catch {
|
|
68994
|
+
usedFallback = true;
|
|
68592
68995
|
const providerKey = provider.toLowerCase();
|
|
68593
68996
|
models = MODEL_LIST[providerKey] || [];
|
|
68594
68997
|
}
|
|
68595
|
-
|
|
68998
|
+
const cacheInfo = getCacheInfo();
|
|
68999
|
+
const cacheAge = formatCacheAge(cacheInfo.timestamp);
|
|
69000
|
+
if (usedFallback) {
|
|
69001
|
+
loadingSpinner.stop(
|
|
69002
|
+
source_default.yellow("Could not fetch models from API. Using default list.")
|
|
69003
|
+
);
|
|
69004
|
+
} else if (cacheAge) {
|
|
69005
|
+
loadingSpinner.stop(`Models loaded ${source_default.dim(`(cached ${cacheAge})`)}`);
|
|
69006
|
+
} else {
|
|
69007
|
+
loadingSpinner.stop("Models loaded");
|
|
69008
|
+
}
|
|
68596
69009
|
if (models.length === 0) {
|
|
68597
69010
|
if (NO_API_KEY_PROVIDERS.includes(provider)) {
|
|
68598
69011
|
return await J4({
|
|
@@ -68844,6 +69257,116 @@ var setupCommand = G3(
|
|
|
68844
69257
|
}
|
|
68845
69258
|
);
|
|
68846
69259
|
|
|
69260
|
+
// src/commands/models.ts
|
|
69261
|
+
init_dist2();
|
|
69262
|
+
function formatCacheAge2(timestamp) {
|
|
69263
|
+
if (!timestamp) return "never";
|
|
69264
|
+
const ageMs = Date.now() - timestamp;
|
|
69265
|
+
const days = Math.floor(ageMs / (1e3 * 60 * 60 * 24));
|
|
69266
|
+
const hours = Math.floor(ageMs / (1e3 * 60 * 60));
|
|
69267
|
+
const minutes = Math.floor(ageMs / (1e3 * 60));
|
|
69268
|
+
if (days > 0) {
|
|
69269
|
+
return `${days} day${days === 1 ? "" : "s"} ago`;
|
|
69270
|
+
} else if (hours > 0) {
|
|
69271
|
+
return `${hours} hour${hours === 1 ? "" : "s"} ago`;
|
|
69272
|
+
} else if (minutes > 0) {
|
|
69273
|
+
return `${minutes} minute${minutes === 1 ? "" : "s"} ago`;
|
|
69274
|
+
}
|
|
69275
|
+
return "just now";
|
|
69276
|
+
}
|
|
69277
|
+
async function listModels(provider, useCache = true) {
|
|
69278
|
+
const config7 = getConfig();
|
|
69279
|
+
const apiKey = config7.OCO_API_KEY;
|
|
69280
|
+
const currentModel = config7.OCO_MODEL;
|
|
69281
|
+
let models = [];
|
|
69282
|
+
if (useCache) {
|
|
69283
|
+
const cached = getCachedModels(provider);
|
|
69284
|
+
if (cached) {
|
|
69285
|
+
models = cached;
|
|
69286
|
+
}
|
|
69287
|
+
}
|
|
69288
|
+
if (models.length === 0) {
|
|
69289
|
+
const providerKey = provider.toLowerCase();
|
|
69290
|
+
models = MODEL_LIST[providerKey] || [];
|
|
69291
|
+
}
|
|
69292
|
+
console.log(`
|
|
69293
|
+
${source_default.bold("Available models for")} ${source_default.cyan(provider)}:
|
|
69294
|
+
`);
|
|
69295
|
+
if (models.length === 0) {
|
|
69296
|
+
console.log(source_default.dim(" No models found"));
|
|
69297
|
+
} else {
|
|
69298
|
+
models.forEach((model) => {
|
|
69299
|
+
const isCurrent = model === currentModel;
|
|
69300
|
+
const prefix = isCurrent ? source_default.green("* ") : " ";
|
|
69301
|
+
const label = isCurrent ? source_default.green(model) : model;
|
|
69302
|
+
console.log(`${prefix}${label}`);
|
|
69303
|
+
});
|
|
69304
|
+
}
|
|
69305
|
+
console.log("");
|
|
69306
|
+
}
|
|
69307
|
+
async function refreshModels(provider) {
|
|
69308
|
+
const config7 = getConfig();
|
|
69309
|
+
const apiKey = config7.OCO_API_KEY;
|
|
69310
|
+
const loadingSpinner = le();
|
|
69311
|
+
loadingSpinner.start(`Fetching models from ${provider}...`);
|
|
69312
|
+
clearModelCache();
|
|
69313
|
+
try {
|
|
69314
|
+
const models = await fetchModelsForProvider(provider, apiKey, void 0, true);
|
|
69315
|
+
loadingSpinner.stop(`${source_default.green("+")} Fetched ${models.length} models`);
|
|
69316
|
+
await listModels(provider, true);
|
|
69317
|
+
} catch (error) {
|
|
69318
|
+
loadingSpinner.stop(source_default.red("Failed to fetch models"));
|
|
69319
|
+
console.error(source_default.red(`Error: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
69320
|
+
}
|
|
69321
|
+
}
|
|
69322
|
+
var modelsCommand = G3(
|
|
69323
|
+
{
|
|
69324
|
+
name: "models" /* models */,
|
|
69325
|
+
help: {
|
|
69326
|
+
description: "List and manage cached models for your AI provider"
|
|
69327
|
+
},
|
|
69328
|
+
flags: {
|
|
69329
|
+
refresh: {
|
|
69330
|
+
type: Boolean,
|
|
69331
|
+
alias: "r",
|
|
69332
|
+
description: "Clear cache and re-fetch models from the provider",
|
|
69333
|
+
default: false
|
|
69334
|
+
},
|
|
69335
|
+
provider: {
|
|
69336
|
+
type: String,
|
|
69337
|
+
alias: "p",
|
|
69338
|
+
description: "Specify provider (defaults to current OCO_AI_PROVIDER)"
|
|
69339
|
+
}
|
|
69340
|
+
}
|
|
69341
|
+
},
|
|
69342
|
+
async ({ flags }) => {
|
|
69343
|
+
const config7 = getConfig();
|
|
69344
|
+
const provider = flags.provider || config7.OCO_AI_PROVIDER || "openai" /* OPENAI */;
|
|
69345
|
+
ae(source_default.bgCyan(" OpenCommit Models "));
|
|
69346
|
+
const cacheInfo = getCacheInfo();
|
|
69347
|
+
if (cacheInfo.timestamp) {
|
|
69348
|
+
console.log(
|
|
69349
|
+
source_default.dim(` Cache last updated: ${formatCacheAge2(cacheInfo.timestamp)}`)
|
|
69350
|
+
);
|
|
69351
|
+
if (cacheInfo.providers.length > 0) {
|
|
69352
|
+
console.log(
|
|
69353
|
+
source_default.dim(` Cached providers: ${cacheInfo.providers.join(", ")}`)
|
|
69354
|
+
);
|
|
69355
|
+
}
|
|
69356
|
+
} else {
|
|
69357
|
+
console.log(source_default.dim(" No cached models"));
|
|
69358
|
+
}
|
|
69359
|
+
if (flags.refresh) {
|
|
69360
|
+
await refreshModels(provider);
|
|
69361
|
+
} else {
|
|
69362
|
+
await listModels(provider);
|
|
69363
|
+
}
|
|
69364
|
+
ce(
|
|
69365
|
+
`Run ${source_default.cyan("oco models --refresh")} to update the model list`
|
|
69366
|
+
);
|
|
69367
|
+
}
|
|
69368
|
+
);
|
|
69369
|
+
|
|
68847
69370
|
// src/utils/checkIsLatestVersion.ts
|
|
68848
69371
|
init_dist2();
|
|
68849
69372
|
|
|
@@ -69036,7 +69559,7 @@ Z2(
|
|
|
69036
69559
|
{
|
|
69037
69560
|
version: package_default.version,
|
|
69038
69561
|
name: "opencommit",
|
|
69039
|
-
commands: [configCommand, hookCommand, commitlintConfigCommand, setupCommand],
|
|
69562
|
+
commands: [configCommand, hookCommand, commitlintConfigCommand, setupCommand, modelsCommand],
|
|
69040
69563
|
flags: {
|
|
69041
69564
|
fgm: {
|
|
69042
69565
|
type: Boolean,
|