diff --git a/out/cli.cjs b/out/cli.cjs index 4b935fc..f9b173a 100755 --- a/out/cli.cjs +++ b/out/cli.cjs @@ -28111,7 +28111,7 @@ function G3(t2, e3) { // package.json var package_default = { name: "opencommit", - version: "3.0.17", + version: "3.0.16", description: "Auto-generate impressive commits in 1 second. Killing lame commits with AI \u{1F92F}\u{1F52B}", keywords: [ "git", @@ -28157,8 +28157,7 @@ var package_default = { "dev:gemini": "OCO_AI_PROVIDER='gemini' ts-node ./src/cli.ts", build: "rimraf out && node esbuild.config.js", "build:push": "npm run build && git add . && git commit -m 'build' && git push", - deploy: "npm run build:push && git push --tags && npm publish --tag latest", - "deploy:patch": "npm version patch && npm run deploy", + deploy: "npm version patch && npm run build:push && git push --tags && npm publish --tag latest", lint: "eslint src --ext ts && tsc --noEmit", format: "prettier --write src", test: "node --no-warnings --experimental-vm-modules $( [ -f ./node_modules/.bin/jest ] && echo ./node_modules/.bin/jest || which jest ) test/unit", @@ -30688,8 +30687,7 @@ var MODEL_LIST = { "gpt-4o-mini-2024-07-18" ], anthropic: [ - "claude-3-5-sonnet-20240620", - "claude-3-opus-20240229", + "claude-3-haiku-20240307", "claude-3-sonnet-20240229", "claude-3-haiku-20240307" ], diff --git a/out/github-action.cjs b/out/github-action.cjs index 9a83162..acd609d 100644 --- a/out/github-action.cjs +++ b/out/github-action.cjs @@ -49498,8 +49498,7 @@ var MODEL_LIST = { "gpt-4o-mini-2024-07-18" ], anthropic: [ - "claude-3-5-sonnet-20240620", - "claude-3-opus-20240229", + "claude-3-haiku-20240307", "claude-3-sonnet-20240229", "claude-3-haiku-20240307" ], diff --git a/src/commands/config.ts b/src/commands/config.ts index 8987144..604a715 100644 --- a/src/commands/config.ts +++ b/src/commands/config.ts @@ -33,7 +33,9 @@ export enum CONFIG_KEYS { OCO_AZURE_ENDPOINT = 'OCO_AZURE_ENDPOINT', OCO_TEST_MOCK_TYPE = 'OCO_TEST_MOCK_TYPE', 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 { @@ -130,7 +132,8 @@ export const configValidators = { config.OCO_ANTHROPIC_API_KEY || config.OCO_AI_PROVIDER.startsWith('ollama') || 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' ); validateConfig( @@ -149,7 +152,8 @@ export const configValidators = { config.OCO_OPENAI_API_KEY || config.OCO_AZURE_API_KEY || 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' ); @@ -175,13 +179,24 @@ export const configValidators = { value || config.OCO_OPENAI_API_KEY || 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' ); 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) { validateConfig( CONFIG_KEYS.OCO_DESCRIPTION, @@ -268,7 +283,8 @@ export const configValidators = { ].includes(value) || config.OCO_AI_PROVIDER == 'ollama' || 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 ${[ ...MODEL_LIST.openai, ...MODEL_LIST.anthropic, @@ -308,9 +324,16 @@ export const configValidators = { [CONFIG_KEYS.OCO_AI_PROVIDER](value: any) { validateConfig( 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; }, @@ -324,6 +347,7 @@ export const configValidators = { return value; }, + [CONFIG_KEYS.OCO_AZURE_ENDPOINT](value: any) { validateConfig( CONFIG_KEYS.OCO_AZURE_ENDPOINT, @@ -333,6 +357,17 @@ export const configValidators = { 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) { validateConfig( CONFIG_KEYS.OCO_TEST_MOCK_TYPE, @@ -361,7 +396,6 @@ export type ConfigType = { const defaultConfigPath = pathJoin(homedir(), '.opencommit'); const defaultEnvPath = pathResolve(process.cwd(), '.env'); - export const getConfig = ({ configPath = defaultConfigPath, envPath = defaultEnvPath @@ -396,9 +430,10 @@ export const getConfig = ({ OCO_ONE_LINE_COMMIT: process.env.OCO_ONE_LINE_COMMIT === 'true' ? true : false, 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_FLOWISE_ENDPOINT: process.env.OCO_FLOWISE_ENDPOINT || ':', + OCO_FLOWISE_API_KEY: process.env.OCO_FLOWISE_API_KEY || undefined }; - const configExists = existsSync(configPath); if (!configExists) return configFromEnv; diff --git a/src/engine/flowise.ts b/src/engine/flowise.ts new file mode 100644 index 0000000..88f4b91 --- /dev/null +++ b/src/engine/flowise.ts @@ -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 + ): Promise { + + 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); + } + } +} diff --git a/src/utils/engine.ts b/src/utils/engine.ts index ac9fdfd..d176d1f 100644 --- a/src/utils/engine.ts +++ b/src/utils/engine.ts @@ -6,6 +6,7 @@ import { OllamaAi } from '../engine/ollama'; import { AnthropicAi } from '../engine/anthropic' import { TestAi } from '../engine/testAi'; import { Azure } from '../engine/azure'; +import { FlowiseAi } from '../engine/flowise' export function getEngine(): AiEngine { const config = getConfig(); @@ -25,6 +26,8 @@ export function getEngine(): AiEngine { return new Gemini(); } else if (provider == 'azure') { return new Azure(); + } else if( provider == 'flowise'){ + return new FlowiseAi(); } //open ai gpt by default diff --git a/test/unit/config.test.ts b/test/unit/config.test.ts index aa44e3b..3112fb1 100644 --- a/test/unit/config.test.ts +++ b/test/unit/config.test.ts @@ -102,4 +102,4 @@ OCO_ONE_LINE_COMMIT="true" await envFile.cleanup(); }); -}); +}); \ No newline at end of file