spanforge 1.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 (174) hide show
  1. spanforge/__init__.py +815 -0
  2. spanforge/_ansi.py +93 -0
  3. spanforge/_batch_exporter.py +409 -0
  4. spanforge/_cli.py +2094 -0
  5. spanforge/_cli_audit.py +639 -0
  6. spanforge/_cli_compliance.py +711 -0
  7. spanforge/_cli_cost.py +243 -0
  8. spanforge/_cli_ops.py +791 -0
  9. spanforge/_cli_phase11.py +356 -0
  10. spanforge/_hooks.py +337 -0
  11. spanforge/_server.py +1708 -0
  12. spanforge/_span.py +1036 -0
  13. spanforge/_store.py +288 -0
  14. spanforge/_stream.py +664 -0
  15. spanforge/_trace.py +335 -0
  16. spanforge/_tracer.py +254 -0
  17. spanforge/actor.py +141 -0
  18. spanforge/alerts.py +469 -0
  19. spanforge/auto.py +464 -0
  20. spanforge/baseline.py +335 -0
  21. spanforge/cache.py +635 -0
  22. spanforge/compliance.py +325 -0
  23. spanforge/config.py +532 -0
  24. spanforge/consent.py +228 -0
  25. spanforge/consumer.py +377 -0
  26. spanforge/core/__init__.py +5 -0
  27. spanforge/core/compliance_mapping.py +1254 -0
  28. spanforge/cost.py +600 -0
  29. spanforge/debug.py +548 -0
  30. spanforge/deprecations.py +205 -0
  31. spanforge/drift.py +482 -0
  32. spanforge/egress.py +58 -0
  33. spanforge/eval.py +648 -0
  34. spanforge/event.py +1064 -0
  35. spanforge/exceptions.py +240 -0
  36. spanforge/explain.py +178 -0
  37. spanforge/export/__init__.py +69 -0
  38. spanforge/export/append_only.py +337 -0
  39. spanforge/export/cloud.py +357 -0
  40. spanforge/export/datadog.py +497 -0
  41. spanforge/export/grafana.py +320 -0
  42. spanforge/export/jsonl.py +195 -0
  43. spanforge/export/openinference.py +158 -0
  44. spanforge/export/otel_bridge.py +294 -0
  45. spanforge/export/otlp.py +811 -0
  46. spanforge/export/otlp_bridge.py +233 -0
  47. spanforge/export/redis_backend.py +282 -0
  48. spanforge/export/siem_schema.py +98 -0
  49. spanforge/export/siem_splunk.py +264 -0
  50. spanforge/export/siem_syslog.py +212 -0
  51. spanforge/export/webhook.py +299 -0
  52. spanforge/exporters/__init__.py +30 -0
  53. spanforge/exporters/console.py +271 -0
  54. spanforge/exporters/jsonl.py +144 -0
  55. spanforge/exporters/sqlite.py +142 -0
  56. spanforge/gate.py +1150 -0
  57. spanforge/governance.py +181 -0
  58. spanforge/hitl.py +295 -0
  59. spanforge/http.py +187 -0
  60. spanforge/inspect.py +427 -0
  61. spanforge/integrations/__init__.py +45 -0
  62. spanforge/integrations/_pricing.py +280 -0
  63. spanforge/integrations/anthropic.py +388 -0
  64. spanforge/integrations/azure_openai.py +133 -0
  65. spanforge/integrations/bedrock.py +292 -0
  66. spanforge/integrations/crewai.py +251 -0
  67. spanforge/integrations/gemini.py +351 -0
  68. spanforge/integrations/groq.py +442 -0
  69. spanforge/integrations/langchain.py +349 -0
  70. spanforge/integrations/langgraph.py +306 -0
  71. spanforge/integrations/llamaindex.py +373 -0
  72. spanforge/integrations/ollama.py +287 -0
  73. spanforge/integrations/openai.py +368 -0
  74. spanforge/integrations/together.py +483 -0
  75. spanforge/io.py +214 -0
  76. spanforge/lint.py +322 -0
  77. spanforge/metrics.py +417 -0
  78. spanforge/metrics_export.py +343 -0
  79. spanforge/migrate.py +402 -0
  80. spanforge/model_registry.py +278 -0
  81. spanforge/models.py +389 -0
  82. spanforge/namespaces/__init__.py +254 -0
  83. spanforge/namespaces/audit.py +256 -0
  84. spanforge/namespaces/cache.py +237 -0
  85. spanforge/namespaces/chain.py +77 -0
  86. spanforge/namespaces/confidence.py +72 -0
  87. spanforge/namespaces/consent.py +92 -0
  88. spanforge/namespaces/cost.py +179 -0
  89. spanforge/namespaces/decision.py +143 -0
  90. spanforge/namespaces/diff.py +157 -0
  91. spanforge/namespaces/drift.py +80 -0
  92. spanforge/namespaces/eval_.py +251 -0
  93. spanforge/namespaces/feedback.py +241 -0
  94. spanforge/namespaces/fence.py +193 -0
  95. spanforge/namespaces/guard.py +105 -0
  96. spanforge/namespaces/hitl.py +91 -0
  97. spanforge/namespaces/latency.py +72 -0
  98. spanforge/namespaces/prompt.py +190 -0
  99. spanforge/namespaces/redact.py +173 -0
  100. spanforge/namespaces/retrieval.py +379 -0
  101. spanforge/namespaces/runtime_governance.py +494 -0
  102. spanforge/namespaces/template.py +208 -0
  103. spanforge/namespaces/tool_call.py +77 -0
  104. spanforge/namespaces/trace.py +1029 -0
  105. spanforge/normalizer.py +171 -0
  106. spanforge/plugins.py +82 -0
  107. spanforge/presidio_backend.py +349 -0
  108. spanforge/processor.py +258 -0
  109. spanforge/prompt_registry.py +418 -0
  110. spanforge/py.typed +0 -0
  111. spanforge/redact.py +914 -0
  112. spanforge/regression.py +192 -0
  113. spanforge/runtime_policy.py +159 -0
  114. spanforge/sampling.py +511 -0
  115. spanforge/schema.py +183 -0
  116. spanforge/schemas/v1.0/schema.json +170 -0
  117. spanforge/schemas/v2.0/schema.json +536 -0
  118. spanforge/sdk/__init__.py +625 -0
  119. spanforge/sdk/_base.py +584 -0
  120. spanforge/sdk/_base.pyi +71 -0
  121. spanforge/sdk/_exceptions.py +1096 -0
  122. spanforge/sdk/_types.py +2184 -0
  123. spanforge/sdk/alert.py +1514 -0
  124. spanforge/sdk/alert.pyi +56 -0
  125. spanforge/sdk/audit.py +1196 -0
  126. spanforge/sdk/audit.pyi +67 -0
  127. spanforge/sdk/cec.py +1215 -0
  128. spanforge/sdk/cec.pyi +37 -0
  129. spanforge/sdk/config.py +641 -0
  130. spanforge/sdk/config.pyi +55 -0
  131. spanforge/sdk/enterprise.py +714 -0
  132. spanforge/sdk/enterprise.pyi +79 -0
  133. spanforge/sdk/explain.py +170 -0
  134. spanforge/sdk/fallback.py +432 -0
  135. spanforge/sdk/feedback.py +351 -0
  136. spanforge/sdk/gate.py +874 -0
  137. spanforge/sdk/gate.pyi +51 -0
  138. spanforge/sdk/identity.py +2114 -0
  139. spanforge/sdk/identity.pyi +47 -0
  140. spanforge/sdk/lineage.py +175 -0
  141. spanforge/sdk/observe.py +1065 -0
  142. spanforge/sdk/observe.pyi +50 -0
  143. spanforge/sdk/operator.py +338 -0
  144. spanforge/sdk/pii.py +1473 -0
  145. spanforge/sdk/pii.pyi +119 -0
  146. spanforge/sdk/pipelines.py +458 -0
  147. spanforge/sdk/pipelines.pyi +39 -0
  148. spanforge/sdk/policy.py +930 -0
  149. spanforge/sdk/rag.py +594 -0
  150. spanforge/sdk/rbac.py +280 -0
  151. spanforge/sdk/registry.py +430 -0
  152. spanforge/sdk/registry.pyi +46 -0
  153. spanforge/sdk/scope.py +279 -0
  154. spanforge/sdk/secrets.py +293 -0
  155. spanforge/sdk/secrets.pyi +25 -0
  156. spanforge/sdk/security.py +560 -0
  157. spanforge/sdk/security.pyi +57 -0
  158. spanforge/sdk/trust.py +472 -0
  159. spanforge/sdk/trust.pyi +41 -0
  160. spanforge/secrets.py +799 -0
  161. spanforge/signing.py +1179 -0
  162. spanforge/stats.py +100 -0
  163. spanforge/stream.py +560 -0
  164. spanforge/testing.py +378 -0
  165. spanforge/testing_mocks.py +1052 -0
  166. spanforge/trace.py +199 -0
  167. spanforge/types.py +696 -0
  168. spanforge/ulid.py +300 -0
  169. spanforge/validate.py +379 -0
  170. spanforge-1.0.0.dist-info/METADATA +1509 -0
  171. spanforge-1.0.0.dist-info/RECORD +174 -0
  172. spanforge-1.0.0.dist-info/WHEEL +4 -0
  173. spanforge-1.0.0.dist-info/entry_points.txt +5 -0
  174. spanforge-1.0.0.dist-info/licenses/LICENSE +128 -0
