Skip to main content

origin_types/
requests.rs

1// SPDX-License-Identifier: Apache-2.0
2//! API request types for all HTTP endpoints.
3
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6
7// ===== Memory CRUD =====
8
9#[derive(Debug, Serialize, Deserialize)]
10pub struct StoreMemoryRequest {
11    pub content: String,
12    #[serde(default)]
13    pub memory_type: Option<String>,
14    #[serde(default)]
15    pub domain: Option<String>,
16    #[serde(default)]
17    pub source_agent: Option<String>,
18    #[serde(default)]
19    pub title: Option<String>,
20    #[serde(default)]
21    pub confidence: Option<f32>,
22    #[serde(default)]
23    pub supersedes: Option<String>,
24    /// Entity name for resolution (e.g. "Alice", "PostgreSQL")
25    #[serde(default)]
26    pub entity: Option<String>,
27    /// Direct entity ID (bypasses name resolution)
28    #[serde(default)]
29    pub entity_id: Option<String>,
30    #[serde(default)]
31    pub structured_fields: Option<serde_json::Value>,
32    #[serde(default)]
33    pub retrieval_cue: Option<String>,
34}
35
36#[derive(Debug, Serialize, Deserialize)]
37pub struct SearchMemoryRequest {
38    pub query: String,
39    #[serde(default = "default_limit")]
40    pub limit: usize,
41    #[serde(default)]
42    pub memory_type: Option<String>,
43    #[serde(default)]
44    pub domain: Option<String>,
45    #[serde(default)]
46    pub source_agent: Option<String>,
47}
48
49#[derive(Debug, Serialize, Deserialize)]
50pub struct ListMemoriesRequest {
51    #[serde(default)]
52    pub memory_type: Option<String>,
53    #[serde(default)]
54    pub domain: Option<String>,
55    #[serde(default = "default_list_limit")]
56    pub limit: usize,
57}
58
59#[derive(Debug, Serialize, Deserialize)]
60pub struct ConfirmRequest {
61    #[serde(default = "default_confirmed")]
62    pub confirmed: bool,
63}
64
65#[derive(Debug, Serialize, Deserialize)]
66pub struct ReclassifyMemoryRequest {
67    pub memory_type: String,
68}
69
70#[derive(Debug, Serialize, Deserialize)]
71pub struct ImportMemoriesRequest {
72    pub source: String,
73    pub content: String,
74    #[serde(default)]
75    pub label: Option<String>,
76}
77
78// ===== General search/context =====
79
80#[derive(Debug, Serialize, Deserialize)]
81pub struct SearchRequest {
82    pub query: String,
83    #[serde(default = "default_limit")]
84    pub limit: usize,
85    pub source_filter: Option<String>,
86    #[serde(default)]
87    pub domain: Option<String>,
88}
89
90#[doc(hidden)]
91#[derive(Debug, Serialize, Deserialize)]
92pub struct ContextRequest {
93    pub current_file: String,
94    pub cursor_prefix: String,
95    #[serde(default = "default_limit")]
96    pub limit: usize,
97}
98
99#[derive(Debug, Serialize, Deserialize)]
100pub struct ChatContextRequest {
101    #[serde(default)]
102    pub query: Option<String>,
103    #[serde(default)]
104    pub conversation_id: Option<String>,
105    #[serde(default = "default_max_chunks")]
106    pub max_chunks: usize,
107    #[serde(default)]
108    pub relevance_threshold: Option<f64>,
109    #[serde(default = "default_true")]
110    pub include_goals: bool,
111    #[serde(default)]
112    pub domain: Option<String>,
113}
114
115// ===== Knowledge graph =====
116
117#[derive(Debug, Serialize, Deserialize)]
118pub struct CreateEntityRequest {
119    pub name: String,
120    pub entity_type: String,
121    #[serde(default)]
122    pub domain: Option<String>,
123    #[serde(default)]
124    pub source_agent: Option<String>,
125    #[serde(default)]
126    pub confidence: Option<f32>,
127}
128
129#[doc(hidden)]
130#[derive(Debug, Serialize, Deserialize)]
131pub struct CreateRelationRequest {
132    pub from_entity: String,
133    pub to_entity: String,
134    pub relation_type: String,
135    #[serde(default)]
136    pub source_agent: Option<String>,
137}
138
139#[derive(Debug, Serialize, Deserialize)]
140pub struct AddObservationRequest {
141    pub entity_id: String,
142    pub content: String,
143    #[serde(default)]
144    pub source_agent: Option<String>,
145    #[serde(default)]
146    pub confidence: Option<f32>,
147}
148
149#[doc(hidden)]
150#[derive(Debug, Serialize, Deserialize)]
151pub struct LinkEntityRequest {
152    pub source_id: String,
153    pub entity_id: String,
154}
155
156#[derive(Debug, Serialize, Deserialize)]
157pub struct ListEntitiesRequest {
158    #[serde(default)]
159    pub entity_type: Option<String>,
160    #[serde(default)]
161    pub domain: Option<String>,
162}
163
164#[derive(Debug, Serialize, Deserialize)]
165pub struct SearchEntitiesRequest {
166    pub query: String,
167    #[serde(default = "default_entity_search_limit")]
168    pub limit: usize,
169}
170
171// ===== Profile & Agents =====
172
173#[derive(Debug, Serialize, Deserialize)]
174pub struct UpdateProfileRequest {
175    #[serde(default)]
176    pub name: Option<String>,
177    #[serde(default)]
178    pub display_name: Option<String>,
179    #[serde(default)]
180    pub email: Option<String>,
181    #[serde(default)]
182    pub bio: Option<String>,
183    #[serde(default)]
184    pub avatar_path: Option<String>,
185}
186
187#[derive(Debug, Serialize, Deserialize)]
188pub struct UpdateAgentRequest {
189    #[serde(default)]
190    pub agent_type: Option<String>,
191    #[serde(default)]
192    pub description: Option<String>,
193    #[serde(default)]
194    pub enabled: Option<bool>,
195    #[serde(default)]
196    pub trust_level: Option<String>,
197    /// Empty string clears the field; None leaves it unchanged.
198    #[serde(default)]
199    pub display_name: Option<String>,
200}
201
202// ===== Spaces =====
203
204#[derive(Debug, Serialize, Deserialize)]
205pub struct CreateSpaceRequest {
206    pub name: String,
207    pub description: Option<String>,
208}
209
210#[derive(Debug, Serialize, Deserialize)]
211pub struct UpdateSpaceRequest {
212    pub new_name: Option<String>,
213    pub description: Option<String>,
214}
215
216// ===== Concepts =====
217
218#[doc(hidden)]
219#[derive(Debug, Serialize, Deserialize)]
220pub struct CreateConceptRequest {
221    pub title: String,
222    pub content: String,
223    #[serde(default)]
224    pub summary: Option<String>,
225    #[serde(default)]
226    pub entity_id: Option<String>,
227    #[serde(default)]
228    pub domain: Option<String>,
229    #[serde(default)]
230    pub source_memory_ids: Vec<String>,
231}
232
233#[derive(Debug, Serialize, Deserialize)]
234pub struct SearchPagesRequest {
235    pub query: String,
236    #[serde(default)]
237    pub limit: Option<usize>,
238}
239
240// ===== Ingest =====
241
242#[derive(Debug, Serialize, Deserialize)]
243pub struct IngestTextRequest {
244    pub source: String,
245    pub source_id: String,
246    pub title: String,
247    pub content: String,
248    pub url: Option<String>,
249    pub metadata: Option<HashMap<String, String>>,
250}
251
252#[doc(hidden)]
253#[derive(Debug, Serialize, Deserialize)]
254pub struct IngestWebpageRequest {
255    pub url: String,
256    pub title: String,
257    pub content: String,
258    pub metadata: Option<HashMap<String, String>>,
259}
260
261#[derive(Debug, Serialize, Deserialize)]
262pub struct IngestMemoryRequest {
263    pub source: String,
264    pub source_id: String,
265    pub title: String,
266    pub content: String,
267    pub url: Option<String>,
268    pub tags: Option<Vec<String>>,
269    pub metadata: Option<HashMap<String, String>>,
270}
271
272// ===== Sources =====
273
274#[doc(hidden)]
275#[derive(Debug, Serialize, Deserialize)]
276pub struct AddSourceRequest {
277    pub source_type: String,
278    /// Filesystem path as a string. Kept as `String` (not `PathBuf`) because
279    /// this is an HTTP wire format — the handler converts it to `PathBuf`.
280    pub path: String,
281}
282
283// ===== Config =====
284
285#[derive(Debug, Serialize, Deserialize)]
286pub struct UpdateConfigRequest {
287    #[serde(default)]
288    pub skip_apps: Option<Vec<String>>,
289    #[serde(default)]
290    pub skip_title_patterns: Option<Vec<String>>,
291    #[serde(default)]
292    pub private_browsing_detection: Option<bool>,
293    #[serde(default)]
294    pub setup_completed: Option<bool>,
295    #[serde(default)]
296    pub clipboard_enabled: Option<bool>,
297    #[serde(default)]
298    pub screen_capture_enabled: Option<bool>,
299    #[serde(default)]
300    pub remote_access_enabled: Option<bool>,
301    /// Anthropic model used for fast/routine tasks (e.g. classification, tagging).
302    #[serde(default)]
303    pub routine_model: Option<String>,
304    /// Anthropic model used for synthesis tasks (e.g. distillation, narrative).
305    #[serde(default)]
306    pub synthesis_model: Option<String>,
307    /// Base URL for an OpenAI-compatible external LLM endpoint.
308    #[serde(default)]
309    pub external_llm_endpoint: Option<String>,
310    /// Model identifier to use with the external LLM endpoint.
311    #[serde(default)]
312    pub external_llm_model: Option<String>,
313}
314
315// ===== Chunks / indexed files =====
316
317#[derive(Debug, Serialize, Deserialize)]
318pub struct DeleteByTimeRangeRequest {
319    pub start: i64,
320    pub end: i64,
321}
322
323#[derive(Debug, Serialize, Deserialize)]
324pub struct BulkDeleteItem {
325    pub source: String,
326    pub source_id: String,
327}
328
329#[derive(Debug, Serialize, Deserialize)]
330pub struct BulkDeleteRequest {
331    pub items: Vec<BulkDeleteItem>,
332}
333
334#[derive(Debug, Serialize, Deserialize)]
335pub struct UpdateChunkRequest {
336    pub content: String,
337}
338
339// ===== Entity / Observation CRUD =====
340
341#[derive(Debug, Serialize, Deserialize)]
342pub struct ConfirmEntityRequest {
343    #[serde(default = "default_confirmed")]
344    pub confirmed: bool,
345}
346
347#[derive(Debug, Serialize, Deserialize)]
348pub struct AddEntityObservationRequest {
349    pub content: String,
350    #[serde(default)]
351    pub source_agent: Option<String>,
352    #[serde(default)]
353    pub confidence: Option<f32>,
354}
355
356#[derive(Debug, Serialize, Deserialize)]
357pub struct UpdateObservationRequest {
358    pub content: String,
359}
360
361#[derive(Debug, Serialize, Deserialize)]
362pub struct ConfirmObservationRequest {
363    #[serde(default = "default_confirmed")]
364    pub confirmed: bool,
365}
366
367// ===== Spaces extended =====
368
369#[derive(Debug, Serialize, Deserialize)]
370pub struct ReorderSpaceRequest {
371    pub name: String,
372    pub new_order: i64,
373}
374
375#[derive(Debug, Serialize, Deserialize)]
376pub struct SetDocumentSpaceRequest {
377    pub space_name: String,
378}
379
380// ===== Tags =====
381
382#[derive(Debug, Serialize, Deserialize)]
383pub struct SetDocumentTagsRequest {
384    pub tags: Vec<String>,
385}
386
387// ===== Memory update =====
388
389#[derive(Debug, Serialize, Deserialize)]
390pub struct UpdateMemoryRequest {
391    #[serde(default)]
392    pub content: Option<String>,
393    #[serde(default)]
394    pub domain: Option<String>,
395    #[serde(default)]
396    pub confirmed: Option<bool>,
397    #[serde(default)]
398    pub memory_type: Option<String>,
399}
400
401#[derive(Debug, Serialize, Deserialize)]
402pub struct SetStabilityRequest {
403    pub stability: String,
404}
405
406#[derive(Debug, Serialize, Deserialize)]
407pub struct CorrectMemoryRequest {
408    pub correction_prompt: String,
409}
410
411// ===== Concepts update =====
412
413#[derive(Debug, Serialize, Deserialize)]
414pub struct UpdatePageRequest {
415    pub content: String,
416}
417
418// ===== Concept Export =====
419
420/// Request body for `POST /api/pages/export` (bulk export all pages to an Obsidian vault).
421#[derive(Debug, Deserialize, Serialize)]
422pub struct ExportPagesRequest {
423    pub vault_path: Option<String>,
424}
425
426#[derive(Debug, Deserialize, Serialize)]
427pub struct ExportPageRequest {
428    pub vault_path: String,
429}
430
431// ===== LLM test =====
432
433/// `POST /api/llm/test` — probe an OpenAI-compatible LLM endpoint with a 1-shot prompt.
434/// Used by the app settings UI to validate a custom endpoint before saving.
435#[derive(Debug, Clone, Serialize, Deserialize)]
436pub struct TestLlmRequest {
437    pub endpoint: String,
438    pub model: String,
439    /// Optional override prompt. Defaults to "Say 'hello' and nothing else." server-side.
440    #[serde(default, skip_serializing_if = "Option::is_none")]
441    pub prompt: Option<String>,
442}
443
444#[derive(Debug, Clone, Serialize, Deserialize)]
445pub struct TestLlmResponse {
446    pub response: String,
447}
448
449// ===== Default value functions =====
450
451fn default_limit() -> usize {
452    10
453}
454
455fn default_list_limit() -> usize {
456    100
457}
458
459fn default_confirmed() -> bool {
460    true
461}
462
463fn default_max_chunks() -> usize {
464    5
465}
466
467fn default_true() -> bool {
468    true
469}
470
471fn default_entity_search_limit() -> usize {
472    20
473}