Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
C
coderai
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexlab
coderai
Commits
6c2c0afc
Commit
6c2c0afc
authored
Mar 16, 2026
by
Your Name
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix LiteLLM
parent
8280060e
Changes
6
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
559 additions
and
9 deletions
+559
-9
__init__.py
codai/__init__.py
+0
-2
__init__.py~
codai/__init__.py~
+45
-0
parsers.py
codai/models/parsers.py
+81
-0
parsers.py~
codai/models/parsers.py~
+206
-0
__init__.py
codai/openai/__init__.py
+0
-3
coderai
coderai
+227
-4
No files found.
codai/__init__.py
View file @
6c2c0afc
...
...
@@ -16,8 +16,6 @@ from .models.parser import (
from
.models.templates
import
AgenticTemplateManager
# OpenAI-compatible backends
__all__
=
[
'ModelParserDispatcher'
,
'BaseParser'
,
...
...
codai/__init__.py~
0 → 100644
View file @
6c2c0afc
# codai module - AI model parsing utilities
from .models.parser import (
ModelParserDispatcher,
BaseParser,
QwenParser,
DeepSeekParser,
LlamaParser,
MistralParser,
ClaudeParser,
CommandRParser,
GemmaParser,
GrokParser,
PhiParser,
ApexBig50Parser,
)
from .models.templates import AgenticTemplateManager
# OpenAI-compatible backends
from .openai.litellm import (
LiteLLMBackend,
get_litellm_backend,
set_litellm_backend,
LITELLM_AVAILABLE,
)
__all__ = [
'ModelParserDispatcher',
'BaseParser',
'QwenParser',
'DeepSeekParser',
'LlamaParser',
'MistralParser',
'ClaudeParser',
'CommandRParser',
'GemmaParser',
'GrokParser',
'PhiParser',
'ApexBig50Parser',
'AgenticTemplateManager',
'LiteLLMBackend',
'get_litellm_backend',
'set_litellm_backend',
'LITELLM_AVAILABLE',
]
codai/models/parsers.py
View file @
6c2c0afc
import
time
import
uuid
# Try to import litellm for response formatting
# Fall back to plain dicts if litellm is not available or doesn't export these
try
:
from
litellm
import
ModelResponse
,
ChatCompletionChunk
LITELLM_AVAILABLE
=
True
except
ImportError
:
LITELLM_AVAILABLE
=
False
ModelResponse
=
None
ChatCompletionChunk
=
None
class
OpenAIFormatter
:
"""Formatter for standardizing chat completion responses in OpenAI format.
...
...
@@ -123,3 +133,74 @@ class OpenAIFormatter:
chunk
[
"usage"
]
=
usage
return
chunk
def
format_litellm_full
(
self
,
text
:
str
,
prompt_tokens
:
int
,
completion_tokens
:
int
,
tool_calls
=
None
)
->
dict
:
"""Format using litellm's ModelResponse if available.
Args:
text: The generated text content
prompt_tokens: Number of tokens in the prompt
completion_tokens: Number of tokens in the completion
tool_calls: Optional list of tool calls to include
Returns:
Dictionary representation of ModelResponse
"""
if
not
LITELLM_AVAILABLE
or
ModelResponse
is
None
:
return
self
.
format_full
(
text
,
prompt_tokens
,
completion_tokens
,
tool_calls
)
try
:
from
litellm
import
Choices
,
Message
,
Usage
return
ModelResponse
(
id
=
self
.
id
,
model
=
self
.
model_name
,
object
=
"chat.completion"
,
created
=
int
(
time
.
time
()),
choices
=
[
Choices
(
finish_reason
=
"tool_calls"
if
tool_calls
else
"stop"
,
index
=
0
,
message
=
Message
(
content
=
text
if
not
tool_calls
else
None
,
role
=
"assistant"
,
tool_calls
=
tool_calls
)
)],
usage
=
Usage
(
prompt_tokens
=
prompt_tokens
,
completion_tokens
=
completion_tokens
,
total_tokens
=
prompt_tokens
+
completion_tokens
)
)
.
model_dump
()
except
Exception
:
# Fall back to plain dict if litellm fails
return
self
.
format_full
(
text
,
prompt_tokens
,
completion_tokens
,
tool_calls
)
def
format_litellm_chunk
(
self
,
delta_text
:
str
,
is_final
:
bool
=
False
,
usage
:
dict
=
None
)
->
dict
:
"""Format streaming chunk using litellm's ChatCompletionChunk if available.
Args:
delta_text: The incremental text content for this chunk
is_final: Whether this is the final chunk
usage: Optional usage information (typically only sent on final chunk)
Returns:
Dictionary representation of ChatCompletionChunk
"""
if
not
LITELLM_AVAILABLE
or
ChatCompletionChunk
is
None
:
return
self
.
format_chunk
(
delta_text
,
is_final
,
usage
)
try
:
from
litellm
import
StreamingChoices
,
Delta
,
Usage
return
ChatCompletionChunk
(
id
=
self
.
id
,
model
=
self
.
model_name
,
object
=
"chat.completion.chunk"
,
created
=
int
(
time
.
time
()),
choices
=
[
StreamingChoices
(
finish_reason
=
"stop"
if
is_final
else
None
,
index
=
0
,
delta
=
Delta
(
content
=
delta_text
,
role
=
"assistant"
)
)],
usage
=
Usage
(
**
usage
)
if
usage
else
None
)
.
model_dump
()
except
Exception
:
# Fall back to plain dict if litellm fails
return
self
.
format_chunk
(
delta_text
,
is_final
,
usage
)
codai/models/parsers.py~
0 → 100644
View file @
6c2c0afc
import time
import uuid
# Try to import litellm for response formatting
# Fall back to plain dicts if litellm is not available or doesn't export these
try:
from litellm import ModelResponse, ChatCompletionChunk
LITELLM_AVAILABLE = True
except ImportError:
LITELLM_AVAILABLE = False
ModelResponse = None
ChatCompletionChunk = None
class OpenAIFormatter:
"""Formatter for standardizing chat completion responses in OpenAI format.
This class provides final sanitization of responses before sending them
to clients. It processes the output of the internal parser and formats
them into proper OpenAI-compatible responses.
"""
def __init__(self, model_name: str):
self.model_name = model_name
self.id = f"chatcmpl-{uuid.uuid4()}"
def format_full(self, text: str, prompt_tokens: int, completion_tokens: int, tool_calls=None) -> dict:
"""Format a standard (non-streaming) response.
Args:
text: The generated text content
prompt_tokens: Number of tokens in the prompt
completion_tokens: Number of tokens in the completion
tool_calls: Optional list of tool calls to include
Returns:
Dictionary representation of the response
"""
message = {
"role": "assistant",
"content": text if not tool_calls else None,
}
if tool_calls:
message["tool_calls"] = tool_calls
choice = {
"index": 0,
"message": message,
"finish_reason": "tool_calls" if tool_calls else "stop",
}
return {
"id": self.id,
"object": "chat.completion",
"created": int(time.time()),
"model": self.model_name,
"choices": [choice],
"usage": {
"prompt_tokens": prompt_tokens,
"completion_tokens": completion_tokens,
"total_tokens": prompt_tokens + completion_tokens,
},
"provider": {
"provider_name": "coderai",
"provider_id": "coderai",
},
}
def format_chunk(self, delta_text: str, is_final: bool = False, usage: dict = None) -> dict:
"""Format a streaming chunk response.
Args:
delta_text: The incremental text content for this chunk
is_final: Whether this is the final chunk
usage: Optional usage information (typically only sent on final chunk)
Returns:
Dictionary representation of the chunk
"""
delta = {
"content": delta_text,
"role": "assistant",
}
choice = {
"index": 0,
"delta": delta,
"finish_reason": "stop" if is_final else None,
}
chunk = {
"id": self.id,
"object": "chat.completion.chunk",
"created": int(time.time()),
"model": self.model_name,
"choices": [choice],
}
if usage and is_final:
chunk["usage"] = usage
return chunk
def format_final_chunk(self, usage: dict = None) -> dict:
"""Format the final streaming chunk with usage information.
Args:
usage: Usage statistics dictionary with prompt_tokens, completion_tokens, total_tokens
Returns:
Dictionary representation of the final chunk
"""
delta = {
"content": None,
"role": "assistant",
}
choice = {
"index": 0,
"delta": delta,
"finish_reason": "stop",
}
chunk = {
"id": self.id,
"object": "chat.completion.chunk",
"created": int(time.time()),
"model": self.model_name,
"choices": [choice],
}
if usage:
chunk["usage"] = usage
return chunk
def format_litellm_full(self, text: str, prompt_tokens: int, completion_tokens: int, tool_calls=None) -> dict:
"""Format using litellm's ModelResponse if available.
Args:
text: The generated text content
prompt_tokens: Number of tokens in the prompt
completion_tokens: Number of tokens in the completion
tool_calls: Optional list of tool calls to include
Returns:
Dictionary representation of ModelResponse
"""
if not LITELLM_AVAILABLE or ModelResponse is None:
return self.format_full(text, prompt_tokens, completion_tokens, tool_calls)
try:
from litellm import Choices, Message, Usage
return ModelResponse(
id=self.id,
model=self.model_name,
object="chat.completion",
created=int(time.time()),
choices=[Choices(
finish_reason="tool_calls" if tool_calls else "stop",
index=0,
message=Message(content=text if not tool_calls else None, role="assistant", tool_calls=tool_calls)
)],
usage=Usage(
prompt_tokens=prompt_tokens,
completion_tokens=completion_tokens,
total_tokens=prompt_tokens + completion_tokens
)
).model_dump()
except Exception:
# Fall back to plain dict if litellm fails
return self.format_full(text, prompt_tokens, completion_tokens, tool_calls)
def format_litellm_chunk(self, delta_text: str, is_final: bool = False, usage: dict = None) -> dict:
"""Format streaming chunk using litellm's ChatCompletionChunk if available.
Args:
delta_text: The incremental text content for this chunk
is_final: Whether this is the final chunk
usage: Optional usage information (typically only sent on final chunk)
Returns:
Dictionary representation of ChatCompletionChunk
"""
if not LITELLM_AVAILABLE or ChatCompletionChunk is None:
return self.format_chunk(delta_text, is_final, usage)
try:
from litellm import StreamingChoices, Delta, Usage
return ChatCompletionChunk(
id=self.id,
model=self.model_name,
object="chat.completion.chunk",
created=int(time.time()),
choices=[StreamingChoices(
finish_reason="stop" if is_final else None,
index=0,
delta=Delta(content=delta_text, role="assistant")
)],
usage=Usage(**usage) if usage else None
).model_dump()
except Exception:
# Fall back to plain dict if litellm fails
return self.format_chunk(delta_text, is_final, usage)
codai/openai/__init__.py
deleted
100644 → 0
View file @
8280060e
# codai.openai - OpenAI-compatible API implementations
__all__
=
[]
coderai
View file @
6c2c0afc
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment