agent_sdk_core/records/tool_pack.rs
1//! Durable and observable SDK records. Use these DTOs for events, journals, effects,
2//! context, output, and feature evidence. Constructing records is data-only;
3//! persistence, publication, and external actions happen through ports or application
4//! coordinators. This file contains the tool pack portion of that contract.
5//!
6use serde::{Deserialize, Serialize};
7
8use crate::{
9 domain::{ContentRef, DestinationRef, EffectId, EntityRef, PolicyRef, SourceRef},
10 effect::EffectKind,
11 package::tool_pack::ToolPackId,
12 tool_records::CanonicalToolName,
13};
14
15#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
16/// Carries the tool pack effect lineage record payload for journal, event, or fixture surfaces.
17/// Creating or cloning it only preserves serialized SDK state; append, publish, replay, or export effects are documented on the runtime and port methods that store it.
18pub struct ToolPackEffectLineage {
19 /// Stable pack id used for typed lineage, lookup, or dedupe.
20 pub pack_id: ToolPackId,
21 /// Tool name used by this record or request.
22 pub tool_name: CanonicalToolName,
23 /// Stable effect id used for typed lineage, lookup, or dedupe.
24 pub effect_id: EffectId,
25 /// Kind discriminator for effect kind.
26 /// Use it to route finite match arms without parsing display text.
27 pub effect_kind: EffectKind,
28 /// Typed subject ref reference. Resolving or executing it is a separate
29 /// policy-gated step.
30 pub subject_ref: EntityRef,
31 /// Source label or ref for this item; it is metadata and does not fetch
32 /// content by itself.
33 pub source: SourceRef,
34 /// Destination label or ref for this item; it is metadata and does not
35 /// deliver content by itself.
36 pub destination: DestinationRef,
37 /// Policy references that govern admission, projection, execution, or
38 /// delivery.
39 pub policy_refs: Vec<PolicyRef>,
40 #[serde(default, skip_serializing_if = "Vec::is_empty")]
41 /// Content references associated with this record; resolving them is a
42 /// separate policy-gated step.
43 pub content_refs: Vec<ContentRef>,
44 #[serde(skip_serializing_if = "Option::is_none")]
45 /// Optional mutation value.
46 /// When absent, callers should use the documented default or skip that optional behavior.
47 pub mutation: Option<WorkspaceMutationLineage>,
48 /// Redacted human-readable summary safe for events, telemetry, and logs.
49 pub redacted_summary: String,
50}
51
52impl ToolPackEffectLineage {
53 /// Returns whether inverse candidate is advisory applies for this contract.
54 /// This is data-only and does not perform I/O, call host ports, append journals, publish
55 /// events, or start processes.
56 pub fn inverse_candidate_is_advisory(&self) -> bool {
57 self.mutation
58 .as_ref()
59 .and_then(|mutation| mutation.inverse_candidate_ref.as_ref())
60 .is_some()
61 }
62}
63
64#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
65/// Carries the workspace mutation lineage record payload for journal, event, or fixture surfaces.
66/// Creating or cloning it only preserves serialized SDK state; append, publish, replay, or export effects are documented on the runtime and port methods that store it.
67pub struct WorkspaceMutationLineage {
68 /// Workspace-relative or resource path selected by the request or result.
69 pub path: String,
70 #[serde(skip_serializing_if = "Option::is_none")]
71 /// Deterministic before hash used for stale checks, package evidence, or
72 /// replay comparisons.
73 pub before_hash: Option<String>,
74 #[serde(skip_serializing_if = "Option::is_none")]
75 /// Deterministic after hash used for stale checks, package evidence, or
76 /// replay comparisons.
77 pub after_hash: Option<String>,
78 #[serde(skip_serializing_if = "Option::is_none")]
79 /// Typed diff ref reference. Resolving or executing it is a separate
80 /// policy-gated step.
81 pub diff_ref: Option<ContentRef>,
82 #[serde(skip_serializing_if = "Option::is_none")]
83 /// Typed inverse candidate ref reference. Resolving or executing it is a
84 /// separate policy-gated step.
85 pub inverse_candidate_ref: Option<ContentRef>,
86 #[serde(skip_serializing_if = "Option::is_none")]
87 /// Optional non reversible reason value.
88 /// When absent, callers should use the documented default or skip that optional behavior.
89 pub non_reversible_reason: Option<String>,
90}
91
92#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
93/// Carries the workspace read lineage record payload for journal, event, or fixture surfaces.
94/// Creating or cloning it only preserves serialized SDK state; append, publish, replay, or export effects are documented on the runtime and port methods that store it.
95pub struct WorkspaceReadLineage {
96 /// Workspace-relative or resource path selected by the request or result.
97 pub path: String,
98 /// Stable hash for the bytes or canonical payload used for stale checks
99 /// and fingerprints.
100 pub content_hash: String,
101 /// Observed byte length for the source, sidecar, or extracted record.
102 pub byte_len: u64,
103 /// Whether output was shortened by byte, item, page, archive, or parser
104 /// limits.
105 pub truncated: bool,
106 /// Detected or declared MIME type used for reader selection and
107 /// provider-safe summaries.
108 pub mime_type: String,
109 /// Typed anchors ref reference. Resolving or executing it is a separate
110 /// policy-gated step.
111 pub anchors_ref: ContentRef,
112}
113
114#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
115/// Carries the shell process lineage record payload for journal, event, or fixture surfaces.
116/// Creating or cloning it only preserves serialized SDK state; append, publish, replay, or export effects are documented on the runtime and port methods that store it.
117pub struct ShellProcessLineage {
118 /// Redacted summary for display, logs, events, or telemetry.
119 /// It should describe the value without exposing raw private content.
120 pub argv_summary: String,
121 /// Typed sandbox policy ref reference. Resolving or executing it is a
122 /// separate policy-gated step.
123 pub sandbox_policy_ref: PolicyRef,
124 /// Timeout budget in milliseconds for the requested operation.
125 pub timeout_ms: u64,
126 /// Whether the SDK/tooling owns the launched process lifecycle for
127 /// cancellation and cleanup evidence.
128 pub agent_owned: bool,
129 /// Whether detach requested is enabled.
130 /// Policy, validation, or routing code uses this flag to choose the explicit behavior.
131 pub detach_requested: bool,
132}
133
134#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
135/// Carries the tool discovery lineage record payload for journal, event, or fixture surfaces.
136/// Creating or cloning it only preserves serialized SDK state; append, publish, replay, or export effects are documented on the runtime and port methods that store it.
137pub struct ToolDiscoveryLineage {
138 /// Stable discovery index id used for typed lineage, lookup, or dedupe.
139 pub discovery_index_id: String,
140 /// Search query supplied by the caller.
141 pub query: String,
142 /// Collection of returned candidates values.
143 /// Ordering and membership should be treated as part of the serialized contract when
144 /// relevant.
145 pub returned_candidates: Vec<String>,
146 /// Whether activation must be applied as a package delta before use.
147 pub package_delta_required: bool,
148}