| 1 | //! Semantic prompt-context shapes for the debug diagnostics slice. |
| 2 | //! |
| 3 | //! No prompt builder or formatter belongs in this module. The TUI host |
| 4 | //! constructs these values from its authoritative report builders; a shared |
| 5 | //! portable renderer consumes them, including from non-command callers. |
| 6 | |
| 7 | use serde::Serialize; |
| 8 | use serde_json::Value; |
| 9 | |
| 10 | #[derive(Debug, Clone, PartialEq, Serialize)] |
| 11 | pub struct DebugPromptSourceMap { |
| 12 | pub entries: Vec<DebugSourceEntry>, |
| 13 | pub total_estimated_tokens: usize, |
| 14 | pub active_context_estimated_tokens: usize, |
| 15 | pub overflow_guard_estimated_tokens: Option<usize>, |
| 16 | pub context_window_tokens: Option<u32>, |
| 17 | pub context_window_source: Option<String>, |
| 18 | pub budget_used_percent: Option<f64>, |
| 19 | /// Host-owned pressure policy result; intentionally absent from the public JSON. |
| 20 | #[serde(skip)] |
| 21 | pub pressure_label: String, |
| 22 | /// Verified provenance from the host route ladder; not a public JSON field. |
| 23 | #[serde(skip)] |
| 24 | pub context_window_verified: bool, |
| 25 | pub generated_at: String, |
| 26 | pub note: String, |
| 27 | } |
| 28 | |
| 29 | #[derive(Debug, Clone, PartialEq, Serialize)] |
| 30 | pub struct DebugSourceEntry { |
| 31 | pub source_kind: DebugSourceKind, |
| 32 | pub label: String, |
| 33 | pub source_path: Option<String>, |
| 34 | pub activation_reason: DebugActivationReason, |
| 35 | pub estimated_tokens: usize, |
| 36 | pub counting_confidence: DebugCountingConfidence, |
| 37 | pub authority_tier: Option<u8>, |
| 38 | pub truncation_reason: Option<String>, |
| 39 | } |
| 40 | |
| 41 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)] |
| 42 | #[serde(rename_all = "snake_case")] |
| 43 | pub enum DebugSourceKind { |
| 44 | Constitution, |
| 45 | UserConstitution, |
| 46 | RepoConstitution, |
| 47 | ProjectContext, |
| 48 | ProjectContextWarning, |
| 49 | ProjectContextPack, |
| 50 | SkillsBlock, |
| 51 | ContextManagement, |
| 52 | CompactionRelayTemplate, |
| 53 | RuntimePolicy, |
| 54 | AuthorityRecap, |
| 55 | EnvironmentBlock, |
| 56 | UserMemory, |
| 57 | SessionGoal, |
| 58 | HandoffRelay, |
| 59 | ToolSchemas, |
| 60 | UserRequest, |
| 61 | ConversationHistory, |
| 62 | ToolResult, |
| 63 | ModelProviderFact, |
| 64 | } |
| 65 | |
| 66 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)] |
| 67 | #[serde(rename_all = "snake_case")] |
| 68 | pub enum DebugActivationReason { |
| 69 | AlwaysOn, |
| 70 | FilePresent, |
| 71 | ConfigEnabled, |
| 72 | RuntimeState, |
| 73 | PerRequest, |
| 74 | Omitted, |
| 75 | } |
| 76 | |
| 77 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)] |
| 78 | #[serde(rename_all = "snake_case")] |
| 79 | pub enum DebugCountingConfidence { |
| 80 | High, |
| 81 | Approximate, |
| 82 | } |
| 83 | |
| 84 | /// The prompt-json shape retains known/unknown state and full ordered tool |
| 85 | /// fields, not an opaque pre-rendered JSON string from the host. |
| 86 | #[derive(Debug, Clone, PartialEq, Serialize)] |
| 87 | pub struct DebugPromptContext { |
| 88 | pub schema_version: u8, |
| 89 | pub provider: String, |
| 90 | pub model: String, |
| 91 | pub system_prompt_state: String, |
| 92 | pub tool_catalog_state: String, |
| 93 | pub sections: Vec<DebugPromptContextSection>, |
| 94 | pub tools: Vec<DebugPromptTool>, |
| 95 | pub source_map: DebugPromptSourceMap, |
| 96 | } |
| 97 | |
| 98 | #[derive(Debug, Clone, PartialEq, Serialize)] |
| 99 | pub struct DebugPromptContextSection { |
| 100 | pub index: usize, |
| 101 | pub block_type: String, |
| 102 | pub cache_control: Option<DebugCacheControl>, |
| 103 | pub estimated_tokens: usize, |
| 104 | pub text: String, |
| 105 | } |
| 106 | |
| 107 | #[derive(Debug, Clone, PartialEq, Eq, Serialize)] |
| 108 | pub struct DebugCacheControl { |
| 109 | #[serde(rename = "type")] |
| 110 | pub cache_type: String, |
| 111 | } |
| 112 | |
| 113 | /// Only the schema field is arbitrary structured JSON, as on the live tool |
| 114 | /// catalog. Optional transport fields retain the core Tool's omission rules. |
| 115 | #[derive(Debug, Clone, PartialEq, Serialize)] |
| 116 | pub struct DebugPromptTool { |
| 117 | #[serde(rename = "type", skip_serializing_if = "Option::is_none")] |
| 118 | pub tool_type: Option<String>, |
| 119 | pub name: String, |
| 120 | pub description: String, |
| 121 | pub input_schema: Value, |
| 122 | #[serde(skip_serializing_if = "Option::is_none")] |
| 123 | pub allowed_callers: Option<Vec<String>>, |
| 124 | #[serde(skip_serializing_if = "Option::is_none")] |
| 125 | pub defer_loading: Option<bool>, |
| 126 | #[serde(skip_serializing_if = "Option::is_none")] |
| 127 | pub input_examples: Option<Vec<Value>>, |
| 128 | #[serde(skip_serializing_if = "Option::is_none")] |
| 129 | pub strict: Option<bool>, |
| 130 | #[serde(skip_serializing_if = "Option::is_none")] |
| 131 | pub cache_control: Option<DebugCacheControl>, |
| 132 | } |
| 133 |