spanforge 2.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. spanforge/__init__.py +695 -0
  2. spanforge/_batch_exporter.py +322 -0
  3. spanforge/_cli.py +3081 -0
  4. spanforge/_hooks.py +340 -0
  5. spanforge/_server.py +953 -0
  6. spanforge/_span.py +1015 -0
  7. spanforge/_store.py +287 -0
  8. spanforge/_stream.py +654 -0
  9. spanforge/_trace.py +334 -0
  10. spanforge/_tracer.py +253 -0
  11. spanforge/actor.py +141 -0
  12. spanforge/alerts.py +464 -0
  13. spanforge/auto.py +181 -0
  14. spanforge/baseline.py +336 -0
  15. spanforge/config.py +460 -0
  16. spanforge/consent.py +227 -0
  17. spanforge/consumer.py +379 -0
  18. spanforge/core/__init__.py +5 -0
  19. spanforge/core/compliance_mapping.py +1060 -0
  20. spanforge/cost.py +597 -0
  21. spanforge/debug.py +514 -0
  22. spanforge/drift.py +488 -0
  23. spanforge/egress.py +63 -0
  24. spanforge/eval.py +575 -0
  25. spanforge/event.py +1052 -0
  26. spanforge/exceptions.py +246 -0
  27. spanforge/explain.py +181 -0
  28. spanforge/export/__init__.py +50 -0
  29. spanforge/export/append_only.py +342 -0
  30. spanforge/export/cloud.py +349 -0
  31. spanforge/export/datadog.py +495 -0
  32. spanforge/export/grafana.py +331 -0
  33. spanforge/export/jsonl.py +198 -0
  34. spanforge/export/otel_bridge.py +291 -0
  35. spanforge/export/otlp.py +817 -0
  36. spanforge/export/otlp_bridge.py +231 -0
  37. spanforge/export/redis_backend.py +282 -0
  38. spanforge/export/webhook.py +302 -0
  39. spanforge/exporters/__init__.py +29 -0
  40. spanforge/exporters/console.py +271 -0
  41. spanforge/exporters/jsonl.py +144 -0
  42. spanforge/hitl.py +297 -0
  43. spanforge/inspect.py +429 -0
  44. spanforge/integrations/__init__.py +39 -0
  45. spanforge/integrations/_pricing.py +277 -0
  46. spanforge/integrations/anthropic.py +388 -0
  47. spanforge/integrations/bedrock.py +306 -0
  48. spanforge/integrations/crewai.py +251 -0
  49. spanforge/integrations/gemini.py +349 -0
  50. spanforge/integrations/groq.py +444 -0
  51. spanforge/integrations/langchain.py +349 -0
  52. spanforge/integrations/llamaindex.py +370 -0
  53. spanforge/integrations/ollama.py +286 -0
  54. spanforge/integrations/openai.py +370 -0
  55. spanforge/integrations/together.py +485 -0
  56. spanforge/metrics.py +393 -0
  57. spanforge/metrics_export.py +342 -0
  58. spanforge/migrate.py +278 -0
  59. spanforge/model_registry.py +282 -0
  60. spanforge/models.py +407 -0
  61. spanforge/namespaces/__init__.py +215 -0
  62. spanforge/namespaces/audit.py +253 -0
  63. spanforge/namespaces/cache.py +209 -0
  64. spanforge/namespaces/chain.py +74 -0
  65. spanforge/namespaces/confidence.py +69 -0
  66. spanforge/namespaces/consent.py +85 -0
  67. spanforge/namespaces/cost.py +175 -0
  68. spanforge/namespaces/decision.py +135 -0
  69. spanforge/namespaces/diff.py +146 -0
  70. spanforge/namespaces/drift.py +79 -0
  71. spanforge/namespaces/eval_.py +232 -0
  72. spanforge/namespaces/fence.py +180 -0
  73. spanforge/namespaces/guard.py +104 -0
  74. spanforge/namespaces/hitl.py +92 -0
  75. spanforge/namespaces/latency.py +69 -0
  76. spanforge/namespaces/prompt.py +185 -0
  77. spanforge/namespaces/redact.py +172 -0
  78. spanforge/namespaces/template.py +197 -0
  79. spanforge/namespaces/tool_call.py +76 -0
  80. spanforge/namespaces/trace.py +1006 -0
  81. spanforge/normalizer.py +183 -0
  82. spanforge/presidio_backend.py +149 -0
  83. spanforge/processor.py +258 -0
  84. spanforge/prompt_registry.py +415 -0
  85. spanforge/py.typed +0 -0
  86. spanforge/redact.py +780 -0
  87. spanforge/sampling.py +500 -0
  88. spanforge/schemas/v1.0/schema.json +170 -0
  89. spanforge/schemas/v2.0/schema.json +536 -0
  90. spanforge/signing.py +1152 -0
  91. spanforge/stream.py +559 -0
  92. spanforge/testing.py +376 -0
  93. spanforge/trace.py +199 -0
  94. spanforge/types.py +696 -0
  95. spanforge/ulid.py +304 -0
  96. spanforge/validate.py +383 -0
  97. spanforge-2.0.0.dist-info/METADATA +1777 -0
  98. spanforge-2.0.0.dist-info/RECORD +101 -0
  99. spanforge-2.0.0.dist-info/WHEEL +4 -0
  100. spanforge-2.0.0.dist-info/entry_points.txt +5 -0
  101. spanforge-2.0.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,536 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://llm-toolkit-schema.dev/schemas/v2.0/schema.json",
