projectdavid-common 0.1.16__tar.gz

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.
Files changed (34) hide show
  1. projectdavid_common-0.1.16/MANIFEST.in +1 -0
  2. projectdavid_common-0.1.16/PKG-INFO +33 -0
  3. projectdavid_common-0.1.16/README.md +17 -0
  4. projectdavid_common-0.1.16/pyproject.toml +55 -0
  5. projectdavid_common-0.1.16/setup.cfg +4 -0
  6. projectdavid_common-0.1.16/src/projectdavid_common/__init__.py +7 -0
  7. projectdavid_common-0.1.16/src/projectdavid_common/constants/__init__.py +0 -0
  8. projectdavid_common-0.1.16/src/projectdavid_common/constants/platform.py +68 -0
  9. projectdavid_common-0.1.16/src/projectdavid_common/schemas/__init__.py +0 -0
  10. projectdavid_common-0.1.16/src/projectdavid_common/schemas/actions.py +103 -0
  11. projectdavid_common-0.1.16/src/projectdavid_common/schemas/assistants.py +102 -0
  12. projectdavid_common-0.1.16/src/projectdavid_common/schemas/enums.py +25 -0
  13. projectdavid_common-0.1.16/src/projectdavid_common/schemas/file_service.py +21 -0
  14. projectdavid_common-0.1.16/src/projectdavid_common/schemas/files.py +34 -0
  15. projectdavid_common-0.1.16/src/projectdavid_common/schemas/inference.py +25 -0
  16. projectdavid_common-0.1.16/src/projectdavid_common/schemas/keys.py +23 -0
  17. projectdavid_common-0.1.16/src/projectdavid_common/schemas/messages.py +95 -0
  18. projectdavid_common-0.1.16/src/projectdavid_common/schemas/runs.py +125 -0
  19. projectdavid_common-0.1.16/src/projectdavid_common/schemas/threads.py +48 -0
  20. projectdavid_common-0.1.16/src/projectdavid_common/schemas/tools.py +65 -0
  21. projectdavid_common-0.1.16/src/projectdavid_common/schemas/users.py +27 -0
  22. projectdavid_common-0.1.16/src/projectdavid_common/schemas/vectors.py +180 -0
  23. projectdavid_common-0.1.16/src/projectdavid_common/utilities/__init__.py +0 -0
  24. projectdavid_common-0.1.16/src/projectdavid_common/utilities/identifier_service.py +81 -0
  25. projectdavid_common-0.1.16/src/projectdavid_common/utilities/logging_service.py +69 -0
  26. projectdavid_common-0.1.16/src/projectdavid_common/utils.py +18 -0
  27. projectdavid_common-0.1.16/src/projectdavid_common/validation.py +180 -0
  28. projectdavid_common-0.1.16/src/projectdavid_common.egg-info/PKG-INFO +33 -0
  29. projectdavid_common-0.1.16/src/projectdavid_common.egg-info/SOURCES.txt +32 -0
  30. projectdavid_common-0.1.16/src/projectdavid_common.egg-info/dependency_links.txt +1 -0
  31. projectdavid_common-0.1.16/src/projectdavid_common.egg-info/entry_points.txt +2 -0
  32. projectdavid_common-0.1.16/src/projectdavid_common.egg-info/requires.txt +6 -0
  33. projectdavid_common-0.1.16/src/projectdavid_common.egg-info/top_level.txt +1 -0
  34. projectdavid_common-0.1.16/tests/test_vector_store_models.py +14 -0
