codemie-sdk-python 0.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of codemie-sdk-python might be problematic. Click here for more details.
- codemie_sdk/__init__.py +23 -0
- codemie_sdk/auth/__init__.py +5 -0
- codemie_sdk/auth/credentials.py +112 -0
- codemie_sdk/client/__init__.py +5 -0
- codemie_sdk/client/client.py +107 -0
- codemie_sdk/exceptions.py +45 -0
- codemie_sdk/models/assistant.py +192 -0
- codemie_sdk/models/common.py +39 -0
- codemie_sdk/models/datasource.py +293 -0
- codemie_sdk/models/integration.py +68 -0
- codemie_sdk/models/llm.py +48 -0
- codemie_sdk/models/task.py +44 -0
- codemie_sdk/models/user.py +50 -0
- codemie_sdk/models/workflow.py +86 -0
- codemie_sdk/services/assistant.py +173 -0
- codemie_sdk/services/datasource.py +150 -0
- codemie_sdk/services/integration.py +152 -0
- codemie_sdk/services/llm.py +38 -0
- codemie_sdk/services/task.py +34 -0
- codemie_sdk/services/user.py +34 -0
- codemie_sdk/services/workflow.py +144 -0
- codemie_sdk/services/workflow_execution.py +102 -0
- codemie_sdk/utils/__init__.py +5 -0
- codemie_sdk/utils/http.py +226 -0
- codemie_sdk_python-0.1.1.dist-info/LICENSE +19 -0
- codemie_sdk_python-0.1.1.dist-info/METADATA +120 -0
- codemie_sdk_python-0.1.1.dist-info/RECORD +28 -0
- codemie_sdk_python-0.1.1.dist-info/WHEEL +4 -0
codemie_sdk/__init__.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CodeMie SDK for Python
|
|
3
|
+
~~~~~~~~~~~~~~~~~~~~~
|
|
4
|
+
|
|
5
|
+
A Python SDK for interacting with CodeMie API.
|
|
6
|
+
|
|
7
|
+
Basic usage:
|
|
8
|
+
|
|
9
|
+
>>> from codemie_sdk import CodeMieClient
|
|
10
|
+
>>> client = CodeMieClient(
|
|
11
|
+
... auth_server_url="https://auth.example.com",
|
|
12
|
+
... auth_client_id="client_id",
|
|
13
|
+
... auth_client_secret="secret",
|
|
14
|
+
... auth_realm_name="realm",
|
|
15
|
+
... codemie_api_domain="api.codemie.com"
|
|
16
|
+
... )
|
|
17
|
+
>>> assistants = client.assistants.list()
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from .client.client import CodeMieClient
|
|
21
|
+
|
|
22
|
+
__version__ = "0.1.11"
|
|
23
|
+
__all__ = ["CodeMieClient"]
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"""Authentication credentials module for CodeMie SDK."""
|
|
2
|
+
|
|
3
|
+
import requests
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class KeycloakCredentials:
|
|
8
|
+
"""Keycloak authentication credentials handler."""
|
|
9
|
+
|
|
10
|
+
def __init__(
|
|
11
|
+
self,
|
|
12
|
+
server_url: str,
|
|
13
|
+
realm_name: str,
|
|
14
|
+
client_id: Optional[str] = None,
|
|
15
|
+
client_secret: Optional[str] = None,
|
|
16
|
+
username: Optional[str] = None,
|
|
17
|
+
password: Optional[str] = None,
|
|
18
|
+
verify_ssl: bool = True,
|
|
19
|
+
):
|
|
20
|
+
"""Initialize Keycloak credentials.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
server_url: Keycloak server URL
|
|
24
|
+
realm_name: Realm name
|
|
25
|
+
client_id: Client ID (optional if using username/password)
|
|
26
|
+
client_secret: Client secret (optional if using username/password)
|
|
27
|
+
username: Username/email for password grant (optional)
|
|
28
|
+
password: Password for password grant (optional)
|
|
29
|
+
verify_ssl: Whether to verify SSL certificates (default: True)
|
|
30
|
+
"""
|
|
31
|
+
self.server_url = server_url.rstrip("/")
|
|
32
|
+
self.realm_name = realm_name
|
|
33
|
+
self.client_id = client_id
|
|
34
|
+
self.client_secret = client_secret
|
|
35
|
+
self.username = username
|
|
36
|
+
self.password = password
|
|
37
|
+
self.verify_ssl = verify_ssl
|
|
38
|
+
|
|
39
|
+
if not ((client_id and client_secret) or (username and password)):
|
|
40
|
+
raise ValueError(
|
|
41
|
+
"Either client credentials (client_id, client_secret) or "
|
|
42
|
+
"user credentials (username, password) must be provided"
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
def get_token(self) -> str:
|
|
46
|
+
"""Get access token using either client credentials or password grant."""
|
|
47
|
+
url = (
|
|
48
|
+
f"{self.server_url}/realms/{self.realm_name}/protocol/openid-connect/token"
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
if self.username and self.password:
|
|
52
|
+
# Use Resource Owner Password Credentials flow
|
|
53
|
+
payload = {
|
|
54
|
+
"grant_type": "password",
|
|
55
|
+
"username": self.username,
|
|
56
|
+
"password": self.password,
|
|
57
|
+
"client_id": self.client_id
|
|
58
|
+
or "codemie-sdk", # Use default client if not specified
|
|
59
|
+
}
|
|
60
|
+
if self.client_secret:
|
|
61
|
+
payload["client_secret"] = self.client_secret
|
|
62
|
+
else:
|
|
63
|
+
# Use Client Credentials flow
|
|
64
|
+
payload = {
|
|
65
|
+
"grant_type": "client_credentials",
|
|
66
|
+
"client_id": self.client_id,
|
|
67
|
+
"client_secret": self.client_secret,
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
response = requests.post(url, data=payload, verify=self.verify_ssl)
|
|
71
|
+
response.raise_for_status()
|
|
72
|
+
return response.json()["access_token"]
|
|
73
|
+
|
|
74
|
+
def exchange_token_for_user(self, email: str, access_token: str) -> str:
|
|
75
|
+
"""Exchange service account token for user token."""
|
|
76
|
+
user_id = self.find_user_by_email(email, access_token)
|
|
77
|
+
return self._exchange_token_for_user(user_id, access_token)
|
|
78
|
+
|
|
79
|
+
def find_user_by_email(self, email: str, access_token: str) -> str:
|
|
80
|
+
"""Find user ID by email."""
|
|
81
|
+
url = f"{self.server_url}/admin/realms/{self.realm_name}/users?email={email}"
|
|
82
|
+
headers = {
|
|
83
|
+
"Authorization": f"Bearer {access_token}",
|
|
84
|
+
"Content-Type": "application/json",
|
|
85
|
+
}
|
|
86
|
+
response = requests.get(url, headers=headers, verify=self.verify_ssl)
|
|
87
|
+
response.raise_for_status()
|
|
88
|
+
|
|
89
|
+
users = response.json()
|
|
90
|
+
if not users:
|
|
91
|
+
raise ValueError(f"User with email {email} not found")
|
|
92
|
+
return users[0]["id"]
|
|
93
|
+
|
|
94
|
+
def _exchange_token_for_user(self, user_id: str, service_account_token: str) -> str:
|
|
95
|
+
"""Exchange token for specific user."""
|
|
96
|
+
url = (
|
|
97
|
+
f"{self.server_url}/realms/{self.realm_name}/protocol/openid-connect/token"
|
|
98
|
+
)
|
|
99
|
+
headers = {"Content-Type": "application/x-www-form-urlencoded"}
|
|
100
|
+
payload = {
|
|
101
|
+
"client_id": self.client_id,
|
|
102
|
+
"client_secret": self.client_secret,
|
|
103
|
+
"grant_type": "urn:ietf:params:oauth:grant-datasource_type:token-exchange",
|
|
104
|
+
"subject_token": service_account_token,
|
|
105
|
+
"requested_subject": user_id,
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
response = requests.post(
|
|
109
|
+
url, headers=headers, data=payload, verify=self.verify_ssl
|
|
110
|
+
)
|
|
111
|
+
response.raise_for_status()
|
|
112
|
+
return response.json()["access_token"]
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"""Base client implementation for CodeMie SDK."""
|
|
2
|
+
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
from ..auth.credentials import KeycloakCredentials
|
|
6
|
+
from ..services.assistant import AssistantService
|
|
7
|
+
from ..services.datasource import DatasourceService
|
|
8
|
+
from ..services.llm import LLMService
|
|
9
|
+
from ..services.integration import IntegrationService
|
|
10
|
+
from ..services.task import TaskService
|
|
11
|
+
from ..services.user import UserService
|
|
12
|
+
from ..services.workflow import WorkflowService
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class CodeMieClient:
|
|
16
|
+
"""Main client class for interacting with CodeMie API."""
|
|
17
|
+
|
|
18
|
+
def __init__(
|
|
19
|
+
self,
|
|
20
|
+
auth_server_url: str,
|
|
21
|
+
auth_realm_name: str,
|
|
22
|
+
codemie_api_domain: str,
|
|
23
|
+
auth_client_id: Optional[str] = None,
|
|
24
|
+
auth_client_secret: Optional[str] = None,
|
|
25
|
+
username: Optional[str] = None,
|
|
26
|
+
password: Optional[str] = None,
|
|
27
|
+
verify_ssl: bool = True,
|
|
28
|
+
):
|
|
29
|
+
"""Initialize CodeMie client with authentication credentials.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
auth_server_url: Keycloak server URL
|
|
33
|
+
auth_realm_name: Realm name for authentication
|
|
34
|
+
codemie_api_domain: CodeMie API domain
|
|
35
|
+
auth_client_id: Client ID for authentication (optional if using username/password)
|
|
36
|
+
auth_client_secret: Client secret for authentication (optional if using username/password)
|
|
37
|
+
username: Username/email for password grant (optional if using client credentials)
|
|
38
|
+
password: Password for password grant (optional if using client credentials)
|
|
39
|
+
verify_ssl: Whether to verify SSL certificates (default: True)
|
|
40
|
+
"""
|
|
41
|
+
self.auth = KeycloakCredentials(
|
|
42
|
+
server_url=auth_server_url,
|
|
43
|
+
realm_name=auth_realm_name,
|
|
44
|
+
client_id=auth_client_id,
|
|
45
|
+
client_secret=auth_client_secret,
|
|
46
|
+
username=username,
|
|
47
|
+
password=password,
|
|
48
|
+
verify_ssl=verify_ssl,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
self._token: Optional[str] = None
|
|
52
|
+
self._api_domain = codemie_api_domain.rstrip("/")
|
|
53
|
+
self._verify_ssl = verify_ssl
|
|
54
|
+
|
|
55
|
+
# Initialize token first
|
|
56
|
+
self._token = self.auth.get_token()
|
|
57
|
+
|
|
58
|
+
# Initialize services with verify_ssl parameter and token
|
|
59
|
+
self.assistants = AssistantService(
|
|
60
|
+
self._api_domain, self._token, verify_ssl=verify_ssl
|
|
61
|
+
)
|
|
62
|
+
self.llms = LLMService(self._api_domain, self._token, verify_ssl=verify_ssl)
|
|
63
|
+
self.integrations = IntegrationService(
|
|
64
|
+
self._api_domain, self._token, verify_ssl=verify_ssl
|
|
65
|
+
)
|
|
66
|
+
self.tasks = TaskService(self._api_domain, self._token, verify_ssl=verify_ssl)
|
|
67
|
+
self.users = UserService(self._api_domain, self._token, verify_ssl=verify_ssl)
|
|
68
|
+
self.datasources = DatasourceService(
|
|
69
|
+
self._api_domain, self._token, verify_ssl=verify_ssl
|
|
70
|
+
)
|
|
71
|
+
self.workflows = WorkflowService(
|
|
72
|
+
self._api_domain, self._token, verify_ssl=self._verify_ssl
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
@property
|
|
76
|
+
def token(self) -> str:
|
|
77
|
+
"""Get current token or fetch new one if not available."""
|
|
78
|
+
if not self._token:
|
|
79
|
+
self._token = self.auth.get_token()
|
|
80
|
+
return self._token
|
|
81
|
+
|
|
82
|
+
def refresh_token(self) -> str:
|
|
83
|
+
"""Force token refresh."""
|
|
84
|
+
self._token = self.auth.get_token()
|
|
85
|
+
# Update token in services
|
|
86
|
+
self.assistants = AssistantService(
|
|
87
|
+
self._api_domain, self._token, verify_ssl=self._verify_ssl
|
|
88
|
+
)
|
|
89
|
+
self.llms = LLMService(
|
|
90
|
+
self._api_domain, self._token, verify_ssl=self._verify_ssl
|
|
91
|
+
)
|
|
92
|
+
self.integrations = IntegrationService(
|
|
93
|
+
self._api_domain, self._token, verify_ssl=self._verify_ssl
|
|
94
|
+
)
|
|
95
|
+
self.tasks = TaskService(
|
|
96
|
+
self._api_domain, self._token, verify_ssl=self._verify_ssl
|
|
97
|
+
)
|
|
98
|
+
self.users = UserService(
|
|
99
|
+
self._api_domain, self._token, verify_ssl=self._verify_ssl
|
|
100
|
+
)
|
|
101
|
+
self.datasources = DatasourceService(
|
|
102
|
+
self._api_domain, self._token, verify_ssl=self._verify_ssl
|
|
103
|
+
)
|
|
104
|
+
self.workflows = WorkflowService(
|
|
105
|
+
self._api_domain, self._token, verify_ssl=self._verify_ssl
|
|
106
|
+
)
|
|
107
|
+
return self._token
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""Custom exceptions for the CodeMie SDK."""
|
|
2
|
+
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class CodeMieError(Exception):
|
|
7
|
+
"""Base exception for all CodeMie SDK errors."""
|
|
8
|
+
|
|
9
|
+
pass
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ApiError(CodeMieError):
|
|
13
|
+
"""Exception raised for API errors."""
|
|
14
|
+
|
|
15
|
+
def __init__(
|
|
16
|
+
self,
|
|
17
|
+
message: str,
|
|
18
|
+
status_code: Optional[int] = None,
|
|
19
|
+
response: Optional[dict] = None,
|
|
20
|
+
):
|
|
21
|
+
"""Initialize API error.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
message: Error message
|
|
25
|
+
status_code: HTTP status code if applicable
|
|
26
|
+
response: Raw API response if available
|
|
27
|
+
"""
|
|
28
|
+
self.status_code = status_code
|
|
29
|
+
self.response = response
|
|
30
|
+
super().__init__(message)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class NotFoundError(ApiError):
|
|
34
|
+
"""Exception raised when a resource is not found."""
|
|
35
|
+
|
|
36
|
+
def __init__(self, resource_type: str, resource_id: str):
|
|
37
|
+
"""Initialize not found error.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
resource_type: Type of resource that was not found (e.g., "Integration")
|
|
41
|
+
resource_id: ID or identifier of the resource
|
|
42
|
+
"""
|
|
43
|
+
super().__init__(
|
|
44
|
+
message=f"{resource_type} with {resource_id} not found", status_code=404
|
|
45
|
+
)
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"""Models for assistant-related data structures."""
|
|
2
|
+
|
|
3
|
+
import uuid
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from enum import Enum
|
|
6
|
+
from typing import List, Optional, Any, Union
|
|
7
|
+
|
|
8
|
+
from pydantic import BaseModel, Field, ConfigDict
|
|
9
|
+
|
|
10
|
+
from .common import User
|
|
11
|
+
from .integration import Integration
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ToolDetails(BaseModel):
|
|
15
|
+
"""Model for tool details."""
|
|
16
|
+
|
|
17
|
+
model_config = ConfigDict(extra="ignore")
|
|
18
|
+
|
|
19
|
+
name: str
|
|
20
|
+
label: Optional[str] = None
|
|
21
|
+
settings_config: bool = False
|
|
22
|
+
user_description: Optional[str] = None
|
|
23
|
+
settings: Optional[Integration] = None
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class ToolKitDetails(BaseModel):
|
|
27
|
+
"""Model for toolkit details."""
|
|
28
|
+
|
|
29
|
+
model_config = ConfigDict(extra="ignore")
|
|
30
|
+
|
|
31
|
+
toolkit: str
|
|
32
|
+
tools: List[ToolDetails]
|
|
33
|
+
label: str = ""
|
|
34
|
+
settings_config: bool = False
|
|
35
|
+
is_external: bool = False
|
|
36
|
+
settings: Optional[Integration] = None
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class ContextType(str, Enum):
|
|
40
|
+
"""Enum for context types."""
|
|
41
|
+
|
|
42
|
+
KNOWLEDGE_BASE = "knowledge_base"
|
|
43
|
+
CODE = "code"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class Context(BaseModel):
|
|
47
|
+
"""Model for context configuration."""
|
|
48
|
+
|
|
49
|
+
model_config = ConfigDict(extra="ignore")
|
|
50
|
+
|
|
51
|
+
context_type: ContextType
|
|
52
|
+
name: str
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class SystemPromptHistory(BaseModel):
|
|
56
|
+
"""Model for system prompt history."""
|
|
57
|
+
|
|
58
|
+
model_config = ConfigDict(extra="ignore")
|
|
59
|
+
|
|
60
|
+
system_prompt: str
|
|
61
|
+
date: datetime
|
|
62
|
+
created_by: Optional[User] = None
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class AssistantBase(BaseModel):
|
|
66
|
+
"""Base model for assistant with common fields."""
|
|
67
|
+
|
|
68
|
+
model_config = ConfigDict(extra="ignore")
|
|
69
|
+
|
|
70
|
+
id: Optional[str] = None
|
|
71
|
+
created_by: Optional[User] = None
|
|
72
|
+
name: str
|
|
73
|
+
description: str
|
|
74
|
+
icon_url: Optional[str] = None
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class Assistant(AssistantBase):
|
|
78
|
+
"""Full assistant model with additional fields."""
|
|
79
|
+
|
|
80
|
+
model_config = ConfigDict(extra="ignore", use_enum_values=True)
|
|
81
|
+
|
|
82
|
+
system_prompt: str
|
|
83
|
+
system_prompt_history: List[SystemPromptHistory] = Field(default_factory=list)
|
|
84
|
+
project: str
|
|
85
|
+
llm_model_type: Optional[str] = None
|
|
86
|
+
toolkits: List[ToolKitDetails] = Field(default_factory=list)
|
|
87
|
+
user_prompts: List[str] = Field(default_factory=list)
|
|
88
|
+
shared: bool = False
|
|
89
|
+
is_react: bool = False
|
|
90
|
+
is_global: bool = False
|
|
91
|
+
created_date: Optional[datetime] = None
|
|
92
|
+
updated_date: Optional[datetime] = None
|
|
93
|
+
creator: str = "system"
|
|
94
|
+
slug: Optional[str] = None
|
|
95
|
+
temperature: Optional[float] = None
|
|
96
|
+
top_p: Optional[float] = None
|
|
97
|
+
context: List[Context] = Field(default_factory=list)
|
|
98
|
+
user_abilities: Optional[List[Any]] = None
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
class AssistantRequestBase(AssistantBase):
|
|
102
|
+
"""Base model for assistant requests with common request fields."""
|
|
103
|
+
|
|
104
|
+
model_config = ConfigDict(extra="ignore", use_enum_values=True)
|
|
105
|
+
|
|
106
|
+
system_prompt: str
|
|
107
|
+
project: str
|
|
108
|
+
context: List[Context] = Field(default_factory=list)
|
|
109
|
+
llm_model_type: str
|
|
110
|
+
toolkits: List[ToolKitDetails]
|
|
111
|
+
user_prompts: List[str] = Field(default_factory=list)
|
|
112
|
+
shared: bool = False
|
|
113
|
+
is_react: bool = False
|
|
114
|
+
is_global: Optional[bool] = False
|
|
115
|
+
slug: Optional[str] = None
|
|
116
|
+
temperature: Optional[float] = None
|
|
117
|
+
top_p: Optional[float] = None
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class AssistantCreateRequest(AssistantRequestBase):
|
|
121
|
+
"""Model for creating a new assistant."""
|
|
122
|
+
|
|
123
|
+
pass
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class AssistantUpdateRequest(AssistantRequestBase):
|
|
127
|
+
"""Model for updating an existing assistant."""
|
|
128
|
+
|
|
129
|
+
pass
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
class ChatRole(str, Enum):
|
|
133
|
+
"""Enum for chat message roles."""
|
|
134
|
+
|
|
135
|
+
ASSISTANT = "Assistant"
|
|
136
|
+
USER = "User"
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
class ChatMessage(BaseModel):
|
|
140
|
+
"""Model for chat message."""
|
|
141
|
+
|
|
142
|
+
role: ChatRole
|
|
143
|
+
message: Optional[str] = Field(default="")
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
class AssistantChatRequest(BaseModel):
|
|
147
|
+
"""Model for chat request to assistant."""
|
|
148
|
+
|
|
149
|
+
conversation_id: Optional[str] = Field(
|
|
150
|
+
default=str(uuid.uuid4()), description="Conversation identifier"
|
|
151
|
+
)
|
|
152
|
+
text: Optional[str] = Field(default=None, description="User's input error_message")
|
|
153
|
+
content_raw: Optional[str] = Field(default="", description="Raw content input")
|
|
154
|
+
file_name: Optional[str] = Field(default=None, description="Associated file name")
|
|
155
|
+
llm_model: Optional[str] = Field(
|
|
156
|
+
default=None, description="Specific LLM model to use"
|
|
157
|
+
)
|
|
158
|
+
history: Union[List[ChatMessage], str] = Field(
|
|
159
|
+
default_factory=list,
|
|
160
|
+
description="Conversation history as list of messages or string",
|
|
161
|
+
)
|
|
162
|
+
history_index: int = Field(
|
|
163
|
+
default=0, description="DataSource in conversation history"
|
|
164
|
+
)
|
|
165
|
+
stream: bool = Field(default=False, description="Enable streaming response")
|
|
166
|
+
top_k: int = Field(default=10, description="Top K results to consider")
|
|
167
|
+
system_prompt: str = Field(default="", description="Override system prompt")
|
|
168
|
+
background_task: bool = Field(default=False, description="Run as background task")
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
class BaseModelResponse(BaseModel):
|
|
172
|
+
"""Model for chat response from assistant."""
|
|
173
|
+
|
|
174
|
+
generated: str = Field(description="Generated response error_message")
|
|
175
|
+
time_elapsed: Optional[float] = Field(
|
|
176
|
+
default=None, alias="timeElapsed", description="Time taken for generation"
|
|
177
|
+
)
|
|
178
|
+
tokens_used: Optional[int] = Field(
|
|
179
|
+
default=None, alias="tokensUsed", description="Number of tokens used"
|
|
180
|
+
)
|
|
181
|
+
thoughts: Optional[List[dict]] = Field(
|
|
182
|
+
default=None, description="Thought process details"
|
|
183
|
+
)
|
|
184
|
+
task_id: Optional[str] = Field(
|
|
185
|
+
default=None, alias="taskId", description="Background task identifier"
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
class Config:
|
|
189
|
+
# Allow population by field name as well as alias
|
|
190
|
+
populate_by_name = True
|
|
191
|
+
# Preserve alias on export
|
|
192
|
+
alias_generator = None
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from typing import Optional, Dict, Any
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, ConfigDict, Field, model_validator
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TokensUsage(BaseModel):
|
|
7
|
+
input_tokens: Optional[int] = None
|
|
8
|
+
output_tokens: Optional[int] = None
|
|
9
|
+
money_spent: Optional[float] = None
|
|
10
|
+
|
|
11
|
+
model_config = ConfigDict(extra="ignore")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class User(BaseModel):
|
|
15
|
+
"""Model representing the User."""
|
|
16
|
+
|
|
17
|
+
model_config = ConfigDict(extra="ignore")
|
|
18
|
+
|
|
19
|
+
user_id: str = Field(None)
|
|
20
|
+
username: str = ""
|
|
21
|
+
name: str = ""
|
|
22
|
+
|
|
23
|
+
@model_validator(mode="before")
|
|
24
|
+
def before_init(cls, values):
|
|
25
|
+
# Check if 'id' is present, then set 'id' field for correct deserialization
|
|
26
|
+
if "id" in values:
|
|
27
|
+
values["user_id"] = values.pop("id")
|
|
28
|
+
return values
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class PaginationParams(BaseModel):
|
|
32
|
+
"""Pagination parameters with validation."""
|
|
33
|
+
|
|
34
|
+
page: int = Field(..., ge=0, description="Page number (0-based)")
|
|
35
|
+
per_page: int = Field(..., gt=0, description="Number of items per page")
|
|
36
|
+
|
|
37
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
38
|
+
"""Convert pagination parameters to dictionary."""
|
|
39
|
+
return self.model_dump(exclude_none=True)
|