Skip to content

Commit c9b4549

Browse files
authored
feat: Add Input Token Limit Config Option (#281)
1 parent 011db5a commit c9b4549

4 files changed

Lines changed: 54 additions & 18 deletions

File tree

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ Create a `.env` file and add OpenCommit config variables there like this:
7777

7878
```env
7979
OCO_OPENAI_API_KEY=<your OpenAI API token>
80-
OCO_OPENAI_MAX_TOKENS=<max response tokens from OpenAI API>
80+
OCO_TOKENS_MAX_INPUT=<max model token limit (default: 4096)>
81+
OCO_TOKENS_MAX_OUTPUT=<max response tokens (default: 500)>
8182
OCO_OPENAI_BASE_PATH=<may be used to set proxy path to OpenAI api>
8283
OCO_DESCRIPTION=<postface a message with ~3 sentences description of the changes>
8384
OCO_EMOJI=<boolean, add GitMoji>
@@ -329,7 +330,8 @@ jobs:
329330
OCO_OPENAI_API_KEY: ${{ secrets.OCO_OPENAI_API_KEY }}
330331
331332
# customization
332-
OCO_OPENAI_MAX_TOKENS: 500
333+
OCO_TOKENS_MAX_INPUT: 4096
334+
OCO_TOKENS_MAX_OUTPUT: 500
333335
OCO_OPENAI_BASE_PATH: ''
334336
OCO_DESCRIPTION: false
335337
OCO_EMOJI: false

src/commands/config.ts

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ dotenv.config();
1515

1616
export enum CONFIG_KEYS {
1717
OCO_OPENAI_API_KEY = 'OCO_OPENAI_API_KEY',
18-
OCO_OPENAI_MAX_TOKENS = 'OCO_OPENAI_MAX_TOKENS',
18+
OCO_TOKENS_MAX_INPUT = 'OCO_TOKENS_MAX_INPUT',
19+
OCO_TOKENS_MAX_OUTPUT = 'OCO_TOKENS_MAX_OUTPUT',
1920
OCO_OPENAI_BASE_PATH = 'OCO_OPENAI_BASE_PATH',
2021
OCO_DESCRIPTION = 'OCO_DESCRIPTION',
2122
OCO_EMOJI = 'OCO_EMOJI',
@@ -26,13 +27,16 @@ export enum CONFIG_KEYS {
2627
OCO_AI_PROVIDER = 'OCO_AI_PROVIDER',
2728
}
2829

29-
export const DEFAULT_MODEL_TOKEN_LIMIT = 4096;
30-
3130
export enum CONFIG_MODES {
3231
get = 'get',
3332
set = 'set'
3433
}
3534

35+
export enum DEFAULT_TOKEN_LIMITS {
36+
DEFAULT_MAX_TOKENS_INPUT = 4096,
37+
DEFAULT_MAX_TOKENS_OUTPUT = 500
38+
}
39+
3640
const validateConfig = (
3741
key: string,
3842
condition: any,
@@ -75,18 +79,37 @@ export const configValidators = {
7579
return value;
7680
},
7781

78-
[CONFIG_KEYS.OCO_OPENAI_MAX_TOKENS](value: any) {
82+
[CONFIG_KEYS.OCO_TOKENS_MAX_INPUT](value: any) {
83+
// If the value is a string, convert it to a number.
84+
if (typeof value === 'string') {
85+
value = parseInt(value);
86+
validateConfig(
87+
CONFIG_KEYS.OCO_TOKENS_MAX_INPUT,
88+
!isNaN(value),
89+
'Must be a number'
90+
);
91+
}
92+
validateConfig(
93+
CONFIG_KEYS.OCO_TOKENS_MAX_INPUT,
94+
value ? typeof value === 'number' : undefined,
95+
'Must be a number'
96+
);
97+
98+
return value;
99+
},
100+
101+
[CONFIG_KEYS.OCO_TOKENS_MAX_OUTPUT](value: any) {
79102
// If the value is a string, convert it to a number.
80103
if (typeof value === 'string') {
81104
value = parseInt(value);
82105
validateConfig(
83-
CONFIG_KEYS.OCO_OPENAI_MAX_TOKENS,
106+
CONFIG_KEYS.OCO_TOKENS_MAX_OUTPUT,
84107
!isNaN(value),
85108
'Must be a number'
86109
);
87110
}
88111
validateConfig(
89-
CONFIG_KEYS.OCO_OPENAI_MAX_TOKENS,
112+
CONFIG_KEYS.OCO_TOKENS_MAX_OUTPUT,
90113
value ? typeof value === 'number' : undefined,
91114
'Must be a number'
92115
);
@@ -178,8 +201,11 @@ const configPath = pathJoin(homedir(), '.opencommit');
178201
export const getConfig = (): ConfigType | null => {
179202
const configFromEnv = {
180203
OCO_OPENAI_API_KEY: process.env.OCO_OPENAI_API_KEY,
181-
OCO_OPENAI_MAX_TOKENS: process.env.OCO_OPENAI_MAX_TOKENS
182-
? Number(process.env.OCO_OPENAI_MAX_TOKENS)
204+
OCO_TOKENS_MAX_INPUT: process.env.OCO_TOKENS_MAX_INPUT
205+
? Number(process.env.OCO_TOKENS_MAX_INPUT)
206+
: undefined,
207+
OCO_TOKENS_MAX_OUTPUT: process.env.OCO_TOKENS_MAX_OUTPUT
208+
? Number(process.env.OCO_TOKENS_MAX_OUTPUT)
183209
: undefined,
184210
OCO_OPENAI_BASE_PATH: process.env.OCO_OPENAI_BASE_PATH,
185211
OCO_DESCRIPTION: process.env.OCO_DESCRIPTION === 'true' ? true : false,

src/engine/openAi.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { intro, outro } from '@clack/prompts';
1111

1212
import {
1313
CONFIG_MODES,
14-
DEFAULT_MODEL_TOKEN_LIMIT,
14+
DEFAULT_TOKEN_LIMITS,
1515
getConfig
1616
} from '../commands/config';
1717
import { GenerateCommitMessageErrorEnum } from '../generateCommitMessageFromGitDiff';
@@ -20,7 +20,8 @@ import { AiEngine } from './Engine';
2020

2121
const config = getConfig();
2222

23-
let maxTokens = config?.OCO_OPENAI_MAX_TOKENS;
23+
const MAX_TOKENS_OUTPUT = config?.OCO_TOKENS_MAX_OUTPUT || DEFAULT_TOKEN_LIMITS.DEFAULT_MAX_TOKENS_OUTPUT;
24+
const MAX_TOKENS_INPUT = config?.OCO_TOKENS_MAX_INPUT || DEFAULT_TOKEN_LIMITS.DEFAULT_MAX_TOKENS_INPUT;
2425
let basePath = config?.OCO_OPENAI_BASE_PATH;
2526
let apiKey = config?.OCO_OPENAI_API_KEY
2627

@@ -65,14 +66,14 @@ class OpenAi implements AiEngine {
6566
messages,
6667
temperature: 0,
6768
top_p: 0.1,
68-
max_tokens: maxTokens || 500
69+
max_tokens: MAX_TOKENS_OUTPUT
6970
};
7071
try {
7172
const REQUEST_TOKENS = messages
7273
.map((msg) => tokenCount(msg.content) + 4)
7374
.reduce((a, b) => a + b, 0);
7475

75-
if (REQUEST_TOKENS > DEFAULT_MODEL_TOKEN_LIMIT - maxTokens) {
76+
if (REQUEST_TOKENS > MAX_TOKENS_INPUT - MAX_TOKENS_OUTPUT) {
7677
throw new Error(GenerateCommitMessageErrorEnum.tooMuchTokens);
7778
}
7879

src/generateCommitMessageFromGitDiff.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ import {
33
ChatCompletionRequestMessageRoleEnum
44
} from 'openai';
55

6-
import { DEFAULT_MODEL_TOKEN_LIMIT, getConfig } from './commands/config';
6+
import { DEFAULT_TOKEN_LIMITS, getConfig } from './commands/config';
77
import { getMainCommitPrompt } from './prompts';
88
import { mergeDiffs } from './utils/mergeDiffs';
99
import { tokenCount } from './utils/tokenCount';
1010
import { getEngine } from './utils/engine';
1111

1212
const config = getConfig();
13+
const MAX_TOKENS_INPUT = config?.OCO_TOKENS_MAX_INPUT || DEFAULT_TOKEN_LIMITS.DEFAULT_MAX_TOKENS_INPUT;
14+
const MAX_TOKENS_OUTPUT = config?.OCO_TOKENS_MAX_OUTPUT || DEFAULT_TOKEN_LIMITS.DEFAULT_MAX_TOKENS_OUTPUT;
1315

1416
const generateCommitMessageChatCompletionPrompt = async (
1517
diff: string
@@ -29,7 +31,8 @@ const generateCommitMessageChatCompletionPrompt = async (
2931
export enum GenerateCommitMessageErrorEnum {
3032
tooMuchTokens = 'TOO_MUCH_TOKENS',
3133
internalError = 'INTERNAL_ERROR',
32-
emptyMessage = 'EMPTY_MESSAGE'
34+
emptyMessage = 'EMPTY_MESSAGE',
35+
outputTokensTooHigh = `Token limit exceeded, OCO_TOKENS_MAX_OUTPUT must not be much higher than the default ${DEFAULT_TOKEN_LIMITS.DEFAULT_MAX_TOKENS_OUTPUT} tokens.`
3336
}
3437

3538
const ADJUSTMENT_FACTOR = 20;
@@ -45,10 +48,10 @@ export const generateCommitMessageByDiff = async (
4548
).reduce((a, b) => a + b, 0);
4649

4750
const MAX_REQUEST_TOKENS =
48-
DEFAULT_MODEL_TOKEN_LIMIT -
51+
MAX_TOKENS_INPUT -
4952
ADJUSTMENT_FACTOR -
5053
INIT_MESSAGES_PROMPT_LENGTH -
51-
config?.OCO_OPENAI_MAX_TOKENS;
54+
MAX_TOKENS_OUTPUT;
5255

5356
if (tokenCount(diff) >= MAX_REQUEST_TOKENS) {
5457
const commitMessagePromises = await getCommitMsgsPromisesFromFileDiffs(
@@ -124,6 +127,10 @@ function splitDiff(diff: string, maxChangeLength: number) {
124127
const splitDiffs = [];
125128
let currentDiff = '';
126129

130+
if (maxChangeLength <= 0) {
131+
throw new Error(GenerateCommitMessageErrorEnum.outputTokensTooHigh);
132+
}
133+
127134
for (let line of lines) {
128135
// If a single line exceeds maxChangeLength, split it into multiple lines
129136
while (tokenCount(line) > maxChangeLength) {

0 commit comments

Comments
 (0)