1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
//! Agent opaque object: wraps `blazen_uniffi::agent::Agent` for the C ABI.
//!
//! Phase R3 Agent D.
//!
//! ## Ownership conventions
//!
//! - The constructor (`Agent::new` in `blazen-uniffi`) takes a `ToolHandler`
//! foreign callback, which depends on the Phase R5 trampoline. The cabi
//! surface therefore does **not** expose `blazen_agent_new` yet — only the
//! `run` / `run_blocking` entry points are wired here. See the deferred-
//! surface note at the bottom of this file.
//! - The `*_blocking` and future-returning `_run` wrappers both produce
//! caller-owned values. `_blocking` writes a `*mut BlazenAgentResult` into
//! `out_result`; the future variant hands the result through
//! [`blazen_future_take_agent_result`].
//! - Errors flow through `*mut *mut BlazenError` out-params on fallible
//! sync wrappers; the future-returning variant funnels errors through
//! `blazen_future_take_agent_result`'s `err` out-param.
//! - [`blazen_agent_free`] releases the opaque handle; the inner `Arc` ref
//! is dropped (the agent's model and tool definitions live behind shared
//! refs, so freeing the handle doesn't necessarily tear those down).
use c_char;
use Arc;
use ;
use BlazenError as InnerError;
use crateBlazenAgentResult;
use crateBlazenError;
use crateBlazenFuture;
use crateruntime;
use cratecstr_to_str;
// ---------------------------------------------------------------------------
// Shared error-out helpers
// ---------------------------------------------------------------------------
/// Writes `e` to the out-param if non-null and returns `-1`. Mirrors the
/// helper in `workflow.rs` so per-method bodies stay focused on the happy
/// path.
///
/// # Safety
///
/// `out_err` must be null OR a valid destination for a single
/// `*mut BlazenError` write (typically a caller's stack-local
/// `*mut BlazenError` initialised to null).
unsafe
/// Writes a synthesised `Internal` error to the out-param and returns `-1`.
/// Used for null-pointer / UTF-8 input failures where there isn't an
/// originating `InnerError`.
///
/// # Safety
///
/// Same contract as [`write_error`]: `out_err` is null OR points at a single
/// writable `*mut BlazenError` slot.
unsafe
// ---------------------------------------------------------------------------
// BlazenAgent
// ---------------------------------------------------------------------------
/// Opaque wrapper around `blazen_uniffi::agent::Agent`.
///
/// The inner `Arc` matches the `self: Arc<Self>` shape of the underlying
/// async methods — each C entry point clones the ref so the spawned task
/// can keep the agent alive for the duration of the run without the cabi
/// handle being pinned to the foreign caller's call stack.
);
/// Synchronously runs the agent loop with `user_input` as the initial user
/// message. Blocks the calling thread on the cabi tokio runtime. Returns `0`
/// on success (writing a caller-owned `*mut BlazenAgentResult` to
/// `out_result`) or `-1` on failure (writing the inner error to `out_err`).
///
/// # Safety
///
/// `agent` must be a valid pointer to a `BlazenAgent` previously produced by
/// the cabi surface. `user_input` must be a valid NUL-terminated UTF-8
/// buffer that remains live for the duration of the call. `out_result` is
/// null OR a valid destination for one `*mut BlazenAgentResult` write.
/// `out_err` is null OR a valid destination for one `*mut BlazenError`
/// write.
pub unsafe extern "C"
/// Runs the agent loop asynchronously, returning an opaque future handle
/// immediately. The caller waits via `blazen_future_wait` / `blazen_future_fd`
/// / `blazen_future_poll`, then takes the result via
/// [`blazen_future_take_agent_result`].
///
/// Returns null if `agent` or `user_input` is null, or if `user_input` is
/// not valid UTF-8. Errors that surface during the async run are delivered
/// through `blazen_future_take_agent_result`'s `err` out-param.
///
/// # Safety
///
/// `agent` must be a valid pointer to a `BlazenAgent` previously produced by
/// the cabi surface. `user_input` must be a valid NUL-terminated UTF-8
/// buffer that remains valid for the duration of this call (the buffer is
/// copied before this function returns).
pub unsafe extern "C"
/// Frees a `BlazenAgent` handle previously produced by the cabi surface
/// (Phase R5 constructor wrapper). No-op on a null pointer.
///
/// # Safety
///
/// `agent` must be null OR a pointer previously produced by the cabi
/// surface as a `BlazenAgent`. Calling this twice on the same non-null
/// pointer is a double-free.
pub unsafe extern "C"
// ---------------------------------------------------------------------------
// Typed future-take for AgentResult
// ---------------------------------------------------------------------------
/// Pops the `AgentResult` out of a future produced by [`blazen_agent_run`].
/// Returns `0` on success or `-1` on error.
///
/// On success, `out` receives a caller-owned `*mut BlazenAgentResult` (free
/// with [`crate::agent_records::blazen_agent_result_free`]). On error, `err`
/// receives a caller-owned `*mut BlazenError` (free with
/// [`crate::error::blazen_error_free`]).
///
/// # Safety
///
/// All three pointers must follow the cabi-future contract: `fut` is a live
/// future produced by [`blazen_agent_run`], observed completed via
/// `blazen_future_poll` / `_wait` / `_fd`. `out` and `err` are valid
/// destinations for a single `*mut` write (typically stack `*mut BlazenX`
/// locals — can be null to discard).
pub unsafe extern "C"
// ---------------------------------------------------------------------------
// Deferred surface
// ---------------------------------------------------------------------------
// `blazen_agent_new` is intentionally **not** exposed in Phase R3. Building
// an `Agent` requires a foreign-language `ToolHandler` trampoline — a
// callback that the Rust agent loop can invoke from arbitrary tokio worker
// threads, with the foreign-language method returning a JSON-encoded tool
// result string. That trampoline lands in Phase R5 alongside the
// `blazen_workflow_builder_step` bridge; until then, the cabi surface is
// run-only against agents constructed via UniFFI or future R5 wiring.