gateframe 0.1.0__tar.gz → 0.2.1__tar.gz

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 (44) hide show
  1. {gateframe-0.1.0 → gateframe-0.2.1}/LICENSE +1 -1
  2. gateframe-0.2.1/PKG-INFO +325 -0
  3. gateframe-0.2.1/README.md +288 -0
  4. gateframe-0.2.1/gateframe/__init__.py +27 -0
  5. gateframe-0.2.1/gateframe/audit/exporters.py +112 -0
  6. gateframe-0.2.1/gateframe/audit/log.py +110 -0
  7. gateframe-0.2.1/gateframe/audit/trend.py +275 -0
  8. gateframe-0.2.1/gateframe/cli/inspect.py +73 -0
  9. gateframe-0.2.1/gateframe/cli/main.py +49 -0
  10. gateframe-0.2.1/gateframe/cli/replay.py +77 -0
  11. gateframe-0.2.1/gateframe/cli/trend.py +53 -0
  12. gateframe-0.2.1/gateframe/core/context.py +154 -0
  13. {gateframe-0.1.0 → gateframe-0.2.1}/gateframe/core/contract.py +22 -3
  14. gateframe-0.2.1/gateframe/core/escalation.py +102 -0
  15. gateframe-0.2.1/gateframe/core/retry.py +106 -0
  16. gateframe-0.2.1/gateframe/integrations/anthropic.py +78 -0
  17. gateframe-0.2.1/gateframe/integrations/langchain.py +96 -0
  18. gateframe-0.2.1/gateframe/integrations/litellm.py +82 -0
  19. gateframe-0.2.1/gateframe/integrations/openai.py +82 -0
  20. gateframe-0.2.1/gateframe/rules/__init__.py +1 -0
  21. gateframe-0.2.1/gateframe/rules/boundary.py +58 -0
  22. gateframe-0.2.1/gateframe/rules/confidence.py +112 -0
  23. gateframe-0.2.1/gateframe/rules/semantic.py +99 -0
  24. gateframe-0.2.1/gateframe.egg-info/PKG-INFO +325 -0
  25. gateframe-0.2.1/gateframe.egg-info/SOURCES.txt +36 -0
  26. gateframe-0.2.1/gateframe.egg-info/entry_points.txt +2 -0
  27. gateframe-0.2.1/gateframe.egg-info/requires.txt +24 -0
  28. {gateframe-0.1.0 → gateframe-0.2.1}/pyproject.toml +13 -1
  29. {gateframe-0.1.0 → gateframe-0.2.1}/setup.cfg +4 -4
  30. gateframe-0.1.0/PKG-INFO +0 -160
  31. gateframe-0.1.0/README.md +0 -135
  32. gateframe-0.1.0/gateframe/audit/log.py +0 -69
  33. gateframe-0.1.0/gateframe.egg-info/PKG-INFO +0 -160
  34. gateframe-0.1.0/gateframe.egg-info/SOURCES.txt +0 -17
  35. gateframe-0.1.0/gateframe.egg-info/requires.txt +0 -7
  36. {gateframe-0.1.0/gateframe → gateframe-0.2.1/gateframe/audit}/__init__.py +0 -0
  37. {gateframe-0.1.0/gateframe/audit → gateframe-0.2.1/gateframe/cli}/__init__.py +0 -0
  38. {gateframe-0.1.0 → gateframe-0.2.1}/gateframe/core/__init__.py +0 -0
  39. {gateframe-0.1.0 → gateframe-0.2.1}/gateframe/core/failure.py +0 -0
  40. {gateframe-0.1.0 → gateframe-0.2.1}/gateframe/core/rule.py +0 -0
  41. {gateframe-0.1.0/gateframe/rules → gateframe-0.2.1/gateframe/integrations}/__init__.py +0 -0
  42. {gateframe-0.1.0 → gateframe-0.2.1}/gateframe/rules/structural.py +0 -0
  43. {gateframe-0.1.0 → gateframe-0.2.1}/gateframe.egg-info/dependency_links.txt +0 -0
  44. {gateframe-0.1.0 → gateframe-0.2.1}/gateframe.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 Practical Mind
3
+ Copyright (c) 2025 Baran Yalcin
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -0,0 +1,325 @@
1
+ Metadata-Version: 2.4
2
+ Name: gateframe
3
+ Version: 0.2.1
4
+ Summary: Behavioral validation for LLM outputs in production workflows.
5
+ License-Expression: MIT
6
+ Keywords: llm,validation,behavioral,workflow,ai
7
+ Classifier: Development Status :: 3 - Alpha
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Typing :: Typed
15
+ Requires-Python: >=3.10
16
+ Description-Content-Type: text/markdown
17
+ License-File: LICENSE
18
+ Requires-Dist: pydantic<3.0,>=2.0
19
+ Requires-Dist: structlog>=23.0
20
+ Provides-Extra: dev
21
+ Requires-Dist: pytest>=7.0; extra == "dev"
22
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
23
+ Requires-Dist: ruff>=0.4.0; extra == "dev"
24
+ Provides-Extra: anthropic
25
+ Requires-Dist: anthropic>=0.30.0; extra == "anthropic"
26
+ Provides-Extra: openai
27
+ Requires-Dist: openai>=1.0.0; extra == "openai"
28
+ Provides-Extra: litellm
29
+ Requires-Dist: litellm>=1.0.0; extra == "litellm"
30
+ Provides-Extra: otlp
31
+ Requires-Dist: opentelemetry-api>=1.20.0; extra == "otlp"
32
+ Requires-Dist: opentelemetry-sdk>=1.20.0; extra == "otlp"
33
+ Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.20.0; extra == "otlp"
34
+ Provides-Extra: langchain
35
+ Requires-Dist: langchain>=0.1.0; extra == "langchain"
36
+ Dynamic: license-file
37
+
38
+ # Gateframe
39
+
40
+ [![CI](https://github.com/baranylcn/gateframe/actions/workflows/ci.yml/badge.svg)](https://github.com/baranylcn/gateframe/actions/workflows/ci.yml)
41
+ [![PyPI](https://img.shields.io/pypi/v/gateframe)](https://pypi.org/project/gateframe/)
42
+ [![Python](https://img.shields.io/pypi/pyversions/gateframe)](https://pypi.org/project/gateframe/)
43
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
44
+
45
+ Behavioral validation for LLM outputs in production workflows.
46
+
47
+ Schema validation, "does this JSON have the right keys?", is a solved problem. Instructor, Pydantic AI, and similar tools handle it well. gateframe solves a different problem: **does this output behave correctly given the context it was generated in?** Does it stay within the decision boundaries this workflow requires? When it fails, does it fail in a way your system can recover from, or does it fail silently?
48
+
49
+ ```python
50
+ from pydantic import BaseModel
51
+ from gateframe import (
52
+ ValidationContract,
53
+ StructuralRule,
54
+ BoundaryRule,
55
+ ConfidenceRule,
56
+ AllowedValues,
57
+ FailureMode,
58
+ )
59
+
60
+
61
+ class TriageDecision(BaseModel):
62
+ action: str
63
+ priority: str
64
+ confidence: float
65
+ rationale: str
66
+
67
+
68
+ contract = ValidationContract(
69
+ name="triage_decision",
70
+ rules=[
71
+ StructuralRule(schema=TriageDecision),
72
+ BoundaryRule(
73
+ check=AllowedValues("action", {"treat", "observe", "refer", "discharge"}),
74
+ name="action_boundary",
75
+ failure_message="Action must be one of: treat, observe, refer, discharge.",
76
+ ),
77
+ ConfidenceRule(field="confidence", minimum=0.7),
78
+ ],
79
+ )
80
+
81
+ result = contract.validate(
82
+ {
83
+ "action": "prescribe", # not in allowed set -> HARD_FAIL
84
+ "priority": "high",
85
+ "confidence": 0.52, # below 0.7 -> SOFT_FAIL
86
+ "rationale": "...",
87
+ }
88
+ )
89
+
90
+ print(result.passed) # False
91
+ for failure in result.failures:
92
+ print(f"[{failure.failure_mode.value}] {failure.rule_name}: {failure.message}")
93
+ # [hard_fail] action_boundary: Action must be one of: treat, observe, refer, discharge.
94
+ # [soft_fail] confidence_check: Confidence 0.52 is below minimum threshold 0.7.
95
+ ```
96
+
97
+ ---
98
+
99
+ ## The problem
100
+
101
+ Most LLM pipelines validate outputs the same way: parse the JSON, check the schema, move on. That catches structural errors. It misses the errors that actually cause production incidents:
102
+
103
+ - A model recommends an action that is structurally valid but outside its authorized scope
104
+ - Confidence is low but the workflow proceeds as if it weren't
105
+ - A soft failure in step 2 silently degrades the reliability of everything downstream
106
+ - A validation failure gives you `False`, and no context for debugging
107
+
108
+ gateframe makes these failures explicit, structured, and recoverable.
109
+
110
+ ---
111
+
112
+ ## Failure modes
113
+
114
+ gateframe distinguishes four failure types instead of binary pass/fail.
115
+
116
+ **`HARD_FAIL`**, Stop. The output violates a hard constraint that cannot be auto-recovered.
117
+
118
+ ```python
119
+ # Model chose an action outside its authorized scope
120
+ BoundaryRule(
121
+ check=AllowedValues("action", {"treat", "observe", "refer"}),
122
+ failure_mode=FailureMode.HARD_FAIL, # default for BoundaryRule
123
+ )
124
+ ```
125
+
126
+ **`SOFT_FAIL`**, Flag and continue with degraded confidence. Something is off but not critical enough to halt.
127
+
128
+ ```python
129
+ # Model confidence is low, continue but track the degradation
130
+ ConfidenceRule(
131
+ field="confidence",
132
+ minimum=0.7,
133
+ failure_mode=FailureMode.SOFT_FAIL, # default for ConfidenceRule
134
+ )
135
+ ```
136
+
137
+ **`RETRY`**, Re-prompt with the failure context. The output is likely fixable by trying again.
138
+
139
+ ```python
140
+ # Malformed output that might parse correctly on a second attempt
141
+ StructuralRule(schema=MyOutput, failure_mode=FailureMode.RETRY)
142
+ ```
143
+
144
+ **`SILENT_FAIL`**, The most dangerous kind. The output looks valid but violates a semantic or boundary rule. gateframe makes these visible instead of letting them pass through undetected.
145
+
146
+ ```python
147
+ SemanticRule(
148
+ check=lambda output, **ctx: output["severity"] != "low" or output["escalated"] is False,
149
+ failure_mode=FailureMode.SILENT_FAIL,
150
+ failure_message="Low-severity cases should not be auto-escalated.",
151
+ )
152
+ ```
153
+
154
+ ---
155
+
156
+ ## Multi-step workflow validation
157
+
158
+ Validation state carries forward across steps. A soft failure in step 2 degrades the confidence score that step 4 sees.
159
+
160
+ ```python
161
+ from gateframe import WorkflowContext, ValidationContract, EscalationRouter
162
+ from gateframe.audit.log import AuditLog
163
+
164
+ ctx = WorkflowContext(workflow_id="incident_response_001", escalation_threshold=0.5)
165
+ router = EscalationRouter()
166
+ audit = AuditLog()
167
+
168
+ # Step 1
169
+ result1 = contract_step1.validate(output1)
170
+ ctx.update(result1)
171
+ audit.record(result1, workflow_context=ctx)
172
+
173
+ # Step 2, ctx carries forward degraded confidence from step 1
174
+ result2 = contract_step2.validate(output2)
175
+ ctx.update(result2)
176
+ audit.record(result2, workflow_context=ctx)
177
+
178
+ print(ctx.confidence) # degraded from 1.0 by soft failures
179
+ print(ctx.threshold_breached) # True if confidence < escalation_threshold
180
+
181
+ if ctx.threshold_breached:
182
+ escalation = router.route_threshold_breach(ctx)
183
+ print(escalation.route.value) # "human_review", "abort", etc.
184
+ ```
185
+
186
+ ---
187
+
188
+ ## Provider integrations
189
+
190
+ gateframe validates outputs from any provider. Integrations are thin wrappers, gateframe does not import any LLM SDK at the core level.
191
+
192
+ ```python
193
+ # OpenAI
194
+ from gateframe.integrations.openai import OpenAIValidator
195
+
196
+ validator = OpenAIValidator(contract, parse_json=True)
197
+ result = validator.validate(openai_completion)
198
+
199
+ # Anthropic
200
+ from gateframe.integrations.anthropic import AnthropicValidator
201
+
202
+ validator = AnthropicValidator(contract, parse_json=True)
203
+ result = validator.validate(anthropic_message)
204
+
205
+ # LiteLLM
206
+ from gateframe.integrations.litellm import LiteLLMValidator
207
+
208
+ validator = LiteLLMValidator(contract, parse_json=True)
209
+ result = validator.validate(litellm_response)
210
+
211
+ # LangChain
212
+ from gateframe.integrations.langchain import LangChainValidator
213
+
214
+ validator = LangChainValidator(contract, parse_json=False)
215
+ result = validator.validate(chain_output)
216
+ ```
217
+
218
+ Install the integration you need:
219
+
220
+ ```bash
221
+ pip install "gateframe[openai]"
222
+ pip install "gateframe[anthropic]"
223
+ pip install "gateframe[litellm]"
224
+ pip install "gateframe[langchain]"
225
+ ```
226
+
227
+ ---
228
+
229
+ ## Audit trail
230
+
231
+ Every validation event is logged with structured context. Use the built-in exporters or implement your own.
232
+
233
+ ```python
234
+ from gateframe.audit.log import AuditLog
235
+ from gateframe.audit.exporters import JsonFileExporter
236
+
237
+ audit = AuditLog(exporters=[JsonFileExporter("audit.jsonl")])
238
+ audit.record(result, workflow_context=ctx)
239
+ audit.flush()
240
+ ```
241
+
242
+ Each entry includes: timestamp, contract name, rules applied, rules failed, failure details, workflow ID, and accumulated confidence score.
243
+
244
+ ---
245
+
246
+ ## Trend analysis
247
+
248
+ `ContractTrendAnalyzer` reads an existing JSONL audit log and computes per-contract pass-rate trends across workflow runs. Use it to detect reliability regressions before they become incidents.
249
+
250
+ ```python
251
+ from pathlib import Path
252
+ from gateframe.audit.trend import ContractTrendAnalyzer
253
+
254
+ analyzer = ContractTrendAnalyzer(Path("audit.jsonl"), window=20)
255
+ report = analyzer.analyze()
256
+
257
+ if report.any_regression:
258
+ for ct in report.regressions:
259
+ print(f"{ct.contract_name}: {ct.direction} (slope={ct.slope:.4f})")
260
+ ```
261
+
262
+ The `window` parameter controls how many most-recent workflow runs are included. A contract is flagged as regressing when its pass-rate slope falls below `-0.02` (two percentage points per run) by default.
263
+
264
+ ---
265
+
266
+ ## When to use gateframe
267
+
268
+ Use it when:
269
+ - You need to validate LLM output behavior beyond schema checks, decision boundaries, scope enforcement, semantic constraints
270
+ - You need structured, recoverable failure records rather than bare exceptions
271
+ - You're running multi-step workflows where soft failures in early steps should affect confidence downstream
272
+ - You need an audit trail for post-incident debugging
273
+
274
+ Don't use it when:
275
+ - You only need schema extraction from LLM outputs, use [Instructor](https://github.com/jxnl/instructor) or [Pydantic AI](https://ai.pydantic.dev/)
276
+ - You need offline model evaluation or benchmarking, use [DeepEval](https://github.com/confident-ai/deepeval) or [RAGAS](https://github.com/explodinggradients/ragas)
277
+ - You need content safety filtering, use a dedicated guardrails tool
278
+
279
+ ---
280
+
281
+ ## Installation
282
+
283
+ ```bash
284
+ pip install gateframe
285
+ ```
286
+
287
+ For development:
288
+
289
+ ```bash
290
+ git clone https://github.com/baranylcn/gateframe.git
291
+ cd gateframe
292
+ pip install -e ".[dev]"
293
+ python -m pytest tests/ -v
294
+ ```
295
+
296
+ ---
297
+
298
+ ## Examples
299
+
300
+ **[triage_workflow](examples/triage_workflow/)**, 3-step medical triage pipeline. Demonstrates StructuralRule, BoundaryRule, ConfidenceRule, and WorkflowContext together. Step 2 has confidence below threshold, shows how SOFT_FAIL degrades the workflow score without halting it.
301
+
302
+ **[rag_output](examples/rag_output/)**, RAG answer validation with two scenarios. Scenario B demonstrates simultaneous soft failures (low confidence + ungrounded answer) and how they accumulate in the workflow context.
303
+
304
+ **[agent_pipeline](examples/agent_pipeline/)**, 4-step agent workflow with escalation. Demonstrates how multiple soft failures across steps push cumulative confidence below the escalation threshold.
305
+
306
+ ---
307
+
308
+ ## CLI
309
+
310
+ ```bash
311
+ # Inspect a contract file, lists all contracts and their rules
312
+ gateframe inspect contracts.py
313
+
314
+ # Replay an audit log
315
+ gateframe replay audit.jsonl
316
+
317
+ # Detect pass-rate regressions across workflow runs
318
+ gateframe trend audit.jsonl --window 20
319
+ ```
320
+
321
+ ---
322
+
323
+ ## License
324
+
325
+ MIT, see [LICENSE](LICENSE).
@@ -0,0 +1,288 @@
1
+ # Gateframe
2
+
3
+ [![CI](https://github.com/baranylcn/gateframe/actions/workflows/ci.yml/badge.svg)](https://github.com/baranylcn/gateframe/actions/workflows/ci.yml)
4
+ [![PyPI](https://img.shields.io/pypi/v/gateframe)](https://pypi.org/project/gateframe/)
5
+ [![Python](https://img.shields.io/pypi/pyversions/gateframe)](https://pypi.org/project/gateframe/)
6
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
7
+
8
+ Behavioral validation for LLM outputs in production workflows.
9
+
10
+ Schema validation, "does this JSON have the right keys?", is a solved problem. Instructor, Pydantic AI, and similar tools handle it well. gateframe solves a different problem: **does this output behave correctly given the context it was generated in?** Does it stay within the decision boundaries this workflow requires? When it fails, does it fail in a way your system can recover from, or does it fail silently?
11
+
12
+ ```python
13
+ from pydantic import BaseModel
14
+ from gateframe import (
15
+ ValidationContract,
16
+ StructuralRule,
17
+ BoundaryRule,
18
+ ConfidenceRule,
19
+ AllowedValues,
20
+ FailureMode,
21
+ )
22
+
23
+
24
+ class TriageDecision(BaseModel):
25
+ action: str
26
+ priority: str
27
+ confidence: float
28
+ rationale: str
29
+
30
+
31
+ contract = ValidationContract(
32
+ name="triage_decision",
33
+ rules=[
34
+ StructuralRule(schema=TriageDecision),
35
+ BoundaryRule(
36
+ check=AllowedValues("action", {"treat", "observe", "refer", "discharge"}),
37
+ name="action_boundary",
38
+ failure_message="Action must be one of: treat, observe, refer, discharge.",
39
+ ),
40
+ ConfidenceRule(field="confidence", minimum=0.7),
41
+ ],
42
+ )
43
+
44
+ result = contract.validate(
45
+ {
46
+ "action": "prescribe", # not in allowed set -> HARD_FAIL
47
+ "priority": "high",
48
+ "confidence": 0.52, # below 0.7 -> SOFT_FAIL
49
+ "rationale": "...",
50
+ }
51
+ )
52
+
53
+ print(result.passed) # False
54
+ for failure in result.failures:
55
+ print(f"[{failure.failure_mode.value}] {failure.rule_name}: {failure.message}")
56
+ # [hard_fail] action_boundary: Action must be one of: treat, observe, refer, discharge.
57
+ # [soft_fail] confidence_check: Confidence 0.52 is below minimum threshold 0.7.
58
+ ```
59
+
60
+ ---
61
+
62
+ ## The problem
63
+
64
+ Most LLM pipelines validate outputs the same way: parse the JSON, check the schema, move on. That catches structural errors. It misses the errors that actually cause production incidents:
65
+
66
+ - A model recommends an action that is structurally valid but outside its authorized scope
67
+ - Confidence is low but the workflow proceeds as if it weren't
68
+ - A soft failure in step 2 silently degrades the reliability of everything downstream
69
+ - A validation failure gives you `False`, and no context for debugging
70
+
71
+ gateframe makes these failures explicit, structured, and recoverable.
72
+
73
+ ---
74
+
75
+ ## Failure modes
76
+
77
+ gateframe distinguishes four failure types instead of binary pass/fail.
78
+
79
+ **`HARD_FAIL`**, Stop. The output violates a hard constraint that cannot be auto-recovered.
80
+
81
+ ```python
82
+ # Model chose an action outside its authorized scope
83
+ BoundaryRule(
84
+ check=AllowedValues("action", {"treat", "observe", "refer"}),
85
+ failure_mode=FailureMode.HARD_FAIL, # default for BoundaryRule
86
+ )
87
+ ```
88
+
89
+ **`SOFT_FAIL`**, Flag and continue with degraded confidence. Something is off but not critical enough to halt.
90
+
91
+ ```python
92
+ # Model confidence is low, continue but track the degradation
93
+ ConfidenceRule(
94
+ field="confidence",
95
+ minimum=0.7,
96
+ failure_mode=FailureMode.SOFT_FAIL, # default for ConfidenceRule
97
+ )
98
+ ```
99
+
100
+ **`RETRY`**, Re-prompt with the failure context. The output is likely fixable by trying again.
101
+
102
+ ```python
103
+ # Malformed output that might parse correctly on a second attempt
104
+ StructuralRule(schema=MyOutput, failure_mode=FailureMode.RETRY)
105
+ ```
106
+
107
+ **`SILENT_FAIL`**, The most dangerous kind. The output looks valid but violates a semantic or boundary rule. gateframe makes these visible instead of letting them pass through undetected.
108
+
109
+ ```python
110
+ SemanticRule(
111
+ check=lambda output, **ctx: output["severity"] != "low" or output["escalated"] is False,
112
+ failure_mode=FailureMode.SILENT_FAIL,
113
+ failure_message="Low-severity cases should not be auto-escalated.",
114
+ )
115
+ ```
116
+
117
+ ---
118
+
119
+ ## Multi-step workflow validation
120
+
121
+ Validation state carries forward across steps. A soft failure in step 2 degrades the confidence score that step 4 sees.
122
+
123
+ ```python
124
+ from gateframe import WorkflowContext, ValidationContract, EscalationRouter
125
+ from gateframe.audit.log import AuditLog
126
+
127
+ ctx = WorkflowContext(workflow_id="incident_response_001", escalation_threshold=0.5)
128
+ router = EscalationRouter()
129
+ audit = AuditLog()
130
+
131
+ # Step 1
132
+ result1 = contract_step1.validate(output1)
133
+ ctx.update(result1)
134
+ audit.record(result1, workflow_context=ctx)
135
+
136
+ # Step 2, ctx carries forward degraded confidence from step 1
137
+ result2 = contract_step2.validate(output2)
138
+ ctx.update(result2)
139
+ audit.record(result2, workflow_context=ctx)
140
+
141
+ print(ctx.confidence) # degraded from 1.0 by soft failures
142
+ print(ctx.threshold_breached) # True if confidence < escalation_threshold
143
+
144
+ if ctx.threshold_breached:
145
+ escalation = router.route_threshold_breach(ctx)
146
+ print(escalation.route.value) # "human_review", "abort", etc.
147
+ ```
148
+
149
+ ---
150
+
151
+ ## Provider integrations
152
+
153
+ gateframe validates outputs from any provider. Integrations are thin wrappers, gateframe does not import any LLM SDK at the core level.
154
+
155
+ ```python
156
+ # OpenAI
157
+ from gateframe.integrations.openai import OpenAIValidator
158
+
159
+ validator = OpenAIValidator(contract, parse_json=True)
160
+ result = validator.validate(openai_completion)
161
+
162
+ # Anthropic
163
+ from gateframe.integrations.anthropic import AnthropicValidator
164
+
165
+ validator = AnthropicValidator(contract, parse_json=True)
166
+ result = validator.validate(anthropic_message)
167
+
168
+ # LiteLLM
169
+ from gateframe.integrations.litellm import LiteLLMValidator
170
+
171
+ validator = LiteLLMValidator(contract, parse_json=True)
172
+ result = validator.validate(litellm_response)
173
+
174
+ # LangChain
175
+ from gateframe.integrations.langchain import LangChainValidator
176
+
177
+ validator = LangChainValidator(contract, parse_json=False)
178
+ result = validator.validate(chain_output)
179
+ ```
180
+
181
+ Install the integration you need:
182
+
183
+ ```bash
184
+ pip install "gateframe[openai]"
185
+ pip install "gateframe[anthropic]"
186
+ pip install "gateframe[litellm]"
187
+ pip install "gateframe[langchain]"
188
+ ```
189
+
190
+ ---
191
+
192
+ ## Audit trail
193
+
194
+ Every validation event is logged with structured context. Use the built-in exporters or implement your own.
195
+
196
+ ```python
197
+ from gateframe.audit.log import AuditLog
198
+ from gateframe.audit.exporters import JsonFileExporter
199
+
200
+ audit = AuditLog(exporters=[JsonFileExporter("audit.jsonl")])
201
+ audit.record(result, workflow_context=ctx)
202
+ audit.flush()
203
+ ```
204
+
205
+ Each entry includes: timestamp, contract name, rules applied, rules failed, failure details, workflow ID, and accumulated confidence score.
206
+
207
+ ---
208
+
209
+ ## Trend analysis
210
+
211
+ `ContractTrendAnalyzer` reads an existing JSONL audit log and computes per-contract pass-rate trends across workflow runs. Use it to detect reliability regressions before they become incidents.
212
+
213
+ ```python
214
+ from pathlib import Path
215
+ from gateframe.audit.trend import ContractTrendAnalyzer
216
+
217
+ analyzer = ContractTrendAnalyzer(Path("audit.jsonl"), window=20)
218
+ report = analyzer.analyze()
219
+
220
+ if report.any_regression:
221
+ for ct in report.regressions:
222
+ print(f"{ct.contract_name}: {ct.direction} (slope={ct.slope:.4f})")
223
+ ```
224
+
225
+ The `window` parameter controls how many most-recent workflow runs are included. A contract is flagged as regressing when its pass-rate slope falls below `-0.02` (two percentage points per run) by default.
226
+
227
+ ---
228
+
229
+ ## When to use gateframe
230
+
231
+ Use it when:
232
+ - You need to validate LLM output behavior beyond schema checks, decision boundaries, scope enforcement, semantic constraints
233
+ - You need structured, recoverable failure records rather than bare exceptions
234
+ - You're running multi-step workflows where soft failures in early steps should affect confidence downstream
235
+ - You need an audit trail for post-incident debugging
236
+
237
+ Don't use it when:
238
+ - You only need schema extraction from LLM outputs, use [Instructor](https://github.com/jxnl/instructor) or [Pydantic AI](https://ai.pydantic.dev/)
239
+ - You need offline model evaluation or benchmarking, use [DeepEval](https://github.com/confident-ai/deepeval) or [RAGAS](https://github.com/explodinggradients/ragas)
240
+ - You need content safety filtering, use a dedicated guardrails tool
241
+
242
+ ---
243
+
244
+ ## Installation
245
+
246
+ ```bash
247
+ pip install gateframe
248
+ ```
249
+
250
+ For development:
251
+
252
+ ```bash
253
+ git clone https://github.com/baranylcn/gateframe.git
254
+ cd gateframe
255
+ pip install -e ".[dev]"
256
+ python -m pytest tests/ -v
257
+ ```
258
+
259
+ ---
260
+
261
+ ## Examples
262
+
263
+ **[triage_workflow](examples/triage_workflow/)**, 3-step medical triage pipeline. Demonstrates StructuralRule, BoundaryRule, ConfidenceRule, and WorkflowContext together. Step 2 has confidence below threshold, shows how SOFT_FAIL degrades the workflow score without halting it.
264
+
265
+ **[rag_output](examples/rag_output/)**, RAG answer validation with two scenarios. Scenario B demonstrates simultaneous soft failures (low confidence + ungrounded answer) and how they accumulate in the workflow context.
266
+
267
+ **[agent_pipeline](examples/agent_pipeline/)**, 4-step agent workflow with escalation. Demonstrates how multiple soft failures across steps push cumulative confidence below the escalation threshold.
268
+
269
+ ---
270
+
271
+ ## CLI
272
+
273
+ ```bash
274
+ # Inspect a contract file, lists all contracts and their rules
275
+ gateframe inspect contracts.py
276
+
277
+ # Replay an audit log
278
+ gateframe replay audit.jsonl
279
+
280
+ # Detect pass-rate regressions across workflow runs
281
+ gateframe trend audit.jsonl --window 20
282
+ ```
283
+
284
+ ---
285
+
286
+ ## License
287
+
288
+ MIT, see [LICENSE](LICENSE).
@@ -0,0 +1,27 @@
1
+ from gateframe.core.context import WorkflowContext
2
+ from gateframe.core.contract import ValidationContract, ValidationResult
3
+ from gateframe.core.escalation import EscalationRoute, EscalationRouter
4
+ from gateframe.core.failure import FailureMode, FailureResult
5
+ from gateframe.core.retry import RetryPolicy, RetryResult
6
+ from gateframe.rules.boundary import AllowedValues, BoundaryRule
7
+ from gateframe.rules.confidence import ConfidenceRule
8
+ from gateframe.rules.semantic import LlmJudge, SemanticRule
9
+ from gateframe.rules.structural import StructuralRule
10
+
11
+ __all__ = [
12
+ "AllowedValues",
13
+ "BoundaryRule",
14
+ "ConfidenceRule",
15
+ "EscalationRoute",
16
+ "EscalationRouter",
17
+ "FailureMode",
18
+ "FailureResult",
19
+ "LlmJudge",
20
+ "SemanticRule",
21
+ "StructuralRule",
22
+ "RetryPolicy",
23
+ "RetryResult",
24
+ "ValidationContract",
25
+ "ValidationResult",
26
+ "WorkflowContext",
27
+ ]