spanforge/__init__.py ADDED
@@ -0,0 +1,815 @@
1
+ """SpanForge — AI lifecycle and governance platform (RFC-0001 SPANFORGE v2.0).
2
+
3
+ Every tool in the LLM Developer Toolkit emits events that conform to the
4
+ :class:`~spanforge.event.Event` envelope defined here. The schema is
5
+ OpenTelemetry-compatible, tamper-evident, and enterprise-grade.
6
+
7
+ Quick start
8
+ -----------
9
+ ::
10
+
11
+ from spanforge import Event, EventType, Tags
12
+
13
+ event = Event(
14
+ event_type=EventType.TRACE_SPAN_COMPLETED,
15
+ source="my-agent@1.0.0",
16
+ payload={"span_name": "run_agent", "status": "ok"},
17
+ tags=Tags(env="production", model="gpt-4o"),
18
+ )
19
+ event.validate()
20
+ print(event.to_json())
21
+
22
+ Public API
23
+ ----------
24
+ Core envelope
25
+ ~~~~~~~~~~~~~
26
+ * :class:`~spanforge.event.Event`
27
+ * :class:`~spanforge.event.Tags`
28
+ * :data:`~spanforge.event.SCHEMA_VERSION`
29
+
30
+ Event types
31
+ ~~~~~~~~~~~
32
+ * :class:`~spanforge.types.EventType` — RFC Appendix B canonical types
33
+ * :func:`~spanforge.types.is_registered`
34
+ * :func:`~spanforge.types.namespace_of`
35
+ * :func:`~spanforge.types.validate_custom`
36
+ * :func:`~spanforge.types.get_by_value`
37
+
38
+ ULID
39
+ ~~~~
40
+ * :func:`~spanforge.ulid.generate`
41
+ * :func:`~spanforge.ulid.validate`
42
+ * :func:`~spanforge.ulid.extract_timestamp_ms`
43
+
44
+ PII redaction (RFC §12)
45
+ ~~~~~~~~~~~~~~~~~~~~~~~
46
+ * :class:`~spanforge.redact.Sensitivity`
47
+ * :class:`~spanforge.redact.Redactable`
48
+ * :class:`~spanforge.redact.RedactionPolicy`
49
+ * :class:`~spanforge.redact.RedactionResult`
50
+ * :class:`~spanforge.redact.PIINotRedactedError`
51
+ * :func:`~spanforge.redact.contains_pii`
52
+ * :func:`~spanforge.redact.assert_redacted`
53
+
54
+ HMAC signing & audit chain (RFC §11)
55
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
56
+ * :func:`~spanforge.signing.sign`
57
+ * :func:`~spanforge.signing.verify`
58
+ * :func:`~spanforge.signing.verify_chain`
59
+ * :func:`~spanforge.signing.assert_verified`
60
+ * :class:`~spanforge.signing.ChainVerificationResult`
61
+ * :class:`~spanforge.signing.AuditStream`
62
+
63
+ Export backends (RFC §14)
64
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
65
+ * :class:`~spanforge.export.otlp.OTLPExporter`
66
+ * :class:`~spanforge.export.otlp.ResourceAttributes`
67
+ * :class:`~spanforge.export.webhook.WebhookExporter`
68
+ * :class:`~spanforge.export.jsonl.JSONLExporter`
69
+
70
+ Event routing (RFC §14)
71
+ ~~~~~~~~~~~~~~~~~~~~~~~
72
+ * :class:`~spanforge.stream.EventStream`
73
+ * :class:`~spanforge.stream.Exporter`
74
+ * :func:`~spanforge.stream.iter_file`
75
+ * :func:`~spanforge.stream.aiter_file`
76
+
77
+ Observability spans & tracing
78
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
79
+ * :class:`~spanforge._span.SpanEvent`
80
+ * :data:`~spanforge.types.SpanErrorCategory`
81
+
82
+ Debug utilities
83
+ ~~~~~~~~~~~~~~~
84
+ * :func:`~spanforge.debug.print_tree`
85
+ * :func:`~spanforge.debug.summary`
86
+ * :func:`~spanforge.debug.visualize`
87
+
88
+ Governance (RFC §13)
89
+ ~~~~~~~~~~~~~~~~~~~~~
90
+ * :class:`~spanforge.governance.EventGovernancePolicy`
91
+ * :class:`~spanforge.governance.GovernanceViolationError`
92
+ * :class:`~spanforge.governance.GovernanceWarning`
93
+
94
+ Consumer registration (RFC §16)
95
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
96
+ * :class:`~spanforge.consumer.ConsumerRecord`
97
+ * :class:`~spanforge.consumer.ConsumerRegistry`
98
+ * :class:`~spanforge.consumer.IncompatibleSchemaError`
99
+ * :func:`~spanforge.consumer.register_consumer`
100
+ * :func:`~spanforge.consumer.assert_compatible`
101
+
102
+ Validation
103
+ ~~~~~~~~~~
104
+ * :func:`~spanforge.validate.validate_event`
105
+
106
+ Exceptions
107
+ ~~~~~~~~~~
108
+ * :class:`~spanforge.exceptions.LLMSchemaError`
109
+ * :class:`~spanforge.exceptions.SchemaValidationError`
110
+ * :class:`~spanforge.exceptions.SchemaVersionError`
111
+ * :class:`~spanforge.exceptions.ULIDError`
112
+ * :class:`~spanforge.exceptions.SerializationError`
113
+ * :class:`~spanforge.exceptions.DeserializationError`
114
+ * :class:`~spanforge.exceptions.EventTypeError`
115
+ * :class:`~spanforge.exceptions.SigningError`
116
+ * :class:`~spanforge.exceptions.VerificationError`
117
+ * :class:`~spanforge.exceptions.ExportError`
118
+
119
+ Version history
120
+ ---------------
121
+ v2.0 — RFC-0001 SPANFORGE v2.0 SDK baseline. Canonical 36-type EventType
122
+ registry (Appendix B), v2.0 envelope (SCHEMA_VERSION="2.0"),
123
+ microsecond-precision timestamp mandate, RFC §6.3 ULID first-char
124
+ constraint, source pattern allowing mixed-case, SchemaVersionError,
125
+ 11 namespace payload modules (RFC §8–§10), audit chain helpers.
126
+ """
127
+
128
+ from __future__ import annotations
129
+
130
+ import re as _re
131
+
132
+ # F-01: Derive __version__ from package metadata so pyproject.toml is the
133
+ # single source of truth. Falls back to "0.0.0+dev" in editable installs
134
+ # where the metadata may not yet be written.
135
+ from importlib import import_module as _import_module
136
+ from importlib.metadata import PackageNotFoundError as _PackageNotFoundError
137
+ from importlib.metadata import version as _pkg_version
138
+ from pathlib import Path as _Path
139
+
140
+ from spanforge._ansi import BOLD, CYAN, GREEN, RED, RESET, YELLOW, strip_ansi
141
+ from spanforge._ansi import color as ansi_color
142
+ from spanforge._batch_exporter import BatchExporter, get_aggregate_health
143
+
144
+ # ---------------------------------------------------------------------------
145
+ # Phase 5: Hook registry
146
+ # ---------------------------------------------------------------------------
147
+ from spanforge._hooks import AsyncHookFn, HookRegistry, hooks
148
+ from spanforge._server import TraceViewerServer
149
+ from spanforge._span import (
150
+ AgentRunContext,
151
+ AgentRunContextManager,
152
+ AgentStepContext,
153
+ AgentStepContextManager,
154
+ Span,
155
+ SpanContextManager,
156
+ copy_context,
157
+ extract_traceparent,
158
+ inject_traceparent,
159
+ )
160
+ from spanforge._store import (
161
+ TraceStore,
162
+ get_last_agent_run,
163
+ get_store,
164
+ get_trace,
165
+ list_llm_calls,
166
+ list_tool_calls,
167
+ trace_store,
168
+ )
169
+ from spanforge._stream import flush, shutdown
170
+
171
+ # ---------------------------------------------------------------------------
172
+ # Phase 1: Trace object and start_trace()
173
+ # ---------------------------------------------------------------------------
174
+ from spanforge._trace import Trace, start_trace
175
+
176
+ # ---------------------------------------------------------------------------
177
+ # Phase 2: Core tracer + span
178
+ # ---------------------------------------------------------------------------
179
+ from spanforge._tracer import Tracer, tracer
180
+ from spanforge.actor import ActorContext
181
+
182
+ # ---------------------------------------------------------------------------
183
+ # Phase 1: Configuration layer
184
+ # ---------------------------------------------------------------------------
185
+ from spanforge.config import SpanForgeConfig, configure, get_config, interpolate_env
186
+
187
+ # ---------------------------------------------------------------------------
188
+ # T.R.U.S.T. Framework — Consent, HITL, Model Registry, Explainability
189
+ # ---------------------------------------------------------------------------
190
+ from spanforge.consent import (
191
+ ConsentBoundary,
192
+ ConsentRecord,
193
+ check_consent,
194
+ grant_consent,
195
+ revoke_consent,
196
+ )
197
+ from spanforge.consumer import (
198
+ ConsumerRecord,
199
+ ConsumerRegistry,
200
+ IncompatibleSchemaError,
201
+ assert_compatible,
202
+ register_consumer,
203
+ )
204
+ from spanforge.consumer import (
205
+ get_registry as get_consumer_registry,
206
+ )
207
+ from spanforge.cost import (
208
+ BudgetMonitor,
209
+ CostRecord,
210
+ CostTracker,
211
+ budget_alert,
212
+ cost_summary,
213
+ emit_cost_attributed,
214
+ emit_cost_event,
215
+ )
216
+ from spanforge.eval import (
217
+ BehaviourScorer,
218
+ EvalReport,
219
+ EvalRunner,
220
+ EvalScore,
221
+ EvalScorer,
222
+ FaithfulnessScorer,
223
+ PIILeakageScorer,
224
+ RefusalDetectionScorer,
225
+ RegressionDetector,
226
+ record_eval_score,
227
+ )
228
+ from spanforge.event import SCHEMA_VERSION, Event, Tags
229
+ from spanforge.exceptions import (
230
+ AuditStorageError,
231
+ DeserializationError,
232
+ EgressViolationError,
233
+ EventTypeError,
234
+ ExportError,
235
+ LLMSchemaError,
236
+ SchemaValidationError,
237
+ SchemaVersionError,
238
+ SerializationError,
239
+ SigningError,
240
+ ULIDError,
241
+ VerificationError,
242
+ )
243
+ from spanforge.explain import (
244
+ ExplainabilityRecord,
245
+ generate_explanation,
246
+ )
247
+ from spanforge.export import (
248
+ AppendOnlyJSONLExporter,
249
+ JSONLExporter,
250
+ OpenInferenceSpanBridge,
251
+ OTelBridgeExporter,
252
+ OTLPExporter,
253
+ ResourceAttributes,
254
+ SplunkHECExporter,
255
+ SyslogExporter,
256
+ WebhookExporter,
257
+ WORMBackend,
258
+ WORMUploadResult,
259
+ event_to_siem_record,
260
+ span_to_openinference_dict,
261
+ )
262
+ from spanforge.export.otlp_bridge import SpanOTLPBridge, span_to_otlp_dict
263
+ from spanforge.hitl import (
264
+ HITLItem,
265
+ HITLQueue,
266
+ list_pending,
267
+ queue_for_review,
268
+ review_item,
269
+ )
270
+ from spanforge.io import append_jsonl, read_events, read_jsonl, write_events, write_jsonl
271
+
272
+ # ---------------------------------------------------------------------------
273
+ # Namespace payload dataclasses (RFC §8-§10, §11 audit)
274
+ # ---------------------------------------------------------------------------
275
+ from spanforge.namespaces.audit import (
276
+ AuditChainTamperedPayload,
277
+ AuditChainVerifiedPayload,
278
+ AuditKeyRotatedPayload,
279
+ )
280
+ from spanforge.namespaces.cache import (
281
+ CacheEvictedPayload,
282
+ CacheHitPayload,
283
+ CacheMissPayload,
284
+ CacheWrittenPayload,
285
+ )
286
+ from spanforge.namespaces.consent import ConsentPayload
287
+ from spanforge.namespaces.cost import (
288
+ CostAttributedPayload,
289
+ CostSessionRecordedPayload,
290
+ CostTokenRecordedPayload,
291
+ )
292
+ from spanforge.namespaces.diff import (
293
+ DiffComputedPayload,
294
+ DiffRegressionFlaggedPayload,
295
+ )
296
+ from spanforge.namespaces.eval_ import (
297
+ EvalRegressionDetectedPayload,
298
+ EvalScenarioCompletedPayload,
299
+ EvalScenarioStartedPayload,
300
+ EvalScoreRecordedPayload,
301
+ )
302
+ from spanforge.namespaces.fence import (
303
+ FenceMaxRetriesExceededPayload,
304
+ FenceRetryTriggeredPayload,
305
+ FenceValidatedPayload,
306
+ )
307
+ from spanforge.namespaces.guard import GuardPayload
308
+ from spanforge.namespaces.hitl import HITLPayload
309
+ from spanforge.namespaces.prompt import (
310
+ PromptRenderedPayload,
311
+ PromptTemplateLoadedPayload,
312
+ PromptVersionChangedPayload,
313
+ )
314
+ from spanforge.namespaces.redact import (
315
+ RedactAppliedPayload,
316
+ RedactPhiDetectedPayload,
317
+ RedactPiiDetectedPayload,
318
+ )
319
+ from spanforge.namespaces.template import (
320
+ TemplateRegisteredPayload,
321
+ TemplateValidationFailedPayload,
322
+ TemplateVariableBoundPayload,
323
+ )
324
+ from spanforge.namespaces.trace import (
325
+ AgentRunPayload,
326
+ AgentStepPayload,
327
+ CostBreakdown,
328
+ DecisionPoint,
329
+ GenAIOperationName,
330
+ GenAISystem,
331
+ ModelInfo,
332
+ PricingTier,
333
+ ReasoningStep,
334
+ SpanEvent,
335
+ SpanKind,
336
+ SpanPayload,
337
+ TokenUsage,
338
+ ToolCall,
339
+ )
340
+ from spanforge.normalizer import GenericNormalizer, ProviderNormalizer
341
+ from spanforge.plugins import discover as discover_plugins
342
+ from spanforge.processor import (
343
+ NoopSpanProcessor,
344
+ ProcessorChain,
345
+ SpanProcessor,
346
+ add_processor,
347
+ clear_processors,
348
+ )
349
+ from spanforge.redact import (
350
+ DPDP_PATTERNS,
351
+ PII_TYPES,
352
+ PIINotRedactedError,
353
+ PIIScanResult,
354
+ Redactable,
355
+ RedactionPolicy,
356
+ RedactionResult,
357
+ Sensitivity,
358
+ assert_redacted,
359
+ contains_pii,
360
+ scan_payload,
361
+ )
362
+ from spanforge.regression import RegressionDetector as PassFailRegressionDetector
363
+ from spanforge.regression import RegressionReport
364
+ from spanforge.regression import compare as compare_regressions
365
+ from spanforge.sampling import (
366
+ AlwaysOffSampler,
367
+ AlwaysOnSampler,
368
+ ComplianceSampler,
369
+ ParentBasedSampler,
370
+ RatioSampler,
371
+ RuleBasedSampler,
372
+ Sampler,
373
+ TailBasedSampler,
374
+ bypass_sampling,
375
+ )
376
+ from spanforge.schema import SchemaValidationError as JsonSchemaValidationError
377
+ from spanforge.schema import validate as validate_json_schema
378
+ from spanforge.schema import validate_strict as validate_json_schema_strict
379
+ from spanforge.signing import (
380
+ AsyncAuditStream,
381
+ AuditStream,
382
+ ChainVerificationResult,
383
+ DictKeyResolver,
384
+ EnvKeyResolver,
385
+ KeyResolver,
386
+ StaticKeyResolver,
387
+ assert_verified,
388
+ check_key_expiry,
389
+ derive_key,
390
+ sign,
391
+ validate_key_strength,
392
+ verify,
393
+ verify_chain,
394
+ )
395
+ from spanforge.stats import latency_summary, percentile
396
+ from spanforge.stream import EventStream, Exporter, aiter_file, iter_file
397
+ from spanforge.trace import trace
398
+ from spanforge.types import (
399
+ EventType,
400
+ SpanErrorCategory,
401
+ get_by_value,
402
+ is_registered,
403
+ namespace_of,
404
+ validate_custom,
405
+ )
406
+ from spanforge.ulid import extract_timestamp_ms
407
+ from spanforge.ulid import generate as generate_ulid
408
+ from spanforge.ulid import validate as validate_ulid
409
+ from spanforge.validate import validate_event
410
+
411
+
412
+ def _resolve_version() -> str:
413
+ """Resolve the package version from the source tree or installed metadata."""
414
+ pyproject = _Path(__file__).resolve().parents[2] / "pyproject.toml"
415
+ if pyproject.exists():
416
+ match = _re.search(
417
+ r'(?m)^version\s*=\s*"([^"]+)"\s*$',
418
+ pyproject.read_text(encoding="utf-8"),
419
+ )
420
+ if match is not None:
421
+ return match.group(1)
422
+ try:
423
+ return _pkg_version("spanforge")
424
+ except _PackageNotFoundError:
425
+ return "0.0.0+dev"
426
+
427
+
428
+ __version__: str = _resolve_version()
429
+
430
+ #: RFC-0001 SPANFORGE conformance profile label.
431
+ from typing import Final as _Final
432
+
433
+ CONFORMANCE_PROFILE: _Final[str] = "SPANFORGE-Enterprise-2.0"
434
+
435
+ _LAZY_MODULE_EXPORTS: dict[str, str] = {
436
+ "auto": "spanforge.auto",
437
+ "metrics": "spanforge.metrics",
438
+ "sdk": "spanforge.sdk",
439
+ "testing": "spanforge.testing",
440
+ }
441
+
442
+ _LAZY_ATTR_EXPORTS: dict[str, tuple[str, str]] = {
443
+ "ChatCompletionResponse": ("spanforge.http", "ChatCompletionResponse"),
444
+ "InspectorSession": ("spanforge.inspect", "InspectorSession"),
445
+ "MetricsSummary": ("spanforge.metrics_export", "MetricsSummary"),
446
+ "MigrationStats": ("spanforge.migrate", "MigrationStats"),
447
+ "ModelRegistry": ("spanforge.model_registry", "ModelRegistry"),
448
+ "ModelRegistryEntry": ("spanforge.model_registry", "ModelRegistryEntry"),
449
+ "PrometheusMetricsExporter": ("spanforge.metrics_export", "PrometheusMetricsExporter"),
450
+ "PromptRegistry": ("spanforge.prompt_registry", "PromptRegistry"),
451
+ "PromptVersion": ("spanforge.prompt_registry", "PromptVersion"),
452
+ "ToolCallRecord": ("spanforge.inspect", "ToolCallRecord"),
453
+ "chat_completion": ("spanforge.http", "chat_completion"),
454
+ "check_egress": ("spanforge.egress", "check_egress"),
455
+ "deprecate_model": ("spanforge.model_registry", "deprecate_model"),
456
+ "get_model": ("spanforge.model_registry", "get_model"),
457
+ "get_prompt_version": ("spanforge.prompt_registry", "get_prompt_version"),
458
+ "inspect_trace": ("spanforge.inspect", "inspect_trace"),
459
+ "list_models": ("spanforge.model_registry", "list_models"),
460
+ "migrate_file": ("spanforge.migrate", "migrate_file"),
461
+ "migrate_from_langsmith": ("spanforge.migrate", "migrate_from_langsmith"),
462
+ "print_tree": ("spanforge.debug", "print_tree"),
463
+ "register_model": ("spanforge.model_registry", "register_model"),
464
+ "register_prompt": ("spanforge.prompt_registry", "register_prompt"),
465
+ "render_prompt": ("spanforge.prompt_registry", "render_prompt"),
466
+ "retire_model": ("spanforge.model_registry", "retire_model"),
467
+ "serve_metrics": ("spanforge.metrics_export", "serve_metrics"),
468
+ "summary": ("spanforge.debug", "summary"),
469
+ "v1_to_v2": ("spanforge.migrate", "v1_to_v2"),
470
+ "visualize": ("spanforge.debug", "visualize"),
471
+ }
472
+
473
+ __all__: list[str] = [
474
+ # Upstream utilities
475
+ "BOLD",
476
+ # Conformance
477
+ "CONFORMANCE_PROFILE",
478
+ "CYAN",
479
+ # DPDP compliance patterns
480
+ "DPDP_PATTERNS",
481
+ "GREEN",
482
+ "PII_TYPES",
483
+ "RED",
484
+ "RESET",
485
+ "SCHEMA_VERSION",
486
+ "YELLOW",
487
+ # Actor identity context
488
+ "ActorContext",
489
+ "AgentRunContext",
490
+ "AgentRunContextManager",
491
+ "AgentRunPayload",
492
+ "AgentStepContext",
493
+ "AgentStepContextManager",
494
+ "AgentStepPayload",
495
+ # Sampling
496
+ "AlwaysOffSampler",
497
+ "AlwaysOnSampler",
498
+ # Append-only export + WORM (SF-13)
499
+ "AppendOnlyJSONLExporter",
500
+ # Async audit stream (GA-06)
501
+ "AsyncAuditStream",
502
+ # Phase 5 — Hooks
503
+ "AsyncHookFn",
504
+ "AuditChainTamperedPayload",
505
+ "AuditChainVerifiedPayload",
506
+ # audit
507
+ "AuditKeyRotatedPayload",
508
+ "AuditStorageError",
509
+ "AuditStream",
510
+ # Batch exporter
511
+ "BatchExporter",
512
+ "get_aggregate_health",
513
+ "BehaviourScorer",
514
+ # Tool 2 — Cost Calculation Engine
515
+ "BudgetMonitor",
516
+ "CacheEvictedPayload",
517
+ # cache
518
+ "CacheHitPayload",
519
+ "CacheMissPayload",
520
+ "CacheWrittenPayload",
521
+ "ChainVerificationResult",
522
+ "ChatCompletionResponse",
523
+ # Compliance sampling (SF-16)
524
+ "ComplianceSampler",
525
+ # ---------------------------------------------------------------------------
526
+ # T.R.U.S.T. Framework — Consent, HITL, Model Registry, Explainability
527
+ # ---------------------------------------------------------------------------
528
+ # Consent boundary
529
+ "ConsentBoundary",
530
+ "ConsentPayload",
531
+ "ConsentRecord",
532
+ # Consumer registration (RFC §16)
533
+ "ConsumerRecord",
534
+ "ConsumerRegistry",
535
+ "CostAttributedPayload",
536
+ "CostBreakdown",
537
+ "CostRecord",
538
+ "CostSessionRecordedPayload",
539
+ # cost
540
+ "CostTokenRecordedPayload",
541
+ "CostTracker",
542
+ "DecisionPoint",
543
+ "DeserializationError",
544
+ "DictKeyResolver",
545
+ # diff
546
+ "DiffComputedPayload",
547
+ "DiffRegressionFlaggedPayload",
548
+ # Egress enforcement exceptions (SF-14)
549
+ "EgressViolationError",
550
+ "EnvKeyResolver",
551
+ "EvalRegressionDetectedPayload",
552
+ # Evaluation hooks
553
+ "EvalReport",
554
+ "EvalRunner",
555
+ "EvalScenarioCompletedPayload",
556
+ "EvalScenarioStartedPayload",
557
+ "EvalScore",
558
+ # eval
559
+ "EvalScoreRecordedPayload",
560
+ "EvalScorer",
561
+ # Core envelope
562
+ "Event",
563
+ # Event routing (RFC §14)
564
+ "EventStream",
565
+ # Event types
566
+ "EventType",
567
+ "EventTypeError",
568
+ # Explainability
569
+ "ExplainabilityRecord",
570
+ "ExportError",
571
+ "Exporter",
572
+ "FaithfulnessScorer",
573
+ "FenceMaxRetriesExceededPayload",
574
+ "FenceRetryTriggeredPayload",
575
+ # fence
576
+ "FenceValidatedPayload",
577
+ "GenAIOperationName",
578
+ # Namespace payload dataclasses (RFC §8-§11)
579
+ # trace — value objects
580
+ "GenAISystem",
581
+ "GenericNormalizer",
582
+ # guard
583
+ "GuardPayload",
584
+ # Human-in-the-loop
585
+ "HITLItem",
586
+ "HITLPayload",
587
+ "HITLQueue",
588
+ "HookRegistry",
589
+ "IncompatibleSchemaError",
590
+ # Tool 3 — Tool Call Inspector
591
+ "InspectorSession",
592
+ "JSONLExporter",
593
+ "JsonSchemaValidationError",
594
+ # Multi-tenant key resolvers (GA-04)
595
+ "KeyResolver",
596
+ # Exceptions
597
+ "LLMSchemaError",
598
+ # Prometheus metrics
599
+ "MetricsSummary",
600
+ # Schema migration (GA-05)
601
+ "MigrationStats",
602
+ "ModelInfo",
603
+ # Model registry
604
+ "ModelRegistry",
605
+ "ModelRegistryEntry",
606
+ "NoopSpanProcessor",
607
+ "OpenInferenceSpanBridge",
608
+ "OTLPExporter",
609
+ # Export backends (RFC §14)
610
+ "OTelBridgeExporter",
611
+ "PIILeakageScorer",
612
+ "PIINotRedactedError",
613
+ # PII deep scan (GA-03)
614
+ "PIIScanResult",
615
+ "ParentBasedSampler",
616
+ "PassFailRegressionDetector",
617
+ "PricingTier",
618
+ "ProcessorChain",
619
+ "PrometheusMetricsExporter",
620
+ # Prompt registry
621
+ "PromptRegistry",
622
+ # prompt
623
+ "PromptRenderedPayload",
624
+ "PromptTemplateLoadedPayload",
625
+ "PromptVersion",
626
+ "PromptVersionChangedPayload",
627
+ # Normalizer (RFC-0001 §10.4)
628
+ "ProviderNormalizer",
629
+ "RatioSampler",
630
+ "ReasoningStep",
631
+ "RedactAppliedPayload",
632
+ "RedactPhiDetectedPayload",
633
+ # redact
634
+ "RedactPiiDetectedPayload",
635
+ "Redactable",
636
+ "RedactionPolicy",
637
+ "RedactionResult",
638
+ "RefusalDetectionScorer",
639
+ "RegressionDetector",
640
+ "RegressionReport",
641
+ "ResourceAttributes",
642
+ "RuleBasedSampler",
643
+ "Sampler",
644
+ "SchemaValidationError",
645
+ "SchemaVersionError",
646
+ # PII Redaction (RFC §12)
647
+ "Sensitivity",
648
+ "SerializationError",
649
+ "SigningError",
650
+ "Span",
651
+ "SpanContextManager",
652
+ "SpanErrorCategory",
653
+ "SpanEvent",
654
+ # Phase 1 — Configuration
655
+ "SpanForgeConfig",
656
+ "SpanKind",
657
+ "SpanOTLPBridge",
658
+ "SplunkHECExporter",
659
+ # trace — payloads
660
+ "SpanPayload",
661
+ # Span processor pipeline
662
+ "SpanProcessor",
663
+ "StaticKeyResolver",
664
+ "SyslogExporter",
665
+ "Tags",
666
+ "TailBasedSampler",
667
+ # template
668
+ "TemplateRegisteredPayload",
669
+ "TemplateValidationFailedPayload",
670
+ "TemplateVariableBoundPayload",
671
+ "TokenUsage",
672
+ "ToolCall",
673
+ "ToolCallRecord",
674
+ # Phase 1 — Trace object
675
+ "Trace",
676
+ "TraceStore",
677
+ # Local trace viewer
678
+ "TraceViewerServer",
679
+ # Phase 2 — Tracer + Span
680
+ "Tracer",
681
+ "ULIDError",
682
+ "VerificationError",
683
+ "WORMBackend",
684
+ "WORMUploadResult",
685
+ "WebhookExporter",
686
+ # Metadata
687
+ "__version__",
688
+ "add_processor",
689
+ "aiter_file",
690
+ "ansi_color",
691
+ "append_jsonl",
692
+ "assert_compatible",
693
+ "assert_redacted",
694
+ "assert_verified",
695
+ "auto",
696
+ "budget_alert",
697
+ "bypass_sampling",
698
+ "chat_completion",
699
+ "check_consent",
700
+ # Egress enforcement (SF-14)
701
+ "check_egress",
702
+ # Key management (GA-01)
703
+ "check_key_expiry",
704
+ "clear_processors",
705
+ "compare_regressions",
706
+ "configure",
707
+ "contains_pii",
708
+ # Context propagation helper (Phase 1)
709
+ "copy_context",
710
+ "cost_summary",
711
+ "deprecate_model",
712
+ "derive_key",
713
+ "discover_plugins",
714
+ "emit_cost_attributed",
715
+ "emit_cost_event",
716
+ "extract_timestamp_ms",
717
+ # W3C context propagation
718
+ "extract_traceparent",
719
+ # Graceful shutdown
720
+ "flush",
721
+ "generate_explanation",
722
+ # ULID
723
+ "generate_ulid",
724
+ "get_by_value",
725
+ "get_config",
726
+ "get_consumer_registry",
727
+ "get_last_agent_run",
728
+ "get_model",
729
+ "get_prompt_version",
730
+ "get_store",
731
+ "get_trace",
732
+ "grant_consent",
733
+ "hooks",
734
+ "inject_traceparent",
735
+ "inspect_trace",
736
+ "interpolate_env",
737
+ "is_registered",
738
+ "iter_file",
739
+ "latency_summary",
740
+ "list_llm_calls",
741
+ "list_models",
742
+ "list_pending",
743
+ "list_tool_calls",
744
+ # Phase 4 — Metrics + trace store
745
+ "metrics",
746
+ "migrate_file",
747
+ "migrate_from_langsmith",
748
+ "namespace_of",
749
+ "percentile",
750
+ # Phase 3 — Debug utilities
751
+ "print_tree",
752
+ "queue_for_review",
753
+ "read_events",
754
+ "read_jsonl",
755
+ "record_eval_score",
756
+ "register_consumer",
757
+ "register_model",
758
+ "register_prompt",
759
+ "render_prompt",
760
+ "retire_model",
761
+ "review_item",
762
+ "revoke_consent",
763
+ "scan_payload",
764
+ "serve_metrics",
765
+ "shutdown",
766
+ # HMAC Signing & Audit Chain (RFC §11)
767
+ "sign",
768
+ "span_to_otlp_dict",
769
+ "span_to_openinference_dict",
770
+ "start_trace",
771
+ "strip_ansi",
772
+ "summary",
773
+ "testing",
774
+ # Tool 1 — @trace() decorator + OTLP bridge
775
+ "trace",
776
+ "trace_store",
777
+ "tracer",
778
+ "v1_to_v2",
779
+ "validate_custom",
780
+ # Validation
781
+ "validate_event",
782
+ "validate_json_schema",
783
+ "validate_json_schema_strict",
784
+ "validate_key_strength",
785
+ "validate_ulid",
786
+ "verify",
787
+ "verify_chain",
788
+ "visualize",
789
+ "write_events",
790
+ "write_jsonl",
791
+ "event_to_siem_record",
792
+ ]
793
+
794
+
795
+ def __getattr__(name: str) -> object:
796
+ """Resolve selected module-style exports lazily from the package root."""
797
+ module_name = _LAZY_MODULE_EXPORTS.get(name)
798
+ if module_name is not None:
799
+ module = _import_module(module_name)
800
+ globals()[name] = module
801
+ return module
802
+
803
+ attr_spec = _LAZY_ATTR_EXPORTS.get(name)
804
+ if attr_spec is None:
805
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
806
+
807
+ module = _import_module(attr_spec[0])
808
+ value = getattr(module, attr_spec[1])
809
+ globals()[name] = value
810
+ return value
811
+
812
+
813
+ def __dir__() -> list[str]:
814
+ """Include lazy exports in interactive attribute discovery."""
815
+ return sorted(set(globals()) | set(__all__) | set(_LAZY_MODULE_EXPORTS) | set(_LAZY_ATTR_EXPORTS))