harn-stdlib 0.10.130

Embedded Harn standard library source catalog
Documentation
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
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
pub type AgentToolLifecycleErrorCategory = "schema_validation" \
  | "tool_error" \
  | "mcp_server_error" \
  | "host_bridge_error" \
  | "permission_denied" \
  | "rejected_loop" \
  | "parse_aborted" \
  | "timeout" \
  | "network" \
  | "resource_busy" \
  | "cancelled" \
  | "abandoned_at_loop_exit" \
  | "unknown"

pub type AgentToolMutationStatus = "applied" | "unchanged" | "not_applied" | "unknown"

/**
 * Explicit handler return for tools that need machine-readable facts beside the
 * model-visible text. The dispatcher preserves `data` on `result` and renders
 * only `text`; ordinary dict returns keep their historical display rendering.
 */
pub type AgentToolHandlerResult<T> = {
  schema: "harn.agent_tool_handler_result.v1",
  text: string,
  data: T,
}

pub type AgentToolPostcondition = {
  schema: "harn.agent_tool_postcondition.v1",
  status: "passed",
  verified_paths: list<string>,
}

/**
 * Certify deterministic read-after-write postconditions for one atomic tool call.
 *
 * @effects: []
 * @errors: []
 */
pub fn agent_tool_postcondition(verified_paths: list<string>) -> AgentToolPostcondition {
  return {
    schema: "harn.agent_tool_postcondition.v1",
    status: "passed",
    verified_paths: verified_paths,
  }
}

/**
 * Pair model-visible tool feedback with typed producer facts.
 *
 * @effects: []
 * @errors: []
 */
pub fn agent_tool_handler_result<T>(text: string, data: T) -> AgentToolHandlerResult<T> {
  return {schema: "harn.agent_tool_handler_result.v1", text: text, data: data}
}

/**
 * Preserve an explicit typed handler result, or pair rendered text with producer data.
 *
 * @effects: []
 * @errors: []
 */
pub fn agent_tool_handler_result_normalize<T>(
  rendered: unknown,
  data: T,
) -> AgentToolHandlerResult<unknown> {
  if type_of(rendered) == "dict"
    && rendered?.schema == "harn.agent_tool_handler_result.v1"
    && type_of(rendered?.text) == "string" {
    return agent_tool_handler_result(rendered.text, rendered?.data)
  }
  return agent_tool_handler_result(to_string(rendered), data)
}

const TOOL_LIFECYCLE_ERROR_CATEGORIES = [
  "schema_validation",
  "tool_error",
  "mcp_server_error",
  "host_bridge_error",
  "permission_denied",
  "rejected_loop",
  "parse_aborted",
  "timeout",
  "network",
  "resource_busy",
  "cancelled",
  "abandoned_at_loop_exit",
  "unknown",
]

/**
 * Normalize VM, provider, and middleware failures to the public tool-event taxonomy.
 *
 * @effects: []
 * @errors: []
 */
pub fn agent_tool_lifecycle_error_category(raw: any) -> AgentToolLifecycleErrorCategory? {
  if raw == nil {
    return nil
  }
  const category = to_string(raw)
  if category == "" {
    return nil
  }
  if contains(TOOL_LIFECYCLE_ERROR_CATEGORIES, category) {
    return category
  }
  if contains(
    [
      "intra_turn_failure_fanout_collapsed",
      "intra_turn_resource_fail_fast",
      "tool_batch_deferred",
      "tool_batch_blocked",
    ],
    category,
  ) {
    return "rejected_loop"
  }
  if contains(["tool_rejected", "consent_denied", "egress_blocked", "scope_violation"], category) {
    return "permission_denied"
  }
  if contains(
    [
      "schema_violation",
      "schema_stream_aborted",
      "validator_failure",
      "repair_failed",
      "invalid_arguments",
    ],
    category,
  ) {
    return "schema_validation"
  }
  if contains(["rate_limit", "overloaded", "server_error", "transient_network"], category) {
    return "network"
  }
  if contains(
    ["tool_middleware_exception", "tool_parallel_dispatch_exception", "generic"],
    category,
  ) {
    return "tool_error"
  }
  if contains(
    ["auth", "channel_closed", "not_found", "circuit_open", "budget_exceeded"],
    category,
  ) {
    return "host_bridge_error"
  }
  return "unknown"
}

