semantic_memory_forge/
tool_receipt.rs1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4use stack_ids::{AttemptId, ContentDigest, TraceCtx, TrialId};
5
6pub const FORGE_TOOL_RECEIPT_V1_SCHEMA: &str = "forge_tool_receipt_v1";
7pub const FORGE_TOOL_RECEIPT_V2_SCHEMA: &str = "forge_tool_receipt_v2";
8
9#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
10pub struct ForgeToolReceiptV1 {
11 pub schema_version: String,
12 pub receipt_id: String,
13 pub tool_run_id: String,
14 pub tool_name: String,
15 pub tool_version: String,
16 pub backend_kind: String,
17 pub input_digest: ContentDigest,
18 pub output_digest_or_refs: Value,
19 pub policy_hash: ContentDigest,
20 pub approval_state: String,
21 pub host_identity: String,
22 pub started_at: String,
23 pub finished_at: String,
24 pub trace_ctx: TraceCtx,
25 pub attempt_id: AttemptId,
26 pub trial_id: TrialId,
27 #[serde(default, skip_serializing_if = "Option::is_none")]
28 pub error_class: Option<String>,
29 pub retry_owner: String,
30 #[serde(default, skip_serializing_if = "Option::is_none")]
31 pub replay_link: Option<String>,
32 #[serde(default, skip_serializing_if = "Option::is_none")]
33 pub provider_call_id: Option<String>,
34 pub raw_payload: Value,
35}
36
37#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
38pub struct ForgeToolBudgetContext {
39 #[serde(default, skip_serializing_if = "Option::is_none")]
40 pub budget_kind: Option<String>,
41 #[serde(default, skip_serializing_if = "Option::is_none")]
42 pub max_steps: Option<u32>,
43 #[serde(default, skip_serializing_if = "Option::is_none")]
44 pub time_budget_ms: Option<u64>,
45 #[serde(default, skip_serializing_if = "Option::is_none")]
46 pub cost_budget_units: Option<u64>,
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
50pub struct ForgeToolReceiptV2 {
51 pub schema_version: String,
52 pub receipt_id: String,
53 pub tool_run_id: String,
54 pub tool_name: String,
55 pub tool_version: String,
56 pub backend_kind: String,
57 pub input_digest: ContentDigest,
58 pub output_digest_or_refs: Value,
59 pub policy_hash: ContentDigest,
60 pub approval_state: String,
61 pub host_identity: String,
62 pub started_at: String,
63 pub finished_at: String,
64 pub trace_ctx: TraceCtx,
65 pub attempt_id: AttemptId,
66 pub trial_id: TrialId,
67 pub planner_stage: String,
68 #[serde(default, skip_serializing_if = "Option::is_none")]
69 pub deadline: Option<String>,
70 #[serde(default, skip_serializing_if = "Option::is_none")]
71 pub workload_class: Option<String>,
72 #[serde(default, skip_serializing_if = "Option::is_none")]
73 pub budget_context: Option<ForgeToolBudgetContext>,
74 #[serde(default, skip_serializing_if = "Option::is_none")]
75 pub parent_receipt_id: Option<String>,
76 #[serde(default, skip_serializing_if = "Option::is_none")]
77 pub family_receipt_id: Option<String>,
78 #[serde(default, skip_serializing_if = "Option::is_none")]
79 pub replay_parent_receipt_id: Option<String>,
80 #[serde(default, skip_serializing_if = "Option::is_none")]
81 pub error_class: Option<String>,
82 pub retry_owner: String,
83 #[serde(default, skip_serializing_if = "Option::is_none")]
84 pub replay_link: Option<String>,
85 #[serde(default, skip_serializing_if = "Option::is_none")]
86 pub provider_call_id: Option<String>,
87 pub raw_payload: Value,
88}