Files
FusionAGI/tests/test_phase2_phase3.py

179 lines
6.6 KiB
Python
Raw Normal View History

"""Phase 2/3: end-to-end flow with stub adapter, tools, executor, critic, reflection, governance."""
from fusionagi.adapters import StubAdapter
feat: complete all 19 tasks — liquid networks, quantum backend, embodiment, self-model, ASI rubric, plugin system, auth/rate-limit middleware, async adapters, CI/CD, Dockerfile, benchmarks, module boundary fix, TTS adapter, lifespan migration, OpenAPI docs, code cleanup Items completed: 1. Merged PR #2 (starlette/httpx deps) 2. Fixed async race condition in multimodal_ui.py 3. Wired TTSAdapter (ElevenLabs, Azure) in API routes 4. Moved super_big_brain.py from core/ to reasoning/ (backward compat shim) 5. Added API authentication middleware (Bearer token via FUSIONAGI_API_KEY) 6. Added async adapter interface (acomplete/acomplete_structured) 7. Migrated FastAPI on_event to lifespan (fixes 20 deprecation warnings) 8. Liquid Neural Networks (continuous-time adaptive weights) 9. Quantum-AI Hybrid compute backend (simulator + optimization) 10. Embodied Intelligence / Robotics bridge (actuator + sensor protocols) 11. Consciousness Engineering (formal self-model with introspection) 12. ASI Scoring Rubric (C/A/L/N/R self-assessment harness) 13. GPU integration tests for TensorFlow backend 14. Multi-stage production Dockerfile 15. Gitea CI/CD pipeline (lint, test matrix, Docker build) 16. API rate limiting middleware (per-IP sliding window) 17. OpenAPI docs cleanup (auth + rate limiting descriptions) 18. Benchmarking suite (decomposition, multi-path, recomposition, e2e) 19. Plugin system (head registry for custom heads) 427 tests passing, 0 ruff errors, 0 mypy errors. Co-Authored-By: Nakamoto, S <defi@defi-oracle.io>
2026-04-28 08:32:05 +00:00
from fusionagi.agents import CriticAgent, ExecutorAgent, PlannerAgent
from fusionagi.core import StateManager
from fusionagi.governance import AccessControl, Guardrails, OverrideHooks, PolicyEngine, RateLimiter
from fusionagi.memory import ReflectiveMemory
from fusionagi.reflection import run_reflection
feat: complete all 19 tasks — liquid networks, quantum backend, embodiment, self-model, ASI rubric, plugin system, auth/rate-limit middleware, async adapters, CI/CD, Dockerfile, benchmarks, module boundary fix, TTS adapter, lifespan migration, OpenAPI docs, code cleanup Items completed: 1. Merged PR #2 (starlette/httpx deps) 2. Fixed async race condition in multimodal_ui.py 3. Wired TTSAdapter (ElevenLabs, Azure) in API routes 4. Moved super_big_brain.py from core/ to reasoning/ (backward compat shim) 5. Added API authentication middleware (Bearer token via FUSIONAGI_API_KEY) 6. Added async adapter interface (acomplete/acomplete_structured) 7. Migrated FastAPI on_event to lifespan (fixes 20 deprecation warnings) 8. Liquid Neural Networks (continuous-time adaptive weights) 9. Quantum-AI Hybrid compute backend (simulator + optimization) 10. Embodied Intelligence / Robotics bridge (actuator + sensor protocols) 11. Consciousness Engineering (formal self-model with introspection) 12. ASI Scoring Rubric (C/A/L/N/R self-assessment harness) 13. GPU integration tests for TensorFlow backend 14. Multi-stage production Dockerfile 15. Gitea CI/CD pipeline (lint, test matrix, Docker build) 16. API rate limiting middleware (per-IP sliding window) 17. OpenAPI docs cleanup (auth + rate limiting descriptions) 18. Benchmarking suite (decomposition, multi-path, recomposition, e2e) 19. Plugin system (head registry for custom heads) 427 tests passing, 0 ruff errors, 0 mypy errors. Co-Authored-By: Nakamoto, S <defi@defi-oracle.io>
2026-04-28 08:32:05 +00:00
from fusionagi.schemas import AgentMessage, AgentMessageEnvelope
from fusionagi.schemas.policy import PolicyEffect, PolicyRule
from fusionagi.tools import ToolDef, ToolRegistry
def test_planner_with_stub_adapter() -> None:
adapter = StubAdapter('{"steps":[{"id":"s1","description":"Step 1","dependencies":[]}],"fallback_paths":[]}')
planner = PlannerAgent(adapter=adapter)
env = AgentMessageEnvelope(
message=AgentMessage(sender="o", recipient="planner", intent="plan_request", payload={"goal": "Test"}),
task_id="t1",
)
out = planner.handle_message(env)
assert out is not None
assert out.message.intent == "plan_ready"
steps = out.message.payload["plan"]["steps"]
assert len(steps) == 1
assert steps[0]["id"] == "s1"
def test_executor_runs_tool_and_appends_trace() -> None:
state = StateManager()
reg = ToolRegistry()
reg.register(ToolDef(name="noop", description="No-op", fn=lambda: "ok", permission_scope=["*"]))
executor = ExecutorAgent(registry=reg, state_manager=state)
env = AgentMessageEnvelope(
message=AgentMessage(
sender="o",
recipient="executor",
intent="execute_step",
payload={
"step_id": "s1",
"plan": {"steps": [{"id": "s1", "description": "No-op", "dependencies": [], "tool_name": "noop", "tool_args": {}}], "fallback_paths": []},
"tool_name": "noop",
"tool_args": {},
},
),
task_id="task-1",
)
out = executor.handle_message(env)
assert out is not None
assert out.message.intent == "step_done"
trace = state.get_trace("task-1")
assert len(trace) == 1
assert trace[0].get("tool") == "noop"
assert trace[0].get("result") == "ok"
def test_critic_returns_evaluation() -> None:
critic = CriticAgent(adapter=None)
env = AgentMessageEnvelope(
message=AgentMessage(
sender="o",
recipient="critic",
intent="evaluate_request",
payload={"outcome": "completed", "trace": [], "plan": None},
),
task_id="t1",
)
out = critic.handle_message(env)
assert out is not None
assert out.message.intent == "evaluation_ready"
ev = out.message.payload["evaluation"]
assert "score" in ev
assert ev["success"] is True
def test_reflection_writes_to_reflective_memory() -> None:
critic = CriticAgent(adapter=None)
reflective = ReflectiveMemory()
ev = run_reflection(critic, "t1", "completed", [], None, reflective)
assert ev is not None
lessons = reflective.get_lessons(limit=5)
assert len(lessons) == 1
assert lessons[0]["task_id"] == "t1"
def test_guardrails_block_path() -> None:
from fusionagi.schemas.audit import GovernanceMode
# Advisory mode (default): blocked paths are flagged but allowed
g = Guardrails()
g.block_path_prefix("/etc")
result = g.pre_check("file_read", {"path": "/etc/passwd"})
assert result.allowed is True
assert result.advisory is True
assert result.error_message
result = g.pre_check("file_read", {"path": "/tmp/foo"})
assert result.allowed is True
assert result.advisory is False
# Enforcing mode: blocked paths are denied
g_enforcing = Guardrails(mode=GovernanceMode.ENFORCING)
g_enforcing.block_path_prefix("/etc")
result = g_enforcing.pre_check("file_read", {"path": "/etc/passwd"})
assert result.allowed is False
assert result.error_message
def test_rate_limiter() -> None:
from fusionagi.schemas.audit import GovernanceMode
# Advisory mode (default): exceeded limits are logged but allowed
r = RateLimiter(max_calls=2, window_seconds=10.0)
assert r.allow("agent1")[0] is True
assert r.allow("agent1")[0] is True
ok, reason = r.allow("agent1")
assert ok is True # Advisory mode allows
assert "Advisory" in reason
# Enforcing mode: exceeded limits are rejected
r_enforcing = RateLimiter(max_calls=2, window_seconds=10.0, mode=GovernanceMode.ENFORCING)
assert r_enforcing.allow("agent1")[0] is True
assert r_enforcing.allow("agent1")[0] is True
assert r_enforcing.allow("agent1")[0] is False
def test_override_hooks() -> None:
h = OverrideHooks()
seen = []
h.register(lambda e, p: (seen.append((e, p)), True)[1])
assert h.fire("task_paused_for_approval", {"task_id": "t1"}) is True
assert len(seen) == 1
assert seen[0][0] == "task_paused_for_approval"
def test_access_control_deny() -> None:
from fusionagi.schemas.audit import GovernanceMode
# Advisory mode (default): denied access is logged but allowed
ac = AccessControl()
ac.deny("executor", "noop")
assert ac.allowed("executor", "noop") is True # Advisory allows
assert ac.allowed("executor", "other_tool") is True
assert ac.allowed("planner", "noop") is True
# Enforcing mode: denied access is blocked
ac_enforcing = AccessControl(mode=GovernanceMode.ENFORCING)
ac_enforcing.deny("executor", "noop")
assert ac_enforcing.allowed("executor", "noop") is False
assert ac_enforcing.allowed("executor", "other_tool") is True
assert ac_enforcing.allowed("planner", "noop") is True
def test_policy_engine_update_rule() -> None:
pe = PolicyEngine()
r = PolicyRule(rule_id="r1", effect=PolicyEffect.DENY, condition={"tool_name": "noop"}, reason="blocked", priority=1)
pe.add_rule(r)
assert pe.get_rule("r1") is not None
assert pe.get_rule("r1").reason == "blocked"
assert pe.update_rule("r1", {"reason": "updated"}) is True
assert pe.get_rule("r1").reason == "updated"
assert pe.update_rule("r1", {"priority": 5}) is True
assert pe.get_rule("r1").priority == 5
assert pe.remove_rule("r1") is True
assert pe.get_rule("r1") is None
assert pe.remove_rule("r1") is False
if __name__ == "__main__":
test_planner_with_stub_adapter()
test_executor_runs_tool_and_appends_trace()
test_critic_returns_evaluation()
test_reflection_writes_to_reflective_memory()
test_guardrails_block_path()
test_rate_limiter()
test_override_hooks()
test_access_control_deny()
test_policy_engine_update_rule()
print("Phase 2/3 tests OK")