/**
 * Normalize execution-boundary mutation evidence without inspecting rendered output.
 *
 * @effects: []
 * @errors: []
 */
pub fn agent_tool_mutation_status(raw: any) -> AgentToolMutationStatus {
  if raw == nil {
    return "unknown"
  }
  const status = to_string(raw)
  if contains(["applied", "unchanged", "not_applied", "unknown"], status) {
    return status
  }
  return "unknown"
}

pub type AgentToolResultOutcomeKind = "ok" | "error" | "unknown"

pub type AgentEditOutcomeStatus = "none" \
  | "rejected_not_applied" \
  | "applied_clean" \
  | "applied_still_failing" \
  | "unknown"

/**
 * A tool result classified from its STRUCTURED envelope alone.
 *
 * - `kind`: transport/product disposition (`ok`, `error`, or `unknown` when no
 *   structured field decided it).
 * - `error_category`: the typed failure taxonomy, resolved from a producer's
 *   `error_category` or the raw `error` code; `nil` when the result is not an
 *   error.
 * - `product_error`: a host/product-level rejection carried on a
 *   transport-successful result. `nil` means the producer has not stamped the
 *   field yet — undeterminable from structure, not "no error".
 * - `edit_status`: the write/edit disposition spine, read from a producer's flat
 *   `edit_status` field or a nested `edit_outcome.edit_status`; `unknown` when
 *   unstamped.
 * - `diagnostics_error_count`: producer-reported error count; `nil` when absent.
 * - `from_structured`: whether any structured field decided the verdict. When
 *   `false`, a result carries no structured signal at all.
 */
pub type AgentToolResultOutcome = {
  kind: AgentToolResultOutcomeKind,
  error_category: AgentToolLifecycleErrorCategory?,
  product_error: bool?,
  edit_status: AgentEditOutcomeStatus,
  diagnostics_error_count: int?,
  from_structured: bool,
}

const AGENT_EDIT_OUTCOME_STATUSES = [
  "none",
  "rejected_not_applied",
  "applied_clean",
  "applied_still_failing",
  "unknown",
]

fn __agent_tool_result_transport_kind(result: dict) -> AgentToolResultOutcomeKind? {
  if result?.ok != nil {
    return result.ok ? "ok" : "error"
  }
  if result?.success != nil {
    return result.success ? "ok" : "error"
  }
  const status = to_string(result?.status ?? "")
  if status == "ok" || status == "success" {
    return "ok"
  }
  if status == "error" || status == "failed" {
    return "error"
  }
  return nil
}

fn __agent_tool_result_error_category(result: dict) -> AgentToolLifecycleErrorCategory? {
  const explicit = agent_tool_lifecycle_error_category(result?.error_category)
  if explicit != nil {
    return explicit
  }
  return agent_tool_lifecycle_error_category(result?.error)
}

fn __agent_edit_status_value(raw: any) -> AgentEditOutcomeStatus {
  const status = to_string(raw ?? "")
  if contains(AGENT_EDIT_OUTCOME_STATUSES, status) {
    return status
  }
  return "unknown"
}

fn __agent_tool_result_edit_status(result: dict) -> AgentEditOutcomeStatus? {
  const flat = result?.edit_status
  if flat != nil {
    return __agent_edit_status_value(flat)
  }
  const nested = result?.edit_outcome?.edit_status
  if nested != nil {
    return __agent_edit_status_value(nested)
  }
  return nil
}

/**
 * The typed denial a tool handler reported about its own execution, or nil.
 *
 * A handler that runs and then refuses reports through
 * `agent_tool_handler_result`, so its denial rides one level deeper than a
 * denial the VM wrote before dispatch: under `data`, not on the result. This
 * is the single owner of that descent. Both authorities that decide whether a
 * call was refused read it here, because a refusal recognized by one reader
 * and not the other is how a refused call reads as a successful one.
 *
 * The shape is required, not assumed. A `denial` key without a gate has not
 * named the authority that refused, and neither a terminal cutoff nor a
 * failure verdict may fire on a shape it cannot attribute.
 *
 * @effects: []
 * @errors: []
 */
