返回 CodeWhale
portable_projection.rs
根目录 / crates / tui / src / tool_inspection / portable_projection.rs
1 //! Value-only projection owned by the authoritative source module.
2 //! No command, App or rendering operation is reachable from these conversions.
3
4 use codewhale_command_contract::facets::*;
5
6 fn bounded(value: &crate::tool_inspection::BoundedString) -> DebugBoundedString {
7 DebugBoundedString {
8 value: value.value.clone(),
9 truncated: value.truncated,
10 }
11 }
12
13 fn evidence<T, U>(
14 value: &crate::tool_inspection::Evidence<T>,
15 convert: impl Fn(&T) -> U,
16 ) -> DebugEvidence<U> {
17 match value {
18 crate::tool_inspection::Evidence::Known { value } => DebugEvidence::Known {
19 value: convert(value),
20 },
21 crate::tool_inspection::Evidence::Unknown { reason } => DebugEvidence::Unknown {
22 reason: reason.clone(),
23 },
24 }
25 }
26
27 fn bounded_list(value: &crate::tool_inspection::BoundedList) -> DebugBoundedList {
28 DebugBoundedList {
29 count: value.count,
30 rendered: value.rendered.iter().map(bounded).collect(),
31 omitted: value.omitted,
32 }
33 }
34
35 pub(crate) fn tool_snapshot(
36 value: &crate::tool_inspection::ToolInspectionSnapshot,
37 ) -> DebugToolSnapshot {
38 use crate::tool_inspection::{
39 ProviderAvailability as P, ToolProvenance as R, ToolVisibility as V, TurnStopReason as S,
40 };
41 DebugToolSnapshot {
42 schema_version: value.schema_version,
43 capture_source: value.capture_source.to_string(),
44 delivery_status: value.delivery_status.to_string(),
45 turn_id: bounded(&value.turn_id),
46 step: value.step,
47 terminal: value
48 .terminal
49 .as_ref()
50 .map(|terminal| DebugTurnStopDiagnostics {
51 status: terminal.status.map(|status| match status {
52 crate::core::events::TurnOutcomeStatus::Completed => {
53 DebugTurnOutcomeStatus::Completed
54 }
55 crate::core::events::TurnOutcomeStatus::Interrupted => {
56 DebugTurnOutcomeStatus::Interrupted
57 }
58 crate::core::events::TurnOutcomeStatus::Failed => {
59 DebugTurnOutcomeStatus::Failed
60 }
61 }),
62 reason: terminal.reason.map(|reason| match reason {
63 S::ProviderNoToolCall => DebugTurnStopReason::ProviderNoToolCall,
64 S::ProviderToolCallMissing => DebugTurnStopReason::ProviderToolCallMissing,
65 S::StepBudgetExhausted => DebugTurnStopReason::StepBudgetExhausted,
66 S::NoProgress => DebugTurnStopReason::NoProgress,
67 S::Interrupted => DebugTurnStopReason::Interrupted,
68 S::Failed => DebugTurnStopReason::Failed,
69 }),
70 effective_max_steps: terminal.effective_max_steps,
71 step_budget_source: terminal.step_budget_source.to_string(),
72 model_step_index: terminal.model_step_index,
73 model_requests_started: terminal.model_requests_started,
74 transport_retries: terminal.transport_retries,
75 transparent_stream_retries: terminal.transparent_stream_retries,
76 stream_resumes: terminal.stream_resumes,
77 reasoning_only_reprompts: terminal.reasoning_only_reprompts,
78 empty_stop_retries: terminal.empty_stop_retries,
79 soft_landing_sent: terminal.soft_landing_sent,
80 final_report_requested: terminal.final_report_requested,
81 permission_strategy_switches: terminal.permission_strategy_switches,
82 permission_denial_rounds_without_progress: terminal
83 .permission_denial_rounds_without_progress,
84 last_provider_finish_reason: terminal
85 .last_provider_finish_reason
86 .as_ref()
87 .map(bounded),
88 last_response_tool_calls: terminal.last_response_tool_calls,
89 last_response_tool_calls_suppressed: terminal.last_response_tool_calls_suppressed,
90 last_reported_input_tokens: terminal.last_reported_input_tokens,
91 route_context_window_tokens: terminal.route_context_window_tokens,
92 last_prepared_output_limit_tokens: terminal.last_prepared_output_limit_tokens,
93 automatic_compaction_attempts: terminal.automatic_compaction_attempts,
94 emergency_compaction_attempts: terminal.emergency_compaction_attempts,
95 }),
96 tools_field_present: value.tools_field_present,
97 tool_count: value.tool_count,
98 rendered_tool_count: value.rendered_tool_count,
99 omitted_tool_count: value.omitted_tool_count,
100 payload_json_bytes: value.payload_json_bytes,
101 payload_measurement_status: value.payload_measurement_status.clone(),
102 active_tool_catalog_sha256: value.active_tool_catalog_sha256.clone(),
103 unavailable_for_this_request: value
104 .unavailable_for_this_request
105 .iter()
106 .map(|item| (*item).to_string())
107 .collect(),
108 provider: match &value.provider {
109 P::Unknown => DebugProviderAvailability::Unknown,
110 P::Available { provider, model } => DebugProviderAvailability::Available {
111 provider: provider.clone(),
112 model: model.clone(),
113 },
114 P::Unavailable { reason } => DebugProviderAvailability::Unavailable {
115 reason: reason.clone(),
116 },
117 },
118 registry_facts_present: value.registry_facts_present,
119 registry_tool_count: evidence(&value.registry_tool_count, |count| *count),
120 registry_only_tools: evidence(&value.registry_only_tools, bounded_list),
121 tools: value
122 .tools
123 .iter()
124 .map(|tool| DebugToolProjection {
125 ordinal: tool.ordinal,
126 name: bounded(&tool.name),
127 tool_type: evidence(&tool.tool_type, bounded),
128 description: bounded(&tool.description),
129 input_schema_json: bounded(&tool.input_schema_json),
130 allowed_callers: evidence(&tool.allowed_callers, bounded_list),
131 defer_loading: evidence(&tool.defer_loading, |flag| *flag),
132 input_examples: evidence(&tool.input_examples, |count| DebugCountOnly {
133 count: count.count,
134 values: count.values.to_string(),
135 }),
136 strict: evidence(&tool.strict, |flag| *flag),
137 cache_control_type: evidence(&tool.cache_control_type, bounded),
138 provenance: evidence(&tool.provenance, |origin| match origin {
139 R::Builtin => DebugToolProvenance::Builtin,
140 R::Plugin => DebugToolProvenance::Plugin,
141 R::Mcp => DebugToolProvenance::Mcp,
142 R::Synthetic => DebugToolProvenance::Synthetic,
143 R::Unknown => DebugToolProvenance::Unknown,
144 }),
145 mcp_server: evidence(&tool.mcp_server, bounded),
146 capabilities: evidence(&tool.capabilities, bounded_list),
147 approval: evidence(&tool.approval, bounded),
148 model_visible: evidence(&tool.model_visible, |flag| *flag),
149 visibility: match tool.visibility {
150 V::Active => DebugToolVisibility::Active,
151 V::Deferred => DebugToolVisibility::Deferred,
152 V::InRequest => DebugToolVisibility::InRequest,
153 },
154 })
155 .collect(),
156 }
157 }
158
158 lines RUST