git-coco 0.17.0 → 0.18.1
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/dist/index.d.ts +3 -2
- package/dist/index.esm.mjs +245 -112
- package/dist/index.js +245 -112
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -11,9 +11,10 @@ import { Color } from 'chalk';
|
|
|
11
11
|
import { TiktokenModel as TiktokenModel$1 } from 'tiktoken';
|
|
12
12
|
|
|
13
13
|
type LLMProvider = 'openai' | 'ollama' | 'anthropic';
|
|
14
|
+
type OpenAIModel = TiktokenModel | 'gpt-4o-mini' | 'gpt-4o' | 'gpt-4.1' | 'gpt-4.1-mini' | 'gpt-4.1-nano';
|
|
14
15
|
type AnthropicModel = 'claude-sonnet-4-0' | 'claude-3-7-sonnet-latest' | 'claude-3-5-haiku-latest' | 'claude-3-5-sonnet-latest' | 'claude-3-5-sonnet-20241022' | 'claude-3-5-sonnet-20240620' | 'claude-3-opus-20240229' | 'claude-3-sonnet-20240229' | 'claude-3-haiku-20240307';
|
|
15
16
|
type OllamaModel = 'deepseek-r1:1.5b' | 'deepseek-r1:8b' | 'deepseek-r1:32b' | 'codegemma:2b' | 'codegemma:7b-code' | 'codegemma' | 'codellama:13b' | 'codellama:34b' | 'codellama:70b' | 'codellama:7b' | 'codellama:instruct' | 'codellama:latest' | 'codellama' | 'gemma:2b' | 'gemma:7b' | 'gemma:latest' | 'gemma' | 'llama2:13b' | 'llama2:70b' | 'llama2:chat' | 'llama2:latest' | 'llama2:text' | 'llama2' | 'llama3:70b-text' | 'llama3:70b' | 'llama3:latest' | 'llama3:text' | 'llama3.1:70b' | 'llama3.1:8b' | 'llama3.1:latest' | 'llama3.2' | 'llama3.2:latest' | 'llama3.2:1b' | 'llama3.2:3b' | 'llama3' | 'llava-llama3:latest' | 'dolphin-llama3:latest' | 'dolphin-llama3:8b' | 'dolphin-llama3:70b' | 'mistral:7b' | 'mistral:latest' | 'mistral:text' | 'mistral' | 'phi3:14b' | 'phi3:3.8b' | 'phi3:instruct' | 'phi3:medium-128k' | 'phi3:medium-4k' | 'phi3:medium' | 'phi3' | 'qwen2:0.5b' | 'qwen2:1.5b' | 'qwen2:72b-text' | 'qwen2:72b' | 'qwen2' | 'qwen2.5-coder:latest' | 'qwen2.5-coder:0.5b' | 'qwen2.5-coder:1.5b' | 'qwen2.5-coder:3b' | 'qwen2.5-coder:7b' | 'qwen2.5-coder:14b' | 'qwen2.5-coder:32b';
|
|
16
|
-
type LLMModel =
|
|
17
|
+
type LLMModel = OpenAIModel | OllamaModel | AnthropicModel;
|
|
17
18
|
type BaseLLMService = {
|
|
18
19
|
provider: LLMProvider;
|
|
19
20
|
model: LLMModel;
|
|
@@ -68,7 +69,7 @@ type OpenAIFields = Partial<OpenAIInput> & BaseLLMParams;
|
|
|
68
69
|
type OllamaFields = Partial<OllamaInput> & BaseLLMParams;
|
|
69
70
|
type OpenAILLMService = BaseLLMService & {
|
|
70
71
|
provider: 'openai';
|
|
71
|
-
model:
|
|
72
|
+
model: OpenAIModel;
|
|
72
73
|
fields?: OpenAIFields;
|
|
73
74
|
};
|
|
74
75
|
type OllamaLLMService = BaseLLMService & {
|
package/dist/index.esm.mjs
CHANGED
|
@@ -46,7 +46,7 @@ import * as readline from 'readline';
|
|
|
46
46
|
/**
|
|
47
47
|
* Current build version from package.json
|
|
48
48
|
*/
|
|
49
|
-
const BUILD_VERSION = "0.
|
|
49
|
+
const BUILD_VERSION = "0.18.1";
|
|
50
50
|
|
|
51
51
|
const isInteractive = (config) => {
|
|
52
52
|
return config?.mode === 'interactive' || !!config?.interactive;
|
|
@@ -345,7 +345,7 @@ function getDefaultServiceApiKey(config) {
|
|
|
345
345
|
}
|
|
346
346
|
const DEFAULT_OPENAI_LLM_SERVICE = {
|
|
347
347
|
provider: 'openai',
|
|
348
|
-
model: 'gpt-4o',
|
|
348
|
+
model: 'gpt-4o-mini',
|
|
349
349
|
tokenLimit: 2024,
|
|
350
350
|
temperature: 0.32,
|
|
351
351
|
authentication: {
|
|
@@ -454,14 +454,29 @@ const CONFIG_KEYS = Object.keys({
|
|
|
454
454
|
**/
|
|
455
455
|
function loadEnvConfig(config) {
|
|
456
456
|
const envConfig = {};
|
|
457
|
-
const envKeys = [
|
|
457
|
+
const envKeys = [
|
|
458
|
+
...CONFIG_KEYS,
|
|
459
|
+
'COCO_SERVICE_PROVIDER',
|
|
460
|
+
'COCO_SERVICE_MODEL',
|
|
461
|
+
'OPEN_AI_KEY',
|
|
462
|
+
'COCO_SERVICE_ENDPOINT',
|
|
463
|
+
'COCO_SERVICE_REQUEST_OPTIONS_TIMEOUT',
|
|
464
|
+
'COCO_SERVICE_REQUEST_OPTIONS_MAX_RETRIES',
|
|
465
|
+
'COCO_SERVICE_FIELDS',
|
|
466
|
+
];
|
|
458
467
|
envKeys.forEach((key) => {
|
|
459
468
|
const envVarName = toEnvVarName(key);
|
|
460
469
|
const envValue = parseEnvValue(key, process.env[envVarName]);
|
|
461
470
|
if (envValue === undefined) {
|
|
462
471
|
return;
|
|
463
472
|
}
|
|
464
|
-
if (key === 'COCO_SERVICE_PROVIDER' ||
|
|
473
|
+
if (key === 'COCO_SERVICE_PROVIDER' ||
|
|
474
|
+
key === 'COCO_SERVICE_MODEL' ||
|
|
475
|
+
key === 'OPEN_AI_KEY' ||
|
|
476
|
+
key === 'COCO_SERVICE_ENDPOINT' ||
|
|
477
|
+
key === 'COCO_SERVICE_REQUEST_OPTIONS_TIMEOUT' ||
|
|
478
|
+
key === 'COCO_SERVICE_REQUEST_OPTIONS_MAX_RETRIES' ||
|
|
479
|
+
key === 'COCO_SERVICE_FIELDS') {
|
|
465
480
|
// NOTE: We want to ensure that the service object is always defined
|
|
466
481
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
467
482
|
// @ts-ignore
|
|
@@ -488,9 +503,28 @@ function handleServiceEnvVar(service, key, value) {
|
|
|
488
503
|
break;
|
|
489
504
|
case 'OPEN_AI_KEY':
|
|
490
505
|
if (service.provider === 'openai') {
|
|
491
|
-
service.
|
|
506
|
+
service.authentication = {
|
|
507
|
+
type: 'APIKey',
|
|
508
|
+
credentials: {
|
|
509
|
+
apiKey: value,
|
|
510
|
+
},
|
|
511
|
+
};
|
|
492
512
|
}
|
|
493
513
|
break;
|
|
514
|
+
case 'COCO_SERVICE_ENDPOINT':
|
|
515
|
+
if (service.provider === 'ollama') {
|
|
516
|
+
service.endpoint = value;
|
|
517
|
+
}
|
|
518
|
+
break;
|
|
519
|
+
case 'COCO_SERVICE_REQUEST_OPTIONS_TIMEOUT':
|
|
520
|
+
service.requestOptions = { ...service.requestOptions, timeout: value };
|
|
521
|
+
break;
|
|
522
|
+
case 'COCO_SERVICE_REQUEST_OPTIONS_MAX_RETRIES':
|
|
523
|
+
service.requestOptions = { ...service.requestOptions, maxRetries: value };
|
|
524
|
+
break;
|
|
525
|
+
case 'COCO_SERVICE_FIELDS':
|
|
526
|
+
service.fields = value;
|
|
527
|
+
break;
|
|
494
528
|
}
|
|
495
529
|
}
|
|
496
530
|
function parseEnvValue(key, value) {
|
|
@@ -509,6 +543,9 @@ function parseEnvValue(key, value) {
|
|
|
509
543
|
// Handle number values
|
|
510
544
|
case typeof value === 'string' && !isNaN(Number(value)):
|
|
511
545
|
return Number(value);
|
|
546
|
+
// Handle JSON strings
|
|
547
|
+
case typeof value === 'string' && value.startsWith('{'):
|
|
548
|
+
return JSON.parse(value);
|
|
512
549
|
default:
|
|
513
550
|
return value;
|
|
514
551
|
}
|
|
@@ -522,32 +559,40 @@ function toEnvVarName(key) {
|
|
|
522
559
|
}
|
|
523
560
|
return `COCO_${key.replace(/([A-Z])/g, '_$1').toLocaleUpperCase()}`;
|
|
524
561
|
}
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
562
|
+
const flattenObject = (obj, prefix = '') => {
|
|
563
|
+
let flattened = {};
|
|
564
|
+
for (const key in obj) {
|
|
565
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
566
|
+
const propName = prefix ? `${prefix}_${key}` : key;
|
|
567
|
+
const value = obj[key];
|
|
568
|
+
// Skip undefined or null values
|
|
569
|
+
if (value === undefined || value === null) {
|
|
570
|
+
continue;
|
|
571
|
+
}
|
|
572
|
+
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
573
|
+
// Handle nested objects, but specifically handle 'fields' as JSON string
|
|
574
|
+
if (key === 'fields') {
|
|
575
|
+
flattened[propName.toUpperCase()] = JSON.stringify(value);
|
|
576
|
+
}
|
|
577
|
+
else {
|
|
578
|
+
flattened = { ...flattened, ...flattenObject(value, propName) };
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
else {
|
|
582
|
+
// For primitive types (string, number, boolean, symbol, bigint) and arrays
|
|
583
|
+
flattened[propName.toUpperCase()] = String(value);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
535
586
|
}
|
|
536
|
-
return
|
|
537
|
-
}
|
|
587
|
+
return flattened;
|
|
588
|
+
};
|
|
538
589
|
const appendToEnvFile = async (filePath, config) => {
|
|
539
590
|
const getNewContent = async () => {
|
|
540
|
-
|
|
591
|
+
const flattenedConfig = flattenObject(config);
|
|
592
|
+
return Object.entries(flattenedConfig)
|
|
541
593
|
.map(([key, value]) => {
|
|
542
|
-
if (key === 'service') {
|
|
543
|
-
const service = value;
|
|
544
|
-
return `${service.provider ? `COCO_SERVICE_PROVIDER=${service.provider}` : ''}\n${service.model ? `COCO_SERVICE_MODEL=${service.model}` : ''}\n${service.authentication.type === 'APIKey'
|
|
545
|
-
? `OPEN_AI_KEY=${service.authentication.credentials.apiKey}`
|
|
546
|
-
: ''}`;
|
|
547
|
-
}
|
|
548
594
|
const envVarName = toEnvVarName(key);
|
|
549
|
-
|
|
550
|
-
return `${envVarName}=${envValue}`;
|
|
595
|
+
return `${envVarName}=${value}`;
|
|
551
596
|
})
|
|
552
597
|
.join('\n');
|
|
553
598
|
};
|
|
@@ -571,22 +616,31 @@ function loadGitConfig(config) {
|
|
|
571
616
|
if (fs.existsSync(gitConfigPath)) {
|
|
572
617
|
const gitConfigRaw = fs.readFileSync(gitConfigPath, 'utf-8');
|
|
573
618
|
const gitConfigParsed = ini.parse(gitConfigRaw);
|
|
574
|
-
const gitConfigServiceObject = gitConfigParsed.coco?.service;
|
|
575
619
|
let service = config.service;
|
|
576
|
-
if (
|
|
577
|
-
|
|
578
|
-
|
|
620
|
+
if (gitConfigParsed.coco) {
|
|
621
|
+
service = {
|
|
622
|
+
provider: gitConfigParsed.coco?.serviceProvider,
|
|
623
|
+
model: gitConfigParsed.coco?.serviceModel,
|
|
624
|
+
authentication: {
|
|
625
|
+
type: 'APIKey',
|
|
626
|
+
credentials: {
|
|
627
|
+
apiKey: gitConfigParsed.coco?.serviceApiKey,
|
|
628
|
+
},
|
|
629
|
+
},
|
|
630
|
+
requestOptions: {
|
|
631
|
+
timeout: Number(gitConfigParsed.coco?.serviceRequestOptionsTimeout),
|
|
632
|
+
maxRetries: Number(gitConfigParsed.coco?.serviceRequestOptionsMaxRetries),
|
|
633
|
+
},
|
|
634
|
+
endpoint: gitConfigParsed.coco?.serviceEndpoint,
|
|
635
|
+
fields: gitConfigParsed.coco?.serviceFields
|
|
636
|
+
? JSON.parse(gitConfigParsed.coco?.serviceFields)
|
|
637
|
+
: undefined,
|
|
638
|
+
};
|
|
579
639
|
}
|
|
580
640
|
config = {
|
|
581
641
|
...config,
|
|
642
|
+
...gitConfigParsed.coco,
|
|
582
643
|
service: service,
|
|
583
|
-
prompt: gitConfigParsed.coco?.prompt || config.prompt,
|
|
584
|
-
mode: gitConfigParsed.coco?.mode || config.mode,
|
|
585
|
-
summarizePrompt: gitConfigParsed.coco?.summarizePrompt || config.summarizePrompt,
|
|
586
|
-
ignoredFiles: gitConfigParsed.coco?.ignoredFiles || config.ignoredFiles,
|
|
587
|
-
ignoredExtensions: gitConfigParsed.coco?.ignoredExtensions || config.ignoredExtensions,
|
|
588
|
-
defaultBranch: gitConfigParsed.coco?.defaultBranch || config.defaultBranch,
|
|
589
|
-
verbose: gitConfigParsed.coco?.verbose || config.verbose,
|
|
590
644
|
};
|
|
591
645
|
}
|
|
592
646
|
return removeUndefined(config);
|
|
@@ -606,9 +660,28 @@ const appendToGitConfig = async (filePath, config) => {
|
|
|
606
660
|
const contentLines = [header];
|
|
607
661
|
for (const key in config) {
|
|
608
662
|
const value = config[key];
|
|
609
|
-
if (
|
|
610
|
-
|
|
611
|
-
contentLines.push(
|
|
663
|
+
if (key === 'service') {
|
|
664
|
+
const service = value;
|
|
665
|
+
contentLines.push(` serviceProvider = ${service.provider}`);
|
|
666
|
+
contentLines.push(` serviceModel = ${service.model}`);
|
|
667
|
+
if (service.authentication.type === 'APIKey') {
|
|
668
|
+
contentLines.push(` serviceApiKey = ${service.authentication.credentials.apiKey}`);
|
|
669
|
+
}
|
|
670
|
+
if (service.requestOptions?.timeout) {
|
|
671
|
+
contentLines.push(` serviceRequestOptionsTimeout = ${service.requestOptions.timeout}`);
|
|
672
|
+
}
|
|
673
|
+
if (service.requestOptions?.maxRetries) {
|
|
674
|
+
contentLines.push(` serviceRequestOptionsMaxRetries = ${service.requestOptions.maxRetries}`);
|
|
675
|
+
}
|
|
676
|
+
if (service.provider === 'ollama') {
|
|
677
|
+
const ollamaService = service;
|
|
678
|
+
if (ollamaService.endpoint) {
|
|
679
|
+
contentLines.push(` serviceEndpoint = ${ollamaService.endpoint}`);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
if (service.fields) {
|
|
683
|
+
contentLines.push(` serviceFields = ${JSON.stringify(service.fields)}`);
|
|
684
|
+
}
|
|
612
685
|
}
|
|
613
686
|
else if (typeof value === 'string' && value.includes('\n')) {
|
|
614
687
|
// Wrap strings with new lines in quotes
|
|
@@ -1062,65 +1135,7 @@ const schema$1 = {
|
|
|
1062
1135
|
"LLMModel": {
|
|
1063
1136
|
"anyOf": [
|
|
1064
1137
|
{
|
|
1065
|
-
"
|
|
1066
|
-
"enum": [
|
|
1067
|
-
"davinci-002",
|
|
1068
|
-
"babbage-002",
|
|
1069
|
-
"text-davinci-003",
|
|
1070
|
-
"text-davinci-002",
|
|
1071
|
-
"text-davinci-001",
|
|
1072
|
-
"text-curie-001",
|
|
1073
|
-
"text-babbage-001",
|
|
1074
|
-
"text-ada-001",
|
|
1075
|
-
"davinci",
|
|
1076
|
-
"curie",
|
|
1077
|
-
"babbage",
|
|
1078
|
-
"ada",
|
|
1079
|
-
"code-davinci-002",
|
|
1080
|
-
"code-davinci-001",
|
|
1081
|
-
"code-cushman-002",
|
|
1082
|
-
"code-cushman-001",
|
|
1083
|
-
"davinci-codex",
|
|
1084
|
-
"cushman-codex",
|
|
1085
|
-
"text-davinci-edit-001",
|
|
1086
|
-
"code-davinci-edit-001",
|
|
1087
|
-
"text-embedding-ada-002",
|
|
1088
|
-
"text-similarity-davinci-001",
|
|
1089
|
-
"text-similarity-curie-001",
|
|
1090
|
-
"text-similarity-babbage-001",
|
|
1091
|
-
"text-similarity-ada-001",
|
|
1092
|
-
"text-search-davinci-doc-001",
|
|
1093
|
-
"text-search-curie-doc-001",
|
|
1094
|
-
"text-search-babbage-doc-001",
|
|
1095
|
-
"text-search-ada-doc-001",
|
|
1096
|
-
"code-search-babbage-code-001",
|
|
1097
|
-
"code-search-ada-code-001",
|
|
1098
|
-
"gpt2",
|
|
1099
|
-
"gpt-3.5-turbo",
|
|
1100
|
-
"gpt-35-turbo",
|
|
1101
|
-
"gpt-3.5-turbo-0301",
|
|
1102
|
-
"gpt-3.5-turbo-0613",
|
|
1103
|
-
"gpt-3.5-turbo-1106",
|
|
1104
|
-
"gpt-3.5-turbo-0125",
|
|
1105
|
-
"gpt-3.5-turbo-16k",
|
|
1106
|
-
"gpt-3.5-turbo-16k-0613",
|
|
1107
|
-
"gpt-3.5-turbo-instruct",
|
|
1108
|
-
"gpt-3.5-turbo-instruct-0914",
|
|
1109
|
-
"gpt-4",
|
|
1110
|
-
"gpt-4-0314",
|
|
1111
|
-
"gpt-4-0613",
|
|
1112
|
-
"gpt-4-32k",
|
|
1113
|
-
"gpt-4-32k-0314",
|
|
1114
|
-
"gpt-4-32k-0613",
|
|
1115
|
-
"gpt-4-turbo",
|
|
1116
|
-
"gpt-4-turbo-2024-04-09",
|
|
1117
|
-
"gpt-4-turbo-preview",
|
|
1118
|
-
"gpt-4-1106-preview",
|
|
1119
|
-
"gpt-4-0125-preview",
|
|
1120
|
-
"gpt-4-vision-preview",
|
|
1121
|
-
"gpt-4o",
|
|
1122
|
-
"gpt-4o-2024-05-13"
|
|
1123
|
-
]
|
|
1138
|
+
"$ref": "#/definitions/OpenAIModel"
|
|
1124
1139
|
},
|
|
1125
1140
|
{
|
|
1126
1141
|
"$ref": "#/definitions/OllamaModel"
|
|
@@ -1130,6 +1145,71 @@ const schema$1 = {
|
|
|
1130
1145
|
}
|
|
1131
1146
|
]
|
|
1132
1147
|
},
|
|
1148
|
+
"OpenAIModel": {
|
|
1149
|
+
"type": "string",
|
|
1150
|
+
"enum": [
|
|
1151
|
+
"davinci-002",
|
|
1152
|
+
"babbage-002",
|
|
1153
|
+
"text-davinci-003",
|
|
1154
|
+
"text-davinci-002",
|
|
1155
|
+
"text-davinci-001",
|
|
1156
|
+
"text-curie-001",
|
|
1157
|
+
"text-babbage-001",
|
|
1158
|
+
"text-ada-001",
|
|
1159
|
+
"davinci",
|
|
1160
|
+
"curie",
|
|
1161
|
+
"babbage",
|
|
1162
|
+
"ada",
|
|
1163
|
+
"code-davinci-002",
|
|
1164
|
+
"code-davinci-001",
|
|
1165
|
+
"code-cushman-002",
|
|
1166
|
+
"code-cushman-001",
|
|
1167
|
+
"davinci-codex",
|
|
1168
|
+
"cushman-codex",
|
|
1169
|
+
"text-davinci-edit-001",
|
|
1170
|
+
"code-davinci-edit-001",
|
|
1171
|
+
"text-embedding-ada-002",
|
|
1172
|
+
"text-similarity-davinci-001",
|
|
1173
|
+
"text-similarity-curie-001",
|
|
1174
|
+
"text-similarity-babbage-001",
|
|
1175
|
+
"text-similarity-ada-001",
|
|
1176
|
+
"text-search-davinci-doc-001",
|
|
1177
|
+
"text-search-curie-doc-001",
|
|
1178
|
+
"text-search-babbage-doc-001",
|
|
1179
|
+
"text-search-ada-doc-001",
|
|
1180
|
+
"code-search-babbage-code-001",
|
|
1181
|
+
"code-search-ada-code-001",
|
|
1182
|
+
"gpt2",
|
|
1183
|
+
"gpt-3.5-turbo",
|
|
1184
|
+
"gpt-35-turbo",
|
|
1185
|
+
"gpt-3.5-turbo-0301",
|
|
1186
|
+
"gpt-3.5-turbo-0613",
|
|
1187
|
+
"gpt-3.5-turbo-1106",
|
|
1188
|
+
"gpt-3.5-turbo-0125",
|
|
1189
|
+
"gpt-3.5-turbo-16k",
|
|
1190
|
+
"gpt-3.5-turbo-16k-0613",
|
|
1191
|
+
"gpt-3.5-turbo-instruct",
|
|
1192
|
+
"gpt-3.5-turbo-instruct-0914",
|
|
1193
|
+
"gpt-4",
|
|
1194
|
+
"gpt-4-0314",
|
|
1195
|
+
"gpt-4-0613",
|
|
1196
|
+
"gpt-4-32k",
|
|
1197
|
+
"gpt-4-32k-0314",
|
|
1198
|
+
"gpt-4-32k-0613",
|
|
1199
|
+
"gpt-4-turbo",
|
|
1200
|
+
"gpt-4-turbo-2024-04-09",
|
|
1201
|
+
"gpt-4-turbo-preview",
|
|
1202
|
+
"gpt-4-1106-preview",
|
|
1203
|
+
"gpt-4-0125-preview",
|
|
1204
|
+
"gpt-4-vision-preview",
|
|
1205
|
+
"gpt-4o",
|
|
1206
|
+
"gpt-4o-2024-05-13",
|
|
1207
|
+
"gpt-4o-mini",
|
|
1208
|
+
"gpt-4.1",
|
|
1209
|
+
"gpt-4.1-mini",
|
|
1210
|
+
"gpt-4.1-nano"
|
|
1211
|
+
]
|
|
1212
|
+
},
|
|
1133
1213
|
"OllamaModel": {
|
|
1134
1214
|
"type": "string",
|
|
1135
1215
|
"enum": [
|
|
@@ -6046,7 +6126,6 @@ function getPrompt({ template, variables, fallback }) {
|
|
|
6046
6126
|
* @throws LangChainExecutionError if the chain execution fails or returns empty results
|
|
6047
6127
|
*/
|
|
6048
6128
|
const executeChain = async ({ llm, prompt, variables, parser }) => {
|
|
6049
|
-
// Validate all required parameters
|
|
6050
6129
|
validateRequired(llm, 'llm', 'executeChain');
|
|
6051
6130
|
validateRequired(prompt, 'prompt', 'executeChain');
|
|
6052
6131
|
validateRequired(variables, 'variables', 'executeChain');
|
|
@@ -6058,7 +6137,6 @@ const executeChain = async ({ llm, prompt, variables, parser }) => {
|
|
|
6058
6137
|
try {
|
|
6059
6138
|
const chain = prompt.pipe(llm).pipe(parser);
|
|
6060
6139
|
const result = await chain.invoke(variables);
|
|
6061
|
-
console.debug('LLMChain call result:', result);
|
|
6062
6140
|
if (result === null || result === undefined) {
|
|
6063
6141
|
throw new LangChainExecutionError('executeChain: Chain execution returned null or undefined result', { variables, promptInputVariables: prompt.inputVariables });
|
|
6064
6142
|
}
|
|
@@ -7406,7 +7484,6 @@ class OutputFixingParser extends BaseOutputParser {
|
|
|
7406
7484
|
* @throws LangChainExecutionError if parser creation fails
|
|
7407
7485
|
*/
|
|
7408
7486
|
function createSchemaParser(schema, llm, options = {}) {
|
|
7409
|
-
// Validate required parameters
|
|
7410
7487
|
validateRequired(schema, 'schema', 'createSchemaParser');
|
|
7411
7488
|
validateRequired(llm, 'llm', 'createSchemaParser');
|
|
7412
7489
|
validateRequired(options, 'options', 'createSchemaParser');
|
|
@@ -7466,7 +7543,6 @@ You must return ONLY valid JSON that matches the schema exactly. Do not include
|
|
|
7466
7543
|
async function executeChainWithSchema(schema, llm, prompt, variables, options = {}) {
|
|
7467
7544
|
const { retryOptions = { maxAttempts: 3 }, fallbackParser, onFallback, ...parserOptions } = options;
|
|
7468
7545
|
const parser = createSchemaParser(schema, llm, parserOptions);
|
|
7469
|
-
// Define the operation to retry
|
|
7470
7546
|
const operation = async () => {
|
|
7471
7547
|
const result = await executeChain({
|
|
7472
7548
|
llm,
|
|
@@ -7477,16 +7553,13 @@ async function executeChainWithSchema(schema, llm, prompt, variables, options =
|
|
|
7477
7553
|
return result;
|
|
7478
7554
|
};
|
|
7479
7555
|
try {
|
|
7480
|
-
// Use the general retry utility
|
|
7481
7556
|
return await withRetry(operation, retryOptions);
|
|
7482
7557
|
}
|
|
7483
7558
|
catch (error) {
|
|
7484
|
-
// If all retries failed and we have a fallback parser, use it
|
|
7485
7559
|
if (fallbackParser) {
|
|
7486
7560
|
if (onFallback) {
|
|
7487
7561
|
onFallback();
|
|
7488
7562
|
}
|
|
7489
|
-
// Generate without structured parsing as fallback
|
|
7490
7563
|
const fallbackResult = await executeChain({
|
|
7491
7564
|
llm,
|
|
7492
7565
|
prompt,
|
|
@@ -10870,6 +10943,11 @@ const handler$3 = async (argv, logger) => {
|
|
|
10870
10943
|
else {
|
|
10871
10944
|
logger.setConfig({ silent: true });
|
|
10872
10945
|
}
|
|
10946
|
+
if (config.service.provider === 'ollama') {
|
|
10947
|
+
logger.verbose('⚠️ Ollama models may not strictly adhere to the output format instructions.', {
|
|
10948
|
+
color: 'yellow',
|
|
10949
|
+
});
|
|
10950
|
+
}
|
|
10873
10951
|
async function factory() {
|
|
10874
10952
|
const changes = await getChanges({
|
|
10875
10953
|
git,
|
|
@@ -10925,11 +11003,6 @@ const handler$3 = async (argv, logger) => {
|
|
|
10925
11003
|
variables: promptTemplate.inputVariables,
|
|
10926
11004
|
fallback: promptTemplate,
|
|
10927
11005
|
});
|
|
10928
|
-
if (config.service.provider === 'ollama') {
|
|
10929
|
-
logger.log('Note: Ollama models may not strictly adhere to the output format instructions.', {
|
|
10930
|
-
color: 'yellow',
|
|
10931
|
-
});
|
|
10932
|
-
}
|
|
10933
11006
|
// Get additional context if provided
|
|
10934
11007
|
let additional_context = '';
|
|
10935
11008
|
if (argv.additional) {
|
|
@@ -10970,7 +11043,7 @@ const handler$3 = async (argv, logger) => {
|
|
|
10970
11043
|
maxAttempts,
|
|
10971
11044
|
onRetry: (attempt, error) => {
|
|
10972
11045
|
logger.verbose(`Failed to parse commit message (attempt ${attempt}/${maxAttempts}): ${error.message}`, { color: 'yellow' });
|
|
10973
|
-
}
|
|
11046
|
+
},
|
|
10974
11047
|
},
|
|
10975
11048
|
fallbackParser: (text) => ({
|
|
10976
11049
|
title: text.split('\n')[0] || 'Auto-generated commit',
|
|
@@ -11191,11 +11264,22 @@ async function getProjectConfigFilePath(configFileName) {
|
|
|
11191
11264
|
}
|
|
11192
11265
|
|
|
11193
11266
|
const OPEN_AI_MODELS = [
|
|
11267
|
+
'gpt-4.5',
|
|
11194
11268
|
'gpt-4o',
|
|
11269
|
+
'gpt-4o-mini',
|
|
11270
|
+
'gpt-4.1',
|
|
11271
|
+
'gpt-4.1',
|
|
11272
|
+
'gpt-4.1-mini',
|
|
11273
|
+
'gpt-4.1-nano',
|
|
11195
11274
|
'gpt-4-32k',
|
|
11196
11275
|
'gpt-4-turbo',
|
|
11197
11276
|
'gpt-4',
|
|
11198
11277
|
'gpt-3.5-turbo',
|
|
11278
|
+
'o1',
|
|
11279
|
+
'o1-mini',
|
|
11280
|
+
'03-mini',
|
|
11281
|
+
'03',
|
|
11282
|
+
'o4-mini',
|
|
11199
11283
|
];
|
|
11200
11284
|
const ANTHROPIC_MODELS = [
|
|
11201
11285
|
'claude-sonnet-4-0',
|
|
@@ -11340,6 +11424,32 @@ const questions = {
|
|
|
11340
11424
|
});
|
|
11341
11425
|
return parseFloat(temperature);
|
|
11342
11426
|
},
|
|
11427
|
+
inputOllamaEndpoint: async () => {
|
|
11428
|
+
return await input({
|
|
11429
|
+
message: 'Ollama endpoint (e.g., http://localhost:11434):',
|
|
11430
|
+
default: 'http://localhost:11434',
|
|
11431
|
+
});
|
|
11432
|
+
},
|
|
11433
|
+
inputRequestTimeout: async () => {
|
|
11434
|
+
const timeout = await input({
|
|
11435
|
+
message: 'Request timeout in milliseconds:',
|
|
11436
|
+
default: '30000',
|
|
11437
|
+
});
|
|
11438
|
+
return parseInt(timeout);
|
|
11439
|
+
},
|
|
11440
|
+
inputRequestMaxRetries: async () => {
|
|
11441
|
+
const maxRetries = await input({
|
|
11442
|
+
message: 'Maximum number of request retries:',
|
|
11443
|
+
default: '3',
|
|
11444
|
+
});
|
|
11445
|
+
return parseInt(maxRetries);
|
|
11446
|
+
},
|
|
11447
|
+
inputServiceFields: async () => {
|
|
11448
|
+
return await editor({
|
|
11449
|
+
message: 'Enter additional service fields as a JSON string (optional):',
|
|
11450
|
+
default: '{}',
|
|
11451
|
+
});
|
|
11452
|
+
},
|
|
11343
11453
|
selectDefaultGitBranch: async () => (await input({
|
|
11344
11454
|
message: 'default branch for the repository:',
|
|
11345
11455
|
default: 'main',
|
|
@@ -11433,6 +11543,29 @@ const handler$2 = async (argv, logger) => {
|
|
|
11433
11543
|
tokenLimit: await questions.inputTokenLimit(),
|
|
11434
11544
|
};
|
|
11435
11545
|
config.verbose = await questions.enableVerboseMode();
|
|
11546
|
+
if (llmProvider === 'ollama') {
|
|
11547
|
+
config.service.endpoint = await questions.inputOllamaEndpoint();
|
|
11548
|
+
}
|
|
11549
|
+
config.service.requestOptions = {
|
|
11550
|
+
timeout: await questions.inputRequestTimeout(),
|
|
11551
|
+
maxRetries: await questions.inputRequestMaxRetries(),
|
|
11552
|
+
};
|
|
11553
|
+
const promptForServiceFields = await confirm({
|
|
11554
|
+
message: 'would you like to configure additional service fields (advanced)?',
|
|
11555
|
+
default: false,
|
|
11556
|
+
});
|
|
11557
|
+
if (promptForServiceFields) {
|
|
11558
|
+
const fieldsJson = await questions.inputServiceFields();
|
|
11559
|
+
try {
|
|
11560
|
+
config.service.fields = JSON.parse(fieldsJson);
|
|
11561
|
+
}
|
|
11562
|
+
catch (e) {
|
|
11563
|
+
logger.log('Invalid JSON for service fields. Skipping.', { color: 'red' });
|
|
11564
|
+
logger.verbose(`Error parsing service fields: ${e.message}`, {
|
|
11565
|
+
color: 'red',
|
|
11566
|
+
});
|
|
11567
|
+
}
|
|
11568
|
+
}
|
|
11436
11569
|
const promptForIgnores = await confirm({
|
|
11437
11570
|
message: 'would you like to configure ignored files and extensions?',
|
|
11438
11571
|
default: false,
|
package/dist/index.js
CHANGED
|
@@ -68,7 +68,7 @@ var readline__namespace = /*#__PURE__*/_interopNamespaceDefault(readline$1);
|
|
|
68
68
|
/**
|
|
69
69
|
* Current build version from package.json
|
|
70
70
|
*/
|
|
71
|
-
const BUILD_VERSION = "0.
|
|
71
|
+
const BUILD_VERSION = "0.18.1";
|
|
72
72
|
|
|
73
73
|
const isInteractive = (config) => {
|
|
74
74
|
return config?.mode === 'interactive' || !!config?.interactive;
|
|
@@ -367,7 +367,7 @@ function getDefaultServiceApiKey(config) {
|
|
|
367
367
|
}
|
|
368
368
|
const DEFAULT_OPENAI_LLM_SERVICE = {
|
|
369
369
|
provider: 'openai',
|
|
370
|
-
model: 'gpt-4o',
|
|
370
|
+
model: 'gpt-4o-mini',
|
|
371
371
|
tokenLimit: 2024,
|
|
372
372
|
temperature: 0.32,
|
|
373
373
|
authentication: {
|
|
@@ -476,14 +476,29 @@ const CONFIG_KEYS = Object.keys({
|
|
|
476
476
|
**/
|
|
477
477
|
function loadEnvConfig(config) {
|
|
478
478
|
const envConfig = {};
|
|
479
|
-
const envKeys = [
|
|
479
|
+
const envKeys = [
|
|
480
|
+
...CONFIG_KEYS,
|
|
481
|
+
'COCO_SERVICE_PROVIDER',
|
|
482
|
+
'COCO_SERVICE_MODEL',
|
|
483
|
+
'OPEN_AI_KEY',
|
|
484
|
+
'COCO_SERVICE_ENDPOINT',
|
|
485
|
+
'COCO_SERVICE_REQUEST_OPTIONS_TIMEOUT',
|
|
486
|
+
'COCO_SERVICE_REQUEST_OPTIONS_MAX_RETRIES',
|
|
487
|
+
'COCO_SERVICE_FIELDS',
|
|
488
|
+
];
|
|
480
489
|
envKeys.forEach((key) => {
|
|
481
490
|
const envVarName = toEnvVarName(key);
|
|
482
491
|
const envValue = parseEnvValue(key, process.env[envVarName]);
|
|
483
492
|
if (envValue === undefined) {
|
|
484
493
|
return;
|
|
485
494
|
}
|
|
486
|
-
if (key === 'COCO_SERVICE_PROVIDER' ||
|
|
495
|
+
if (key === 'COCO_SERVICE_PROVIDER' ||
|
|
496
|
+
key === 'COCO_SERVICE_MODEL' ||
|
|
497
|
+
key === 'OPEN_AI_KEY' ||
|
|
498
|
+
key === 'COCO_SERVICE_ENDPOINT' ||
|
|
499
|
+
key === 'COCO_SERVICE_REQUEST_OPTIONS_TIMEOUT' ||
|
|
500
|
+
key === 'COCO_SERVICE_REQUEST_OPTIONS_MAX_RETRIES' ||
|
|
501
|
+
key === 'COCO_SERVICE_FIELDS') {
|
|
487
502
|
// NOTE: We want to ensure that the service object is always defined
|
|
488
503
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
489
504
|
// @ts-ignore
|
|
@@ -510,9 +525,28 @@ function handleServiceEnvVar(service, key, value) {
|
|
|
510
525
|
break;
|
|
511
526
|
case 'OPEN_AI_KEY':
|
|
512
527
|
if (service.provider === 'openai') {
|
|
513
|
-
service.
|
|
528
|
+
service.authentication = {
|
|
529
|
+
type: 'APIKey',
|
|
530
|
+
credentials: {
|
|
531
|
+
apiKey: value,
|
|
532
|
+
},
|
|
533
|
+
};
|
|
514
534
|
}
|
|
515
535
|
break;
|
|
536
|
+
case 'COCO_SERVICE_ENDPOINT':
|
|
537
|
+
if (service.provider === 'ollama') {
|
|
538
|
+
service.endpoint = value;
|
|
539
|
+
}
|
|
540
|
+
break;
|
|
541
|
+
case 'COCO_SERVICE_REQUEST_OPTIONS_TIMEOUT':
|
|
542
|
+
service.requestOptions = { ...service.requestOptions, timeout: value };
|
|
543
|
+
break;
|
|
544
|
+
case 'COCO_SERVICE_REQUEST_OPTIONS_MAX_RETRIES':
|
|
545
|
+
service.requestOptions = { ...service.requestOptions, maxRetries: value };
|
|
546
|
+
break;
|
|
547
|
+
case 'COCO_SERVICE_FIELDS':
|
|
548
|
+
service.fields = value;
|
|
549
|
+
break;
|
|
516
550
|
}
|
|
517
551
|
}
|
|
518
552
|
function parseEnvValue(key, value) {
|
|
@@ -531,6 +565,9 @@ function parseEnvValue(key, value) {
|
|
|
531
565
|
// Handle number values
|
|
532
566
|
case typeof value === 'string' && !isNaN(Number(value)):
|
|
533
567
|
return Number(value);
|
|
568
|
+
// Handle JSON strings
|
|
569
|
+
case typeof value === 'string' && value.startsWith('{'):
|
|
570
|
+
return JSON.parse(value);
|
|
534
571
|
default:
|
|
535
572
|
return value;
|
|
536
573
|
}
|
|
@@ -544,32 +581,40 @@ function toEnvVarName(key) {
|
|
|
544
581
|
}
|
|
545
582
|
return `COCO_${key.replace(/([A-Z])/g, '_$1').toLocaleUpperCase()}`;
|
|
546
583
|
}
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
584
|
+
const flattenObject = (obj, prefix = '') => {
|
|
585
|
+
let flattened = {};
|
|
586
|
+
for (const key in obj) {
|
|
587
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
588
|
+
const propName = prefix ? `${prefix}_${key}` : key;
|
|
589
|
+
const value = obj[key];
|
|
590
|
+
// Skip undefined or null values
|
|
591
|
+
if (value === undefined || value === null) {
|
|
592
|
+
continue;
|
|
593
|
+
}
|
|
594
|
+
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
595
|
+
// Handle nested objects, but specifically handle 'fields' as JSON string
|
|
596
|
+
if (key === 'fields') {
|
|
597
|
+
flattened[propName.toUpperCase()] = JSON.stringify(value);
|
|
598
|
+
}
|
|
599
|
+
else {
|
|
600
|
+
flattened = { ...flattened, ...flattenObject(value, propName) };
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
else {
|
|
604
|
+
// For primitive types (string, number, boolean, symbol, bigint) and arrays
|
|
605
|
+
flattened[propName.toUpperCase()] = String(value);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
557
608
|
}
|
|
558
|
-
return
|
|
559
|
-
}
|
|
609
|
+
return flattened;
|
|
610
|
+
};
|
|
560
611
|
const appendToEnvFile = async (filePath, config) => {
|
|
561
612
|
const getNewContent = async () => {
|
|
562
|
-
|
|
613
|
+
const flattenedConfig = flattenObject(config);
|
|
614
|
+
return Object.entries(flattenedConfig)
|
|
563
615
|
.map(([key, value]) => {
|
|
564
|
-
if (key === 'service') {
|
|
565
|
-
const service = value;
|
|
566
|
-
return `${service.provider ? `COCO_SERVICE_PROVIDER=${service.provider}` : ''}\n${service.model ? `COCO_SERVICE_MODEL=${service.model}` : ''}\n${service.authentication.type === 'APIKey'
|
|
567
|
-
? `OPEN_AI_KEY=${service.authentication.credentials.apiKey}`
|
|
568
|
-
: ''}`;
|
|
569
|
-
}
|
|
570
616
|
const envVarName = toEnvVarName(key);
|
|
571
|
-
|
|
572
|
-
return `${envVarName}=${envValue}`;
|
|
617
|
+
return `${envVarName}=${value}`;
|
|
573
618
|
})
|
|
574
619
|
.join('\n');
|
|
575
620
|
};
|
|
@@ -593,22 +638,31 @@ function loadGitConfig(config) {
|
|
|
593
638
|
if (fs__namespace.existsSync(gitConfigPath)) {
|
|
594
639
|
const gitConfigRaw = fs__namespace.readFileSync(gitConfigPath, 'utf-8');
|
|
595
640
|
const gitConfigParsed = ini__namespace.parse(gitConfigRaw);
|
|
596
|
-
const gitConfigServiceObject = gitConfigParsed.coco?.service;
|
|
597
641
|
let service = config.service;
|
|
598
|
-
if (
|
|
599
|
-
|
|
600
|
-
|
|
642
|
+
if (gitConfigParsed.coco) {
|
|
643
|
+
service = {
|
|
644
|
+
provider: gitConfigParsed.coco?.serviceProvider,
|
|
645
|
+
model: gitConfigParsed.coco?.serviceModel,
|
|
646
|
+
authentication: {
|
|
647
|
+
type: 'APIKey',
|
|
648
|
+
credentials: {
|
|
649
|
+
apiKey: gitConfigParsed.coco?.serviceApiKey,
|
|
650
|
+
},
|
|
651
|
+
},
|
|
652
|
+
requestOptions: {
|
|
653
|
+
timeout: Number(gitConfigParsed.coco?.serviceRequestOptionsTimeout),
|
|
654
|
+
maxRetries: Number(gitConfigParsed.coco?.serviceRequestOptionsMaxRetries),
|
|
655
|
+
},
|
|
656
|
+
endpoint: gitConfigParsed.coco?.serviceEndpoint,
|
|
657
|
+
fields: gitConfigParsed.coco?.serviceFields
|
|
658
|
+
? JSON.parse(gitConfigParsed.coco?.serviceFields)
|
|
659
|
+
: undefined,
|
|
660
|
+
};
|
|
601
661
|
}
|
|
602
662
|
config = {
|
|
603
663
|
...config,
|
|
664
|
+
...gitConfigParsed.coco,
|
|
604
665
|
service: service,
|
|
605
|
-
prompt: gitConfigParsed.coco?.prompt || config.prompt,
|
|
606
|
-
mode: gitConfigParsed.coco?.mode || config.mode,
|
|
607
|
-
summarizePrompt: gitConfigParsed.coco?.summarizePrompt || config.summarizePrompt,
|
|
608
|
-
ignoredFiles: gitConfigParsed.coco?.ignoredFiles || config.ignoredFiles,
|
|
609
|
-
ignoredExtensions: gitConfigParsed.coco?.ignoredExtensions || config.ignoredExtensions,
|
|
610
|
-
defaultBranch: gitConfigParsed.coco?.defaultBranch || config.defaultBranch,
|
|
611
|
-
verbose: gitConfigParsed.coco?.verbose || config.verbose,
|
|
612
666
|
};
|
|
613
667
|
}
|
|
614
668
|
return removeUndefined(config);
|
|
@@ -628,9 +682,28 @@ const appendToGitConfig = async (filePath, config) => {
|
|
|
628
682
|
const contentLines = [header];
|
|
629
683
|
for (const key in config) {
|
|
630
684
|
const value = config[key];
|
|
631
|
-
if (
|
|
632
|
-
|
|
633
|
-
contentLines.push(
|
|
685
|
+
if (key === 'service') {
|
|
686
|
+
const service = value;
|
|
687
|
+
contentLines.push(` serviceProvider = ${service.provider}`);
|
|
688
|
+
contentLines.push(` serviceModel = ${service.model}`);
|
|
689
|
+
if (service.authentication.type === 'APIKey') {
|
|
690
|
+
contentLines.push(` serviceApiKey = ${service.authentication.credentials.apiKey}`);
|
|
691
|
+
}
|
|
692
|
+
if (service.requestOptions?.timeout) {
|
|
693
|
+
contentLines.push(` serviceRequestOptionsTimeout = ${service.requestOptions.timeout}`);
|
|
694
|
+
}
|
|
695
|
+
if (service.requestOptions?.maxRetries) {
|
|
696
|
+
contentLines.push(` serviceRequestOptionsMaxRetries = ${service.requestOptions.maxRetries}`);
|
|
697
|
+
}
|
|
698
|
+
if (service.provider === 'ollama') {
|
|
699
|
+
const ollamaService = service;
|
|
700
|
+
if (ollamaService.endpoint) {
|
|
701
|
+
contentLines.push(` serviceEndpoint = ${ollamaService.endpoint}`);
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
if (service.fields) {
|
|
705
|
+
contentLines.push(` serviceFields = ${JSON.stringify(service.fields)}`);
|
|
706
|
+
}
|
|
634
707
|
}
|
|
635
708
|
else if (typeof value === 'string' && value.includes('\n')) {
|
|
636
709
|
// Wrap strings with new lines in quotes
|
|
@@ -1084,65 +1157,7 @@ const schema$1 = {
|
|
|
1084
1157
|
"LLMModel": {
|
|
1085
1158
|
"anyOf": [
|
|
1086
1159
|
{
|
|
1087
|
-
"
|
|
1088
|
-
"enum": [
|
|
1089
|
-
"davinci-002",
|
|
1090
|
-
"babbage-002",
|
|
1091
|
-
"text-davinci-003",
|
|
1092
|
-
"text-davinci-002",
|
|
1093
|
-
"text-davinci-001",
|
|
1094
|
-
"text-curie-001",
|
|
1095
|
-
"text-babbage-001",
|
|
1096
|
-
"text-ada-001",
|
|
1097
|
-
"davinci",
|
|
1098
|
-
"curie",
|
|
1099
|
-
"babbage",
|
|
1100
|
-
"ada",
|
|
1101
|
-
"code-davinci-002",
|
|
1102
|
-
"code-davinci-001",
|
|
1103
|
-
"code-cushman-002",
|
|
1104
|
-
"code-cushman-001",
|
|
1105
|
-
"davinci-codex",
|
|
1106
|
-
"cushman-codex",
|
|
1107
|
-
"text-davinci-edit-001",
|
|
1108
|
-
"code-davinci-edit-001",
|
|
1109
|
-
"text-embedding-ada-002",
|
|
1110
|
-
"text-similarity-davinci-001",
|
|
1111
|
-
"text-similarity-curie-001",
|
|
1112
|
-
"text-similarity-babbage-001",
|
|
1113
|
-
"text-similarity-ada-001",
|
|
1114
|
-
"text-search-davinci-doc-001",
|
|
1115
|
-
"text-search-curie-doc-001",
|
|
1116
|
-
"text-search-babbage-doc-001",
|
|
1117
|
-
"text-search-ada-doc-001",
|
|
1118
|
-
"code-search-babbage-code-001",
|
|
1119
|
-
"code-search-ada-code-001",
|
|
1120
|
-
"gpt2",
|
|
1121
|
-
"gpt-3.5-turbo",
|
|
1122
|
-
"gpt-35-turbo",
|
|
1123
|
-
"gpt-3.5-turbo-0301",
|
|
1124
|
-
"gpt-3.5-turbo-0613",
|
|
1125
|
-
"gpt-3.5-turbo-1106",
|
|
1126
|
-
"gpt-3.5-turbo-0125",
|
|
1127
|
-
"gpt-3.5-turbo-16k",
|
|
1128
|
-
"gpt-3.5-turbo-16k-0613",
|
|
1129
|
-
"gpt-3.5-turbo-instruct",
|
|
1130
|
-
"gpt-3.5-turbo-instruct-0914",
|
|
1131
|
-
"gpt-4",
|
|
1132
|
-
"gpt-4-0314",
|
|
1133
|
-
"gpt-4-0613",
|
|
1134
|
-
"gpt-4-32k",
|
|
1135
|
-
"gpt-4-32k-0314",
|
|
1136
|
-
"gpt-4-32k-0613",
|
|
1137
|
-
"gpt-4-turbo",
|
|
1138
|
-
"gpt-4-turbo-2024-04-09",
|
|
1139
|
-
"gpt-4-turbo-preview",
|
|
1140
|
-
"gpt-4-1106-preview",
|
|
1141
|
-
"gpt-4-0125-preview",
|
|
1142
|
-
"gpt-4-vision-preview",
|
|
1143
|
-
"gpt-4o",
|
|
1144
|
-
"gpt-4o-2024-05-13"
|
|
1145
|
-
]
|
|
1160
|
+
"$ref": "#/definitions/OpenAIModel"
|
|
1146
1161
|
},
|
|
1147
1162
|
{
|
|
1148
1163
|
"$ref": "#/definitions/OllamaModel"
|
|
@@ -1152,6 +1167,71 @@ const schema$1 = {
|
|
|
1152
1167
|
}
|
|
1153
1168
|
]
|
|
1154
1169
|
},
|
|
1170
|
+
"OpenAIModel": {
|
|
1171
|
+
"type": "string",
|
|
1172
|
+
"enum": [
|
|
1173
|
+
"davinci-002",
|
|
1174
|
+
"babbage-002",
|
|
1175
|
+
"text-davinci-003",
|
|
1176
|
+
"text-davinci-002",
|
|
1177
|
+
"text-davinci-001",
|
|
1178
|
+
"text-curie-001",
|
|
1179
|
+
"text-babbage-001",
|
|
1180
|
+
"text-ada-001",
|
|
1181
|
+
"davinci",
|
|
1182
|
+
"curie",
|
|
1183
|
+
"babbage",
|
|
1184
|
+
"ada",
|
|
1185
|
+
"code-davinci-002",
|
|
1186
|
+
"code-davinci-001",
|
|
1187
|
+
"code-cushman-002",
|
|
1188
|
+
"code-cushman-001",
|
|
1189
|
+
"davinci-codex",
|
|
1190
|
+
"cushman-codex",
|
|
1191
|
+
"text-davinci-edit-001",
|
|
1192
|
+
"code-davinci-edit-001",
|
|
1193
|
+
"text-embedding-ada-002",
|
|
1194
|
+
"text-similarity-davinci-001",
|
|
1195
|
+
"text-similarity-curie-001",
|
|
1196
|
+
"text-similarity-babbage-001",
|
|
1197
|
+
"text-similarity-ada-001",
|
|
1198
|
+
"text-search-davinci-doc-001",
|
|
1199
|
+
"text-search-curie-doc-001",
|
|
1200
|
+
"text-search-babbage-doc-001",
|
|
1201
|
+
"text-search-ada-doc-001",
|
|
1202
|
+
"code-search-babbage-code-001",
|
|
1203
|
+
"code-search-ada-code-001",
|
|
1204
|
+
"gpt2",
|
|
1205
|
+
"gpt-3.5-turbo",
|
|
1206
|
+
"gpt-35-turbo",
|
|
1207
|
+
"gpt-3.5-turbo-0301",
|
|
1208
|
+
"gpt-3.5-turbo-0613",
|
|
1209
|
+
"gpt-3.5-turbo-1106",
|
|
1210
|
+
"gpt-3.5-turbo-0125",
|
|
1211
|
+
"gpt-3.5-turbo-16k",
|
|
1212
|
+
"gpt-3.5-turbo-16k-0613",
|
|
1213
|
+
"gpt-3.5-turbo-instruct",
|
|
1214
|
+
"gpt-3.5-turbo-instruct-0914",
|
|
1215
|
+
"gpt-4",
|
|
1216
|
+
"gpt-4-0314",
|
|
1217
|
+
"gpt-4-0613",
|
|
1218
|
+
"gpt-4-32k",
|
|
1219
|
+
"gpt-4-32k-0314",
|
|
1220
|
+
"gpt-4-32k-0613",
|
|
1221
|
+
"gpt-4-turbo",
|
|
1222
|
+
"gpt-4-turbo-2024-04-09",
|
|
1223
|
+
"gpt-4-turbo-preview",
|
|
1224
|
+
"gpt-4-1106-preview",
|
|
1225
|
+
"gpt-4-0125-preview",
|
|
1226
|
+
"gpt-4-vision-preview",
|
|
1227
|
+
"gpt-4o",
|
|
1228
|
+
"gpt-4o-2024-05-13",
|
|
1229
|
+
"gpt-4o-mini",
|
|
1230
|
+
"gpt-4.1",
|
|
1231
|
+
"gpt-4.1-mini",
|
|
1232
|
+
"gpt-4.1-nano"
|
|
1233
|
+
]
|
|
1234
|
+
},
|
|
1155
1235
|
"OllamaModel": {
|
|
1156
1236
|
"type": "string",
|
|
1157
1237
|
"enum": [
|
|
@@ -6068,7 +6148,6 @@ function getPrompt({ template, variables, fallback }) {
|
|
|
6068
6148
|
* @throws LangChainExecutionError if the chain execution fails or returns empty results
|
|
6069
6149
|
*/
|
|
6070
6150
|
const executeChain = async ({ llm, prompt, variables, parser }) => {
|
|
6071
|
-
// Validate all required parameters
|
|
6072
6151
|
validateRequired(llm, 'llm', 'executeChain');
|
|
6073
6152
|
validateRequired(prompt, 'prompt', 'executeChain');
|
|
6074
6153
|
validateRequired(variables, 'variables', 'executeChain');
|
|
@@ -6080,7 +6159,6 @@ const executeChain = async ({ llm, prompt, variables, parser }) => {
|
|
|
6080
6159
|
try {
|
|
6081
6160
|
const chain = prompt.pipe(llm).pipe(parser);
|
|
6082
6161
|
const result = await chain.invoke(variables);
|
|
6083
|
-
console.debug('LLMChain call result:', result);
|
|
6084
6162
|
if (result === null || result === undefined) {
|
|
6085
6163
|
throw new LangChainExecutionError('executeChain: Chain execution returned null or undefined result', { variables, promptInputVariables: prompt.inputVariables });
|
|
6086
6164
|
}
|
|
@@ -7428,7 +7506,6 @@ class OutputFixingParser extends output_parsers.BaseOutputParser {
|
|
|
7428
7506
|
* @throws LangChainExecutionError if parser creation fails
|
|
7429
7507
|
*/
|
|
7430
7508
|
function createSchemaParser(schema, llm, options = {}) {
|
|
7431
|
-
// Validate required parameters
|
|
7432
7509
|
validateRequired(schema, 'schema', 'createSchemaParser');
|
|
7433
7510
|
validateRequired(llm, 'llm', 'createSchemaParser');
|
|
7434
7511
|
validateRequired(options, 'options', 'createSchemaParser');
|
|
@@ -7488,7 +7565,6 @@ You must return ONLY valid JSON that matches the schema exactly. Do not include
|
|
|
7488
7565
|
async function executeChainWithSchema(schema, llm, prompt, variables, options = {}) {
|
|
7489
7566
|
const { retryOptions = { maxAttempts: 3 }, fallbackParser, onFallback, ...parserOptions } = options;
|
|
7490
7567
|
const parser = createSchemaParser(schema, llm, parserOptions);
|
|
7491
|
-
// Define the operation to retry
|
|
7492
7568
|
const operation = async () => {
|
|
7493
7569
|
const result = await executeChain({
|
|
7494
7570
|
llm,
|
|
@@ -7499,16 +7575,13 @@ async function executeChainWithSchema(schema, llm, prompt, variables, options =
|
|
|
7499
7575
|
return result;
|
|
7500
7576
|
};
|
|
7501
7577
|
try {
|
|
7502
|
-
// Use the general retry utility
|
|
7503
7578
|
return await withRetry(operation, retryOptions);
|
|
7504
7579
|
}
|
|
7505
7580
|
catch (error) {
|
|
7506
|
-
// If all retries failed and we have a fallback parser, use it
|
|
7507
7581
|
if (fallbackParser) {
|
|
7508
7582
|
if (onFallback) {
|
|
7509
7583
|
onFallback();
|
|
7510
7584
|
}
|
|
7511
|
-
// Generate without structured parsing as fallback
|
|
7512
7585
|
const fallbackResult = await executeChain({
|
|
7513
7586
|
llm,
|
|
7514
7587
|
prompt,
|
|
@@ -10892,6 +10965,11 @@ const handler$3 = async (argv, logger) => {
|
|
|
10892
10965
|
else {
|
|
10893
10966
|
logger.setConfig({ silent: true });
|
|
10894
10967
|
}
|
|
10968
|
+
if (config.service.provider === 'ollama') {
|
|
10969
|
+
logger.verbose('⚠️ Ollama models may not strictly adhere to the output format instructions.', {
|
|
10970
|
+
color: 'yellow',
|
|
10971
|
+
});
|
|
10972
|
+
}
|
|
10895
10973
|
async function factory() {
|
|
10896
10974
|
const changes = await getChanges({
|
|
10897
10975
|
git,
|
|
@@ -10947,11 +11025,6 @@ const handler$3 = async (argv, logger) => {
|
|
|
10947
11025
|
variables: promptTemplate.inputVariables,
|
|
10948
11026
|
fallback: promptTemplate,
|
|
10949
11027
|
});
|
|
10950
|
-
if (config.service.provider === 'ollama') {
|
|
10951
|
-
logger.log('Note: Ollama models may not strictly adhere to the output format instructions.', {
|
|
10952
|
-
color: 'yellow',
|
|
10953
|
-
});
|
|
10954
|
-
}
|
|
10955
11028
|
// Get additional context if provided
|
|
10956
11029
|
let additional_context = '';
|
|
10957
11030
|
if (argv.additional) {
|
|
@@ -10992,7 +11065,7 @@ const handler$3 = async (argv, logger) => {
|
|
|
10992
11065
|
maxAttempts,
|
|
10993
11066
|
onRetry: (attempt, error) => {
|
|
10994
11067
|
logger.verbose(`Failed to parse commit message (attempt ${attempt}/${maxAttempts}): ${error.message}`, { color: 'yellow' });
|
|
10995
|
-
}
|
|
11068
|
+
},
|
|
10996
11069
|
},
|
|
10997
11070
|
fallbackParser: (text) => ({
|
|
10998
11071
|
title: text.split('\n')[0] || 'Auto-generated commit',
|
|
@@ -11213,11 +11286,22 @@ async function getProjectConfigFilePath(configFileName) {
|
|
|
11213
11286
|
}
|
|
11214
11287
|
|
|
11215
11288
|
const OPEN_AI_MODELS = [
|
|
11289
|
+
'gpt-4.5',
|
|
11216
11290
|
'gpt-4o',
|
|
11291
|
+
'gpt-4o-mini',
|
|
11292
|
+
'gpt-4.1',
|
|
11293
|
+
'gpt-4.1',
|
|
11294
|
+
'gpt-4.1-mini',
|
|
11295
|
+
'gpt-4.1-nano',
|
|
11217
11296
|
'gpt-4-32k',
|
|
11218
11297
|
'gpt-4-turbo',
|
|
11219
11298
|
'gpt-4',
|
|
11220
11299
|
'gpt-3.5-turbo',
|
|
11300
|
+
'o1',
|
|
11301
|
+
'o1-mini',
|
|
11302
|
+
'03-mini',
|
|
11303
|
+
'03',
|
|
11304
|
+
'o4-mini',
|
|
11221
11305
|
];
|
|
11222
11306
|
const ANTHROPIC_MODELS = [
|
|
11223
11307
|
'claude-sonnet-4-0',
|
|
@@ -11362,6 +11446,32 @@ const questions = {
|
|
|
11362
11446
|
});
|
|
11363
11447
|
return parseFloat(temperature);
|
|
11364
11448
|
},
|
|
11449
|
+
inputOllamaEndpoint: async () => {
|
|
11450
|
+
return await prompts.input({
|
|
11451
|
+
message: 'Ollama endpoint (e.g., http://localhost:11434):',
|
|
11452
|
+
default: 'http://localhost:11434',
|
|
11453
|
+
});
|
|
11454
|
+
},
|
|
11455
|
+
inputRequestTimeout: async () => {
|
|
11456
|
+
const timeout = await prompts.input({
|
|
11457
|
+
message: 'Request timeout in milliseconds:',
|
|
11458
|
+
default: '30000',
|
|
11459
|
+
});
|
|
11460
|
+
return parseInt(timeout);
|
|
11461
|
+
},
|
|
11462
|
+
inputRequestMaxRetries: async () => {
|
|
11463
|
+
const maxRetries = await prompts.input({
|
|
11464
|
+
message: 'Maximum number of request retries:',
|
|
11465
|
+
default: '3',
|
|
11466
|
+
});
|
|
11467
|
+
return parseInt(maxRetries);
|
|
11468
|
+
},
|
|
11469
|
+
inputServiceFields: async () => {
|
|
11470
|
+
return await prompts.editor({
|
|
11471
|
+
message: 'Enter additional service fields as a JSON string (optional):',
|
|
11472
|
+
default: '{}',
|
|
11473
|
+
});
|
|
11474
|
+
},
|
|
11365
11475
|
selectDefaultGitBranch: async () => (await prompts.input({
|
|
11366
11476
|
message: 'default branch for the repository:',
|
|
11367
11477
|
default: 'main',
|
|
@@ -11455,6 +11565,29 @@ const handler$2 = async (argv, logger) => {
|
|
|
11455
11565
|
tokenLimit: await questions.inputTokenLimit(),
|
|
11456
11566
|
};
|
|
11457
11567
|
config.verbose = await questions.enableVerboseMode();
|
|
11568
|
+
if (llmProvider === 'ollama') {
|
|
11569
|
+
config.service.endpoint = await questions.inputOllamaEndpoint();
|
|
11570
|
+
}
|
|
11571
|
+
config.service.requestOptions = {
|
|
11572
|
+
timeout: await questions.inputRequestTimeout(),
|
|
11573
|
+
maxRetries: await questions.inputRequestMaxRetries(),
|
|
11574
|
+
};
|
|
11575
|
+
const promptForServiceFields = await prompts.confirm({
|
|
11576
|
+
message: 'would you like to configure additional service fields (advanced)?',
|
|
11577
|
+
default: false,
|
|
11578
|
+
});
|
|
11579
|
+
if (promptForServiceFields) {
|
|
11580
|
+
const fieldsJson = await questions.inputServiceFields();
|
|
11581
|
+
try {
|
|
11582
|
+
config.service.fields = JSON.parse(fieldsJson);
|
|
11583
|
+
}
|
|
11584
|
+
catch (e) {
|
|
11585
|
+
logger.log('Invalid JSON for service fields. Skipping.', { color: 'red' });
|
|
11586
|
+
logger.verbose(`Error parsing service fields: ${e.message}`, {
|
|
11587
|
+
color: 'red',
|
|
11588
|
+
});
|
|
11589
|
+
}
|
|
11590
|
+
}
|
|
11458
11591
|
const promptForIgnores = await prompts.confirm({
|
|
11459
11592
|
message: 'would you like to configure ignored files and extensions?',
|
|
11460
11593
|
default: false,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "git-coco",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.1",
|
|
4
4
|
"description": "zero-effort git commits with coco.",
|
|
5
5
|
"author": "gfargo <ghfargo@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -105,7 +105,7 @@
|
|
|
105
105
|
"performance-now": "2.1.0",
|
|
106
106
|
"pretty-ms": "7.0.1",
|
|
107
107
|
"simple-git": "3.27.0",
|
|
108
|
-
"tiktoken": "^1.0.
|
|
108
|
+
"tiktoken": "^1.0.21",
|
|
109
109
|
"yargs": "17.7.2"
|
|
110
110
|
},
|
|
111
111
|
"resolutions": {
|