Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ IPS="420.69.247.365"
NODE_ENV="development"
OPENAI_API_KEY="DEEZ"
CLAUDE_API_KEY="NUTZ"
DEEPSEEK_API_KEY="BALLZ"

# notify
NOTIFY_URL="https://notify.jaw.dev"
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ env:
NODE_ENV: 'testing'
OPENAI_API_KEY: 'DEEZ'
CLAUDE_API_KEY: 'NUTZ'
DEEPSEEK_API_KEY: 'BALLZ'
DISCORD_WEBHOOK_URL: 'x'

jobs:
Expand Down
4 changes: 4 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@
"cSpell.words": [
"adminjs",
"aicommit",
"BALLZ",
"claudeai",
"deepseek",
"DEEZ",
"fastq",
"healthz",
"nofollow",
"NUTZ",
"openai",
"pacman",
"Tahoma",
Expand Down
38 changes: 38 additions & 0 deletions src/ai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
.filter((choice) => choice.message?.content)
.map((choice) => choice.message.content);
return getRandomElement(messages);
} catch (error: any) {

Check warning on line 98 in src/ai.ts

View workflow job for this annotation

GitHub Actions / ESLint (22.x)

Unexpected any. Specify a different type
if (error.code === 'insufficient_quota') {
throw new UnauthorizedError(
'You exceeded your current quota, please check your plan and billing details',
Expand Down Expand Up @@ -133,7 +133,7 @@
});
// @ts-ignore - trust me bro
return getRandomElement(messages.content).text;
} catch (error: any) {

Check warning on line 136 in src/ai.ts

View workflow job for this annotation

GitHub Actions / ESLint (22.x)

Unexpected any. Specify a different type
if (error?.error?.error?.type === 'authentication_error') {
throw new UnauthorizedError(error.error.error.message);
}
Expand All @@ -142,10 +142,48 @@
},
};

export const deepseekAI: AIService = {
generate: async (diff: string, apiKey?: string) => {
try {
const API_KEY = apiKey ? apiKey : appConfig.DEEPSEEK_API_KEY;
const chatCompletion = await new OpenAI({
baseURL: 'https://api.deepseek.com',
apiKey: API_KEY,
}).chat.completions.create({
model: 'deepseek-chat',
temperature: 0.7,
max_tokens: 200,
stream: false,
messages: [
{
role: 'system',
content: prompt,
},
{
role: 'user',
content: diff,
},
],
});
const messages = chatCompletion.choices
.filter((choice) => choice.message?.content)
.map((choice) => choice.message.content);
return getRandomElement(messages);
} catch (error: any) {

Check warning on line 172 in src/ai.ts

View workflow job for this annotation

GitHub Actions / ESLint (22.x)

Unexpected any. Specify a different type
if (error?.error?.type === 'invalid_api_key') {
throw new UnauthorizedError(error.message);
}
throw error;
}
},
};

