Initial commit: add .gitignore and README
This commit is contained in:
5
fusionagi/verification/__init__.py
Normal file
5
fusionagi/verification/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from fusionagi.verification.outcome import OutcomeVerifier
|
||||
from fusionagi.verification.contradiction import ContradictionDetector
|
||||
from fusionagi.verification.validators import FormalValidators
|
||||
|
||||
__all__ = ["OutcomeVerifier", "ContradictionDetector", "FormalValidators"]
|
||||
21
fusionagi/verification/contradiction.py
Normal file
21
fusionagi/verification/contradiction.py
Normal file
@@ -0,0 +1,21 @@
|
||||
from typing import Any, Protocol
|
||||
|
||||
class SemanticLike(Protocol):
|
||||
def query(self, domain, limit): ...
|
||||
|
||||
class ContradictionDetector:
|
||||
def __init__(self, semantic=None):
|
||||
self._semantic = semantic
|
||||
def check(self, claim, context=None):
|
||||
out = []
|
||||
if not claim or not claim.strip():
|
||||
return out
|
||||
ctx = context or {}
|
||||
domain = ctx.get("domain", "")
|
||||
if self._semantic:
|
||||
facts = self._semantic.query(domain or None, 50)
|
||||
for f in facts:
|
||||
st = f.get("statement", "")
|
||||
if st and "not " in claim.lower() and st.lower() in claim.lower():
|
||||
out.append("Contradicts: " + st[:100])
|
||||
return out
|
||||
17
fusionagi/verification/outcome.py
Normal file
17
fusionagi/verification/outcome.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from typing import Any, Callable
|
||||
from fusionagi._logger import logger
|
||||
|
||||
class OutcomeVerifier:
|
||||
def __init__(self, verify_fn=None):
|
||||
self._verify_fn = verify_fn
|
||||
def verify(self, step_result, context=None):
|
||||
ctx = context or {}
|
||||
if self._verify_fn:
|
||||
try:
|
||||
return self._verify_fn(step_result, ctx)
|
||||
except Exception:
|
||||
logger.exception("OutcomeVerifier failed")
|
||||
return False
|
||||
if isinstance(step_result, dict) and step_result.get("error"):
|
||||
return False
|
||||
return True
|
||||
51
fusionagi/verification/validators.py
Normal file
51
fusionagi/verification/validators.py
Normal file
@@ -0,0 +1,51 @@
|
||||
"""Formal validators: JSON schema, policy constraints, lint/type check on outputs."""
|
||||
|
||||
import json
|
||||
from typing import Any
|
||||
|
||||
from fusionagi._logger import logger
|
||||
|
||||
|
||||
class FormalValidators:
|
||||
"""
|
||||
Validates outputs against JSON schema, policy constraints.
|
||||
Extend with lint/type check for code outputs.
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self._schemas: dict[str, dict[str, Any]] = {} # name -> JSON schema
|
||||
|
||||
def register_schema(self, name: str, schema: dict[str, Any]) -> None:
|
||||
"""Register a JSON schema for output validation."""
|
||||
self._schemas[name] = schema
|
||||
|
||||
def validate_json(self, data: str | dict[str, Any], schema_name: str | None = None) -> tuple[bool, str]:
|
||||
"""
|
||||
Validate JSON structure. If schema_name given, validate against that schema
|
||||
(requires jsonschema lib for full validation; else structure-only).
|
||||
Returns (valid, error_message).
|
||||
"""
|
||||
if isinstance(data, dict):
|
||||
obj = data
|
||||
else:
|
||||
try:
|
||||
obj = json.loads(data)
|
||||
except json.JSONDecodeError as e:
|
||||
return False, str(e)
|
||||
if schema_name and schema_name in self._schemas:
|
||||
try:
|
||||
import jsonschema
|
||||
jsonschema.validate(instance=obj, schema=self._schemas[schema_name])
|
||||
except ImportError:
|
||||
logger.warning("jsonschema not installed; skipping schema validation")
|
||||
except Exception as e:
|
||||
return False, str(e)
|
||||
return True, ""
|
||||
|
||||
def validate_policy(self, action: str, context: dict[str, Any]) -> tuple[bool, str]:
|
||||
"""
|
||||
Check action against policy (context has tool_name, domain, etc.).
|
||||
Returns (allowed, reason).
|
||||
"""
|
||||
# Placeholder: no policy rules by default
|
||||
return True, ""
|
||||
Reference in New Issue
Block a user