git-coco 0.3.0 → 0.3.2

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.js CHANGED
@@ -1,28 +1,27 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict';
3
3
 
4
+ var yargs = require('yargs');
4
5
  var prompts$1 = require('@inquirer/prompts');
6
+ var simpleGit = require('simple-git');
5
7
  var fs = require('fs');
6
8
  var os = require('os');
7
9
  var path = require('path');
8
10
  var ini = require('ini');
9
- var yargs = require('yargs');
10
- var helpers = require('yargs/helpers');
11
11
  var prompts = require('langchain/prompts');
12
12
  var pQueue = require('p-queue');
13
- var chalk = require('chalk');
14
- var ora = require('ora');
15
- var now = require('performance-now');
16
- var prettyMilliseconds = require('pretty-ms');
17
13
  var document = require('langchain/document');
18
14
  var hf = require('langchain/llms/hf');
19
15
  var chains = require('langchain/chains');
20
16
  var openai = require('langchain/llms/openai');
21
17
  var text_splitter = require('langchain/text_splitter');
22
18
  var diff = require('diff');
19
+ var chalk = require('chalk');
23
20
  var GPT3NodeTokenizer = require('gpt3-tokenizer');
21
+ var ora = require('ora');
22
+ var now = require('performance-now');
23
+ var prettyMilliseconds = require('pretty-ms');
24
24
  var minimatch = require('minimatch');
25
- var simpleGit = require('simple-git');
26
25
 
