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