assay_core/explain_next/
model.rs1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct ExplainedStep {
7 pub index: usize,
8 pub tool: String,
9
10 #[serde(default, skip_serializing_if = "Option::is_none")]
12 pub args: Option<serde_json::Value>,
13
14 pub verdict: StepVerdict,
16
17 pub rules_evaluated: Vec<RuleEvaluation>,
19
20 #[serde(default, skip_serializing_if = "HashMap::is_empty")]
22 pub state_snapshot: HashMap<String, String>,
23}
24
25#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
26#[serde(rename_all = "lowercase")]
27pub enum StepVerdict {
28 Allowed,
30 Blocked,
32 Warning,
34}
35
36#[derive(Debug, Clone, Serialize, Deserialize)]
37pub struct RuleEvaluation {
38 pub rule_id: String,
39 pub rule_type: String,
40 pub passed: bool,
41 pub explanation: String,
42
43 #[serde(default, skip_serializing_if = "Option::is_none")]
44 pub context: Option<serde_json::Value>,
45}
46
47#[derive(Debug, Clone, Serialize, Deserialize)]
49pub struct TraceExplanation {
50 pub policy_name: String,
51 pub policy_version: String,
52 pub total_steps: usize,
53 pub allowed_steps: usize,
54 pub blocked_steps: usize,
55
56 #[serde(skip_serializing_if = "Option::is_none")]
57 pub first_block_index: Option<usize>,
58
59 pub steps: Vec<ExplainedStep>,
61
62 pub blocking_rules: Vec<String>,
64}
65
66#[derive(Debug, Clone, Deserialize)]
68pub struct ToolCall {
69 #[serde(alias = "name", alias = "tool_name")]
71 pub tool: String,
72
73 #[serde(default)]
75 pub args: Option<serde_json::Value>,
76}