pub fn agent_tool_handler_result_denial(result: dict) -> dict? {
  const payload = result?.result
  if payload?.schema != "harn.agent_tool_handler_result.v1" {
    return nil
  }
  const denial = payload?.data?.denial
  if type_of(denial) != "dict" {
    return nil
  }
  if to_string(denial?.gate ?? "") == "" {
    return nil
  }
  return denial
}

fn __agent_tool_result_product_error(result: dict) -> bool? {
  const raw = result?.product_error
  if raw != nil {
    return raw ? true : false
  }
  const payload = result?.result
  if type_of(payload) != "dict" {
    return nil
  }
  if payload?.ok != nil {
    return payload.ok ? false : true
  }
  if payload?.success != nil {
    return payload.success ? false : true
  }
  // A handler that reported a permanent denial about itself did not succeed,
  // whatever its transport said. Reading this only from a separate `ok` flag
  // would make one fact depend on two switches a producer must remember to
  // set together, and a producer that set the denial and forgot the flag
  // would read back as "not denied" — the case this reader exists to close.
  const denial = agent_tool_handler_result_denial(result)
  if denial != nil && denial?.retryable == false {
    return true
  }
  return nil
}

fn __agent_tool_result_diagnostics_error_count(result: dict) -> int? {
  const raw = result?.diagnostics_error_count ?? result?.diagnostics?.error_count
  if raw == nil {
    return nil
  }
  return to_int(raw)
}

fn __agent_tool_result_kind(
  transport_kind: AgentToolResultOutcomeKind?,
  error_category: AgentToolLifecycleErrorCategory?,
  product_error: bool?,
) -> AgentToolResultOutcomeKind {
  if product_error == true || error_category != nil {
    return "error"
  }
  if transport_kind != nil {
    return transport_kind
  }
  return "unknown"
}

/**
 * Classify a dispatched tool result from its STRUCTURED envelope fields only —
 * transport status (`ok`/`success`/`status`), the typed error code/category,
 * and any producer-stamped `product_error` / `edit_status` / diagnostics
 * fields. A typed payload returned under `result` may also report its domain
 * outcome with `ok` or `success`; `false` is a product failure even when the
 * transport completed. It never inspects rendered or observation prose. This
 * is the single contract both the agent loop and host tool-result classifiers
 * converge on.
 *
 * @effects: []
 * @errors: []
 */
pub fn agent_tool_result_outcome(result: any) -> AgentToolResultOutcome {
  if type_of(result) != "dict" {
    return {
      kind: "unknown",
      error_category: nil,
      product_error: nil,
      edit_status: "unknown",
      diagnostics_error_count: nil,
      from_structured: false,
    }
  }
  const transport_kind = __agent_tool_result_transport_kind(result)
  const error_category = __agent_tool_result_error_category(result)
  const product_error = __agent_tool_result_product_error(result)
  const edit_status = __agent_tool_result_edit_status(result)
  const diagnostics_error_count = __agent_tool_result_diagnostics_error_count(result)
  const from_structured = transport_kind != nil
    || error_category != nil
    || product_error != nil
    || edit_status != nil
    || diagnostics_error_count != nil
  return {
    kind: __agent_tool_result_kind(transport_kind, error_category, product_error),
    error_category: error_category,
    product_error: product_error,
    edit_status: edit_status ?? "unknown",
    diagnostics_error_count: diagnostics_error_count,
    from_structured: from_structured,
  }
}

/**
 * Structured is-ok verdict for scheduling and rejected-tool accounting. Returns
 * a concrete bool when the envelope carries a structured signal, or `nil` when
 * it carries none. A
 * transport-successful write tool whose producer has not yet stamped
 * `product_error` reports `kind == "ok"` with `product_error == nil`.
 *
 * @effects: []
 * @errors: []
 */
pub fn agent_tool_result_is_ok(outcome: AgentToolResultOutcome) -> bool? {
  if outcome.product_error == true {
    return false
  }
  if outcome.kind == "error" {
    return false
  }
  if outcome.kind == "ok" {
    return true
  }
  return nil
}