openai/chatkit-python

Public

mirrored fromhttps://github.com/openai/chatkit-pythonAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
8b263facaeaba1c1035a4d92befabf8f2c75436c

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

chatkit/store.py

162lines · modecode

1import uuid
2from abc import ABC, abstractmethod
3from typing import Any, Generic, Literal
4
5from typing_extensions import TypeVar
6
7from .types import (
8 Attachment,
9 AttachmentCreateParams,
10 Page,
11 ThreadItem,
12 ThreadMetadata,
13)
14
15TContext = TypeVar("TContext", default=Any)
16
17StoreItemType = Literal[
18 "thread",
19 "message",
20 "tool_call",
21 "task",
22 "workflow",
23 "attachment",
24 "sdk_hidden_context",
25]
26
27
28_ID_PREFIXES: dict[StoreItemType, str] = {
29 "thread": "thr",
30 "message": "msg",
31 "tool_call": "tc",
32 "workflow": "wf",
33 "task": "tsk",
34 "attachment": "atc",
35 "sdk_hidden_context": "shcx",
36}
37
38
39def default_generate_id(item_type: StoreItemType) -> str:
40 prefix = _ID_PREFIXES[item_type]
41 return f"{prefix}_{uuid.uuid4().hex[:8]}"
42
43
44class NotFoundError(Exception):
45 pass
46
47
48class AttachmentStore(ABC, Generic[TContext]):
49 @abstractmethod
50 async def delete_attachment(self, attachment_id: str, context: TContext) -> None:
51 """Delete an attachment by id."""
52 pass
53
54 async def create_attachment(
55 self, input: AttachmentCreateParams, context: TContext
56 ) -> Attachment:
57 """Create an attachment record from upload metadata."""
58 raise NotImplementedError(
59 f"{type(self).__name__} must override create_attachment() to support two-phase file upload"
60 )
61
62 def generate_attachment_id(self, mime_type: str, context: TContext) -> str:
63 """Return a new identifier for a file. Override this method to customize file ID generation."""
64
65 return default_generate_id("attachment")
66
67
68class Store(ABC, Generic[TContext]):
69 def generate_thread_id(self, context: TContext) -> str:
70 """Return a new identifier for a thread. Override this method to customize thread ID generation."""
71
72 return default_generate_id("thread")
73
74 def generate_item_id(
75 self, item_type: StoreItemType, thread: ThreadMetadata, context: TContext
76 ) -> str:
77 """Return a new identifier for a thread item. Override this method to customize item ID generation."""
78
79 return default_generate_id(item_type)
80
81 @abstractmethod
82 async def load_thread(self, thread_id: str, context: TContext) -> ThreadMetadata:
83 """Load a thread's metadata by id."""
84 pass
85
86 @abstractmethod
87 async def save_thread(self, thread: ThreadMetadata, context: TContext) -> None:
88 """Persist thread metadata (title, status, etc.)."""
89 pass
90
91 @abstractmethod
92 async def load_thread_items(
93 self,
94 thread_id: str,
95 after: str | None,
96 limit: int,
97 order: str,
98 context: TContext,
99 ) -> Page[ThreadItem]:
100 """Load a page of thread items with pagination controls."""
101 pass
102
103 @abstractmethod
104 async def save_attachment(self, attachment: Attachment, context: TContext) -> None:
105 """Upsert attachment metadata."""
106 pass
107
108 @abstractmethod
109 async def load_attachment(
110 self, attachment_id: str, context: TContext
111 ) -> Attachment:
112 """Load attachment metadata by id."""
113 pass
114
115 @abstractmethod
116 async def delete_attachment(self, attachment_id: str, context: TContext) -> None:
117 """Delete attachment metadata by id."""
118 pass
119
120 @abstractmethod
121 async def load_threads(
122 self,
123 limit: int,
124 after: str | None,
125 order: str,
126 context: TContext,
127 ) -> Page[ThreadMetadata]:
128 """Load a page of threads with pagination controls."""
129 pass
130
131 @abstractmethod
132 async def add_thread_item(
133 self, thread_id: str, item: ThreadItem, context: TContext
134 ) -> None:
135 """Persist a newly created thread item."""
136 pass
137
138 @abstractmethod
139 async def save_item(
140 self, thread_id: str, item: ThreadItem, context: TContext
141 ) -> None:
142 """Upsert a thread item by id."""
143 pass
144
145 @abstractmethod
146 async def load_item(
147 self, thread_id: str, item_id: str, context: TContext
148 ) -> ThreadItem:
149 """Load a thread item by id."""
150 pass
151
152 @abstractmethod
153 async def delete_thread(self, thread_id: str, context: TContext) -> None:
154 """Delete a thread and its items."""
155 pass
156
157 @abstractmethod
158 async def delete_thread_item(
159 self, thread_id: str, item_id: str, context: TContext
160 ) -> None:
161 """Delete a thread item by id."""
162 pass
163