deepstrike_sdk/
harness.rs1use async_trait::async_trait;
2
3#[derive(Debug, Clone)]
4pub struct Criterion {
5 pub text: String,
6 pub required: bool,
7 pub weight: f32,
8 pub id: Option<String>,
10 pub machine_checkable: Option<bool>,
12}
13
14impl Criterion {
15 pub fn required(text: impl Into<String>) -> Self {
16 Self {
17 text: text.into(),
18 required: true,
19 weight: 1.0,
20 id: None,
21 machine_checkable: None,
22 }
23 }
24
25 pub fn optional(text: impl Into<String>) -> Self {
26 Self {
27 text: text.into(),
28 required: false,
29 weight: 1.0,
30 id: None,
31 machine_checkable: None,
32 }
33 }
34
35 pub fn with_weight(mut self, w: f32) -> Self {
36 self.weight = w;
37 self
38 }
39
40 pub fn with_id(mut self, id: impl Into<String>) -> Self {
42 self.id = Some(id.into());
43 self
44 }
45
46 pub fn machine_checkable(mut self, on: bool) -> Self {
48 self.machine_checkable = Some(on);
49 self
50 }
51}
52
53#[derive(Debug, Clone)]
54pub struct CriterionResult {
55 pub criterion: String,
56 pub passed: bool,
57 pub score: f32,
58 pub feedback: String,
59}
60
61#[derive(Debug, Clone)]
62pub struct HarnessRequest {
63 pub goal: String,
64 pub criteria: Vec<Criterion>,
65 pub extensions: Option<serde_json::Value>,
66}
67
68impl HarnessRequest {
69 pub fn new(goal: impl Into<String>) -> Self {
70 Self {
71 goal: goal.into(),
72 criteria: Vec::new(),
73 extensions: None,
74 }
75 }
76}
77
78#[derive(Debug, Clone)]
79pub struct HarnessOutcome {
80 pub result: String,
81 pub passed: bool,
82 pub iterations: u32,
83 pub total_tokens: u64,
84 pub status: String,
85 pub overall_score: f32,
86 pub feedback: Option<String>,
87 pub details: Vec<CriterionResult>,
88}
89
90#[derive(Debug, Clone)]
91pub struct Verdict {
92 pub passed: bool,
93 pub overall_score: f32,
94 pub feedback: String,
95 pub details: Vec<CriterionResult>,
96}
97
98#[derive(Debug, Clone)]
99pub enum HarnessEvent {
100 Token(String),
101 ToolCall {
102 id: String,
103 name: String,
104 },
105 ToolResult {
106 call_id: String,
107 content: String,
108 is_error: bool,
109 },
110 Supervising,
111 Revising {
112 verdict: Verdict,
113 },
114 Done {
115 verdict: Verdict,
116 iterations: u32,
117 total_tokens: u64,
118 status: String,
119 },
120 MaxAttemptsReached,
121}
122
123#[async_trait]
124pub trait QualityGate: Send + Sync {
125 async fn evaluate(
126 &self,
127 request: &HarnessRequest,
128 outcome: &HarnessOutcome,
129 ) -> crate::Result<bool>;
130}
131
132#[async_trait]
133pub trait Harness: Send + Sync {
134 async fn run(&self, request: HarnessRequest) -> crate::Result<HarnessOutcome>;
135}