@@ -0,0 +1 @@
1
+ include README.md
@@ -0,0 +1,33 @@
1
+ Metadata-Version: 2.4
2
+ Name: projectdavid_common
3
+ Version: 0.1.16
4
+ Summary: Common shared custom packages
5
+ Author-email: "Francis N." <francis.neequaye@projectdavid.co.uk>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/frankie336/projectdavid_common
8
+ Keywords: shared,internal,utilities,schemas
9
+ Requires-Python: >=3.10
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: pydantic
12
+ Requires-Dist: typing_extensions
13
+ Requires-Dist: fastapi>=0.70.0
14
+ Provides-Extra: dev
15
+ Requires-Dist: pytest; extra == "dev"
16
+
17
+ # Entities Common
18
+ [![Test, Tag, Publish Status](https://github.com/frankie336/entities_common/actions/workflows/test_tag_release.yml/badge.svg)](https://github.com/frankie336/entitites_sdk/actions/workflows/test_tag_release.yml)
19
+
20
+ The **Projectdavid Common** SDK is a shared library that serves as a central resource for multiple components within the same
21
+ project. It consolidates common functionality across disparate parts of the project, reducing duplication and improving
22
+ maintainability. By providing a unified interface, Entities Common simplifies interactions with the
23
+ and future related products.
24
+
25
+ [Entities API](https://github.com/frankie336/entities_api), the [projectdavid SDK](https://github.com/frankie336/entitites_sdk) ,
26
+
27
+
28
+ # Resources
29
+
30
+ | Resource | Descrption |
31
+ |---------------------------------------------------------|------------------------------------|
32
+ | [ValidationInterface](/docs/validation_interface.md) | Unified pydentc validation classes |
33
+ | [UtilsInterface](/docs/utils_interface.md) | Utilites and tools |
@@ -0,0 +1,17 @@
1
+ # Entities Common
2
+ [![Test, Tag, Publish Status](https://github.com/frankie336/entities_common/actions/workflows/test_tag_release.yml/badge.svg)](https://github.com/frankie336/entitites_sdk/actions/workflows/test_tag_release.yml)
3
+
4
+ The **Projectdavid Common** SDK is a shared library that serves as a central resource for multiple components within the same
5
+ project. It consolidates common functionality across disparate parts of the project, reducing duplication and improving
6
+ maintainability. By providing a unified interface, Entities Common simplifies interactions with the
7
+ and future related products.
8
+
9
+ [Entities API](https://github.com/frankie336/entities_api), the [projectdavid SDK](https://github.com/frankie336/entitites_sdk) ,
10
+
11
+
12
+ # Resources
13
+
14
+ | Resource | Descrption |
15
+ |---------------------------------------------------------|------------------------------------|
16
+ | [ValidationInterface](/docs/validation_interface.md) | Unified pydentc validation classes |
17
+ | [UtilsInterface](/docs/utils_interface.md) | Utilites and tools |
@@ -0,0 +1,55 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "projectdavid_common"
7
+ version = "0.1.16"
8
+ description = "Common shared custom packages"
9
+ readme = "README.md"
10
+ authors = [
11
+ { name = "Francis N.", email = "francis.neequaye@projectdavid.co.uk" }
12
+ ]
13
+ license = { text = "MIT" }
14
+ keywords = ["shared", "internal", "utilities", "schemas"]
15
+ requires-python = ">=3.10"
16
+
17
+ dependencies = [
18
+ "pydantic",
19
+ "typing_extensions",
20
+ "fastapi>=0.70.0" # Added FastAPI as a dependency
21
+ ]
22
+
23
+ [project.optional-dependencies]
24
+ dev = [
25
+ "pytest"
26
+ ]
27
+
28
+ [project.urls]
29
+ Homepage = "https://github.com/frankie336/projectdavid_common"
30
+
31
+ [project.scripts]
32
+ projectdavid_common-api = "projectdavid_common.main:main"
33
+
34
+ [tool.setuptools]
35
+ package-dir = { "" = "src" }
36
+
37
+ [tool.setuptools.packages.find]
38
+ where = ["src"]
39
+ include = ["projectdavid_common", "projectdavid_common.*"]
40
+
41
+ [tool.setuptools.dynamic]
42
+ version = { attr = "projectdavid_common.__version__.__version__" }
43
+
44
+ [tool.black]
45
+ line-length = 100
46
+ target-version = ["py310"]
47
+ skip-string-normalization = true
48
+
49
+ [tool.flake8]
50
+ max-line-length = 200
51
+ extend-ignore = ["E203"]
52
+ exclude = [".venv", ".git", "__pycache__", "build", "dist"]
53
+
54
+ [tool.isort]
55
+ profile = "black"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,7 @@
1
+ from .utils import UtilsInterface
2
+ from .validation import ValidationInterface
3
+
4
+ __all__ = [
5
+ "ValidationInterface",
6
+ "UtilsInterface",
7
+ ]
@@ -0,0 +1,68 @@
1
+ from dotenv import load_dotenv
2
+
3
+ load_dotenv()
4
+
5
+ PLATFORM_TOOLS = [
6
+ "code_interpreter",
7
+ "web_search",
8
+ "vector_store_search",
9
+ "computer",
10
+ ]
11
+
12
+ TOOLS_ID_MAP = {
13
+ "code_interpreter": "tool_79YkQEz5cDwpJjnR7oJ80D",
14
+ "web_search": "tool_BiIwycpLo1n5Dh6BHN01v8",
15
+ "vector_store_search": "tool_MCaJpXJU3eW6vaMUybEf6i",
16
+ "computer": "tool_PJQ6VcnkmRCMankObjtRcn",
17
+ }
18
+
19
+ SPECIAL_CASE_TOOL_HANDLING = ["computer", "code_interpreter"]
20
+
21
+ ERROR_NO_CONTENT = (
22
+ "ERROR: The Tool has failed to return any content. The current stage of "
23
+ "the workflow is tool submission. Please inform the user."
24
+ )
25
+
26
+ DIRECT_DATABASE_URL = "mysql+pymysql://ollama:3e4Qv5uo2Cg31zC1@localhost:3307/cosmic_catalyst"
27
+
28
+ # ------------------------------------------------
29
+ # Vendors sometimes have clashing model names.
30
+ # This can interfere with routing logic
31
+ # ------------------------------------------------
32
+ MODEL_MAP = {
33
+ "deepseek-ai/deepseek-reasoner": "deepseek-reasoner",
34
+ "deepseek-ai/deepseek-chat": "deepseek-chat",
35
+ "together-ai/deepseek-ai/DeepSeek-R1": "deepseek-ai/DeepSeek-R1",
36
+ "together-ai/deepseek-ai/DeepSeek-V3": "deepseek-ai/DeepSeek-V3",
37
+ "hyperbolic/deepseek-ai/DeepSeek-R1": "deepseek-ai/DeepSeek-R1",
38
+ "hyperbolic/deepseek-ai/DeepSeek-V3": "deepseek-ai/DeepSeek-V3",
39
+ }
40
+
41
+ WEB_SEARCH_BASE_URL = "http://localhost:8080/"
42
+
43
+ SUPPORTED_MIME_TYPES = {
44
+ ".c": "text/x-c",
45
+ ".cpp": "text/x-c++",
46
+ ".cs": "text/x-csharp",
47
+ ".css": "text/css",
48
+ ".doc": "application/msword",
49
+ ".docx": ("application/vnd.openxmlformats-officedocument.wordprocessingml." "document"),
50
+ ".go": "text/x-golang",
51
+ ".html": "text/html",
52
+ ".java": "text/x-java",
53
+ ".js": "text/javascript",
54
+ ".json": "application/json",
55
+ ".md": "text/markdown",
56
+ ".pdf": "application/pdf",
57
+ ".php": "text/x-php",
58
+ ".pptx": ("application/vnd.openxmlformats-officedocument.presentationml." "presentation"),
59
+ ".py": "text/x-python",
60
+ ".pyx": "text/x-script.python",
61
+ ".rb": "text/x-ruby",
62
+ ".sh": "application/x-sh",
63
+ ".tex": "text/x-tex",
64
+ ".ts": "application/typescript",
65
+ ".txt": "text/plain",
66
+ }
67
+
68
+ ALLOWED_TEXT_ENCODINGS = ["utf-8", "utf-16", "ascii"]
@@ -0,0 +1,103 @@
1
+ # src/projectdavid_common/schemas/actions.py
2
+ from datetime import datetime
3
+ from enum import Enum
4
+ from typing import Any, Dict, List, Optional
5
+
6
+ from pydantic import BaseModel, ConfigDict, Field, field_validator
7
+
8
+
9
+ class ActionBase(BaseModel):
10
+ id: str
11
+ run_id: str
12
+ triggered_at: datetime
13
+ expires_at: Optional[datetime] = None
14
+ is_processed: bool
15
+ processed_at: Optional[datetime] = None
16
+ status: str = "pending"
17
+ function_args: Optional[Dict[str, Any]] = None
18
+ result: Optional[Dict[str, Any]] = None
19
+
20
+ model_config = ConfigDict(from_attributes=True)
21
+
22
+
23
+ class ActionStatus(str, Enum):
24
+ pending = "pending"
25
+ processing = "processing"
26
+ completed = "completed"
27
+ failed = "failed"
28
+ expired = "expired"
29
+ cancelled = "cancelled"
30
+ retrying = "retrying"
31
+
32
+
33
+ class ActionCreate(BaseModel):
34
+ id: Optional[str] = None
35
+ tool_name: Optional[str] = None
36
+ run_id: str
37
+ function_args: Optional[Dict[str, Any]] = {}
38
+ expires_at: Optional[datetime] = None
39
+ status: Optional[str] = "pending"
40
+
41
+ @field_validator("tool_name", mode="before")
42
+ @classmethod
43
+ def validate_tool_fields(cls, v: Optional[str]) -> Optional[str]:
44
+ if not v:
45
+ raise ValueError("Tool name must be provided.")
46
+ return v
47
+
48
+ model_config = ConfigDict(
49
+ json_schema_extra={
50
+ "example": {
51
+ "tool_name": "example_tool_name",
52
+ "run_id": "example_run_id",
53
+ "function_args": {"arg1": "value1", "arg2": "value2"},
54
+ "expires_at": "2024-09-10T12:00:00Z",
55
+ "status": "pending",
56
+ }
57
+ }
58
+ )
59
+
60
+
61
+ class ActionRead(BaseModel):
62
+ id: str = Field(...)
63
+ run_id: Optional[str] = None
64
+ tool_id: Optional[str] = None
65
+ tool_name: Optional[str] = None
66
+ triggered_at: Optional[str] = None
67
+ expires_at: Optional[str] = None
68
+ is_processed: Optional[bool] = None
69
+ processed_at: Optional[str] = None
70
+ status: Optional[str] = None
71
+ function_args: Optional[dict] = None
72
+ result: Optional[dict] = None
73
+
74
+ model_config = ConfigDict(
75
+ extra="forbid",
76
+ validate_assignment=True,
77
+ json_schema_extra={
78
+ "example": {
79
+ "id": "action_123456",
80
+ "run_id": "run_123456",
81
+ "tool_id": "tool_123456",
82
+ "tool_name": "code_interpreter",
83
+ "triggered_at": "2025-03-24T12:00:00Z",
84
+ "expires_at": "2025-03-24T12:05:00Z",
85
+ "is_processed": False,
86
+ "processed_at": "2025-03-24T12:01:00Z",
87
+ "status": "in_progress",
88
+ "function_args": {"param1": "value1"},
89
+ "result": {"output": "result data"},
90
+ }
91
+ },
92
+ )
93
+
94
+
95
+ class ActionList(BaseModel):
96
+ actions: List[ActionRead]
97
+
98
+
99
+ class ActionUpdate(BaseModel):
100
+ status: ActionStatus
101
+ result: Optional[Dict[str, Any]] = None
102
+
103
+ model_config = ConfigDict(from_attributes=True)
@@ -0,0 +1,102 @@
1
+ from typing import Any, Dict, List, Optional
2
+
3
+ from pydantic import BaseModel, ConfigDict, Field
4
+
5
+ from projectdavid_common.schemas.vectors import VectorStoreRead
6
+
7
+
8
+ class AssistantCreate(BaseModel):
9
+ id: Optional[str] = Field(
10
+ None,
11
+ description="Unique identifier for the assistant. Optional on creation.",
12
+ )
13
+ name: str = Field(..., description="Name of the assistant")
14
+ description: str = Field("", description="A brief description of the assistant")
15
+ model: str = Field(..., description="Model used by the assistant")
16
+ instructions: str = Field(
17
+ "", description="Special instructions or guidelines for the assistant"
18
+ )
19
+ tools: Optional[List[dict]] = Field(
20
+ None,
21
+ description="A list of tools available to the assistant, each defined as a dictionary",
22
+ )
23
+ meta_data: Optional[dict] = Field(None, description="Additional metadata for the assistant")
24
+ top_p: float = Field(1.0, description="Top-p sampling parameter for text generation")
25
+ temperature: float = Field(1.0, description="Temperature parameter for text generation")
26
+ response_format: str = Field("auto", description="Format of the assistant's response")
27
+
28
+ model_config = ConfigDict(
29
+ json_schema_extra={
30
+ "example": {
31
+ "name": "ChatGPT Assistant",
32
+ "description": "An assistant for handling tasks",
33
+ "model": "gpt-4",
34
+ "instructions": "Be friendly and concise",
35
+ "tools": [{"name": "code_interpreter"}],
36
+ "meta_data": {"project": "alpha"},
37
+ "top_p": 0.9,
38
+ "temperature": 0.8,
39
+ "response_format": "auto",
40
+ }
41
+ }
42
+ )
43
+
44
+
45
+ class AssistantRead(BaseModel):
46
+ id: str = Field(..., description="Unique identifier for the assistant")
47
+ user_id: Optional[str] = Field(
48
+ None, description="Identifier for the user associated with " "the assistant"
49
+ )
50
+ object: str = Field(..., description="Object type")
51
+ created_at: int = Field(..., description="Timestamp when the assistant was created")
52
+ name: str = Field(..., description="Name of the assistant")
53
+ description: Optional[str] = Field(None, description="Description of the assistant")
54
+ model: str = Field(..., description="Model used by the assistant")
55
+ instructions: Optional[str] = Field(None, description="Instructions provided to the assistant")
56
+ tools: Optional[List[dict]] = Field(
57
+ None, description="List of tool definitions associated " "with " "the assistant"
58
+ )
59
+ meta_data: Optional[Dict[str, Any]] = Field(
60
+ None, description="Additional metadata for " "the assistant"
61
+ )
62
+ top_p: float = Field(..., description="Top-p sampling parameter")
63
+ temperature: float = Field(..., description="Temperature parameter")
64
+ response_format: str = Field(..., description="Response format")
65
+ vector_stores: Optional[List[VectorStoreRead]] = Field(
66
+ default_factory=list, description="List of associated vector stores"
67
+ )
68
+
69
+ model_config = ConfigDict(
70
+ json_schema_extra={
71
+ "example": {
72
+ "id": "asst_abc123",
73
+ "user_id": "user_xyz",
74
+ "object": "assistant",
75
+ "created_at": 1710000000,
76
+ "name": "Doc Searcher",
77
+ "description": "Assistant for searching documents",
78
+ "model": "gpt-4",
79
+ "instructions": "Answer based on vector store contents",
80
+ "tools": [{"name": "vector_store_search"}],
81
+ "meta_data": {"department": "research"},
82
+ "top_p": 1.0,
83
+ "temperature": 0.7,
84
+ "response_format": "auto",
85
+ "vector_stores": [],
86
+ }
87
+ }
88
+ )
89
+
90
+
91
+ class AssistantUpdate(BaseModel):
92
+ name: Optional[str] = Field(None, description="Updated name for the assistant")
93
+ description: Optional[str] = Field(None, description="Updated description for the assistant")
94
+ model: Optional[str] = Field(None, description="Updated model name")
95
+ instructions: Optional[str] = Field(None, description="Updated instructions for the assistant")
96
+ tools: Optional[List[Any]] = Field(None, description="Updated list of tools for the assistant")
97
+ meta_data: Optional[Dict[str, Any]] = Field(
98
+ None, description="Updated metadata for the " "assistant"
99
+ )
100
+ top_p: Optional[float] = Field(None, description="Updated top-p parameter")
101
+ temperature: Optional[float] = Field(None, description="Updated temperature parameter")
102
+ response_format: Optional[str] = Field(None, description="Updated response format")
@@ -0,0 +1,25 @@
1
+ from enum import Enum
2
+
3
+
4
+ class ProviderEnum(str, Enum):
5
+ openai = "openai"
6
+ deepseek = "deepseek"
7
+ hyperbolic = "Hyperbolic"
8
+ togetherai = "togetherai"
9
+ local = "local"
10
+
11
+
12
+ class StatusEnum(str, Enum):
13
+ deleted = "deleted"
14
+ active = "active"
15
+ queued = "queued"
16
+ in_progress = "in_progress"
17
+ pending_action = "action_required"
18
+ completed = "completed"
19
+ failed = "failed"
20
+ cancelling = "cancelling"
21
+ cancelled = "cancelled"
22
+ pending = "pending"
23
+ processing = "processing"
24
+ expired = "expired"
25
+ retrying = "retrying"
@@ -0,0 +1,21 @@
1
+ from typing import Optional
2
+
3
+ from pydantic import BaseModel, ConfigDict, Field
4
+
5
+
6
+ class FileUploadRequest(BaseModel):
7
+ purpose: str = Field(..., description="Purpose for uploading the file")
8
+ user_id: str = Field(..., description="ID of the uploading user")
9
+
10
+
11
+ class FileResponse(BaseModel):
12
+ id: str
13
+ object: str = "file"
14
+ bytes: int
15
+ created_at: int
16
+ filename: str
17
+ purpose: str
18
+ status: str = "uploaded"
19
+ expires_at: Optional[int] = None
20
+
21
+ model_config = ConfigDict(from_attributes=True)
@@ -0,0 +1,34 @@
1
+ from datetime import datetime
2
+ from typing import Optional
3
+
4
+ from fastapi import Form
5
+ from pydantic import BaseModel, ConfigDict, field_validator
6
+
7
+
8
+ class FileUploadRequest(BaseModel):
9
+ """Schema for file upload request data."""
10
+
11
+ purpose: str = Form(...)
12
+ user_id: str = Form(...)
13
+
14
+
15
+ class FileResponse(BaseModel):
16
+ """Schema for file response data."""
17
+
18
+ id: str
19
+ object: str = "file"
20
+ bytes: int
21
+ created_at: int
22
+ filename: str
23
+ purpose: str
24
+ status: str = "uploaded"
25
+ expires_at: Optional[int] = None
26
+
27
+ @field_validator("created_at", mode="before")
28
+ @classmethod
29
+ def datetime_to_timestamp(cls, value):
30
+ if isinstance(value, datetime):
31
+ return int(value.timestamp())
32
+ return value
33
+
34
+ model_config = ConfigDict(from_attributes=True)
@@ -0,0 +1,25 @@
1
+ from typing import Optional
2
+
3
+ from pydantic import BaseModel, ConfigDict, Field
4
+
5
+ from projectdavid_common.schemas.enums import ProviderEnum
6
+
7
+
8
+ class ProcessOutput(BaseModel):
9
+ store_name: str
10
+ status: str
11
+ chunks_processed: int
12
+
13
+ model_config = ConfigDict(from_attributes=True)
14
+
15
+
16
+ class StreamRequest(BaseModel):
17
+ provider: ProviderEnum = Field(..., description="The inference provider")
18
+ model: str = Field(..., description="The model to use for inference")
19
+ api_key: Optional[str] = Field(None, description="Optional API key for third-party providers")
20
+ thread_id: str = Field(..., description="Thread identifier")
21
+ message_id: str = Field(..., description="Message identifier")
22
+ run_id: str = Field(..., description="Run identifier")
23
+ assistant_id: str = Field(..., description="Assistant identifier")
24
+
25
+ model_config = ConfigDict(from_attributes=True)
@@ -0,0 +1,23 @@
1
+ from datetime import datetime
2
+ from typing import Optional
3
+
4
+ from pydantic import BaseModel, ConfigDict, Field
5
+
6
+
7
+ class APIKeyRead(BaseModel):
8
+ id: str = Field(..., description="The unique identifier for this API key")
9
+ user_id: str = Field(..., description="User who owns the key")
10
+ name: str = Field(..., description="Human-readable name of the key")
11
+ created_at: int = Field(..., description="Unix timestamp of key creation")
12
+ revoked: bool = Field(..., description="Whether the key has been revoked")
13
+ revoked_at: Optional[int] = Field(None, description="Unix timestamp of revocation (if revoked)")
14
+
15
+ model_config = ConfigDict(from_attributes=True)
16
+
17
+
18
+ class APIKeyCreate(BaseModel):
19
+ user_id: str = Field(..., description="ID of the user creating the key")
20
+ name: Optional[str] = Field(None, description="Optional human-readable name for the key")
21
+ expires_at: Optional[datetime] = Field(
22
+ None, description="Optional expiration date for the API key"
23
+ )
@@ -0,0 +1,95 @@
1
+ #! python
2
+ from enum import Enum
3
+ from typing import Any, Dict, List, Optional
4
+
5
+ from pydantic import BaseModel, ConfigDict, field_validator
6
+
7
+
8
+ class MessageRole(str, Enum):
9
+ PLATFORM = "platform"
10
+ ASSISTANT = "assistant"
11
+ USER = "user"
12
+ SYSTEM = "system"
13
+ TOOL = "tool"
14
+
15
+
16
+ class MessageCreate(BaseModel):
17
+ content: str
18
+ thread_id: str
19
+ sender_id: Optional[str] = None
20
+ assistant_id: str
21
+ role: str # Using string instead of Enum to allow flexible validation
22
+ tool_id: Optional[str] = None
23
+ meta_data: Optional[Dict[str, Any]] = None
24
+ is_last_chunk: bool = False
25
+
26
+ @field_validator("role", mode="before")
27
+ @classmethod
28
+ def validate_role(cls, v):
29
+ valid_roles = {"platform", "assistant", "user", "system", "tool"}
30
+ if isinstance(v, str):
31
+ v = v.lower()
32
+ if v in valid_roles:
33
+ return v
34
+ raise ValueError(f"Invalid role: {v}. Must be one of {list(valid_roles)}")
35
+
36
+ model_config = ConfigDict(
37
+ json_schema_extra={
38
+ "example": {
39
+ "content": "Hello, this is a test message.",
40
+ "thread_id": "example_thread_id",
41
+ "assistant_id": "example_assistant_id",
42
+ "meta_data": {"key": "value"},
43
+ "role": "user",
44
+ }
45
+ }
46
+ )
47
+
48
+
49
+ class ToolMessageCreate(BaseModel):
50
+ content: str
51
+
52
+ model_config = ConfigDict(
53
+ json_schema_extra={"example": {"content": "This is the content of the tool message."}}
54
+ )
55
+
56
+
57
+ class MessageRead(BaseModel):
58
+ id: str
59
+ assistant_id: Optional[str]
60
+ attachments: List[Any]
61
+ completed_at: Optional[int]
62
+ content: str
63
+ created_at: int
64
+ incomplete_at: Optional[int]
65
+ incomplete_details: Optional[Dict[str, Any]]
66
+ meta_data: Dict[str, Any]
67
+ object: str
68
+ role: str
69
+ run_id: Optional[str]
70
+ tool_id: Optional[str] = None
71
+ status: Optional[str]
72
+ thread_id: str
73
+ sender_id: Optional[str] = None
74
+
75
+ model_config = ConfigDict(from_attributes=True)
76
+
77
+
78
+ class MessageUpdate(BaseModel):
79
+ content: Optional[str]
80
+ meta_data: Optional[Dict[str, Any]]
81
+ status: Optional[str]
82
+ role: Optional[str]
83
+
84
+ @field_validator("role", mode="before")
85
+ @classmethod
86
+ def validate_role(cls, v):
87
+ if v is None:
88
+ return v
89
+ valid_roles = {"platform", "assistant", "user", "system", "tool"}
90
+ v = v.lower()
91
+ if v in valid_roles:
92
+ return v
93
+ raise ValueError(f"Invalid role: {v}. Must be one of {list(valid_roles)}")
94
+
95
+ model_config = ConfigDict(from_attributes=True)