Skip to content
This repository was archived by the owner on Mar 9, 2026. It is now read-only.

Commit 48e328d

Browse files
committed
Refactor get_llm_model and add token size checks 🔄🔍
This commit moves the `get_llm_model` function from `cli.py` to `helpers.py` for better code organization. It also introduces token size checks in various functions in `cli.py` to ensure the token size does not exceed the model's capacity. If the token size is too large, an exception is raised with a helpful error message. 🚀📏 In `prompts/sidekick.py`, token length is now logged for each file in the context, providing useful debugging information. 📊🔍 These changes improve the robustness of the code and provide better feedback to the user when the token size is too large. 🛠️👍
1 parent 8df4dc4 commit 48e328d

File tree

3 files changed

+60
-39
lines changed

3 files changed

+60
-39
lines changed

aicodebot/cli.py

Lines changed: 17 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from aicodebot import version as aicodebot_version
2-
from aicodebot.helpers import exec_and_get_output, get_token_length, git_diff_context, logger
2+
from aicodebot.helpers import exec_and_get_output, get_llm_model, get_token_length, git_diff_context, logger
33
from aicodebot.prompts import generate_files_context, generate_sidekick_prompt
44
from dotenv import load_dotenv
55
from langchain.callbacks.base import BaseCallbackHandler
@@ -120,6 +120,10 @@ def commit(verbose, response_token_size, yes, skip_pre_commit):
120120
# Check the size of the diff context and adjust accordingly
121121
request_token_size = get_token_length(diff_context) + get_token_length(prompt.template)
122122
model = get_llm_model(request_token_size)
123+
if model is None:
124+
raise click.ClickException(
125+
f"The diff is too large to generate a commit message ({request_token_size} tokens). 😢"
126+
)
123127

124128
# Set up the language model
125129
llm = ChatOpenAI(model=model, temperature=PRECISE_TEMPERATURE, max_tokens=DEFAULT_MAX_TOKENS, verbose=verbose)
@@ -181,7 +185,10 @@ def debug(command, verbose):
181185
logger.trace(f"Prompt: {prompt}")
182186

183187
# Set up the language model
184-
model = get_llm_model(get_token_length(error_output) + get_token_length(prompt.template))
188+
request_token_size = get_token_length(error_output) + get_token_length(prompt.template)
189+
model = get_llm_model(request_token_size)
190+
if model is None:
191+
raise click.ClickException(f"The output is too large to debug ({request_token_size} tokens). 😢")
185192

