3.0.18 (#382)
* 📝 (README.md): add support for custom AI models and update documentation to reflect new environment variable OCO_ AI_PROVIDER (#351) * feat/add gemini (#349) * fix: prompt-module/@commitlint (#336) * docs: spelling fix (#325) --------- Co-authored-by: tumf <y.takahara@gmail.com> Co-authored-by: Drew Payment <drew.payment@gmail.com> Co-authored-by: Takanori Matsumoto <matscube@gmail.com> Co-authored-by: Kellan Stevens <kellan@kellanstevens.com> Co-authored-by: JMN09 <jmn09@mail.aub.edu> Co-authored-by: JMN09 <157629053+JMN09@users.noreply.github.com>
This commit is contained in:
+436
-381
File diff suppressed because it is too large
Load Diff
+424
-372
File diff suppressed because it is too large
Load Diff
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "opencommit",
|
"name": "opencommit",
|
||||||
"version": "3.0.17",
|
"version": "3.0.18",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "opencommit",
|
"name": "opencommit",
|
||||||
"version": "3.0.17",
|
"version": "3.0.18",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.10.0",
|
"@actions/core": "^1.10.0",
|
||||||
|
|||||||
+4
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "opencommit",
|
"name": "opencommit",
|
||||||
"version": "3.0.17",
|
"version": "3.0.18",
|
||||||
"description": "Auto-generate impressive commits in 1 second. Killing lame commits with AI 🤯🔫",
|
"description": "Auto-generate impressive commits in 1 second. Killing lame commits with AI 🤯🔫",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"git",
|
"git",
|
||||||
@@ -98,5 +98,8 @@
|
|||||||
"ini": "^3.0.1",
|
"ini": "^3.0.1",
|
||||||
"inquirer": "^9.1.4",
|
"inquirer": "^9.1.4",
|
||||||
"openai": "^3.2.1"
|
"openai": "^3.2.1"
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"whatwg-url": "13.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+46
-11
@@ -33,7 +33,9 @@ export enum CONFIG_KEYS {
|
|||||||
OCO_AZURE_ENDPOINT = 'OCO_AZURE_ENDPOINT',
|
OCO_AZURE_ENDPOINT = 'OCO_AZURE_ENDPOINT',
|
||||||
OCO_TEST_MOCK_TYPE = 'OCO_TEST_MOCK_TYPE',
|
OCO_TEST_MOCK_TYPE = 'OCO_TEST_MOCK_TYPE',
|
||||||
OCO_API_URL = 'OCO_API_URL',
|
OCO_API_URL = 'OCO_API_URL',
|
||||||
OCO_OLLAMA_API_URL = 'OCO_OLLAMA_API_URL'
|
OCO_OLLAMA_API_URL = 'OCO_OLLAMA_API_URL',
|
||||||
|
OCO_FLOWISE_ENDPOINT = 'OCO_FLOWISE_ENDPOINT',
|
||||||
|
OCO_FLOWISE_API_KEY = 'OCO_FLOWISE_API_KEY'
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum CONFIG_MODES {
|
export enum CONFIG_MODES {
|
||||||
@@ -130,7 +132,8 @@ export const configValidators = {
|
|||||||
config.OCO_ANTHROPIC_API_KEY ||
|
config.OCO_ANTHROPIC_API_KEY ||
|
||||||
config.OCO_AI_PROVIDER.startsWith('ollama') ||
|
config.OCO_AI_PROVIDER.startsWith('ollama') ||
|
||||||
config.OCO_AZURE_API_KEY ||
|
config.OCO_AZURE_API_KEY ||
|
||||||
config.OCO_AI_PROVIDER == 'test',
|
config.OCO_AI_PROVIDER == 'test' ||
|
||||||
|
config.OCO_AI_PROVIDER == 'flowise',
|
||||||
'You need to provide an OpenAI/Anthropic/Azure API key'
|
'You need to provide an OpenAI/Anthropic/Azure API key'
|
||||||
);
|
);
|
||||||
validateConfig(
|
validateConfig(
|
||||||
@@ -149,7 +152,8 @@ export const configValidators = {
|
|||||||
config.OCO_OPENAI_API_KEY ||
|
config.OCO_OPENAI_API_KEY ||
|
||||||
config.OCO_AZURE_API_KEY ||
|
config.OCO_AZURE_API_KEY ||
|
||||||
config.OCO_AI_PROVIDER == 'ollama' ||
|
config.OCO_AI_PROVIDER == 'ollama' ||
|
||||||
config.OCO_AI_PROVIDER == 'test',
|
config.OCO_AI_PROVIDER == 'test' ||
|
||||||
|
config.OCO_AI_PROVIDER == 'flowise',
|
||||||
'You need to provide an OpenAI/Anthropic/Azure API key'
|
'You need to provide an OpenAI/Anthropic/Azure API key'
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -175,13 +179,24 @@ export const configValidators = {
|
|||||||
value ||
|
value ||
|
||||||
config.OCO_OPENAI_API_KEY ||
|
config.OCO_OPENAI_API_KEY ||
|
||||||
config.OCO_AI_PROVIDER == 'ollama' ||
|
config.OCO_AI_PROVIDER == 'ollama' ||
|
||||||
config.OCO_AI_PROVIDER == 'test',
|
config.OCO_AI_PROVIDER == 'test' ||
|
||||||
|
config.OCO_AI_PROVIDER == 'flowise',
|
||||||
'You need to provide an OpenAI/Anthropic API key'
|
'You need to provide an OpenAI/Anthropic API key'
|
||||||
);
|
);
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
[CONFIG_KEYS.OCO_FLOWISE_API_KEY](value: any, config: any = {}) {
|
||||||
|
validateConfig(
|
||||||
|
CONFIG_KEYS.OCO_FLOWISE_API_KEY,
|
||||||
|
value || config.OCO_AI_PROVIDER != 'flowise',
|
||||||
|
'You need to provide a flowise API key'
|
||||||
|
);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
|
||||||
[CONFIG_KEYS.OCO_DESCRIPTION](value: any) {
|
[CONFIG_KEYS.OCO_DESCRIPTION](value: any) {
|
||||||
validateConfig(
|
validateConfig(
|
||||||
CONFIG_KEYS.OCO_DESCRIPTION,
|
CONFIG_KEYS.OCO_DESCRIPTION,
|
||||||
@@ -268,7 +283,8 @@ export const configValidators = {
|
|||||||
].includes(value) ||
|
].includes(value) ||
|
||||||
config.OCO_AI_PROVIDER == 'ollama' ||
|
config.OCO_AI_PROVIDER == 'ollama' ||
|
||||||
config.OCO_AI_PROVIDER == 'azure' ||
|
config.OCO_AI_PROVIDER == 'azure' ||
|
||||||
config.OCO_AI_PROVIDER == 'test',
|
config.OCO_AI_PROVIDER == 'test' ||
|
||||||
|
config.OCO_AI_PROVIDER == 'flowise',
|
||||||
`${value} is not supported yet, use:\n\n ${[
|
`${value} is not supported yet, use:\n\n ${[
|
||||||
...MODEL_LIST.openai,
|
...MODEL_LIST.openai,
|
||||||
...MODEL_LIST.anthropic,
|
...MODEL_LIST.anthropic,
|
||||||
@@ -308,9 +324,16 @@ export const configValidators = {
|
|||||||
[CONFIG_KEYS.OCO_AI_PROVIDER](value: any) {
|
[CONFIG_KEYS.OCO_AI_PROVIDER](value: any) {
|
||||||
validateConfig(
|
validateConfig(
|
||||||
CONFIG_KEYS.OCO_AI_PROVIDER,
|
CONFIG_KEYS.OCO_AI_PROVIDER,
|
||||||
['', 'openai', 'anthropic', 'gemini', 'azure', 'test'].includes(value) ||
|
[
|
||||||
value.startsWith('ollama'),
|
'',
|
||||||
`${value} is not supported yet, use 'ollama', 'anthropic', 'azure', 'gemini' or 'openai' (default)`
|
'openai',
|
||||||
|
'anthropic',
|
||||||
|
'gemini',
|
||||||
|
'azure',
|
||||||
|
'test',
|
||||||
|
'flowise'
|
||||||
|
].includes(value) || value.startsWith('ollama'),
|
||||||
|
`${value} is not supported yet, use 'ollama', 'anthropic', 'azure', 'gemini', 'flowise' or 'openai' (default)`
|
||||||
);
|
);
|
||||||
return value;
|
return value;
|
||||||
},
|
},
|
||||||
@@ -324,6 +347,7 @@ export const configValidators = {
|
|||||||
|
|
||||||
return value;
|
return value;
|
||||||
},
|
},
|
||||||
|
|
||||||
[CONFIG_KEYS.OCO_AZURE_ENDPOINT](value: any) {
|
[CONFIG_KEYS.OCO_AZURE_ENDPOINT](value: any) {
|
||||||
validateConfig(
|
validateConfig(
|
||||||
CONFIG_KEYS.OCO_AZURE_ENDPOINT,
|
CONFIG_KEYS.OCO_AZURE_ENDPOINT,
|
||||||
@@ -333,6 +357,17 @@ export const configValidators = {
|
|||||||
|
|
||||||
return value;
|
return value;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
[CONFIG_KEYS.OCO_FLOWISE_ENDPOINT](value: any) {
|
||||||
|
validateConfig(
|
||||||
|
CONFIG_KEYS.OCO_FLOWISE_ENDPOINT,
|
||||||
|
typeof value === 'string' && value.includes(':'),
|
||||||
|
'Value must be string and should include both I.P. and port number' // Considering the possibility of DNS lookup or feeding the I.P. explicitely, there is no pattern to verify, except a column for the port number
|
||||||
|
);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
|
||||||
[CONFIG_KEYS.OCO_TEST_MOCK_TYPE](value: any) {
|
[CONFIG_KEYS.OCO_TEST_MOCK_TYPE](value: any) {
|
||||||
validateConfig(
|
validateConfig(
|
||||||
CONFIG_KEYS.OCO_TEST_MOCK_TYPE,
|
CONFIG_KEYS.OCO_TEST_MOCK_TYPE,
|
||||||
@@ -361,7 +396,6 @@ export type ConfigType = {
|
|||||||
|
|
||||||
const defaultConfigPath = pathJoin(homedir(), '.opencommit');
|
const defaultConfigPath = pathJoin(homedir(), '.opencommit');
|
||||||
const defaultEnvPath = pathResolve(process.cwd(), '.env');
|
const defaultEnvPath = pathResolve(process.cwd(), '.env');
|
||||||
|
|
||||||
export const getConfig = ({
|
export const getConfig = ({
|
||||||
configPath = defaultConfigPath,
|
configPath = defaultConfigPath,
|
||||||
envPath = defaultEnvPath
|
envPath = defaultEnvPath
|
||||||
@@ -397,9 +431,10 @@ export const getConfig = ({
|
|||||||
process.env.OCO_ONE_LINE_COMMIT === 'true' ? true : false,
|
process.env.OCO_ONE_LINE_COMMIT === 'true' ? true : false,
|
||||||
OCO_AZURE_ENDPOINT: process.env.OCO_AZURE_ENDPOINT || undefined,
|
OCO_AZURE_ENDPOINT: process.env.OCO_AZURE_ENDPOINT || undefined,
|
||||||
OCO_TEST_MOCK_TYPE: process.env.OCO_TEST_MOCK_TYPE || 'commit-message',
|
OCO_TEST_MOCK_TYPE: process.env.OCO_TEST_MOCK_TYPE || 'commit-message',
|
||||||
OCO_OLLAMA_API_URL: process.env.OCO_OLLAMA_API_URL || undefined,
|
OCO_FLOWISE_ENDPOINT: process.env.OCO_FLOWISE_ENDPOINT || ':',
|
||||||
|
OCO_FLOWISE_API_KEY: process.env.OCO_FLOWISE_API_KEY || undefined,
|
||||||
|
OCO_OLLAMA_API_URL: process.env.OCO_OLLAMA_API_URL || undefined
|
||||||
};
|
};
|
||||||
|
|
||||||
const configExists = existsSync(configPath);
|
const configExists = existsSync(configPath);
|
||||||
if (!configExists) return configFromEnv;
|
if (!configExists) return configFromEnv;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import axios, { AxiosError } from 'axios';
|
||||||
|
import { ChatCompletionRequestMessage } from 'openai';
|
||||||
|
import { AiEngine } from './Engine';
|
||||||
|
|
||||||
|
import {
|
||||||
|
getConfig
|
||||||
|
} from '../commands/config';
|
||||||
|
|
||||||
|
const config = getConfig();
|
||||||
|
|
||||||
|
export class FlowiseAi implements AiEngine {
|
||||||
|
|
||||||
|
async generateCommitMessage(
|
||||||
|
messages: Array<ChatCompletionRequestMessage>
|
||||||
|
): Promise<string | undefined> {
|
||||||
|
|
||||||
|
const gitDiff = messages[ messages.length - 1 ]?.content?.replace(/\\/g, '\\\\')
|
||||||
|
.replace(/"/g, '\\"')
|
||||||
|
.replace(/\n/g, '\\n')
|
||||||
|
.replace(/\r/g, '\\r')
|
||||||
|
.replace(/\t/g, '\\t');
|
||||||
|
const url = `http://${config?.OCO_FLOWISE_ENDPOINT}/api/v1/prediction/${config?.OCO_FLOWISE_API_KEY}`;
|
||||||
|
const payload = {
|
||||||
|
question : gitDiff,
|
||||||
|
overrideConfig : {
|
||||||
|
systemMessagePrompt: messages[0]?.content,
|
||||||
|
},
|
||||||
|
history : messages.slice( 1, -1 )
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const response = await axios.post(url, payload, {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const message = response.data;
|
||||||
|
return message?.text;
|
||||||
|
} catch (err: any) {
|
||||||
|
const message = err.response?.data?.error ?? err.message;
|
||||||
|
throw new Error('local model issues. details: ' + message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ import { OllamaAi } from '../engine/ollama';
|
|||||||
import { AnthropicAi } from '../engine/anthropic'
|
import { AnthropicAi } from '../engine/anthropic'
|
||||||
import { TestAi } from '../engine/testAi';
|
import { TestAi } from '../engine/testAi';
|
||||||
import { Azure } from '../engine/azure';
|
import { Azure } from '../engine/azure';
|
||||||
|
import { FlowiseAi } from '../engine/flowise'
|
||||||
|
|
||||||
export function getEngine(): AiEngine {
|
export function getEngine(): AiEngine {
|
||||||
const config = getConfig();
|
const config = getConfig();
|
||||||
@@ -27,6 +28,8 @@ export function getEngine(): AiEngine {
|
|||||||
return new Gemini();
|
return new Gemini();
|
||||||
} else if (provider == 'azure') {
|
} else if (provider == 'azure') {
|
||||||
return new Azure();
|
return new Azure();
|
||||||
|
} else if( provider == 'flowise'){
|
||||||
|
return new FlowiseAi();
|
||||||
}
|
}
|
||||||
|
|
||||||
//open ai gpt by default
|
//open ai gpt by default
|
||||||
|
|||||||
@@ -102,4 +102,4 @@ OCO_ONE_LINE_COMMIT="true"
|
|||||||
|
|
||||||
await envFile.cleanup();
|
await envFile.cleanup();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
Reference in New Issue
Block a user