Server
Clients
OS
Khoj version
2.0.0-b.22
Describe the bug
When using Groq as an OpenAI-compatible provider, chat requests fail with a BadRequestError: 400 for any model. The error message indicates that max_completion_tokens is either incorrectly set or not supported in the way it’s being passed.
Current Behavior
[02:46:02.469490] DEBUG uvicorn.error: > TEXT '{"error": protocol.py:1170
"Internal server error"}' [34 bytes]
[02:46:02.473333] ERROR khoj.routers.api_chat: Error api_chat.py:1699
processing chat request: Error code:
400 - {'error': {'message':
'max_completion_tokens must be
less than or equal to 8192, the
maximum value for
max_completion_tokens is less than
the context_window for this
model', 'type':
'invalid_request_error', 'param':
'max_completion_tokens'}}
╭─ Traceback (most recent call las─╮
│ /app/src/khoj/routers/api_chat.p │
│ y:1623 in process_chat_request │
│ │
│ 1620 │ │ │ websocket, │
│ 1621 │ │ │ interrupt_que │
│ 1622 │ │ ) │
│ ❱ 1623 │ │ async for event i │
│ 1624 │ │ │ if not event: │
│ 1625 │ │ │ │ continue │
│ 1626 │ │ │ elif event.st │
│ │
│ /app/src/khoj/routers/api_chat.p │
│ y:983 in event_generator │
│ │
│ 980 │ │
│ 981 │ if conversation_comma │
│ 982 │ │ try: │
│ ❱ 983 │ │ │ chosen_io = a │
│ 984 │ │ │ │ q, │
│ 985 │ │ │ │ chat_hist │
│ 986 │ │ │ │ user=user │
│ │
│ /app/src/khoj/routers/helpers.py │
│ :414 in │
│ aget_data_sources_and_output_for │
│ mat │
│ │
│ 411 │ │ output: str │
│ 412 │ │
│ 413 │ with timer("Chat acto │
│ ❱ 414 │ │ raw_response = aw │
│ 415 │ │ │ relevant_tool │
│ 416 │ │ │ query_files=q │
│ 417 │ │ │ query_images= │
│ │
│ /app/src/khoj/routers/helpers.py │
│ :1581 in │
│ send_message_to_model_wrapper │
│ │
│ 1578 │ │ ) │
│ 1579 │ │ │
│ 1580 │ │ try: │
│ ❱ 1581 │ │ │ return send_m │
│ 1582 │ │ │ │ chat_mode │
│ 1583 │ │ │ │ truncated │
│ 1584 │ │ │ │ response_ │
│ │
│ /app/src/khoj/routers/helpers.py │
│ :1476 in send_message_to_model │
│ │
│ 1473 │ api_base_url = chat_m │
│ 1474 │ │
│ 1475 │ if model_type == Chat │
│ ❱ 1476 │ │ return openai_sen │
│ 1477 │ │ │ messages=trun │
│ 1478 │ │ │ api_key=api_k │
│ 1479 │ │ │ model=chat_mo │
│ │
│ /app/src/khoj/processor/conversa │
│ tion/openai/gpt.py:95 in │
│ openai_send_message_to_model │
│ │
│ 92 │ │ │ tracer=tracer, │
│ 93 │ │ ) │
│ 94 │ else: │
│ ❱ 95 │ │ return completion_ │
│ 96 │ │ │ messages=messa │
│ 97 │ │ │ model_name=mod │
│ 98 │ │ │ openai_api_key │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/tenacity/init.py:338 │
│ in wrapped_f │
│ │
│ 335 │ │ │ # calling the │
│ 336 │ │ │ copy = self.co │
│ 337 │ │ │ wrapped_f.stat │
│ ❱ 338 │ │ │ return copy(f, │
│ 339 │ │ │
│ 340 │ │ def retry_with(*ar │
│ 341 │ │ │ return self.co │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/tenacity/init.py:477 │
│ in call │
│ │
│ 474 │ │ │
│ 475 │ │ retry_state = Retr │
│ 476 │ │ while True: │
│ ❱ 477 │ │ │ do = self.iter │
│ 478 │ │ │ if isinstance( │
│ 479 │ │ │ │ try: │
│ 480 │ │ │ │ │ result │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/tenacity/init.py:378 │
│ in iter │
│ │
│ 375 │ │ self._begin_iter(r │
│ 376 │ │ result = None │
│ 377 │ │ for action in self │
│ ❱ 378 │ │ │ result = actio │
│ 379 │ │ return result │
│ 380 │ │
│ 381 │ def begin_iter(self, │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/tenacity/init.py:400 │
│ in │
│ │
│ 397 │ │
│ 398 │ def post_retry_check │
│ 399 │ │ if not (self.iter │
│ ❱ 400 │ │ │ self._add_acti │
│ 401 │ │ │ return │
│ 402 │ │ │
│ 403 │ │ if self.after is n │
│ │
│ /usr/lib/python3.10/concurrent/f │
│ utures/_base.py:451 in result │
│ │
│ 448 │ │ │ │ if self._s │
│ 449 │ │ │ │ │ raise │
│ 450 │ │ │ │ elif self. │
│ ❱ 451 │ │ │ │ │ return │
│ 452 │ │ │ │ │
│ 453 │ │ │ │ self._cond │
│ 454 │
│ │
│ /usr/lib/python3.10/concurrent/f │
│ utures/_base.py:403 in │
│ __get_result │
│ │
│ 400 │ def __get_result(self) │
│ 401 │ │ if self.exception │
│ 402 │ │ │ try: │
│ ❱ 403 │ │ │ │ raise self │
│ 404 │ │ │ finally: │
│ 405 │ │ │ │ # Break a │
│ 406 │ │ │ │ self = Non │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/tenacity/init.py:480 │
│ in call │
│ │
│ 477 │ │ │ do = self.iter │
│ 478 │ │ │ if isinstance( │
│ 479 │ │ │ │ try: │
│ ❱ 480 │ │ │ │ │ result │
│ 481 │ │ │ │ except Bas │
│ 482 │ │ │ │ │ retry │
│ 483 │ │ │ │ else: │
│ │
│ /app/src/khoj/processor/conversa │
│ tion/openai/utils.py:195 in │
│ completion_with_backoff │
│ │
│ 192 │ │ # if model_kwa │
│ 193 │ │ # model_kw │
│ 194 │ │ # --------------- │
│ ❱ 195 │ │ with client.beta. │
│ 196 │ │ │ messages=form │
│ 197 │ │ │ model=model_n │
│ 198 │ │ │ timeout=httpx │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/openai/lib/streaming/cha │
│ t/_completions.py:150 in │
│ enter │
│ │
│ 147 │ │ self.__input_tools │
│ 148 │ │
│ 149 │ def enter(self) -> │
│ ❱ 150 │ │ raw_stream = self. │
│ 151 │ │ │
│ 152 │ │ self.__stream = Ch │
│ 153 │ │ │ raw_stream=raw │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/openai/_utils/_utils.py: │
│ 286 in wrapper │
│ │
│ 283 │ │ │ │ │ else: │
│ 284 │ │ │ │ │ │ ms │
│ 285 │ │ │ │ raise Type │
│ ❱ 286 │ │ │ return func(*a │
│ 287 │ │ │
│ 288 │ │ return wrapper # │
│ 289 │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/openai/resources/chat/co │
│ mpletions/completions.py:1192 in │
│ create │
│ │
│ 1189 │ │ timeout: float | │
│ 1190 │ ) -> ChatCompletion | │
│ 1191 │ │ validate_response │
│ ❱ 1192 │ │ return self._post │
│ 1193 │ │ │ "/chat/comple │
│ 1194 │ │ │ body=maybe_tr │
│ 1195 │ │ │ │ { │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/openai/_base_client.py:1 │
│ 259 in post │
│ │
│ 1256 │ │ opts = FinalReque │
│ 1257 │ │ │ method="post" │
│ **options │
│ 1258 │ │ ) │
│ ❱ 1259 │ │ return cast(Respo │
│ stream_cls=stream_cls)) │
│ 1260 │ │
│ 1261 │ def patch( │
│ 1262 │ │ self, │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/openai/_base_client.py:1 │
│ 047 in request │
│ │
│ 1044 │ │ │ │ │ err.r │
│ 1045 │ │ │ │ │
│ 1046 │ │ │ │ log.debug │
│ ❱ 1047 │ │ │ │ raise sel │
│ 1048 │ │ │ │
│ 1049 │ │ │ break │
│ 1050 │
╰──────────────────────────────────╯
BadRequestError: Error code: 400 -
{'error': {'message':
'max_completion_tokens must be
less than or equal to 8192, the
maximum value for
max_completion_tokens is less than
the context_window for this
model', 'type':
'invalid_request_error', 'param':
'max_completion_tokens'}}
Expected Behavior
The API models should reply without errors, returning 200 status code.
Reproduction Steps
- Configure Khoj to use Groq as an OpenAI-compatible chat provider.
- Attempt to start a chat session.
- Observe the 400 Bad Request error in the logs.
Possible Workaround
No response
Additional Information
No response
Link to Discord or Github discussion
No response
Server
Clients
OS
Khoj version
2.0.0-b.22
Describe the bug
When using Groq as an OpenAI-compatible provider, chat requests fail with a BadRequestError: 400 for any model. The error message indicates that max_completion_tokens is either incorrectly set or not supported in the way it’s being passed.
Current Behavior
[02:46:02.469490] DEBUG uvicorn.error: > TEXT '{"error": protocol.py:1170
"Internal server error"}' [34 bytes]
[02:46:02.473333] ERROR khoj.routers.api_chat: Error api_chat.py:1699
processing chat request: Error code:
400 - {'error': {'message':
'
max_completion_tokensmust beless than or equal to
8192, themaximum value for
max_completion_tokensis less thanthe
context_windowfor thismodel', 'type':
'invalid_request_error', 'param':
'max_completion_tokens'}}
╭─ Traceback (most recent call las─╮
│ /app/src/khoj/routers/api_chat.p │
│ y:1623 in process_chat_request │
│ │
│ 1620 │ │ │ websocket, │
│ 1621 │ │ │ interrupt_que │
│ 1622 │ │ ) │
│ ❱ 1623 │ │ async for event i │
│ 1624 │ │ │ if not event: │
│ 1625 │ │ │ │ continue │
│ 1626 │ │ │ elif event.st │
│ │
│ /app/src/khoj/routers/api_chat.p │
│ y:983 in event_generator │
│ │
│ 980 │ │
│ 981 │ if conversation_comma │
│ 982 │ │ try: │
│ ❱ 983 │ │ │ chosen_io = a │
│ 984 │ │ │ │ q, │
│ 985 │ │ │ │ chat_hist │
│ 986 │ │ │ │ user=user │
│ │
│ /app/src/khoj/routers/helpers.py │
│ :414 in │
│ aget_data_sources_and_output_for │
│ mat │
│ │
│ 411 │ │ output: str │
│ 412 │ │
│ 413 │ with timer("Chat acto │
│ ❱ 414 │ │ raw_response = aw │
│ 415 │ │ │ relevant_tool │
│ 416 │ │ │ query_files=q │
│ 417 │ │ │ query_images= │
│ │
│ /app/src/khoj/routers/helpers.py │
│ :1581 in │
│ send_message_to_model_wrapper │
│ │
│ 1578 │ │ ) │
│ 1579 │ │ │
│ 1580 │ │ try: │
│ ❱ 1581 │ │ │ return send_m │
│ 1582 │ │ │ │ chat_mode │
│ 1583 │ │ │ │ truncated │
│ 1584 │ │ │ │ response_ │
│ │
│ /app/src/khoj/routers/helpers.py │
│ :1476 in send_message_to_model │
│ │
│ 1473 │ api_base_url = chat_m │
│ 1474 │ │
│ 1475 │ if model_type == Chat │
│ ❱ 1476 │ │ return openai_sen │
│ 1477 │ │ │ messages=trun │
│ 1478 │ │ │ api_key=api_k │
│ 1479 │ │ │ model=chat_mo │
│ │
│ /app/src/khoj/processor/conversa │
│ tion/openai/gpt.py:95 in │
│ openai_send_message_to_model │
│ │
│ 92 │ │ │ tracer=tracer, │
│ 93 │ │ ) │
│ 94 │ else: │
│ ❱ 95 │ │ return completion_ │
│ 96 │ │ │ messages=messa │
│ 97 │ │ │ model_name=mod │
│ 98 │ │ │ openai_api_key │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/tenacity/init.py:338 │
│ in wrapped_f │
│ │
│ 335 │ │ │ # calling the │
│ 336 │ │ │ copy = self.co │
│ 337 │ │ │ wrapped_f.stat │
│ ❱ 338 │ │ │ return copy(f, │
│ 339 │ │ │
│ 340 │ │ def retry_with(*ar │
│ 341 │ │ │ return self.co │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/tenacity/init.py:477 │
│ in call │
│ │
│ 474 │ │ │
│ 475 │ │ retry_state = Retr │
│ 476 │ │ while True: │
│ ❱ 477 │ │ │ do = self.iter │
│ 478 │ │ │ if isinstance( │
│ 479 │ │ │ │ try: │
│ 480 │ │ │ │ │ result │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/tenacity/init.py:378 │
│ in iter │
│ │
│ 375 │ │ self._begin_iter(r │
│ 376 │ │ result = None │
│ 377 │ │ for action in self │
│ ❱ 378 │ │ │ result = actio │
│ 379 │ │ return result │
│ 380 │ │
│ 381 │ def begin_iter(self, │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/tenacity/init.py:400 │
│ in │
│ │
│ 397 │ │
│ 398 │ def post_retry_check │
│ 399 │ │ if not (self.iter │
│ ❱ 400 │ │ │ self._add_acti │
│ 401 │ │ │ return │
│ 402 │ │ │
│ 403 │ │ if self.after is n │
│ │
│ /usr/lib/python3.10/concurrent/f │
│ utures/_base.py:451 in result │
│ │
│ 448 │ │ │ │ if self._s │
│ 449 │ │ │ │ │ raise │
│ 450 │ │ │ │ elif self. │
│ ❱ 451 │ │ │ │ │ return │
│ 452 │ │ │ │ │
│ 453 │ │ │ │ self._cond │
│ 454 │
│ │
│ /usr/lib/python3.10/concurrent/f │
│ utures/_base.py:403 in │
│ __get_result │
│ │
│ 400 │ def __get_result(self) │
│ 401 │ │ if self.exception │
│ 402 │ │ │ try: │
│ ❱ 403 │ │ │ │ raise self │
│ 404 │ │ │ finally: │
│ 405 │ │ │ │ # Break a │
│ 406 │ │ │ │ self = Non │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/tenacity/init.py:480 │
│ in call │
│ │
│ 477 │ │ │ do = self.iter │
│ 478 │ │ │ if isinstance( │
│ 479 │ │ │ │ try: │
│ ❱ 480 │ │ │ │ │ result │
│ 481 │ │ │ │ except Bas │
│ 482 │ │ │ │ │ retry │
│ 483 │ │ │ │ else: │
│ │
│ /app/src/khoj/processor/conversa │
│ tion/openai/utils.py:195 in │
│ completion_with_backoff │
│ │
│ 192 │ │ # if model_kwa │
│ 193 │ │ # model_kw │
│ 194 │ │ # --------------- │
│ ❱ 195 │ │ with client.beta. │
│ 196 │ │ │ messages=form │
│ 197 │ │ │ model=model_n │
│ 198 │ │ │ timeout=httpx │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/openai/lib/streaming/cha │
│ t/_completions.py:150 in │
│ enter │
│ │
│ 147 │ │ self.__input_tools │
│ 148 │ │
│ 149 │ def enter(self) -> │
│ ❱ 150 │ │ raw_stream = self. │
│ 151 │ │ │
│ 152 │ │ self.__stream = Ch │
│ 153 │ │ │ raw_stream=raw │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/openai/_utils/_utils.py: │
│ 286 in wrapper │
│ │
│ 283 │ │ │ │ │ else: │
│ 284 │ │ │ │ │ │ ms │
│ 285 │ │ │ │ raise Type │
│ ❱ 286 │ │ │ return func(*a │
│ 287 │ │ │
│ 288 │ │ return wrapper # │
│ 289 │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/openai/resources/chat/co │
│ mpletions/completions.py:1192 in │
│ create │
│ │
│ 1189 │ │ timeout: float | │
│ 1190 │ ) -> ChatCompletion | │
│ 1191 │ │ validate_response │
│ ❱ 1192 │ │ return self._post │
│ 1193 │ │ │ "/chat/comple │
│ 1194 │ │ │ body=maybe_tr │
│ 1195 │ │ │ │ { │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/openai/_base_client.py:1 │
│ 259 in post │
│ │
│ 1256 │ │ opts = FinalReque │
│ 1257 │ │ │ method="post" │
│ **options │
│ 1258 │ │ ) │
│ ❱ 1259 │ │ return cast(Respo │
│ stream_cls=stream_cls)) │
│ 1260 │ │
│ 1261 │ def patch( │
│ 1262 │ │ self, │
│ │
│ /usr/local/lib/python3.10/dist-p │
│ ackages/openai/_base_client.py:1 │
│ 047 in request │
│ │
│ 1044 │ │ │ │ │ err.r │
│ 1045 │ │ │ │ │
│ 1046 │ │ │ │ log.debug │
│ ❱ 1047 │ │ │ │ raise sel │
│ 1048 │ │ │ │
│ 1049 │ │ │ break │
│ 1050 │
╰──────────────────────────────────╯
BadRequestError: Error code: 400 -
{'error': {'message':
'
max_completion_tokensmust beless than or equal to
8192, themaximum value for
max_completion_tokensis less thanthe
context_windowfor thismodel', 'type':
'invalid_request_error', 'param':
'max_completion_tokens'}}
Expected Behavior
The API models should reply without errors, returning 200 status code.
Reproduction Steps
Possible Workaround
No response
Additional Information
No response
Link to Discord or Github discussion
No response