git-coco 0.2.1 โ†’ 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -113,7 +113,7 @@ Remember, command line flags and environment variables should be defined in `UPP
113
113
  - [x] LangChain integration ๐Ÿฆœ
114
114
  - [ ] Additional tests! ๐Ÿงช
115
115
  - [ ] Conventional commits ๐Ÿ”œ
116
- - [ ] HuggingFace integration ๐Ÿ”œ
116
+ - [x] HuggingFace integration ๐Ÿ”œ
117
117
  - [ ] Google Vertex AI integration (?)
118
118
  - [ ] Automatic changelog generation ๐Ÿซฃ
119
119
  - [ ] Rebase support ๐Ÿ”€
@@ -14,6 +14,7 @@ import ora from 'ora';
14
14
  import now from 'performance-now';
15
15
  import prettyMilliseconds from 'pretty-ms';
16
16
  import { Document } from 'langchain/document';
17
+ import { HuggingFaceInference } from 'langchain/llms/hf';
17
18
  import { loadSummarizationChain, LLMChain } from 'langchain/chains';
18
19
  import { OpenAI } from 'langchain/llms/openai';
19
20
  import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter';
@@ -40,7 +41,9 @@ function removeUndefined(obj) {
40
41
  **/
41
42
  function loadEnvConfig(config) {
42
43
  const envConfig = {
44
+ model: process.env.COCO_MODEL || undefined,
43
45
  openAIApiKey: process.env.OPENAI_API_KEY || undefined,
46
+ huggingFaceHubApiKey: process.env.HUGGINGFACE_HUB_API_KEY || undefined,
44
47
  tokenLimit: process.env.COCO_TOKEN_LIMIT
45
48
  ? parseInt(process.env.COCO_TOKEN_LIMIT)
46
49
  : undefined,
@@ -71,7 +74,9 @@ function loadGitConfig(config) {
71
74
  const gitConfigParsed = ini.parse(gitConfigRaw);
72
75
  config = {
73
76
  ...config,
77
+ model: gitConfigParsed.coco?.model || config.model,
74
78
  openAIApiKey: gitConfigParsed.coco?.openAIApiKey || config.openAIApiKey,
79
+ huggingFaceHubApiKey: gitConfigParsed.coco?.huggingFaceHubApiKey || config.huggingFaceHubApiKey,
75
80
  tokenLimit: parseInt(gitConfigParsed.coco?.tokenLimit) || config.tokenLimit,
76
81
  prompt: gitConfigParsed.coco?.prompt || config.prompt,
77
82
  mode: gitConfigParsed.coco?.mode || config.mode,
@@ -151,7 +156,9 @@ function loadXDGConfig(config) {
151
156
  * Command line options via yargs
152
157
  */
153
158
  const options = {
159
+ model: { type: 'string', description: 'LLM/Model-Name' },
154
160
  openAIApiKey: { type: 'string', description: 'OpenAI API Key' },
161
+ huggingFaceHubApiKey: { type: 'string', description: 'HuggingFace Hub API Key' },
155
162
  tokenLimit: { type: 'number', description: 'Token limit' },
156
163
  prompt: {
157
164
  type: 'string',
@@ -248,7 +255,7 @@ const SUMMARIZE_PROMPT = new PromptTemplate({
248
255
  * @type {Config}
249
256
  */
250
257
  const DEFAULT_CONFIG = {
251
- openAIApiKey: '',
258
+ model: 'openai/gpt-3.5-turbo',
252
259
  verbose: false,
253
260
  tokenLimit: 1024,
254
261
  prompt: COMMIT_PROMPT.template,
@@ -258,7 +265,6 @@ const DEFAULT_CONFIG = {
258
265
  ignoredFiles: ['package-lock.json'],
259
266
  ignoredExtensions: ['.map', '.lock'],
260
267
  };
261
-
262
268
  /**
263
269
  * Load application config
264
270
  *
@@ -542,18 +548,34 @@ async function collectDiffs(node, getFileDiff, tokenizer, logger = new Logger(co
542
548
  };
543
549
  }
544
550
 
545
- // TODO: Extend this to support other models! ๐ŸŽ‰
551
+ /**
552
+ * Get LLM Model Based on Configuration
553
+ *
554
+ * @param fields
555
+ * @param configuration
556
+ * @returns LLM Model
557
+ */
546
558
  function getModel(fields, configuration) {
547
- return new OpenAI(fields, configuration);
548
- // return new HuggingFaceInference({
549
- // // model: 'gpt2',
550
- // // model: 'bigcode/starcoder',
551
- // model: 'bigscience/bloom',
552
- // apiKey: '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',
553
- // maxConcurrency: 4,
554
- // cache: true,
555
- // // maxTokens: 2046,
556
- // })
559
+ const [llm, model] = config.model.split(/\/(.*)/s);
560
+ if (!model) {
561
+ throw new Error(`Invalid model: ${config.model}`);
562
+ }
563
+ switch (llm) {
564
+ case 'huggingface':
565
+ return new HuggingFaceInference({
566
+ model: model,
567
+ apiKey: config.huggingFaceHubApiKey,
568
+ maxConcurrency: 4,
569
+ ...fields,
570
+ });
571
+ case 'openai':
572
+ default:
573
+ return new OpenAI({
574
+ openAIApiKey: config.openAIApiKey,
575
+ modelName: model,
576
+ ...fields,
577
+ }, configuration);
578
+ }
557
579
  }
558
580
  function getTextSplitter(options = {}) {
559
581
  return new RecursiveCharacterTextSplitter(options);
@@ -682,10 +704,25 @@ const getTokenizer = () => {
682
704
  };
683
705
 
684
706
  const llm = async ({ llm, prompt, variables }) => {
707
+ if (!llm || !prompt || !variables) {
708
+ throw new Error('The input parameters "llm", "prompt", and "variables" are all required.');
709
+ }
685
710
  const chain = new LLMChain({ llm, prompt });
686
- const res = await chain.call(variables);
687
- if (res.error)
688
- throw new Error(res.error);
711
+ let res;
712
+ try {
713
+ res = await chain.call(variables);
714
+ }
715
+ catch (error) {
716
+ if (error instanceof Error) {
717
+ throw new Error(`LLMChain call error: ${error.message}`);
718
+ }
719
+ }
720
+ if (!res) {
721
+ throw new Error('Empty response from LLMChain call');
722
+ }
723
+ if (res.error) {
724
+ throw new Error(`LLMChain response error: ${res.error}`);
725
+ }
689
726
  return res.text.trim();
690
727
  };
691
728