186193
with Live(Markdown(""), auto_refresh=True) as live:
187194
llm = ChatOpenAI(
@@ -250,7 +257,8 @@ def review(commit, verbose):
250257
response_token_size = DEFAULT_MAX_TOKENS
251258
request_token_size = get_token_length(diff_context) + get_token_length(prompt.template)
252259
model = get_llm_model(request_token_size)
253-
logger.info(f"Diff context token size: {request_token_size}, using model: {model}")
260+
if model is None:
261+
raise click.ClickException(f"The diff is too large to review ({request_token_size} tokens). 😢")
254262

255263
with Live(Markdown(""), auto_refresh=True) as live:
256264
llm = ChatOpenAI(
@@ -291,7 +299,12 @@ def sidekick(request, verbose, files):
291299

292300
# Generate the prompt and set up the model
293301
prompt = generate_sidekick_prompt(request, files)
294-
model = get_llm_model(get_token_length(prompt.template) + get_token_length(context))
302+
request_token_size = get_token_length(prompt.template) + get_token_length(context)
303+
model = get_llm_model(request_token_size)
304+
if model is None:
305+
raise click.ClickException(
306+
f"The file context you supplied is too large ({request_token_size} tokens). 😢 Try again with less files."
307+
)
295308

296309
llm = ChatOpenAI(
297310
model=model,
@@ -400,41 +413,6 @@ def setup_environment():
400413
)
401414

402415

403-
def get_llm_model(token_size=0):
404-
# https://platform.openai.com/docs/models/gpt-3-5
405-
# We want to use GPT-4, if it is available for this OPENAI_API_KEY, otherwise GPT-3.5
406-
# We also want to use the largest model that supports the token size we need
407-
model_options = {
408-
"gpt-4": 8192,
409-
"gpt-4-32k": 32768,
410-
"gpt-3.5-turbo": 4096,
411-
"gpt-3.5-turbo-16k": 16384,
412-
}
413-
gpt_4_supported = os.getenv("GPT_4_SUPPORTED") == "true"
414-
415-
# For some unknown reason, tiktoken often underestimates the token size by ~10%, so let's buffer
416-
token_size = int(token_size * 1.1)
417-
418-
if gpt_4_supported:
419-
if token_size <= model_options["gpt-4"]:
420-
logger.info(f"Using GPT-4 for token size {token_size}")
421-
return "gpt-4"
422-
elif token_size <= model_options["gpt-4-32k"]:
423-
logger.info(f"Using GPT-4-32k for token size {token_size}")
424-
return "gpt-4-32k"
425-
else:
426-
raise click.ClickException("🛑 The context is too large to for the Model. 😞")
427-
else:
428-
if token_size <= model_options["gpt-3.5-turbo"]: # noqa: PLR5501
429-
logger.info(f"Using GPT-3.5-turbo for token size {token_size}")
430-
return "gpt-3.5-turbo"
431-
elif token_size <= model_options["gpt-3.5-turbo-16k"]:
432-
logger.info(f"Using GPT-3.5-turbo-16k for token size {token_size}")
433-
return "gpt-3.5-turbo-16k"
434-
else:
435-
raise click.ClickException("🛑 The context is too large to for the Model. 😞")
436-
437-
438416
class RichLiveCallbackHandler(BaseCallbackHandler):
439417
buffer = []
440418

aicodebot/helpers.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,43 @@
2020
# ---------------------------------------------------------------------------- #
2121

2222

23+
def get_llm_model(token_size=0):
24+
# https://platform.openai.com/docs/models/gpt-3-5
25+
# We want to use GPT-4, if it is available for this OPENAI_API_KEY, otherwise GPT-3.5
26+
# We also want to use the largest model that supports the token size we need
27+
model_options = {
28+
"gpt-4": 8192,
29+
"gpt-4-32k": 32768,
30+
"gpt-3.5-turbo": 4096,
31+
"gpt-3.5-turbo-16k": 16384,
32+
}
33+
gpt_4_supported = os.getenv("GPT_4_SUPPORTED") == "true"
34+
35+
# For some unknown reason, tiktoken often underestimates the token size by ~10%, so let's buffer
36+
token_size = int(token_size * 1.1)
37+
38+
if gpt_4_supported:
39+
if token_size <= model_options["gpt-4"]:
40+
logger.info(f"Using GPT-4 for token size {token_size}")
41+
return "gpt-4"
42+
elif token_size <= model_options["gpt-4-32k"]:
43+
logger.info(f"Using GPT-4-32k for token size {token_size}")
44+
return "gpt-4-32k"
45+
else:
46+
logger.critical("🛑 The context is too large to for the Model. 😞")
47+
return None
48+
else:
49+
if token_size <= model_options["gpt-3.5-turbo"]: # noqa: PLR5501
50+
logger.info(f"Using GPT-3.5-turbo for token size {token_size}")
51+
return "gpt-3.5-turbo"
52+
elif token_size <= model_options["gpt-3.5-turbo-16k"]:
53+
logger.info(f"Using GPT-3.5-turbo-16k for token size {token_size}")
54+
return "gpt-3.5-turbo-16k"
55+
else:
56+
logger.critical("🛑 The context is too large to for the Model. 😞")
57+
return None
58+
59+
2360
def get_token_length(text, model="gpt-3.5-turbo"):
2461
"""Get the number of tokens in a string using the tiktoken library."""
2562
encoding = tiktoken.encoding_for_model(model)

aicodebot/prompts/sidekick.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from aicodebot.helpers import get_token_length, logger
12
from aicodebot.prompts.personalities import get_personality_prompt
23
from langchain import PromptTemplate
34
from pathlib import Path
@@ -25,6 +26,11 @@ def generate_files_context(files):
2526
files_context = "Here are the relevant files we are working with in this session:\n"
2627
for file_name in files:
2728
contents = Path(file_name).read_text()
29+
token_length = get_token_length(contents)
30+
if token_length > 2_000:
31+
logger.warning(f"File {file_name} is large, using {token_length} tokens")
32+
else:
33+
logger.debug(f"File {file_name} is {token_length} tokens")
2834
files_context += f"--- START OF FILE: {file_name} ---\n"
2935
files_context += contents
3036
files_context += f"\n--- END OF FILE: {file_name} ---\n\n"

0 commit comments

Comments
 (0)