export function ai(type?: Provider): AIService {
switch (type) {
case 'claudeai':
return claudeAI;
case 'deepseek':
return deepseekAI;
case 'openai':
default:
return openAI;
Expand Down
4 changes: 2 additions & 2 deletions src/commit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ show_help() {
printf "${YELLOW}Options:${NC}\n"
printf " ${GREEN}-dr, --dry-run${NC} Run the script without making any changes\n"
printf " ${GREEN}-nv, --no-verify${NC} Skip message selection\n"
printf " ${GREEN}-ai, --ai-provider${NC} Specify AI provider (openai or claude, default: openai)\n"
printf " ${GREEN}-ai, --ai-provider${NC} Specify AI provider (openai, claude or deepseek, default: openai)\n"
printf " ${GREEN}-k, --api-key${NC} Specify the API key for the AI provider\n"
printf " ${GREEN}-v, --verbose${NC} Enable verbose logging\n"
printf " ${GREEN}-h, --help${NC} Display this help message\n"
Expand Down Expand Up @@ -71,7 +71,7 @@ parse_arguments() {
-ai|--ai-provider)
AI_PROVIDER=$2
log_verbose "AI provider set to: " "$AI_PROVIDER"
if [[ "$AI_PROVIDER" != "openai" && "$AI_PROVIDER" != "claudeai" ]]; then
if [[ "$AI_PROVIDER" != "openai" && "$AI_PROVIDER" != "claudeai" && "$AI_PROVIDER" != "deepseek" ]]; then
log_verbose "Invalid AI provider specified"
echo -e "${RED}Invalid AI provider. Please use 'openai' or 'claudeai'.${NC}\n"
exit 1
Expand Down
5 changes: 5 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,33 @@
NOTIFY_URL: {
value: process.env.NOTIFY_URL,
required: true,
type: (value: any) => String(value),

Check warning on line 11 in src/config.ts

View workflow job for this annotation

GitHub Actions / ESLint (22.x)

Unexpected any. Specify a different type
},
NOTIFY_X_API_KEY: {
value: process.env.NOTIFY_X_API_KEY,
required: true,
type: (value: any) => String(value),

Check warning on line 16 in src/config.ts

View workflow job for this annotation

GitHub Actions / ESLint (22.x)

Unexpected any. Specify a different type
},
IPS: {
value: process.env.IPS,
required: true,
type: (value: any) => String(value),

Check warning on line 21 in src/config.ts

View workflow job for this annotation

GitHub Actions / ESLint (22.x)

Unexpected any. Specify a different type
},
PORT: {
value: process.env.PORT,
default: 80,
type: (value: any) => Number(value),

Check warning on line 26 in src/config.ts

View workflow job for this annotation

GitHub Actions / ESLint (22.x)

Unexpected any. Specify a different type
required: false,
},
OPENAI_API_KEY: {
value: process.env.OPENAI_API_KEY,
required: true,
type: (value: any) => String(value),

Check warning on line 32 in src/config.ts

View workflow job for this annotation

GitHub Actions / ESLint (22.x)

Unexpected any. Specify a different type
},
CLAUDE_API_KEY: {
value: process.env.CLAUDE_API_KEY,
required: true,
type: (value: any) => String(value),

Check warning on line 37 in src/config.ts

View workflow job for this annotation

GitHub Actions / ESLint (22.x)

Unexpected any. Specify a different type
},
NODE_ENV: {
value: process.env.NODE_ENV,
Expand All @@ -42,4 +42,9 @@
required: false,
type: (value: any) => value as 'development' | 'production',
},
DEEPSEEK_API_KEY: {
value: process.env.DEEPSEEK_API_KEY,
required: true,
type: (value: any) => String(value),
},
});
2 changes: 1 addition & 1 deletion src/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export function postGenerateCommitMessageHandler(ai: (type?: Provider) => AIServ
throw new ValidationError('Diff must not be empty!');
}

if (provider && provider !== 'openai' && provider !== 'claudeai') {
if (provider && provider !== 'openai' && provider !== 'claudeai' && provider !== 'deepseek') {
throw new ValidationError('Invalid provider specified!');
}

Expand Down
4 changes: 2 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Request } from 'express';

export type Provider = 'openai' | 'claudeai';
export type Provider = 'openai' | 'claudeai' | 'deepseek';

export interface GenerateCommitMessageRequest extends Request {
body: {
Expand All @@ -27,7 +27,7 @@ export interface ConfigItem<T> {
readonly required: boolean;
}

export interface Logger {
export interface LoggerType {
debug: (...value: any) => void;
error: (...value: any) => void;
info: (...value: any) => void;
Expand Down
4 changes: 2 additions & 2 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import fastq from 'fastq';
import { Request } from 'express';
import { styleText } from 'node:util';
import { appConfig } from './config';
import { CacheType, ConfigItem, Logger } from './types';
import { CacheType, ConfigItem, LoggerType } from './types';

export const sendNotificationQueue = fastq.promise(sendNotification, 1);

Expand Down Expand Up @@ -81,7 +81,7 @@ function Cache(): CacheType {

export const cache = Cache();

export const logger: Logger = {
export const logger: LoggerType = {
debug: (...value: any) => {
const timestamp = new Date().toLocaleString();
console.debug(styleText('red', `🐛 ${timestamp} ${value}`));
Expand Down
Loading