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    /// Deprecated: goal-typed memories were folded into identity by migration 45
110    /// (Phase 0). Daemon ignores this field — no goal-load path exists anymore.
111    /// Field stays for wire backward compat; will be removed in 0.4.
112    #[deprecated(
113        since = "0.3.2",
114        note = "Goal taxonomy folded into Identity by migration 45 (Phase 0). \
115                Daemon ignores this field. Will be removed in 0.4."
116    )]
117    #[serde(default = "default_true")]
118    pub include_goals: bool,
119    #[serde(default)]
120    pub domain: Option<String>,
121}
122
123// ===== Knowledge graph =====
124
125#[derive(Debug, Serialize, Deserialize)]
126pub struct CreateEntityRequest {
127    pub name: String,
128    pub entity_type: String,
129    #[serde(default)]
130    pub domain: Option<String>,
131    #[serde(default)]
132    pub source_agent: Option<String>,
133    #[serde(default)]
134    pub confidence: Option<f32>,
135}
136
137#[doc(hidden)]
138#[derive(Debug, Serialize, Deserialize)]
139pub struct CreateRelationRequest {
140    pub from_entity: String,
141    pub to_entity: String,
142    pub relation_type: String,
143    #[serde(default)]
144    pub source_agent: Option<String>,
145}
146
147#[derive(Debug, Serialize, Deserialize)]
148pub struct AddObservationRequest {
149    pub entity_id: String,
150    pub content: String,
151    #[serde(default)]
152    pub source_agent: Option<String>,
153    #[serde(default)]
154    pub confidence: Option<f32>,
155}
156
157#[doc(hidden)]
158#[derive(Debug, Serialize, Deserialize)]
159pub struct LinkEntityRequest {
160    pub source_id: String,
161    pub entity_id: String,
162}
163
164#[derive(Debug, Serialize, Deserialize)]
165pub struct ListEntitiesRequest {
166    #[serde(default)]
167    pub entity_type: Option<String>,
168    #[serde(default)]
169    pub domain: Option<String>,
170}
171
172#[derive(Debug, Serialize, Deserialize)]
173pub struct SearchEntitiesRequest {
174    pub query: String,
175    #[serde(default = "default_entity_search_limit")]
176    pub limit: usize,
177}
178
179// ===== Profile & Agents =====
180
181#[derive(Debug, Serialize, Deserialize)]
182pub struct UpdateProfileRequest {
183    #[serde(default)]
184    pub name: Option<String>,
185    #[serde(default)]
186    pub display_name: Option<String>,
187    #[serde(default)]
188    pub email: Option<String>,
189    #[serde(default)]
190    pub bio: Option<String>,
191    #[serde(default)]
192    pub avatar_path: Option<String>,
193}
194
195#[derive(Debug, Serialize, Deserialize)]
196pub struct UpdateAgentRequest {
197    #[serde(default)]
198    pub agent_type: Option<String>,
199    #[serde(default)]
200    pub description: Option<String>,
201    #[serde(default)]
202    pub enabled: Option<bool>,
203    #[serde(default)]
204    pub trust_level: Option<String>,
205    /// Empty string clears the field; None leaves it unchanged.
206    #[serde(default)]
207    pub display_name: Option<String>,
208}
209
210// ===== Spaces =====
211
212#[derive(Debug, Serialize, Deserialize)]
213pub struct CreateSpaceRequest {
214    pub name: String,
215    pub description: Option<String>,
216}
217
218#[derive(Debug, Serialize, Deserialize)]
219pub struct UpdateSpaceRequest {
220    pub new_name: Option<String>,
221    pub description: Option<String>,
222}
223
224// ===== Concepts =====
225
226#[doc(hidden)]
227#[derive(Debug, Serialize, Deserialize)]
228pub struct CreateConceptRequest {
229    pub title: String,
230    pub content: String,
231    #[serde(default)]
232    pub summary: Option<String>,
233    #[serde(default)]
234    pub entity_id: Option<String>,
235    #[serde(default)]
236    pub domain: Option<String>,
237    #[serde(default)]
238    pub source_memory_ids: Vec<String>,
239}
240
241#[derive(Debug, Serialize, Deserialize)]
242pub struct SearchPagesRequest {
243    pub query: String,
244    #[serde(default)]
245    pub limit: Option<usize>,
246}
247
248// ===== Ingest =====
249
250#[derive(Debug, Serialize, Deserialize)]
251pub struct IngestTextRequest {
252    pub source: String,
253    pub source_id: String,
254    pub title: String,
255    pub content: String,
256    pub url: Option<String>,
257    pub metadata: Option<HashMap<String, String>>,
258}
259
260#[doc(hidden)]
261#[derive(Debug, Serialize, Deserialize)]
262pub struct IngestWebpageRequest {
263    pub url: String,
264    pub title: String,
265    pub content: String,
266    pub metadata: Option<HashMap<String, String>>,
267}
268
269#[derive(Debug, Serialize, Deserialize)]
270pub struct IngestMemoryRequest {
271    pub source: String,
272    pub source_id: String,
273    pub title: String,
274    pub content: String,
275    pub url: Option<String>,
276    pub tags: Option<Vec<String>>,
277    pub metadata: Option<HashMap<String, String>>,
278}
279
280// ===== Sources =====
281
282#[doc(hidden)]
283#[derive(Debug, Serialize, Deserialize)]
284pub struct AddSourceRequest {
285    pub source_type: String,
286    /// Filesystem path as a string. Kept as `String` (not `PathBuf`) because
287    /// this is an HTTP wire format — the handler converts it to `PathBuf`.
288    pub path: String,
289}
290
291// ===== Config =====
292
293#[derive(Debug, Serialize, Deserialize)]
294pub struct UpdateConfigRequest {
295    #[serde(default)]
296    pub skip_apps: Option<Vec<String>>,
297    #[serde(default)]
298    pub skip_title_patterns: Option<Vec<String>>,
299    #[serde(default)]
300    pub private_browsing_detection: Option<bool>,
301    #[serde(default)]
302    pub setup_completed: Option<bool>,
303    #[serde(default)]
304    pub clipboard_enabled: Option<bool>,
305    #[serde(default)]
306    pub screen_capture_enabled: Option<bool>,
307    #[serde(default)]
308    pub remote_access_enabled: Option<bool>,
309    /// Anthropic model used for fast/routine tasks (e.g. classification, tagging).
310    #[serde(default)]
311    pub routine_model: Option<String>,
312    /// Anthropic model used for synthesis tasks (e.g. distillation, narrative).
313    #[serde(default)]
314    pub synthesis_model: Option<String>,
315    /// Base URL for an OpenAI-compatible external LLM endpoint.
316    #[serde(default)]
317    pub external_llm_endpoint: Option<String>,
318    /// Model identifier to use with the external LLM endpoint.
319    #[serde(default)]
320    pub external_llm_model: Option<String>,
321}
322
323// ===== Chunks / indexed files =====
324
325#[derive(Debug, Serialize, Deserialize)]
326pub struct DeleteByTimeRangeRequest {
327    pub start: i64,
328    pub end: i64,
329}
330
331#[derive(Debug, Serialize, Deserialize)]
332pub struct BulkDeleteItem {
333    pub source: String,
334    pub source_id: String,
335}
336
337#[derive(Debug, Serialize, Deserialize)]
338pub struct BulkDeleteRequest {
339    pub items: Vec<BulkDeleteItem>,
340}
341
342#[derive(Debug, Serialize, Deserialize)]
343pub struct UpdateChunkRequest {
344    pub content: String,
345}
346
347// ===== Entity / Observation CRUD =====
348
349#[derive(Debug, Serialize, Deserialize)]
350pub struct ConfirmEntityRequest {
351    #[serde(default = "default_confirmed")]
352    pub confirmed: bool,
353}
354
355#[derive(Debug, Serialize, Deserialize)]
356pub struct AddEntityObservationRequest {
357    pub content: String,
358    #[serde(default)]
359    pub source_agent: Option<String>,
360    #[serde(default)]
361    pub confidence: Option<f32>,
362}
363
364#[derive(Debug, Serialize, Deserialize)]
365pub struct UpdateObservationRequest {
366    pub content: String,
367}
368
369#[derive(Debug, Serialize, Deserialize)]
370pub struct ConfirmObservationRequest {
371    #[serde(default = "default_confirmed")]
372    pub confirmed: bool,
373}
374
375// ===== Spaces extended =====
376
377#[derive(Debug, Serialize, Deserialize)]
378pub struct ReorderSpaceRequest {
379    pub name: String,
380    pub new_order: i64,
381}
382
383#[derive(Debug, Serialize, Deserialize)]
384pub struct SetDocumentSpaceRequest {
385    pub space_name: String,
386}
387
388// ===== Tags =====
389
390#[derive(Debug, Serialize, Deserialize)]
391pub struct SetDocumentTagsRequest {
392    pub tags: Vec<String>,
393}
394
395// ===== Memory update =====
396
397#[derive(Debug, Serialize, Deserialize)]
398pub struct UpdateMemoryRequest {
399    #[serde(default)]
400    pub content: Option<String>,
401    #[serde(default)]
402    pub domain: Option<String>,
403    #[serde(default)]
404    pub confirmed: Option<bool>,
405    #[serde(default)]
406    pub memory_type: Option<String>,
407}
408
409#[derive(Debug, Serialize, Deserialize)]
410pub struct SetStabilityRequest {
411    pub stability: String,
412}
413
414#[derive(Debug, Serialize, Deserialize)]
415pub struct CorrectMemoryRequest {
416    pub correction_prompt: String,
417}
418
419// ===== Concepts update =====
420
421#[derive(Debug, Serialize, Deserialize)]
422pub struct UpdatePageRequest {
423    pub content: String,
424}
425
426// ===== Concept Export =====
427
428/// Request body for `POST /api/pages/export` (bulk export all pages to an Obsidian vault).
429#[derive(Debug, Deserialize, Serialize)]
430pub struct ExportPagesRequest {
431    pub vault_path: Option<String>,
432}
433
434#[derive(Debug, Deserialize, Serialize)]
435pub struct ExportPageRequest {
436    pub vault_path: String,
437}
438
439// ===== LLM test =====
440
441/// `POST /api/llm/test` — probe an OpenAI-compatible LLM endpoint with a 1-shot prompt.
442/// Used by the app settings UI to validate a custom endpoint before saving.
443#[derive(Debug, Clone, Serialize, Deserialize)]
444pub struct TestLlmRequest {
445    pub endpoint: String,
446    pub model: String,
447    /// Optional override prompt. Defaults to "Say 'hello' and nothing else." server-side.
448    #[serde(default, skip_serializing_if = "Option::is_none")]
449    pub prompt: Option<String>,
450}
451
452#[derive(Debug, Clone, Serialize, Deserialize)]
453pub struct TestLlmResponse {
454    pub response: String,
455}
456
457// ===== Default value functions =====
458
459fn default_limit() -> usize {
460    10
461}
462
463fn default_list_limit() -> usize {
464    100
465}
466
467fn default_confirmed() -> bool {
468    true
469}
470
471fn default_max_chunks() -> usize {
472    5
473}
474
475fn default_true() -> bool {
476    true
477}
478
479fn default_entity_search_limit() -> usize {
480    20
481}