1use schemars::JsonSchema;
11use serde::Deserialize;
12
13#[derive(Deserialize, JsonSchema, Debug)]
19pub struct AssembleContextRequest {
20 #[schemars(description = r#"Session UUID. Required when workspace_id is not provided.
22
23Format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
24
25Note: If both session_id and workspace_id are provided, workspace_id takes precedence
26(context is merged across all sessions in the workspace)."#)]
27 pub session_id: Option<String>,
28 #[schemars(
30 description = r#"Workspace UUID. When provided, context is merged across all sessions in the workspace.
31
32Format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
33
34Note: Takes precedence over session_id."#
35 )]
36 pub workspace_id: Option<String>,
37 #[schemars(description = r#"The query/topic to assemble context for.
39
40Example: "How does authentication interact with the user profile service?"
41
42Note: Entity extraction runs on this query to seed graph traversal."#)]
43 pub query: String,
44 #[schemars(
46 description = r#"Token budget for the assembled context (default: 4000).
47
48Examples:
49- 2000: tight context window
50- 4000: default (matches Axon's per-call budget)
51- 8000: extended chains / orchestration
52
53Note: Must be > 0. Items are packed highest-score-first until budget is consumed."#
54 )]
55 pub token_budget: Option<u32>,
56}
57
58#[derive(Deserialize, JsonSchema, Debug)]
64pub struct ManageEntityRequest {
65 #[schemars(description = r#"Action to perform on session content.
67
68Valid values:
69- delete: Remove an entity from the session (cascades typed edges). Requires entity_name.
70- delete_update: Remove a single context update (ghost / bad row) by entry_id. Requires entry_id.
71
72Note: Must be lowercase. Additional actions may be added later."#)]
73 pub action: String,
74 #[schemars(description = r#"Session UUID containing the entity/update.
76
77Format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"#)]
78 pub session_id: String,
79 #[schemars(description = r#"Entity name to operate on (required for action=delete).
81
82Example: "RocksDB"
83
84Note: Names are matched case-insensitively in the entity graph."#)]
85 pub entity_name: Option<String>,
86 #[schemars(description = r#"Context-update id (required for action=delete_update).
88
89Format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
90
91Note: This is the `entry_id` returned by `assemble_context` items, or the id of a
92ContextUpdate stored in the session. Use it to remove ghost / mis-shaped writes."#)]
93 pub entry_id: Option<String>,
94}
95
96#[derive(Deserialize, JsonSchema, Debug)]
102pub struct AdminRequest {
103 #[schemars(description = r#"Administrative action on the Post-Cortex daemon.
105
106Valid values:
107- health: Report daemon health (active sessions, embeddings status, version)
108- vectorize_session: Backfill embeddings for an existing session (requires session_id)
109- vectorize_stats: Return embedding-pipeline statistics as JSON
110- create_checkpoint: Persist a snapshot of a session for later recall (requires session_id)
111
112Examples:
113✅ {"action": "health"}
114✅ {"action": "vectorize_session", "session_id": "60c598e2-..."}
115✅ {"action": "vectorize_stats"}
116✅ {"action": "create_checkpoint", "session_id": "60c598e2-..."}
117
118Note: Must be lowercase."#)]
119 pub action: String,
120 #[schemars(description = r#"Session UUID for vectorize_session and create_checkpoint.
122
123Format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"#)]
124 pub session_id: Option<String>,
125}
126
127#[derive(Deserialize, JsonSchema, Debug)]
133pub struct SessionRequest {
134 #[schemars(description = r#"Action to perform on sessions.
136
137Valid values:
138- create: Create a new session and return a UUID (optional: name, description)
139- list: List all existing sessions
140- load: Load metadata for a single session (requires session_id)
141- search: Find sessions by name or description substring (requires query)
142- update_metadata: Update session name and/or description (requires session_id; provide name and/or description)
143- delete: Permanently delete a session and its updates (requires session_id)
144
145Examples:
146✅ {"action": "create", "name": "Auth", "description": "OAuth2 work"}
147✅ {"action": "load", "session_id": "60c598e2-..."}
148✅ {"action": "search", "query": "auth"}
149✅ {"action": "update_metadata", "session_id": "60c598e2-...", "name": "New name"}
150✅ {"action": "delete", "session_id": "60c598e2-..."}
151
152Note: Must be lowercase."#)]
153 pub action: String,
154 #[schemars(description = r#"Session name (used by create and update_metadata).
156
157Examples:
158- "Feature: Authentication"
159- "Bug Fix: Memory Leak"
160
161Note: For update_metadata, only provided fields are changed."#)]
162 pub name: Option<String>,
163 #[schemars(description = r#"Session description (used by create and update_metadata).
165
166Example: "Working on implementing OAuth2 login flow"
167
168Note: For update_metadata, only provided fields are changed."#)]
169 pub description: Option<String>,
170 #[schemars(description = r#"Session UUID (required for load, update_metadata, delete).
172
173Format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
174
175Example: "60c598e2-d602-4e07-a328-c458006d48c7""#)]
176 pub session_id: Option<String>,
177 #[schemars(description = r#"Search query for the search action.
179
180Examples:
181- "authentication"
182- "image pipeline"
183
184Note: Matches session name or description (case-insensitive substring)."#)]
185 pub query: Option<String>,
186}
187
188#[derive(Deserialize, JsonSchema, Debug, Clone)]
194pub struct ContextUpdateItem {
195 #[schemars(description = r#"Type of interaction (must be exact lowercase value).
197
198Valid values:
199- qa: Questions and answers about the codebase
200- decision_made: Architectural decisions and trade-offs
201- problem_solved: Bug fixes and solutions to technical problems
202- code_change: Code modifications and refactoring
203- requirement_added: New requirements or constraints
204- concept_defined: Technical concepts and patterns explained
205
206Examples:
207✅ "decision_made" (correct)
208❌ "DecisionMade" (wrong - must be lowercase)
209❌ "made_decision" (wrong - use exact term)"#)]
210 pub interaction_type: String,
211 #[schemars(
213 description = r#"Content as key-value pairs (all values must be strings).
214
215Format: HashMap<String, String> where both keys and values are strings.
216
217Examples:
218Simple: {"decision": "Use Rust", "rationale": "Performance"}
219Complex: {"criteria": "{\"performance\": 9, \"safety\": 10}", "date": "2025-01-12"}
220
221Note: For complex nested data, stringify as JSON first. Do not pass nested objects directly."#
222 )]
223 pub content: std::collections::HashMap<String, String>,
224 #[serde(default)]
227 #[schemars(
228 description = r#"Named entities mentioned in this update.
229
230Each entry: {"name": "<unique name>", "entity_type": "concept|technology|problem|solution|decision|code_component"}.
231Required (must contain at least one entity) so the entity graph captures every write."#
232 )]
233 pub entities: Vec<post_cortex_mcp::EntityItem>,
234 #[serde(default)]
236 #[schemars(
237 description = r#"Relations between the entities listed above.
238
239Each entry: {"from_entity": "<name>", "to_entity": "<name>", "relation_type": "depends_on|implements|caused_by|leads_to|related_to|required_by|conflicts_with|solves", "context": "<short why>"}.
240Required (must contain at least one relation). Both endpoints must appear in the `entities` array; self-relations and dangling references are rejected with InvalidArgument."#
241 )]
242 pub relations: Vec<post_cortex_mcp::RelationItem>,
243 #[schemars(description = r#"Optional code reference for context.
245
246Can be a simple string or complex object:
247
248Examples:
249- Simple: "src/main.rs:42"
250- Complex: {"file": "src/main.rs", "line": 42, "function": "process_data"}
251
252Note: Helps link context to specific code locations."#)]
253 pub code_reference: Option<serde_json::Value>,
254}
255
256#[derive(Deserialize, JsonSchema, Debug)]
258pub struct UpdateConversationContextRequest {
259 #[schemars(description = r#"Session ID (36-char UUID format with hyphens).
261
262Format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
263
264How to get:
2651. Create session: Use session tool with action='create'
2662. Find session: Use semantic_search to search for previous sessions
267
268Example: "60c598e2-d602-4e07-a328-c458006d48c7"
269
270Note: Must be a string, not a number. UUIDs are always strings."#)]
271 pub session_id: String,
272 #[schemars(
274 description = r#"Type of interaction for single update (must be exact lowercase value).
275
276Valid values:
277- qa: Questions and answers about the codebase
278- decision_made: Architectural decisions and trade-offs
279- problem_solved: Bug fixes and solutions to technical problems
280- code_change: Code modifications and refactoring
281- requirement_added: New requirements or constraints
282- concept_defined: Technical concepts and patterns explained
283
284Note: Required for single update mode (when 'updates' array is not provided)."#
285 )]
286 pub interaction_type: Option<String>,
287 #[schemars(
289 description = r#"Content as key-value pairs for single update (all values must be strings).
290
291Format: HashMap<String, String> where both keys and values are strings.
292
293Examples:
294Simple: {"decision": "Use Rust", "rationale": "Performance"}
295Complex: {"criteria": "{\"performance\": 9}", "date": "2025-01-12"}
296
297Note: For complex nested data, stringify as JSON first. Required for single update mode."#
298 )]
299 pub content: Option<std::collections::HashMap<String, String>>,
300 #[serde(default)]
303 #[schemars(
304 description = r#"Named entities mentioned in this update.
305
306Each entry: {"name": "<unique name>", "entity_type": "concept|technology|problem|solution|decision|code_component"}.
307Required (must contain at least one entity) so the entity graph captures every write."#
308 )]
309 pub entities: Vec<post_cortex_mcp::EntityItem>,
310 #[serde(default)]
312 #[schemars(
313 description = r#"Relations between the entities listed above.
314
315Each entry: {"from_entity": "<name>", "to_entity": "<name>", "relation_type": "depends_on|implements|caused_by|leads_to|related_to|required_by|conflicts_with|solves", "context": "<short why>"}.
316Required (must contain at least one relation). Both endpoints must appear in the `entities` array; self-relations and dangling references are rejected with InvalidArgument."#
317 )]
318 pub relations: Vec<post_cortex_mcp::RelationItem>,
319 #[schemars(description = r#"Optional code reference for single update.
321
322Can be a simple string or complex object:
323
324Examples:
325- Simple: "src/main.rs:42"
326- Complex: {"file": "src/main.rs", "line": 42, "function": "process_data"}"#)]
327 pub code_reference: Option<serde_json::Value>,
328 #[schemars(
330 description = r#"Array of updates for bulk operation (overrides single fields if provided).
331
332Use this mode to add multiple updates at once.
333
334Format: Array of objects, each with interaction_type and content.
335
336Example:
337{
338 "session_id": "60c598e2-d602-4e07-a328-c458006d48c7",
339 "updates": [
340 {
341 "interaction_type": "decision_made",
342 "content": {"decision": "Use Rust", "rationale": "Performance"}
343 },
344 {
345 "interaction_type": "code_change",
346 "content": {"file": "main.rs", "change": "Add error handling"}
347 }
348 ]
349}
350
351Note: When provided, 'interaction_type' and 'content' fields are ignored."#
352 )]
353 pub updates: Option<Vec<ContextUpdateItem>>,
354 #[schemars(
356 description = r#"If true, validate the request without making any changes.
357
358When dry_run is true, the request will be validated and a preview of what would happen will be returned, but no data will be stored.
359
360Use cases:
361- Test if your request format is correct
362- Preview what would be stored
363- Validate interaction_type and content structure
364- Check if session exists
365
366Example: {"dry_run": true, "session_id": "...", "interaction_type": "decision_made", "content": {...}}
367
368Note: No changes are made to the session when dry_run is true."#
369 )]
370 pub dry_run: Option<bool>,
371}
372
373#[derive(Deserialize, JsonSchema, Debug)]
379pub struct SemanticSearchRequest {
380 #[schemars(description = r#"Search query for semantic search.
382
383Examples:
384- "How did we handle authentication?"
385- "What were the performance issues?"
386- "decision_made API design"
387
388Note: Natural language queries work best. The search understands context."#)]
389 pub query: String,
390 #[schemars(
392 description = r#"Search scope: 'session', 'workspace', or 'global' (default: 'global').
393
394Valid values:
395- session: Search within a specific session (requires scope_id)
396- workspace: Search within a workspace (requires scope_id)
397- global: Search across all data (default, no scope_id needed)
398
399Examples:
400✅ {"query": "performance", "scope": "global"} (default, searches everywhere)
401✅ {"query": "auth", "scope": "session", "scope_id": "60c598e2-d602-4e07-a328-c458006d48c7"} (search specific session)
402✅ {"query": "API", "scope": "workspace", "scope_id": "f1d2e3a4-b5c6-7d8e-9f0a-1b2c3d4e5f6f"} (search specific workspace)
403
404Note: scope must be lowercase. When using 'session' or 'workspace', you must provide scope_id."#
405 )]
406 pub scope: Option<String>,
407 #[schemars(
409 description = r#"Session ID or Workspace ID (required when scope is 'session' or 'workspace').
410
411Format: 36-char UUID string (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
412
413When to use:
414- Required when scope='session' (provide session UUID)
415- Required when scope='workspace' (provide workspace UUID)
416- Ignored when scope='global' or not specified
417
418Examples:
419✅ {"scope": "session", "scope_id": "60c598e2-d602-4e07-a328-c458006d48c7"} (correct)
420❌ {"scope": "session"} (missing scope_id - will error)
421❌ {"scope": "global", "scope_id": "..."} (scope_id ignored for global)
422
423Note: Must be a valid UUID string. Use 'session' or 'semantic_search' tools to find UUIDs."#
424 )]
425 pub scope_id: Option<String>,
426 #[schemars(
428 description = r#"Maximum number of results to return (default: 10, max: 100).
429
430Examples:
431- 5: Return top 5 most relevant results
432- 20: Return top 20 results
433- null or omit: Use default of 10
434
435Note: Higher values may slow down search. Maximum allowed is 100."#
436 )]
437 pub limit: Option<usize>,
438 #[schemars(
440 description = r#"Filter results from this date onwards (ISO 8601 format).
441
442Format: YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ
443
444Examples:
445- "2025-01-01": Results from January 1st, 2025 onwards
446- "2025-01-15T10:00:00Z": Results from January 15th, 2025 at 10am UTC onwards
447
448Note: Use with date_to to specify a date range."#
449 )]
450 pub date_from: Option<String>,
451 #[schemars(description = r#"Filter results up to this date (ISO 8601 format).
453
454Format: YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ
455
456Examples:
457- "2025-01-31": Results up to January 31st, 2025
458- "2025-01-15T10:00:00Z": Results up to January 15th, 2025 at 10am UTC
459
460Note: Use with date_from to specify a date range."#)]
461 pub date_to: Option<String>,
462 #[schemars(description = r#"Filter by interaction types (array of strings).
464
465Valid types:
466- qa: Questions and answers
467- decision_made: Architectural decisions
468- problem_solved: Bug fixes and solutions
469- code_change: Code modifications
470- requirement_added: New requirements
471- concept_defined: Technical concepts
472
473Examples:
474- ["decision_made"]: Only show decisions
475- ["decision_made", "problem_solved"]: Show decisions and solutions
476- null or omit: Show all interaction types
477
478Note: Must be exact lowercase values. Filters reduce results to only these types."#)]
479 pub interaction_type: Option<Vec<String>>,
480 #[schemars(
482 description = r#"Temporal decay factor to prioritize recent content (default: 0.0 = disabled).
483
484Valid values:
485- 0.0: Disabled - pure relevance ranking (default, backward compatible)
486- 0.1 - 0.5: Soft bias toward recent content
487- 0.5 - 1.0: Moderate bias toward recent content
488- 1.0+: Aggressive bias toward recent content
489
490How it works:
491- Uses exponential decay: score × e^(-λ × days/365)
492- Older content gets progressively lower scores
493- Fresh content (1 day) retains ~99.9% score at λ=0.5
494- Year-old content retains ~60.6% score at λ=0.5, ~36.8% at λ=1.0
495
496When to use:
497- Debugging recent issues: 0.5 - 1.0
498- Finding latest solutions: 0.3 - 0.7
499- Architecture docs (timeless): 0.0 or omit
500- Current context: 1.0+
501
502Examples:
503✅ {"query": "timeout error", "recency_bias": 0.5} (recent bugs prioritized)
504✅ {"query": "authentication", "recency_bias": 0.0} (all docs equal)
505✅ {"query": "performance", "recency_bias": 1.0} (very recent)
506
507Note: Only affects ranking order, doesn't filter out old results."#
508 )]
509 pub recency_bias: Option<f32>,
510}
511
512#[derive(Deserialize, JsonSchema, Debug)]
518pub struct GetStructuredSummaryRequest {
519 #[schemars(description = "Session ID")]
521 pub session_id: String,
522 #[schemars(
524 description = "Sections to include: decisions, insights, entities, all (default: all)"
525 )]
526 pub include: Option<Vec<String>>,
527 #[schemars(description = "Maximum decisions to include")]
529 pub decisions_limit: Option<usize>,
530 #[schemars(description = "Maximum entities to include")]
532 pub entities_limit: Option<usize>,
533 #[schemars(description = "Maximum questions to include")]
535 pub questions_limit: Option<usize>,
536 #[schemars(description = "Maximum concepts to include")]
538 pub concepts_limit: Option<usize>,
539 #[schemars(description = "Minimum confidence level")]
541 pub min_confidence: Option<f32>,
542 #[schemars(description = "Use compact format for large sessions")]
544 pub compact: Option<bool>,
545}
546
547#[derive(Deserialize, JsonSchema, Debug)]
553pub struct QueryConversationContextRequest {
554 #[schemars(description = "Session ID")]
556 pub session_id: String,
557 #[schemars(
559 description = "Query type. Supported: find_related_entities, get_entity_context, search_updates, entity_importance, entity_network, find_related_content (topic, max_results), key_decisions, key_insights (limit), session_statistics, structured_summary, decisions, open_questions, related_entities, all_entities, trace_relationships, get_most_important_entities, get_recently_mentioned_entities, analyze_entity_importance, find_entities_by_type, assemble_context, recent_changes, code_references."
560 )]
561 pub query_type: String,
562 #[schemars(description = "Query parameters as key-value pairs")]
564 pub parameters: std::collections::HashMap<String, String>,
565}
566
567#[derive(Deserialize, JsonSchema, Debug)]
573pub struct ManageWorkspaceRequest {
574 #[schemars(description = r#"Action to perform on workspaces.
576
577Valid values:
578- create: Create a new workspace (requires name and description)
579- list: List all workspaces
580- get: Get workspace details (requires workspace_id)
581- delete: Delete a workspace (requires workspace_id)
582- add_session: Add a session to workspace (requires workspace_id, session_id, optional role)
583- remove_session: Remove a session from workspace (requires workspace_id, session_id)
584
585Examples:
586✅ {"action": "create", "name": "Auth Feature", "description": "OAuth2 work"}
587✅ {"action": "get", "workspace_id": "f1d2e3a4-..."}
588✅ {"action": "add_session", "workspace_id": "...", "session_id": "...", "role": "primary"}
589
590Note: Must be lowercase. Different actions require different parameters."#)]
591 pub action: String,
592 #[schemars(
594 description = r#"Workspace ID (36-char UUID) for get/delete/add_session/remove_session actions.
595
596Format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
597
598When to use:
599- Required for: get, delete, add_session, remove_session
600- Not used for: create, list
601
602How to get:
603- Use manage_workspace with action='list' to see all workspaces
604- Use semantic_search to find workspaces by name
605
606Example: "f1d2e3a4-b5c6-7d8e-9f0a-1b2c3d4e5f6f"
607
608Note: Must be a valid UUID string. Not a number."#
609 )]
610 pub workspace_id: Option<String>,
611 #[schemars(
613 description = r#"Session ID (36-char UUID) for add_session/remove_session actions.
614
615Format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
616
617When to use:
618- Required for: add_session, remove_session
619- Not used for: create, list, get, delete
620
621How to get:
622- Use session tool with action='list' to see all sessions
623- Use semantic_search to find sessions
624
625Example: "60c598e2-d602-4e07-a328-c458006d48c7"
626
627Note: Must be a valid UUID string. Not a number."#
628 )]
629 pub session_id: Option<String>,
630 #[schemars(description = r#"Workspace name (for create action).
632
633Example: "Authentication Feature" or "API Design"
634
635Note: Only used when action='create'. Helps identify the workspace."#)]
636 pub name: Option<String>,
637 #[schemars(description = r#"Workspace description (for create action).
639
640Example: "Working on OAuth2 authentication and user management"
641
642Note: Only used when action='create'. Provides context for the workspace."#)]
643 pub description: Option<String>,
644 #[schemars(
646 description = r#"Session role in workspace (for add_session action, default: 'related').
647
648Valid values:
649- primary: Main session for this workspace
650- related: Related context session
651- dependency: Required dependency session
652- shared: Shared reference session
653
654Examples:
655✅ {"action": "add_session", "workspace_id": "...", "session_id": "...", "role": "primary"}
656✅ {"action": "add_session", "workspace_id": "...", "session_id": "...", "role": "related"}
657✅ {"action": "add_session", "workspace_id": "...", "session_id": "..."} (defaults to "related")
658
659Note: Only used when action='add_session'. Defaults to 'related' if omitted."#
660 )]
661 pub role: Option<String>,
662}