4
+ "title": "AGENTOBS Event Envelope v2.0",
5
+ "description": "Normative JSON Schema for the AGENTOBS v2.0 Event Envelope (RFC-0001-AGENTOBS §5, Appendix A). Every event emitted by a conformant implementation MUST validate against this schema. Language-neutral portability contract per RFC §21.2.",
6
+ "type": "object",
7
+ "required": [
8
+ "schema_version",
9
+ "event_id",
10
+ "event_type",
11
+ "timestamp",
12
+ "source",
13
+ "payload"
14
+ ],
15
+ "additionalProperties": false,
16
+ "properties": {
17
+ "schema_version": {
18
+ "type": "string",
19
+ "description": "Schema version. MUST be '2.0' for AGENTOBS v2.0 events. '1.0' is also accepted for backward compatibility (RFC §15.5).",
20
+ "enum": ["1.0", "2.0"],
21
+ "examples": ["2.0", "1.0"]
22
+ },
23
+ "event_id": {
24
+ "type": "string",
25
+ "description": "Universally unique ULID. 26-character Crockford Base32; first character MUST be in [0-7] (RFC §6.3).",
26
+ "pattern": "^[0-7][0-9A-HJKMNP-TV-Z]{25}$",
27
+ "minLength": 26,
28
+ "maxLength": 26,
29
+ "examples": ["01HZ8G3EPRP1YF2QV70NMBE6J4"]
30
+ },
31
+ "event_type": {
32
+ "type": "string",
33
+ "description": "Dot-separated namespaced event type (RFC §7). Must use a registered namespace or vendor-prefixed extension namespace.",
34
+ "oneOf": [
35
+ {
36
+ "enum": [
37
+ "llm.trace.span.started",
38
+ "llm.trace.span.completed",
39
+ "llm.trace.span.failed",
40
+ "llm.trace.agent.step",
41
+ "llm.trace.agent.completed",
42
+ "llm.trace.reasoning.step",
43
+ "llm.cost.token.recorded",
44
+ "llm.cost.session.recorded",
45
+ "llm.cost.attributed",
46
+ "llm.cache.hit",
47
+ "llm.cache.miss",
48
+ "llm.cache.evicted",
49
+ "llm.cache.written",
50
+ "llm.eval.score.recorded",
51
+ "llm.eval.regression.detected",
52
+ "llm.eval.scenario.started",
53
+ "llm.eval.scenario.completed",
54
+ "llm.guard.input.blocked",
55
+ "llm.guard.input.passed",
56
+ "llm.guard.output.blocked",
57
+ "llm.guard.output.passed",
58
+ "llm.fence.validated",
59
+ "llm.fence.retry.triggered",
60
+ "llm.fence.max_retries.exceeded",
61
+ "llm.prompt.rendered",
62
+ "llm.prompt.template.loaded",
63
+ "llm.prompt.version.changed",
64
+ "llm.redact.pii.detected",
65
+ "llm.redact.phi.detected",
66
+ "llm.redact.applied",
67
+ "llm.diff.computed",
68
+ "llm.diff.regression.flagged",
69
+ "llm.template.registered",
70
+ "llm.template.variable.bound",
71
+ "llm.template.validation.failed",
72
+ "llm.audit.key.rotated"
73
+ ]
74
+ },
75
+ {
76
+ "pattern": "^(?!llm\\.)[a-z][a-z0-9-]*(?:\\.[a-z][a-z0-9-]*)+\\.[a-z][a-z0-9_]*\\.[a-z][a-z0-9_]*$"
77
+ }
78
+ ],
79
+ "examples": [
80
+ "llm.trace.span.completed",
81
+ "llm.cost.token.recorded",
82
+ "llm.redact.pii.detected",
83
+ "llm.audit.key.rotated"
84
+ ]
85
+ },
86
+ "timestamp": {
87
+ "type": "string",
88
+ "description": "UTC ISO-8601 timestamp with microsecond precision. Format: YYYY-MM-DDThh:mm:ss.ffffffZ (RFC §5.1).",
89
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{6}Z$",
90
+ "examples": ["2026-03-09T12:00:00.000000Z"]
91
+ },
92
+ "source": {
93
+ "type": "string",
94
+ "description": "Emitting service in 'name@semver' format (RFC §5.1).",
95
+ "pattern": "^[a-zA-Z][a-zA-Z0-9._-]*@\\d+\\.\\d+\\.\\d+(?:[.-][a-zA-Z0-9.]+)?$",
96
+ "examples": ["agentobs@1.0.7", "my-agent@2.1.0-beta.1"]
97
+ },
98
+ "payload": {
99
+ "type": "object",
100
+ "description": "Event-type-specific data. MUST contain at least one property (RFC §5.1).",
101
+ "minProperties": 1
102
+ },
103
+ "trace_id": {
104
+ "type": "string",
105
+ "description": "W3C / OTel trace identifier — exactly 32 lowercase hexadecimal characters.",
106
+ "pattern": "^[0-9a-f]{32}$",
107
+ "examples": ["4bf92f3577b34da6a3ce929d0e0e4736"]
108
+ },
109
+ "span_id": {
110
+ "type": "string",
111
+ "description": "W3C / OTel span identifier — exactly 16 lowercase hexadecimal characters.",
112
+ "pattern": "^[0-9a-f]{16}$",
113
+ "examples": ["00f067aa0ba902b7"]
114
+ },
115
+ "parent_span_id": {
116
+ "type": "string",
117
+ "description": "Parent span identifier — exactly 16 lowercase hexadecimal characters.",
118
+ "pattern": "^[0-9a-f]{16}$"
119
+ },
120
+ "org_id": {
121
+ "type": "string",
122
+ "description": "Organisation identifier for multi-tenant deployments.",
123
+ "minLength": 1
124
+ },
125
+ "team_id": {
126
+ "type": "string",
127
+ "description": "Team identifier.",
128
+ "minLength": 1
129
+ },
130
+ "actor_id": {
131
+ "type": "string",
132
+ "description": "User or service-account that triggered the event.",
133
+ "minLength": 1
134
+ },
135
+ "session_id": {
136
+ "type": "string",
137
+ "description": "Session identifier grouping a series of related events.",
138
+ "minLength": 1
139
+ },
140
+ "tags": {
141
+ "type": "object",
142
+ "description": "Arbitrary string key→value metadata. Maximum 50 keys recommended (RFC §19.4).",
143
+ "maxProperties": 50,
144
+ "propertyNames": {
145
+ "type": "string",
146
+ "minLength": 1
147
+ },
148
+ "additionalProperties": {
149
+ "type": "string",
150
+ "minLength": 1
151
+ }
152
+ },
153
+ "checksum": {
154
+ "type": "string",
155
+ "description": "SHA-256 digest of the canonical payload JSON. Format: 'sha256:' + 64 lowercase hex (RFC §11).",
156
+ "pattern": "^sha256:[0-9a-f]{64}$"
157
+ },
158
+ "signature": {
159
+ "type": "string",
160
+ "description": "HMAC-SHA256 audit chain signature. Format: 'hmac-sha256:' + 64 lowercase hex (RFC §11).",
161
+ "pattern": "^hmac-sha256:[0-9a-f]{64}$"
162
+ },
163
+ "prev_id": {
164
+ "type": "string",
165
+ "description": "ULID of the immediately preceding event in the audit chain (RFC §11).",
166
+ "pattern": "^[0-7][0-9A-HJKMNP-TV-Z]{25}$",
167
+ "minLength": 26,
168
+ "maxLength": 26
169
+ }
170
+ },
171
+ "$defs": {
172
+ "ulid": {
173
+ "type": "string",
174
+ "pattern": "^[0-7][0-9A-HJKMNP-TV-Z]{25}$",
175
+ "minLength": 26,
176
+ "maxLength": 26
177
+ },
178
+ "trace_id": {
179
+ "type": "string",
180
+ "pattern": "^[0-9a-f]{32}$"
181
+ },
182
+ "span_id": {
183
+ "type": "string",
184
+ "pattern": "^[0-9a-f]{16}$"
185
+ },
186
+ "sha256_hex": {
187
+ "type": "string",
188
+ "pattern": "^[0-9a-f]{64}$",
189
+ "minLength": 64,
190
+ "maxLength": 64
191
+ },
192
+ "iso_date": {
193
+ "type": "string",
194
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
195
+ },
196
+ "iso_timestamp_us": {
197
+ "type": "string",
198
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{6}Z$"
199
+ },
200
+ "gen_ai_system": {
201
+ "type": "string",
202
+ "description": "Provider identifier (RFC §10.1, Appendix C).",
203
+ "enum": [
204
+ "openai",
205
+ "anthropic",
206
+ "cohere",
207
+ "vertex_ai",
208
+ "aws_bedrock",
209
+ "az.ai.inference",
210
+ "groq",
211
+ "ollama",
212
+ "mistral_ai",
213
+ "together_ai",
214
+ "hugging_face",
215
+ "_custom"
216
+ ]
217
+ },
218
+ "gen_ai_operation_name": {
219
+ "type": "string",
220
+ "description": "Type of LLM operation (RFC §10.2).",
221
+ "enum": [
222
+ "chat",
223
+ "text_completion",
224
+ "embeddings",
225
+ "image_generation",
226
+ "execute_tool",
227
+ "invoke_agent",
228
+ "create_agent",
229
+ "reasoning"
230
+ ]
231
+ },
232
+ "span_kind": {
233
+ "type": "string",
234
+ "description": "OTel SpanKind for LLM operations (RFC §10.3).",
235
+ "enum": ["CLIENT", "SERVER", "INTERNAL", "CONSUMER", "PRODUCER"]
236
+ },
237
+ "token_usage": {
238
+ "type": "object",
239
+ "description": "Token consumption record (RFC §9.1).",
240
+ "required": ["input_tokens", "output_tokens", "total_tokens"],
241
+ "additionalProperties": false,
242
+ "properties": {
243
+ "input_tokens": {"type": "integer", "minimum": 0},
244
+ "output_tokens": {"type": "integer", "minimum": 0},
245
+ "total_tokens": {"type": "integer", "minimum": 0},
246
+ "cached_tokens": {"type": "integer", "minimum": 0},
247
+ "cache_creation_tokens": {"type": "integer", "minimum": 0},
248
+ "reasoning_tokens": {"type": "integer", "minimum": 0},
249
+ "image_tokens": {"type": "integer", "minimum": 0}
250
+ }
251
+ },
252
+ "model_info": {
253
+ "type": "object",
254
+ "description": "Model identity and provider information (RFC §9.2). custom_system_name is REQUIRED when system is '_custom'.",
255
+ "required": ["system", "name"],
256
+ "additionalProperties": false,
257
+ "properties": {
258
+ "system": {"$ref": "#/$defs/gen_ai_system"},
259
+ "name": {"type": "string", "minLength": 1},
260
+ "response_model": {"type": "string", "minLength": 1},
261
+ "version": {"type": "string", "minLength": 1},
262
+ "custom_system_name": {"type": "string", "minLength": 1}
263
+ },
264
+ "allOf": [
265
+ {
266
+ "if": {
267
+ "properties": {
268
+ "system": {"const": "_custom"}
269
+ }
270
+ },
271
+ "then": {
272
+ "required": ["custom_system_name"]
273
+ }
274
+ }
275
+ ]
276
+ },
277
+ "cost_breakdown": {
278
+ "type": "object",
279
+ "description": "Typed cost attribution record (RFC §9.3).",
280
+ "required": ["input_cost_usd", "output_cost_usd", "total_cost_usd"],
281
+ "additionalProperties": false,
282
+ "properties": {
283
+ "input_cost_usd": {"type": "number", "minimum": 0},
284
+ "output_cost_usd": {"type": "number", "minimum": 0},
285
+ "total_cost_usd": {"type": "number", "minimum": 0},
286
+ "cached_discount_usd": {"type": "number", "minimum": 0},
287
+ "reasoning_cost_usd": {"type": "number", "minimum": 0},
288
+ "currency": {
289
+ "type": "string",
290
+ "pattern": "^[A-Z]{3}$",
291
+ "default": "USD"
292
+ },
293
+ "pricing_date": {"$ref": "#/$defs/iso_date"}
294
+ }
295
+ },
296
+ "pricing_tier": {
297
+ "type": "object",
298
+ "description": "Pricing rates snapshot for cost reproducibility (RFC §9.4).",
299
+ "required": [
300
+ "system",
301
+ "model",
302
+ "input_per_million_usd",
303
+ "output_per_million_usd",
304
+ "effective_date"
305
+ ],
306
+ "additionalProperties": false,
307
+ "properties": {
308
+ "system": {"$ref": "#/$defs/gen_ai_system"},
309
+ "model": {"type": "string", "minLength": 1},
310
+ "input_per_million_usd": {"type": "number", "minimum": 0},
311
+ "output_per_million_usd": {"type": "number", "minimum": 0},
312
+ "effective_date": {"$ref": "#/$defs/iso_date"},
313
+ "cached_input_per_million_usd": {"type": "number", "minimum": 0},
314
+ "reasoning_per_million_usd": {"type": "number", "minimum": 0}
315
+ }
316
+ },
317
+ "tool_call": {
318
+ "type": "object",
319
+ "description": "A single tool invocation within a span (RFC §8.1).",
320
+ "required": ["tool_call_id", "function_name", "status"],
321
+ "additionalProperties": false,
322
+ "properties": {
323
+ "tool_call_id": {"type": "string", "minLength": 1},
324
+ "function_name": {"type": "string", "minLength": 1},
325
+ "status": {
326
+ "type": "string",
327
+ "enum": ["success", "error", "timeout", "cancelled"]
328
+ },
329
+ "arguments_hash": {"$ref": "#/$defs/sha256_hex"},
330
+ "error_type": {"type": "string"},
331
+ "duration_ms": {"type": "number", "minimum": 0},
332
+ "arguments_raw": {"type": "string"},
333
+ "result_raw": {"type": "string"},
334
+ "retry_count": {"type": "integer", "minimum": 0},
335
+ "external_api": {"type": "string"}
336
+ }
337
+ },
338
+ "span_event": {
339
+ "type": "object",
340
+ "description": "An instantaneous named event within a span.",
341
+ "required": ["name", "timestamp_ns"],
342
+ "additionalProperties": false,
343
+ "properties": {
344
+ "name": {"type": "string", "minLength": 1},
345
+ "timestamp_ns": {"type": "integer", "minimum": 0},
346
+ "metadata": {
347
+ "type": "object",
348
+ "additionalProperties": true
349
+ }
350
+ }
351
+ },
352
+ "reasoning_step": {
353
+ "type": "object",
354
+ "description": "A discrete chain-of-thought unit (RFC §8.2). Raw content MUST NOT be stored.",
355
+ "required": ["step_index", "reasoning_tokens"],
356
+ "additionalProperties": false,
357
+ "properties": {
358
+ "step_index": {"type": "integer", "minimum": 0},
359
+ "reasoning_tokens": {"type": "integer", "minimum": 0},
360
+ "duration_ms": {"type": "number", "minimum": 0},
361
+ "content_hash": {"$ref": "#/$defs/sha256_hex"}
362
+ }
363
+ },
364
+ "decision_point": {
365
+ "type": "object",
366
+ "description": "An explicit branching decision recorded during an agent step (RFC §8.3).",
367
+ "required": [
368
+ "decision_id",
369
+ "decision_type",
370
+ "options_considered",
371
+ "chosen_option"
372
+ ],
373
+ "additionalProperties": false,
374
+ "properties": {
375
+ "decision_id": {"type": "string", "minLength": 1},
376
+ "decision_type": {
377
+ "type": "string",
378
+ "enum": [
379
+ "tool_selection",
380
+ "route_choice",
381
+ "loop_termination",
382
+ "escalation"
383
+ ]
384
+ },
385
+ "options_considered": {
386
+ "type": "array",
387
+ "items": {"type": "string"},
388
+ "minItems": 1
389
+ },
390
+ "chosen_option": {"type": "string", "minLength": 1},
391
+ "rationale": {"type": "string"}
392
+ }
393
+ },
394
+ "span_payload": {
395
+ "type": "object",
396
+ "description": "SpanPayload — a single unit of LLM work (RFC §8.1).",
397
+ "required": [
398
+ "span_id",
399
+ "trace_id",
400
+ "span_name",
401
+ "operation",
402
+ "span_kind",
403
+ "status",
404
+ "start_time_unix_nano",
405
+ "end_time_unix_nano",
406
+ "duration_ms",
407
+ "tool_calls"
408
+ ],
409
+ "additionalProperties": true,
410
+ "properties": {
411
+ "span_id": {"$ref": "#/$defs/span_id"},
412
+ "trace_id": {"$ref": "#/$defs/trace_id"},
413
+ "span_name": {"type": "string", "minLength": 1},
414
+ "operation": {"$ref": "#/$defs/gen_ai_operation_name"},
415
+ "span_kind": {"$ref": "#/$defs/span_kind"},
416
+ "status": {"type": "string", "enum": ["ok", "error", "timeout"]},
417
+ "start_time_unix_nano": {"type": "integer", "minimum": 0},
418
+ "end_time_unix_nano": {"type": "integer", "minimum": 0},
419
+ "duration_ms": {"type": "number", "minimum": 0},
420
+ "tool_calls": {
421
+ "type": "array",
422
+ "items": {"$ref": "#/$defs/tool_call"}
423
+ },
424
+ "reasoning_steps": {
425
+ "type": "array",
426
+ "items": {"$ref": "#/$defs/reasoning_step"}
427
+ },
428
+ "parent_span_id": {"$ref": "#/$defs/span_id"},
429
+ "agent_run_id": {"type": "string", "minLength": 1},
430
+ "model": {"$ref": "#/$defs/model_info"},
431
+ "token_usage": {"$ref": "#/$defs/token_usage"},
432
+ "cost": {"$ref": "#/$defs/cost_breakdown"},
433
+ "finish_reason": {"type": "string"},
434
+ "error": {"type": "string"},
435
+ "error_type": {"type": "string"},
436
+ "error_category": {"type": "string"},
437
+ "attributes": {"type": "object"},
438
+ "temperature": {"type": "number"},
439
+ "top_p": {"type": "number"},
440
+ "max_tokens": {"type": "integer"},
441
+ "events": {
442
+ "type": "array",
443
+ "items": {"$ref": "#/$defs/span_event"}
444
+ }
445
+ }
446
+ },
447
+ "agent_step_payload": {
448
+ "type": "object",
449
+ "description": "AgentStepPayload — one iteration of a multi-step agent loop (RFC §8.4).",
450
+ "required": [
451
+ "agent_run_id",
452
+ "step_index",
453
+ "span_id",
454
+ "trace_id",
455
+ "operation",
456
+ "tool_calls",
457
+ "reasoning_steps",
458
+ "decision_points",
459
+ "status",
460
+ "start_time_unix_nano",
461
+ "end_time_unix_nano",
462
+ "duration_ms"
463
+ ],
464
+ "additionalProperties": true,
465
+ "properties": {
466
+ "agent_run_id": {"type": "string", "minLength": 1},
467
+ "step_index": {"type": "integer", "minimum": 0},
468
+ "span_id": {"$ref": "#/$defs/span_id"},
469
+ "trace_id": {"$ref": "#/$defs/trace_id"},
470
+ "operation": {"$ref": "#/$defs/gen_ai_operation_name"},
471
+ "tool_calls": {
472
+ "type": "array",
473
+ "items": {"$ref": "#/$defs/tool_call"}
474
+ },
475
+ "reasoning_steps": {
476
+ "type": "array",
477
+ "items": {"$ref": "#/$defs/reasoning_step"}
478
+ },
479
+ "decision_points": {
480
+ "type": "array",
481
+ "items": {"$ref": "#/$defs/decision_point"}
482
+ },
483
+ "status": {"type": "string", "enum": ["ok", "error", "timeout"]},
484
+ "start_time_unix_nano": {"type": "integer", "minimum": 0},
485
+ "end_time_unix_nano": {"type": "integer", "minimum": 0},
486
+ "duration_ms": {"type": "number", "minimum": 0},
487
+ "parent_span_id": {"$ref": "#/$defs/span_id"},
488
+ "model": {"$ref": "#/$defs/model_info"},
489
+ "token_usage": {"$ref": "#/$defs/token_usage"},
490
+ "cost": {"$ref": "#/$defs/cost_breakdown"},
491
+ "error": {"type": "string"},
492
+ "error_type": {"type": "string"},
493
+ "step_name": {"type": "string"}
494
+ }
495
+ },
496
+ "agent_run_payload": {
497
+ "type": "object",
498
+ "description": "AgentRunPayload — root-level summary for a complete agent run (RFC §8.5).",
499
+ "required": [
500
+ "agent_run_id",
501
+ "agent_name",
502
+ "trace_id",
503
+ "root_span_id",
504
+ "total_steps",
505
+ "total_model_calls",
506
+ "total_tool_calls",
507
+ "total_token_usage",
508
+ "total_cost",
509
+ "status",
510
+ "start_time_unix_nano",
511
+ "end_time_unix_nano",
512
+ "duration_ms"
513
+ ],
514
+ "additionalProperties": true,
515
+ "properties": {
516
+ "agent_run_id": {"type": "string", "minLength": 1},
517
+ "agent_name": {"type": "string", "minLength": 1},
518
+ "trace_id": {"$ref": "#/$defs/trace_id"},
519
+ "root_span_id": {"$ref": "#/$defs/span_id"},
520
+ "total_steps": {"type": "integer", "minimum": 0},
521
+ "total_model_calls": {"type": "integer", "minimum": 0},
522
+ "total_tool_calls": {"type": "integer", "minimum": 0},
523
+ "total_token_usage": {"$ref": "#/$defs/token_usage"},
524
+ "total_cost": {"$ref": "#/$defs/cost_breakdown"},
525
+ "status": {
526
+ "type": "string",
527
+ "enum": ["ok", "error", "timeout", "max_steps_exceeded"]
528
+ },
529
+ "start_time_unix_nano": {"type": "integer", "minimum": 0},
530
+ "end_time_unix_nano": {"type": "integer", "minimum": 0},
531
+ "duration_ms": {"type": "number", "minimum": 0},
532
+ "termination_reason": {"type": "string"}
533
+ }
534
+ }
535
+ }
536
+ }