omni-cortex 1.11.3__py3-none-any.whl → 1.12.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.
- {omni_cortex-1.11.3.data → omni_cortex-1.12.1.data}/data/share/omni-cortex/dashboard/backend/chat_service.py +57 -3
- {omni_cortex-1.11.3.data → omni_cortex-1.12.1.data}/data/share/omni-cortex/dashboard/backend/database.py +1430 -1094
- {omni_cortex-1.11.3.data → omni_cortex-1.12.1.data}/data/share/omni-cortex/dashboard/backend/main.py +1592 -1381
- {omni_cortex-1.11.3.data → omni_cortex-1.12.1.data}/data/share/omni-cortex/dashboard/backend/models.py +370 -285
- {omni_cortex-1.11.3.data → omni_cortex-1.12.1.data}/data/share/omni-cortex/hooks/post_tool_use.py +71 -3
- {omni_cortex-1.11.3.data → omni_cortex-1.12.1.data}/data/share/omni-cortex/hooks/pre_tool_use.py +69 -1
- {omni_cortex-1.11.3.data → omni_cortex-1.12.1.data}/data/share/omni-cortex/hooks/stop.py +41 -6
- omni_cortex-1.12.1.data/data/share/omni-cortex/hooks/user_prompt.py +220 -0
- {omni_cortex-1.11.3.dist-info → omni_cortex-1.12.1.dist-info}/METADATA +1 -1
- omni_cortex-1.12.1.dist-info/RECORD +26 -0
- omni_cortex-1.11.3.dist-info/RECORD +0 -25
- {omni_cortex-1.11.3.data → omni_cortex-1.12.1.data}/data/share/omni-cortex/dashboard/backend/.env.example +0 -0
- {omni_cortex-1.11.3.data → omni_cortex-1.12.1.data}/data/share/omni-cortex/dashboard/backend/backfill_summaries.py +0 -0
- {omni_cortex-1.11.3.data → omni_cortex-1.12.1.data}/data/share/omni-cortex/dashboard/backend/image_service.py +0 -0
- {omni_cortex-1.11.3.data → omni_cortex-1.12.1.data}/data/share/omni-cortex/dashboard/backend/logging_config.py +0 -0
- {omni_cortex-1.11.3.data → omni_cortex-1.12.1.data}/data/share/omni-cortex/dashboard/backend/project_config.py +0 -0
- {omni_cortex-1.11.3.data → omni_cortex-1.12.1.data}/data/share/omni-cortex/dashboard/backend/project_scanner.py +0 -0
- {omni_cortex-1.11.3.data → omni_cortex-1.12.1.data}/data/share/omni-cortex/dashboard/backend/prompt_security.py +0 -0
- {omni_cortex-1.11.3.data → omni_cortex-1.12.1.data}/data/share/omni-cortex/dashboard/backend/pyproject.toml +0 -0
- {omni_cortex-1.11.3.data → omni_cortex-1.12.1.data}/data/share/omni-cortex/dashboard/backend/security.py +0 -0
- {omni_cortex-1.11.3.data → omni_cortex-1.12.1.data}/data/share/omni-cortex/dashboard/backend/uv.lock +0 -0
- {omni_cortex-1.11.3.data → omni_cortex-1.12.1.data}/data/share/omni-cortex/dashboard/backend/websocket_manager.py +0 -0
- {omni_cortex-1.11.3.data → omni_cortex-1.12.1.data}/data/share/omni-cortex/hooks/session_utils.py +0 -0
- {omni_cortex-1.11.3.data → omni_cortex-1.12.1.data}/data/share/omni-cortex/hooks/subagent_stop.py +0 -0
- {omni_cortex-1.11.3.dist-info → omni_cortex-1.12.1.dist-info}/WHEEL +0 -0
- {omni_cortex-1.11.3.dist-info → omni_cortex-1.12.1.dist-info}/entry_points.txt +0 -0
- {omni_cortex-1.11.3.dist-info → omni_cortex-1.12.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,285 +1,370 @@
|
|
|
1
|
-
"""Pydantic models for the dashboard API."""
|
|
2
|
-
|
|
3
|
-
from datetime import datetime
|
|
4
|
-
from typing import Optional
|
|
5
|
-
|
|
6
|
-
from pydantic import BaseModel, Field
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class ProjectInfo(BaseModel):
|
|
10
|
-
"""Information about a project with omni-cortex database."""
|
|
11
|
-
|
|
12
|
-
name: str
|
|
13
|
-
path: str
|
|
14
|
-
db_path: str
|
|
15
|
-
last_modified: Optional[datetime] = None
|
|
16
|
-
memory_count: int = 0
|
|
17
|
-
is_global: bool = False
|
|
18
|
-
is_favorite: bool = False
|
|
19
|
-
is_registered: bool = False
|
|
20
|
-
display_name: Optional[str] = None
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class ScanDirectory(BaseModel):
|
|
24
|
-
"""A directory being scanned for projects."""
|
|
25
|
-
|
|
26
|
-
path: str
|
|
27
|
-
project_count: int = 0
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
class ProjectRegistration(BaseModel):
|
|
31
|
-
"""Request to register a project."""
|
|
32
|
-
|
|
33
|
-
path: str
|
|
34
|
-
display_name: Optional[str] = None
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
class ProjectConfigResponse(BaseModel):
|
|
38
|
-
"""Response with project configuration."""
|
|
39
|
-
|
|
40
|
-
scan_directories: list[str]
|
|
41
|
-
registered_count: int
|
|
42
|
-
favorites_count: int
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
class Memory(BaseModel):
|
|
46
|
-
"""Memory record from the database."""
|
|
47
|
-
|
|
48
|
-
id: str
|
|
49
|
-
content: str
|
|
50
|
-
context: Optional[str] = None
|
|
51
|
-
memory_type: str = Field(default="other", validation_alias="type")
|
|
52
|
-
status: str = "fresh"
|
|
53
|
-
importance_score: int = 50
|
|
54
|
-
access_count: int = 0
|
|
55
|
-
created_at: datetime
|
|
56
|
-
last_accessed: Optional[datetime] = None
|
|
57
|
-
tags: list[str] = []
|
|
58
|
-
|
|
59
|
-
model_config = {"populate_by_name": True}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
class MemoryStats(BaseModel):
|
|
63
|
-
"""Statistics about memories in a database."""
|
|
64
|
-
|
|
65
|
-
total_count: int
|
|
66
|
-
by_type: dict[str, int]
|
|
67
|
-
by_status: dict[str, int]
|
|
68
|
-
avg_importance: float
|
|
69
|
-
total_access_count: int
|
|
70
|
-
tags: list[dict[str, int | str]]
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
class FilterParams(BaseModel):
|
|
74
|
-
"""Query filter parameters."""
|
|
75
|
-
|
|
76
|
-
memory_type: Optional[str] = None
|
|
77
|
-
status: Optional[str] = None
|
|
78
|
-
tags: Optional[list[str]] = None
|
|
79
|
-
search: Optional[str] = None
|
|
80
|
-
min_importance: Optional[int] = None
|
|
81
|
-
max_importance: Optional[int] = None
|
|
82
|
-
sort_by: str = "last_accessed"
|
|
83
|
-
sort_order: str = "desc"
|
|
84
|
-
limit: int = 50
|
|
85
|
-
offset: int = 0
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
class AggregateMemoryRequest(BaseModel):
|
|
89
|
-
"""Request for aggregate memory data across projects."""
|
|
90
|
-
|
|
91
|
-
projects: list[str] = Field(..., description="List of project db paths")
|
|
92
|
-
filters: Optional[FilterParams] = None
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
class AggregateStatsRequest(BaseModel):
|
|
96
|
-
"""Request for aggregate statistics."""
|
|
97
|
-
|
|
98
|
-
projects: list[str] = Field(..., description="List of project db paths")
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
class AggregateStatsResponse(BaseModel):
|
|
102
|
-
"""Aggregate statistics across multiple projects."""
|
|
103
|
-
|
|
104
|
-
total_count: int
|
|
105
|
-
total_access_count: int
|
|
106
|
-
avg_importance: float
|
|
107
|
-
by_type: dict[str, int]
|
|
108
|
-
by_status: dict[str, int]
|
|
109
|
-
project_count: int
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
class AggregateChatRequest(BaseModel):
|
|
113
|
-
"""Request for chat across multiple projects."""
|
|
114
|
-
|
|
115
|
-
projects: list[str] = Field(..., description="List of project db paths")
|
|
116
|
-
question: str = Field(..., min_length=1, max_length=2000)
|
|
117
|
-
max_memories_per_project: int = Field(default=5, ge=1, le=20)
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
class Activity(BaseModel):
|
|
121
|
-
"""Activity log record."""
|
|
122
|
-
|
|
123
|
-
id: str
|
|
124
|
-
session_id: Optional[str] = None
|
|
125
|
-
event_type: str
|
|
126
|
-
tool_name: Optional[str] = None
|
|
127
|
-
tool_input: Optional[str] = None
|
|
128
|
-
tool_output: Optional[str] = None
|
|
129
|
-
success: bool = True
|
|
130
|
-
error_message: Optional[str] = None
|
|
131
|
-
duration_ms: Optional[int] = None
|
|
132
|
-
file_path: Optional[str] = None
|
|
133
|
-
timestamp: datetime
|
|
134
|
-
# Command analytics fields
|
|
135
|
-
command_name: Optional[str] = None
|
|
136
|
-
command_scope: Optional[str] = None
|
|
137
|
-
mcp_server: Optional[str] = None
|
|
138
|
-
skill_name: Optional[str] = None
|
|
139
|
-
# Natural language summary fields
|
|
140
|
-
summary: Optional[str] = None
|
|
141
|
-
summary_detail: Optional[str] = None
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
class Session(BaseModel):
|
|
145
|
-
"""Session record."""
|
|
146
|
-
|
|
147
|
-
id: str
|
|
148
|
-
project_path: str
|
|
149
|
-
started_at: datetime
|
|
150
|
-
ended_at: Optional[datetime] = None
|
|
151
|
-
summary: Optional[str] = None
|
|
152
|
-
activity_count: int = 0
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
class TimelineEntry(BaseModel):
|
|
156
|
-
"""Entry in the timeline view."""
|
|
157
|
-
|
|
158
|
-
timestamp: datetime
|
|
159
|
-
entry_type: str # "memory" or "activity"
|
|
160
|
-
data: dict
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
class MemoryCreateRequest(BaseModel):
|
|
164
|
-
"""Create request for a new memory."""
|
|
165
|
-
|
|
166
|
-
content: str = Field(..., min_length=1, max_length=50000)
|
|
167
|
-
memory_type: str = Field(default="general")
|
|
168
|
-
context: Optional[str] = None
|
|
169
|
-
importance_score: int = Field(default=50, ge=1, le=100)
|
|
170
|
-
tags: list[str] = Field(default_factory=list)
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
class MemoryUpdate(BaseModel):
|
|
174
|
-
"""Update request for a memory."""
|
|
175
|
-
|
|
176
|
-
content: Optional[str] = None
|
|
177
|
-
context: Optional[str] = None
|
|
178
|
-
memory_type: Optional[str] = Field(None, validation_alias="type")
|
|
179
|
-
status: Optional[str] = None
|
|
180
|
-
importance_score: Optional[int] = Field(None, ge=1, le=100)
|
|
181
|
-
tags: Optional[list[str]] = None
|
|
182
|
-
|
|
183
|
-
model_config = {"populate_by_name": True}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
class WSEvent(BaseModel):
|
|
187
|
-
"""WebSocket event message."""
|
|
188
|
-
|
|
189
|
-
event_type: str
|
|
190
|
-
data: dict
|
|
191
|
-
timestamp: datetime = Field(default_factory=datetime.now)
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
class ChatRequest(BaseModel):
|
|
195
|
-
"""Request for the chat endpoint."""
|
|
196
|
-
|
|
197
|
-
question: str = Field(..., min_length=1, max_length=2000)
|
|
198
|
-
max_memories: int = Field(default=10, ge=1, le=50)
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
1
|
+
"""Pydantic models for the dashboard API."""
|
|
2
|
+
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ProjectInfo(BaseModel):
|
|
10
|
+
"""Information about a project with omni-cortex database."""
|
|
11
|
+
|
|
12
|
+
name: str
|
|
13
|
+
path: str
|
|
14
|
+
db_path: str
|
|
15
|
+
last_modified: Optional[datetime] = None
|
|
16
|
+
memory_count: int = 0
|
|
17
|
+
is_global: bool = False
|
|
18
|
+
is_favorite: bool = False
|
|
19
|
+
is_registered: bool = False
|
|
20
|
+
display_name: Optional[str] = None
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ScanDirectory(BaseModel):
|
|
24
|
+
"""A directory being scanned for projects."""
|
|
25
|
+
|
|
26
|
+
path: str
|
|
27
|
+
project_count: int = 0
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ProjectRegistration(BaseModel):
|
|
31
|
+
"""Request to register a project."""
|
|
32
|
+
|
|
33
|
+
path: str
|
|
34
|
+
display_name: Optional[str] = None
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class ProjectConfigResponse(BaseModel):
|
|
38
|
+
"""Response with project configuration."""
|
|
39
|
+
|
|
40
|
+
scan_directories: list[str]
|
|
41
|
+
registered_count: int
|
|
42
|
+
favorites_count: int
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class Memory(BaseModel):
|
|
46
|
+
"""Memory record from the database."""
|
|
47
|
+
|
|
48
|
+
id: str
|
|
49
|
+
content: str
|
|
50
|
+
context: Optional[str] = None
|
|
51
|
+
memory_type: str = Field(default="other", validation_alias="type")
|
|
52
|
+
status: str = "fresh"
|
|
53
|
+
importance_score: int = 50
|
|
54
|
+
access_count: int = 0
|
|
55
|
+
created_at: datetime
|
|
56
|
+
last_accessed: Optional[datetime] = None
|
|
57
|
+
tags: list[str] = []
|
|
58
|
+
|
|
59
|
+
model_config = {"populate_by_name": True}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class MemoryStats(BaseModel):
|
|
63
|
+
"""Statistics about memories in a database."""
|
|
64
|
+
|
|
65
|
+
total_count: int
|
|
66
|
+
by_type: dict[str, int]
|
|
67
|
+
by_status: dict[str, int]
|
|
68
|
+
avg_importance: float
|
|
69
|
+
total_access_count: int
|
|
70
|
+
tags: list[dict[str, int | str]]
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class FilterParams(BaseModel):
|
|
74
|
+
"""Query filter parameters."""
|
|
75
|
+
|
|
76
|
+
memory_type: Optional[str] = None
|
|
77
|
+
status: Optional[str] = None
|
|
78
|
+
tags: Optional[list[str]] = None
|
|
79
|
+
search: Optional[str] = None
|
|
80
|
+
min_importance: Optional[int] = None
|
|
81
|
+
max_importance: Optional[int] = None
|
|
82
|
+
sort_by: str = "last_accessed"
|
|
83
|
+
sort_order: str = "desc"
|
|
84
|
+
limit: int = 50
|
|
85
|
+
offset: int = 0
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class AggregateMemoryRequest(BaseModel):
|
|
89
|
+
"""Request for aggregate memory data across projects."""
|
|
90
|
+
|
|
91
|
+
projects: list[str] = Field(..., description="List of project db paths")
|
|
92
|
+
filters: Optional[FilterParams] = None
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class AggregateStatsRequest(BaseModel):
|
|
96
|
+
"""Request for aggregate statistics."""
|
|
97
|
+
|
|
98
|
+
projects: list[str] = Field(..., description="List of project db paths")
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
class AggregateStatsResponse(BaseModel):
|
|
102
|
+
"""Aggregate statistics across multiple projects."""
|
|
103
|
+
|
|
104
|
+
total_count: int
|
|
105
|
+
total_access_count: int
|
|
106
|
+
avg_importance: float
|
|
107
|
+
by_type: dict[str, int]
|
|
108
|
+
by_status: dict[str, int]
|
|
109
|
+
project_count: int
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class AggregateChatRequest(BaseModel):
|
|
113
|
+
"""Request for chat across multiple projects."""
|
|
114
|
+
|
|
115
|
+
projects: list[str] = Field(..., description="List of project db paths")
|
|
116
|
+
question: str = Field(..., min_length=1, max_length=2000)
|
|
117
|
+
max_memories_per_project: int = Field(default=5, ge=1, le=20)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class Activity(BaseModel):
|
|
121
|
+
"""Activity log record."""
|
|
122
|
+
|
|
123
|
+
id: str
|
|
124
|
+
session_id: Optional[str] = None
|
|
125
|
+
event_type: str
|
|
126
|
+
tool_name: Optional[str] = None
|
|
127
|
+
tool_input: Optional[str] = None
|
|
128
|
+
tool_output: Optional[str] = None
|
|
129
|
+
success: bool = True
|
|
130
|
+
error_message: Optional[str] = None
|
|
131
|
+
duration_ms: Optional[int] = None
|
|
132
|
+
file_path: Optional[str] = None
|
|
133
|
+
timestamp: datetime
|
|
134
|
+
# Command analytics fields
|
|
135
|
+
command_name: Optional[str] = None
|
|
136
|
+
command_scope: Optional[str] = None
|
|
137
|
+
mcp_server: Optional[str] = None
|
|
138
|
+
skill_name: Optional[str] = None
|
|
139
|
+
# Natural language summary fields
|
|
140
|
+
summary: Optional[str] = None
|
|
141
|
+
summary_detail: Optional[str] = None
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
class Session(BaseModel):
|
|
145
|
+
"""Session record."""
|
|
146
|
+
|
|
147
|
+
id: str
|
|
148
|
+
project_path: str
|
|
149
|
+
started_at: datetime
|
|
150
|
+
ended_at: Optional[datetime] = None
|
|
151
|
+
summary: Optional[str] = None
|
|
152
|
+
activity_count: int = 0
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
class TimelineEntry(BaseModel):
|
|
156
|
+
"""Entry in the timeline view."""
|
|
157
|
+
|
|
158
|
+
timestamp: datetime
|
|
159
|
+
entry_type: str # "memory" or "activity"
|
|
160
|
+
data: dict
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
class MemoryCreateRequest(BaseModel):
|
|
164
|
+
"""Create request for a new memory."""
|
|
165
|
+
|
|
166
|
+
content: str = Field(..., min_length=1, max_length=50000)
|
|
167
|
+
memory_type: str = Field(default="general")
|
|
168
|
+
context: Optional[str] = None
|
|
169
|
+
importance_score: int = Field(default=50, ge=1, le=100)
|
|
170
|
+
tags: list[str] = Field(default_factory=list)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
class MemoryUpdate(BaseModel):
|
|
174
|
+
"""Update request for a memory."""
|
|
175
|
+
|
|
176
|
+
content: Optional[str] = None
|
|
177
|
+
context: Optional[str] = None
|
|
178
|
+
memory_type: Optional[str] = Field(None, validation_alias="type")
|
|
179
|
+
status: Optional[str] = None
|
|
180
|
+
importance_score: Optional[int] = Field(None, ge=1, le=100)
|
|
181
|
+
tags: Optional[list[str]] = None
|
|
182
|
+
|
|
183
|
+
model_config = {"populate_by_name": True}
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
class WSEvent(BaseModel):
|
|
187
|
+
"""WebSocket event message."""
|
|
188
|
+
|
|
189
|
+
event_type: str
|
|
190
|
+
data: dict
|
|
191
|
+
timestamp: datetime = Field(default_factory=datetime.now)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
class ChatRequest(BaseModel):
|
|
195
|
+
"""Request for the chat endpoint."""
|
|
196
|
+
|
|
197
|
+
question: str = Field(..., min_length=1, max_length=2000)
|
|
198
|
+
max_memories: int = Field(default=10, ge=1, le=50)
|
|
199
|
+
use_style: bool = Field(default=False)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
class ChatSource(BaseModel):
|
|
203
|
+
"""Source memory reference in chat response."""
|
|
204
|
+
|
|
205
|
+
id: str
|
|
206
|
+
type: str
|
|
207
|
+
content_preview: str
|
|
208
|
+
tags: list[str]
|
|
209
|
+
project_path: Optional[str] = None
|
|
210
|
+
project_name: Optional[str] = None
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
class ChatResponse(BaseModel):
|
|
214
|
+
"""Response from the chat endpoint."""
|
|
215
|
+
|
|
216
|
+
answer: str
|
|
217
|
+
sources: list[ChatSource]
|
|
218
|
+
error: Optional[str] = None
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
class ConversationMessage(BaseModel):
|
|
222
|
+
"""A message in a conversation."""
|
|
223
|
+
|
|
224
|
+
role: str # 'user' or 'assistant'
|
|
225
|
+
content: str
|
|
226
|
+
timestamp: str
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
class ConversationSaveRequest(BaseModel):
|
|
230
|
+
"""Request to save a conversation as memory."""
|
|
231
|
+
|
|
232
|
+
messages: list[ConversationMessage]
|
|
233
|
+
referenced_memory_ids: Optional[list[str]] = None
|
|
234
|
+
importance: Optional[int] = Field(default=60, ge=1, le=100)
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
class ConversationSaveResponse(BaseModel):
|
|
238
|
+
"""Response after saving a conversation."""
|
|
239
|
+
|
|
240
|
+
memory_id: str
|
|
241
|
+
summary: str
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
# --- Image Generation Models ---
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
class SingleImageRequestModel(BaseModel):
|
|
248
|
+
"""Request for a single image in a batch."""
|
|
249
|
+
preset: str = "custom" # Maps to ImagePreset enum
|
|
250
|
+
custom_prompt: str = ""
|
|
251
|
+
aspect_ratio: str = "16:9"
|
|
252
|
+
image_size: str = "2K"
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
class BatchImageGenerationRequest(BaseModel):
|
|
256
|
+
"""Request for generating multiple images."""
|
|
257
|
+
images: list[SingleImageRequestModel] # 1, 2, or 4 images
|
|
258
|
+
memory_ids: list[str] = []
|
|
259
|
+
chat_messages: list[dict] = [] # Recent chat for context
|
|
260
|
+
use_search_grounding: bool = False
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
class ImageRefineRequest(BaseModel):
|
|
264
|
+
"""Request for refining an existing image."""
|
|
265
|
+
image_id: str
|
|
266
|
+
refinement_prompt: str
|
|
267
|
+
aspect_ratio: Optional[str] = None
|
|
268
|
+
image_size: Optional[str] = None
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
class SingleImageResponseModel(BaseModel):
|
|
272
|
+
"""Response for a single generated image."""
|
|
273
|
+
success: bool
|
|
274
|
+
image_data: Optional[str] = None # Base64 encoded
|
|
275
|
+
text_response: Optional[str] = None
|
|
276
|
+
thought_signature: Optional[str] = None
|
|
277
|
+
image_id: Optional[str] = None
|
|
278
|
+
error: Optional[str] = None
|
|
279
|
+
index: int = 0
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
class BatchImageGenerationResponse(BaseModel):
|
|
283
|
+
"""Response for batch image generation."""
|
|
284
|
+
success: bool
|
|
285
|
+
images: list[SingleImageResponseModel] = []
|
|
286
|
+
errors: list[str] = []
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
# --- User Messages & Style Profile Models ---
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
class UserMessage(BaseModel):
|
|
293
|
+
"""User message record from the database."""
|
|
294
|
+
|
|
295
|
+
id: str
|
|
296
|
+
session_id: Optional[str] = None
|
|
297
|
+
timestamp: str
|
|
298
|
+
content: str
|
|
299
|
+
word_count: Optional[int] = None
|
|
300
|
+
char_count: Optional[int] = None
|
|
301
|
+
line_count: Optional[int] = None
|
|
302
|
+
has_code_blocks: bool = False
|
|
303
|
+
has_questions: bool = False
|
|
304
|
+
has_commands: bool = False
|
|
305
|
+
tone_indicators: list[str] = []
|
|
306
|
+
project_path: Optional[str] = None
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
class UserMessageFilters(BaseModel):
|
|
310
|
+
"""Query filter parameters for user messages."""
|
|
311
|
+
|
|
312
|
+
session_id: Optional[str] = None
|
|
313
|
+
search: Optional[str] = None
|
|
314
|
+
has_code_blocks: Optional[bool] = None
|
|
315
|
+
has_questions: Optional[bool] = None
|
|
316
|
+
has_commands: Optional[bool] = None
|
|
317
|
+
tone_filter: Optional[str] = None
|
|
318
|
+
sort_by: str = "timestamp"
|
|
319
|
+
sort_order: str = "desc"
|
|
320
|
+
limit: int = Field(default=50, ge=1, le=500)
|
|
321
|
+
offset: int = Field(default=0, ge=0)
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
class UserMessagesResponse(BaseModel):
|
|
325
|
+
"""Response containing user messages with pagination info."""
|
|
326
|
+
|
|
327
|
+
messages: list[UserMessage]
|
|
328
|
+
total_count: int
|
|
329
|
+
limit: int
|
|
330
|
+
offset: int
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
class StyleSample(BaseModel):
|
|
334
|
+
"""A sample message for style preview."""
|
|
335
|
+
|
|
336
|
+
id: str
|
|
337
|
+
timestamp: str
|
|
338
|
+
content_preview: str
|
|
339
|
+
word_count: Optional[int] = None
|
|
340
|
+
has_code_blocks: bool = False
|
|
341
|
+
has_questions: bool = False
|
|
342
|
+
tone_indicators: list[str] = []
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
class StyleProfile(BaseModel):
|
|
346
|
+
"""User style profile for aggregated style analysis."""
|
|
347
|
+
|
|
348
|
+
id: str
|
|
349
|
+
project_path: Optional[str] = None
|
|
350
|
+
total_messages: int = 0
|
|
351
|
+
avg_word_count: Optional[float] = None
|
|
352
|
+
avg_char_count: Optional[float] = None
|
|
353
|
+
common_phrases: Optional[list[str]] = None
|
|
354
|
+
vocabulary_richness: Optional[float] = None
|
|
355
|
+
formality_score: Optional[float] = None
|
|
356
|
+
question_frequency: Optional[float] = None
|
|
357
|
+
command_frequency: Optional[float] = None
|
|
358
|
+
code_block_frequency: Optional[float] = None
|
|
359
|
+
punctuation_style: Optional[dict] = None
|
|
360
|
+
greeting_patterns: Optional[list[str]] = None
|
|
361
|
+
instruction_style: Optional[dict] = None
|
|
362
|
+
sample_messages: Optional[list[str]] = None
|
|
363
|
+
created_at: str
|
|
364
|
+
updated_at: str
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
class BulkDeleteRequest(BaseModel):
|
|
368
|
+
"""Request body for bulk delete operations."""
|
|
369
|
+
|
|
370
|
+
message_ids: list[str] = Field(..., min_length=1, max_length=100)
|