27
26
  function _interopNamespaceDefault(e) {
28
27
  var n = Object.create(null);
@@ -175,74 +174,6 @@ function loadXDGConfig(config) {
175
174
  return config;
176
175
  }
177
176
 
178
- /**
179
- * Command line options via yargs
180
- */
181
- const options = {
182
- model: { type: 'string', description: 'LLM/Model-Name' },
183
- openAIApiKey: { type: 'string', description: 'OpenAI API Key' },
184
- huggingFaceHubApiKey: { type: 'string', description: 'HuggingFace Hub API Key' },
185
- tokenLimit: { type: 'number', description: 'Token limit' },
186
- prompt: {
187
- type: 'string',
188
- alias: 'p',
189
- description: 'Commit message prompt',
190
- },
191
- interactive: {
192
- type: 'boolean',
193
- alias: 'i',
194
- description: 'Toggle interactive mode',
195
- },
196
- commit: {
197
- type: 'boolean',
198
- alias: 's',
199
- description: 'Commit staged changes with generated commit message',
200
- default: false,
201
- },
202
- openInEditor: {
203
- type: 'boolean',
204
- alias: 'e',
205
- description: 'Open commit message in editor before proceeding',
206
- },
207
- verbose: {
208
- type: 'boolean',
209
- description: 'Enable verbose logging',
210
- },
211
- summarizePrompt: {
212
- type: 'string',
213
- description: 'Large file summary prompt',
214
- },
215
- ignoredFiles: {
216
- type: 'array',
217
- description: 'Ignored files',
218
- },
219
- ignoredExtensions: {
220
- type: 'array',
221
- description: 'Ignored extensions',
222
- },
223
- };
224
- /**
225
- * Load command line flags via yargs
226
- *
227
- * @returns {Partial<Config>} Updated config
228
- */
229
- const loadArgv = () => {
230
- return yargs(helpers.hideBin(process.argv)).options(options).parseSync();
231
- };
232
- /**
233
- * Load command line flags
234
- *
235
- * Note: Arugments are parsed using yargs.
236
- *
237
- * @param {Config} config
238
- * @returns {Config} Updated config
239
- **/
240
- function loadCmdLineFlags(config) {
241
- const argv = loadArgv();
242
- config = { ...config, ...argv };
243
- return config;
244
- }
245
-
246
177
  const template$1 = `Write informative git commit message based on the diffs & file changes provided in the "Diff Summary" section.
247
178
  Commit Messages must have a short description that is less than 50 characters followed by a newline character and then a more verbose detailed description.
248
179
  - Write concisely using an informal tone
@@ -305,7 +236,7 @@ const DEFAULT_CONFIG = {
305
236
  *
306
237
  * @returns {Config} application config
307
238
  **/
308
- function loadConfig() {
239
+ function loadConfig(argv = {}) {
309
240
  // Default config
310
241
  let config = DEFAULT_CONFIG;
311
242
  config = loadGitignore(config);
@@ -314,60 +245,7 @@ function loadConfig() {
314
245
  config = loadGitConfig(config);
315
246
  config = loadProjectConfig(config);
316
247
  config = loadEnvConfig(config);
317
- config = loadCmdLineFlags(config);
318
- return config;
319
- }
320
- const config = loadConfig();
321
-
322
- class Logger {
323
- constructor(config) {
324
- this.config = config;
325
- this.spinner = null;
326
- }
327
- log(message, options = { color: 'blue' }) {
328
- let outputMessage = message;
329
- if (options.color) {
330
- outputMessage = chalk[options.color](outputMessage);
331
- }
332
- console.log(outputMessage);
333
- return this;
334
- }
335
- verbose(message, options = {}) {
336
- if (!this.config?.verbose) {
337
- return this;
338
- }
339
- this.log(message, options);
340
- return this;
341
- }
342
- startTimer() {
343
- this.timerStart = now();
344
- return this;
345
- }
346
- stopTimer(message, options = { color: 'yellow' }) {
347
- if (!this.config?.verbose || !this.timerStart) {
348
- return this;
349
- }
350
- const elapsedTime = prettyMilliseconds(now() - this.timerStart);
351
- let outputMessage = message
352
- ? `${message} (⏲ ${elapsedTime})`
353
- : `⏲ ${elapsedTime}`;
354
- if (options.color) {
355
- outputMessage = chalk[options.color](outputMessage);
356
- }
357
- console.log(outputMessage);
358
- return this;
359
- }
360
- startSpinner(message, options = { color: 'green' }) {
361
- const spinnerMessage = options.color ? chalk[options.color](message) : message;
362
- this.spinner = ora(spinnerMessage).start();
363
- return this;
364
- }
365
- stopSpinner(message = '', options = { mode: 'succeed', color: 'green' }) {
366
- const spinnerMessage = options?.color ? chalk[options.color](message) : message;
367
- this.spinner?.[options.mode || 'succeed'](spinnerMessage);
368
- this.spinner = null;
369
- return this;
370
- }
248
+ return { ...config, ...argv };
371
249
  }
372
250
 
373
251
  /**
@@ -454,8 +332,7 @@ const defaultOutputCallback = (group) => {
454
332
  }
455
333
  return output;
456
334
  };
457
- async function summarizeDiffs(rootDiffNode, { tokenizer, maxTokens = 2048, textSplitter, chain, handleOutput = defaultOutputCallback, }) {
458
- const logger = new Logger(config);
335
+ async function summarizeDiffs(rootDiffNode, { tokenizer, logger, maxTokens = 2048, textSplitter, chain, handleOutput = defaultOutputCallback, }) {
459
336
  const queue = new pQueue({ concurrency: 8 });
460
337
  logger.startTimer().startSpinner(`Organizing Diffs...`, { color: 'blue' });
461
338
  const directoryDiffs = createDirectoryDiffs(rootDiffNode);
@@ -541,7 +418,7 @@ const createDiffTree = (changes) => {
541
418
  /**
542
419
  * Asynchronously collect diffs for a given node and its children.
543
420
  */
544
- async function collectDiffs(node, getFileDiff, tokenizer, logger = new Logger(config)) {
421
+ async function collectDiffs(node, getFileDiff, tokenizer, logger) {
545
422
  // Collect diffs for the files of the current node
546
423
  const diffPromises = node.files.map(async (nodeFile) => {
547
424
  const diff = await getFileDiff(nodeFile);
@@ -559,7 +436,7 @@ async function collectDiffs(node, getFileDiff, tokenizer, logger = new Logger(co
559
436
  };
560
437
  });
561
438
  // Collect diffs for the children of the current node
562
- const childrenPromises = Array.from(node.children.values()).map(async (child) => collectDiffs(child, getFileDiff, tokenizer));
439
+ const childrenPromises = Array.from(node.children.values()).map(async (child) => collectDiffs(child, getFileDiff, tokenizer, logger));
563
440
  const [diffs, children] = await Promise.all([
564
441
  Promise.all(diffPromises),
565
442
  Promise.all(childrenPromises),
@@ -573,36 +450,65 @@ async function collectDiffs(node, getFileDiff, tokenizer, logger = new Logger(co
573
450
 
574
451
  /**
575
452
  * Get LLM Model Based on Configuration
576
- *
577
453
  * @param fields
578
454
  * @param configuration
579
455
  * @returns LLM Model
580
456
  */
581
- function getModel(fields, configuration) {
582
- const [llm, model] = config.model.split(/\/(.*)/s);
457
+ function getModel(name, key, fields, configuration) {
458
+ const [llm, model] = name.split(/\/(.*)/s);
583
459
  if (!model) {
584
- throw new Error(`Invalid model: ${config.model}`);
460
+ throw new Error(`Invalid model: ${name}`);
585
461
  }
586
462
  switch (llm) {
587
463
  case 'huggingface':
588
464
  return new hf.HuggingFaceInference({
589
465
  model: model,
590
- apiKey: config.huggingFaceHubApiKey,
466
+ apiKey: key,
591
467
  maxConcurrency: 4,
592
468
  ...fields,
593
469
  });
594
470
  case 'openai':
595
471
  default:
596
472
  return new openai.OpenAI({
597
- openAIApiKey: config.openAIApiKey,
473
+ openAIApiKey: key,
598
474
  modelName: model,
599
475
  ...fields,
600
476
  }, configuration);
601
477
  }
602
478
  }
479
+ /**
480
+ * Retrieve appropriate API key based on selected model
481
+ * @param name
482
+ * @param options
483
+ * @returns
484
+ */
485
+ function getModelAPIKey(name, options) {
486
+ const [llm, model] = name.split(/\/(.*)/s);
487
+ if (!model) {
488
+ throw new Error(`Invalid model: ${name}`);
489
+ }
490
+ switch (llm) {
491
+ case 'huggingface':
492
+ return options.huggingFaceHubApiKey;
493
+ case 'openai':
494
+ default:
495
+ return options.openAIApiKey;
496
+ }
497
+ }
498
+ /**
499
+ * Get Recursive Character Text Splitter
500
+ * @param options
501
+ * @returns
502
+ */
603
503
  function getTextSplitter(options = {}) {
604
504
  return new text_splitter.RecursiveCharacterTextSplitter(options);
605
505
  }
506
+ /**
507
+ * Get Summarization Chain
508
+ * @param model
509
+ * @param options
510
+ * @returns
511
+ */
606
512
  function getChain(model, options = { type: 'map_reduce' }) {
607
513
  return chains.loadSummarizationChain(model, options);
608
514
  }
@@ -616,6 +522,12 @@ function getPrompt({ template, variables, fallback }) {
616
522
  })
617
523
  : fallback);
618
524
  }
525
+ /**
526
+ * Verify template string contains all required input variables
527
+ * @param text template string
528
+ * @param inputVariables template variables
529
+ * @returns boolean or error message
530
+ */
619
531
  function validatePromptTemplate(text, inputVariables) {
620
532
  if (!text) {
621
533
  return 'Prompt template cannot be empty';
@@ -669,8 +581,7 @@ const getDiff = async (nodeFile, { git, logger, }) => {
669
581
  };
670
582
 
671
583
  const MAX_TOKENS_PER_SUMMARY = 2048;
672
- const fileChangeParser = async (changes, { tokenizer, git, model }) => {
673
- const logger = new Logger(config);
584
+ const fileChangeParser = async (changes, { tokenizer, git, model, logger }) => {
674
585
  const textSplitter = getTextSplitter({ chunkSize: 2000, chunkOverlap: 125, });
675
586
  const summarizationChain = getChain(model, {
676
587
  type: 'map_reduce',
@@ -691,6 +602,7 @@ const fileChangeParser = async (changes, { tokenizer, git, model }) => {
691
602
  maxTokens: MAX_TOKENS_PER_SUMMARY,
692
603
  textSplitter,
693
604
  chain: summarizationChain,
605
+ logger
694
606
  });
695
607
  logger.stopTimer(`\nSummary generated for ${changes.length} staged files`, { color: 'green' });
696
608
  return summary;
@@ -726,6 +638,57 @@ const getTokenizer = () => {
726
638
  return tokenizer;
727
639
  };
728
640
 
641
+ class Logger {
642
+ constructor(config) {
643
+ this.config = config;
644
+ this.spinner = null;
645
+ }
646
+ log(message, options = { color: 'blue' }) {
647
+ let outputMessage = message;
648
+ if (options.color) {
649
+ outputMessage = chalk[options.color](outputMessage);
650
+ }
651
+ console.log(outputMessage);
652
+ return this;
653
+ }
654
+ verbose(message, options = {}) {
655
+ if (!this.config?.verbose) {
656
+ return this;
657
+ }
658
+ this.log(message, options);
659
+ return this;
660
+ }
661
+ startTimer() {
662
+ this.timerStart = now();
663
+ return this;
664
+ }
665
+ stopTimer(message, options = { color: 'yellow' }) {
666
+ if (!this.config?.verbose || !this.timerStart) {
667
+ return this;
668
+ }
669
+ const elapsedTime = prettyMilliseconds(now() - this.timerStart);
670
+ let outputMessage = message
671
+ ? `${message} (⏲ ${elapsedTime})`
672
+ : `⏲ ${elapsedTime}`;
673
+ if (options.color) {
674
+ outputMessage = chalk[options.color](outputMessage);
675
+ }
676
+ console.log(outputMessage);
677
+ return this;
678
+ }
679
+ startSpinner(message, options = { color: 'green' }) {
680
+ const spinnerMessage = options.color ? chalk[options.color](message) : message;
681
+ this.spinner = ora(spinnerMessage).start();
682
+ return this;
683
+ }
684
+ stopSpinner(message = '', options = { mode: 'succeed', color: 'green' }) {
685
+ const spinnerMessage = options?.color ? chalk[options.color](message) : message;
686
+ this.spinner?.[options.mode || 'succeed'](spinnerMessage);
687
+ this.spinner = null;
688
+ return this;
689
+ }
690
+ }
691
+
729
692
  const llm = async ({ llm, prompt, variables }) => {
730
693
  if (!llm || !prompt || !variables) {
731
694
  throw new Error('The input parameters "llm", "prompt", and "variables" are all required.');
@@ -783,6 +746,7 @@ const getSummaryText = (file, change) => {
783
746
  return `${status}: ${file.path}`;
784
747
  };
785
748
 
749
+ const config = loadConfig();
786
750
  const DEFAULT_IGNORED_FILES = config?.ignoredFiles?.length ? config.ignoredFiles : [];
787
751
  const DEFAULT_IGNORED_EXTENSIONS = config?.ignoredExtensions?.length ? config.ignoredExtensions : [];
788
752
  async function getChanges(git, options = {}) {
@@ -837,62 +801,117 @@ async function getChanges(git, options = {}) {
837
801
 
838
802
  const noResult = async ({ git, logger }) => {
839
803
  const { staged, unstaged, untracked } = await getChanges(git);
840
- if (staged.length > 0) {
804
+ const hasStaged = staged && staged.length > 0;
805
+ const hasUnstaged = unstaged && unstaged.length > 0;
806
+ const hasUntracked = untracked && untracked.length > 0;
807
+ if (hasStaged) {
841
808
  logger.log(`Staged files detected, but no summary generated...`, { color: 'red' });
842
809
  logger.log(`Files are likely either:\n • changed files are ignored\n • file diff is too large.`, { color: 'yellow' });
843
810
  }
844
- else if (unstaged && unstaged.length > 0) {
845
- logger.log('No staged files detected, but unstaged files detected.', { color: 'yellow' });
846
- logger.verbose(`\n Unstaged Changes: \n ${unstaged.map(({ summary }) => summary).join('\n ')}`, {
847
- color: 'yellow',
848
- });
849
- }
850
- else if (untracked && untracked.length > 0) {
851
- logger.log('No staged files detected, but untracked files detected.', { color: 'yellow' });
852
- logger.verbose(`\n Untracked Changes: \n ${untracked.map(({ summary }) => summary).join('\n ')}`, {
853
- color: 'yellow',
854
- });
811
+ else if (hasUnstaged || hasUntracked) {
812
+ logger.log('Forget something? No staged changes found... 👻', { color: 'red' });
813
+ if (hasUnstaged) {
814
+ logger.log('\nDetected unstaged changes', { color: 'yellow' });
815
+ logger.verbose(`\t${unstaged.map(({ summary }) => summary).join('\n\t')}`, {
816
+ color: 'red',
817
+ });
818
+ }
819
+ if (hasUntracked) {
820
+ logger.log('\nDetected untracked changes', { color: 'yellow' });
821
+ logger.verbose(`\t${untracked.map(({ summary }) => summary).join('\n\t')}`, {
822
+ color: 'red',
823
+ });
824
+ }
855
825
  }
856
826
  else {
857
- logger.log('No repo changes detected.', { color: 'yellow' });
827
+ logger.log('No repo changes detected. 👀', { color: 'blue' });
858
828
  }
859
- process.exit(0);
860
829
  };
861
830
 
862
831
  async function createCommit(commitMsg, git) {
863
832
  return await git.commit(commitMsg);
864
833
  }
865
834
 
866
- const argv = loadArgv();
835
+ // const argv = loadArgv()
867
836
  const tokenizer = getTokenizer();
868
837
  const git = simpleGit.simpleGit();
869
- async function main(options) {
870
- const logger = new Logger(config);
871
- if (!config.openAIApiKey) {
838
+ const command = ['commit', '$0'];
839
+ const description = 'Generate a commit message based on the diff summary';
840
+ const builder = {
841
+ model: { type: 'string', description: 'LLM/Model-Name' },
842
+ openAIApiKey: {
843
+ type: 'string',
844
+ description: 'OpenAI API Key',
845
+ conflicts: 'huggingFaceHubApiKey',
846
+ },
847
+ huggingFaceHubApiKey: {
848
+ type: 'string',
849
+ description: 'HuggingFace Hub API Key',
850
+ conflicts: 'openAIApiKey',
851
+ },
852
+ tokenLimit: { type: 'number', description: 'Token limit' },
853
+ prompt: {
854
+ type: 'string',
855
+ alias: 'p',
856
+ description: 'Commit message prompt',
857
+ },
858
+ i: {
859
+ type: 'boolean',
860
+ alias: 'interactive',
861
+ description: 'Toggle interactive mode',
862
+ },
863
+ s: {
864
+ type: 'boolean',
865
+ description: 'Automatically commit staged changes with generated commit message',
866
+ default: false,
867
+ },
868
+ e: {
869
+ type: 'boolean',
870
+ alias: 'edit',
871
+ description: 'Open commit message in editor before proceeding',
872
+ },
873
+ summarizePrompt: {
874
+ type: 'string',
875
+ description: 'Large file summary prompt',
876
+ },
877
+ ignoredFiles: {
878
+ type: 'array',
879
+ description: 'Ignored files',
880
+ },
881
+ ignoredExtensions: {
882
+ type: 'array',
883
+ description: 'Ignored extensions',
884
+ },
885
+ };
886
+ async function handler(argv) {
887
+ const options = loadConfig(argv);
888
+ const logger = new Logger(options);
889
+ const key = getModelAPIKey(options.model, options);
890
+ if (!key) {
872
891
  logger.log(`No API Key found. 🗝️🚪`, { color: 'red' });
873
892
  process.exit(1);
874
893
  }
875
- const model = getModel({
894
+ const model = getModel(options.model, key, {
876
895
  temperature: 0.4,
877
896
  maxConcurrency: 10,
878
- openAIApiKey: config.openAIApiKey,
879
897
  });
880
- const INTERACTIVE = config?.mode === 'interactive' || options.interactive;
898
+ const INTERACTIVE = options?.mode === 'interactive' || options.interactive;
881
899
  const { staged: changes } = await getChanges(git);
882
900
  let summary = '';
883
901
  let commitMsg = '';
884
- let promptTemplate = config?.prompt || '';
902
+ let promptTemplate = options?.prompt || '';
885
903
  let modifyPrompt = false;
886
904
  while (true) {
887
905
  if (changes.length !== 0 && !summary.length) {
888
906
  logger.verbose(`\nChanged Files: \n ${changes.map(({ summary }) => summary).join('\n ')}`, {
889
907
  color: 'blue',
890
908
  });
891
- summary = await fileChangeParser(changes, { tokenizer, git, model });
909
+ summary = await fileChangeParser(changes, { tokenizer, git, model, logger });
892
910
  }
893
911
  // Handle empty summary
894
912
  if (!summary.length) {
895
- noResult({ git, logger });
913
+ await noResult({ git, logger });
914
+ process.exit(0);
896
915
  }
897
916
  // Prompt user for commit template prompt, if necessary
898
917
  if (modifyPrompt) {
@@ -968,7 +987,7 @@ async function main(options) {
968
987
  process.exit(0);
969
988
  }
970
989
  if (reviewAnswer === 'edit') {
971
- config.openInEditor = true;
990
+ options.openInEditor = true;
972
991
  }
973
992
  if (reviewAnswer === 'retryFull') {
974
993
  summary = '';
@@ -987,7 +1006,7 @@ async function main(options) {
987
1006
  continue;
988
1007
  }
989
1008
  }
990
- if (config.openInEditor) {
1009
+ if (options.openInEditor) {
991
1010
  commitMsg = await prompts$1.editor({
992
1011
  message: 'Edit the commit message',
993
1012
  default: commitMsg,
@@ -1002,7 +1021,7 @@ async function main(options) {
1002
1021
  }
1003
1022
  const MODE = (options.interactive && 'interactive') ||
1004
1023
  (options.commit && 'interactive') ||
1005
- config?.mode ||
1024
+ options?.mode ||
1006
1025
  'stdout';
1007
1026
  // Handle resulting commit message
1008
1027
  switch (MODE) {
@@ -1018,4 +1037,28 @@ async function main(options) {
1018
1037
  process.exit(0);
1019
1038
  }
1020
1039
  }
1021
- main(argv).catch(console.error);
1040
+
1041
+ var commit = /*#__PURE__*/Object.freeze({
1042
+ __proto__: null,
1043
+ builder: builder,
1044
+ command: command,
1045
+ description: description,
1046
+ handler: handler
1047
+ });
1048
+
1049
+ yargs
1050
+ .scriptName('coco')
1051
+ .commandDir('./commands', {
1052
+ extensions: ['ts'],
1053
+ })
1054
+ .demandCommand()
1055
+ .strict()
1056
+ .option('h', { alias: 'help' })
1057
+ .option('v', {
1058
+ alias: 'verbose',
1059
+ type: 'boolean',
1060
+ description: 'Run with verbose logging',
1061
+ }).argv;
1062
+
1063
+ exports.commit = commit;
1064
+ exports.loadConfig = loadConfig;
@@ -22,6 +22,4 @@ export declare const DEFAULT_CONFIG: Config;
22
22
  *
23
23
  * @returns {Config} application config
24
24
  **/
25
- export declare function loadConfig(): Config;
26
- declare const config: Config;
27
- export default config;
25
+ export declare function loadConfig(argv?: {}): Config;
@@ -5,17 +5,35 @@ import { BaseLLMParams } from 'langchain/llms/base';
5
5
  import { AzureOpenAIInput, OpenAIInput, OpenAI } from 'langchain/llms/openai';
6
6
  import { RecursiveCharacterTextSplitter, RecursiveCharacterTextSplitterParams } from 'langchain/text_splitter';
7
7
  import { ConfigurationParameters } from 'openai';
8
+ import { BaseCommandOptions } from '../../types';
8
9
  /**
9
10
  * Get LLM Model Based on Configuration
10
- *
11
11
  * @param fields
12
12
  * @param configuration
13
13
  * @returns LLM Model
14
14
  */
15
- export declare function getModel(fields?: (Partial<OpenAIInput> & Partial<AzureOpenAIInput> & BaseLLMParams & {
15
+ export declare function getModel(name: string, key: string, fields?: (Partial<OpenAIInput> & Partial<AzureOpenAIInput> & BaseLLMParams & {
16
16
  configuration?: ConfigurationParameters | undefined;
17
17
  }) | undefined, configuration?: ConfigurationParameters | undefined): OpenAI | HuggingFaceInference;
18
+ /**
19
+ * Retrieve appropriate API key based on selected model
20
+ * @param name
21
+ * @param options
22
+ * @returns
23
+ */
24
+ export declare function getModelAPIKey(name: string, options: BaseCommandOptions): string;
25
+ /**
26
+ * Get Recursive Character Text Splitter
27
+ * @param options
28
+ * @returns
29
+ */
18
30
  export declare function getTextSplitter(options?: Partial<RecursiveCharacterTextSplitterParams>): RecursiveCharacterTextSplitter;
31
+ /**
32
+ * Get Summarization Chain
33
+ * @param model
34
+ * @param options
35
+ * @returns
36
+ */
19
37
  export declare function getChain(model: ReturnType<typeof getModel>, options?: SummarizationChainParams): import("langchain/chains").StuffDocumentsChain | import("langchain/chains").MapReduceDocumentsChain | import("langchain/chains").RefineDocumentsChain;
20
38
  type CreatePromptInput = {
21
39
  template?: string;
@@ -23,5 +41,11 @@ type CreatePromptInput = {
23
41
  fallback?: PromptTemplate;
24
42
  };
25
43
  export declare function getPrompt({ template, variables, fallback }: CreatePromptInput): PromptTemplate;
44
+ /**
45
+ * Verify template string contains all required input variables
46
+ * @param text template string
47
+ * @param inputVariables template variables
48
+ * @returns boolean or error message
49
+ */
26
50
  export declare function validatePromptTemplate(text: string, inputVariables: string[]): string | true;
27
51
  export {};
@@ -5,4 +5,4 @@ import { DiffTreeNode } from './createDiffTree';
5
5
  /**
6
6
  * Asynchronously collect diffs for a given node and its children.
7
7
  */
8
- export declare function collectDiffs(node: DiffTreeNode, getFileDiff: (change: FileChange) => Promise<string>, tokenizer: GPT3Tokenizer, logger?: Logger): Promise<DiffNode>;
8
+ export declare function collectDiffs(node: DiffTreeNode, getFileDiff: (change: FileChange) => Promise<string>, tokenizer: GPT3Tokenizer, logger: Logger): Promise<DiffNode>;
@@ -1,5 +1,6 @@
1
1
  import GPT3Tokenizer from 'gpt3-tokenizer';
2
2
  import { DirectoryDiff, DiffNode } from '../../../types';
3
+ import { Logger } from '../../../utils/logger';
3
4
  import { SummarizeContext } from '../../../langchain/chains/summarize';
4
5
  /**
5
6
  * Create groups from a given node info.
@@ -17,8 +18,9 @@ export declare function summarizeDirectoryDiff(directory: DirectoryDiff, { chain
17
18
  declare const defaultOutputCallback: (group: DirectoryDiff) => string;
18
19
  type SummarizeDiffsOptions = {
19
20
  tokenizer: GPT3Tokenizer;
21
+ logger: Logger;
20
22
  maxTokens: number;
21
23
  handleOutput?: typeof defaultOutputCallback;
22
24
  } & SummarizeContext;
23
- export declare function summarizeDiffs(rootDiffNode: DiffNode, { tokenizer, maxTokens, textSplitter, chain, handleOutput, }: SummarizeDiffsOptions): Promise<string>;
25
+ export declare function summarizeDiffs(rootDiffNode: DiffNode, { tokenizer, logger, maxTokens, textSplitter, chain, handleOutput, }: SummarizeDiffsOptions): Promise<string>;
24
26
  export {};
@@ -3,4 +3,4 @@ import { SimpleGit } from 'simple-git';
3
3
  export declare const noResult: ({ git, logger }: {
4
4
  git: SimpleGit;
5
5
  logger: Logger;
6
- }) => Promise<never>;
6
+ }) => Promise<void>;
@@ -1,6 +1,7 @@
1
1
  import GPT3Tokenizer from 'gpt3-tokenizer';
2
2
  import { getModel } from './langchain/utils';
3
3
  import { SimpleGit } from 'simple-git';
4
+ import { Logger } from './utils/logger';
4
5
  export type FileChangeStatus = 'modified' | 'renamed' | 'added' | 'deleted' | 'untracked' | 'unknown';
5
6
  export interface FileChange {
6
7
  summary: string;
@@ -30,5 +31,6 @@ export interface BaseParser {
30
31
  tokenizer: GPT3Tokenizer;
31
32
  model: ReturnType<typeof getModel>;
32
33
  git: SimpleGit;
34
+ logger: Logger;
33
35
  }): Promise<string>;
34
36
  }