198 lines
6.2 KiB
Python
198 lines
6.2 KiB
Python
"""
|
|
Integration tests for Phase 1 autonomy features.
|
|
Tests monologue integration, executive planning, and self-state persistence.
|
|
"""
|
|
|
|
import asyncio
|
|
import json
|
|
import sys
|
|
import os
|
|
|
|
# Add parent directory to path for imports
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
|
|
from autonomy.monologue.monologue import InnerMonologue
|
|
from autonomy.self.state import load_self_state, update_self_state, get_self_state_instance
|
|
from autonomy.executive.planner import plan_execution
|
|
|
|
|
|
async def test_monologue_integration():
|
|
"""Test monologue generates valid output."""
|
|
print("\n" + "="*60)
|
|
print("TEST 1: Monologue Integration")
|
|
print("="*60)
|
|
|
|
mono = InnerMonologue()
|
|
|
|
context = {
|
|
"user_message": "Explain quantum computing to me like I'm 5",
|
|
"session_id": "test_001",
|
|
"self_state": load_self_state(),
|
|
"context_summary": {"message_count": 5}
|
|
}
|
|
|
|
result = await mono.process(context)
|
|
|
|
assert "intent" in result, "Missing intent field"
|
|
assert "tone" in result, "Missing tone field"
|
|
assert "depth" in result, "Missing depth field"
|
|
assert "consult_executive" in result, "Missing consult_executive field"
|
|
|
|
print("✓ Monologue integration test passed")
|
|
print(f" Result: {json.dumps(result, indent=2)}")
|
|
|
|
return result
|
|
|
|
|
|
async def test_executive_planning():
|
|
"""Test executive planner generates valid plans."""
|
|
print("\n" + "="*60)
|
|
print("TEST 2: Executive Planning")
|
|
print("="*60)
|
|
|
|
plan = await plan_execution(
|
|
user_prompt="Help me build a distributed system with microservices architecture",
|
|
intent="technical_implementation",
|
|
context_state={
|
|
"tools_available": ["RAG", "WEB", "CODEBRAIN"],
|
|
"message_count": 3,
|
|
"minutes_since_last_msg": 2.5,
|
|
"active_project": None
|
|
},
|
|
identity_block={}
|
|
)
|
|
|
|
assert "summary" in plan, "Missing summary field"
|
|
assert "plan_text" in plan, "Missing plan_text field"
|
|
assert "steps" in plan, "Missing steps field"
|
|
assert len(plan["steps"]) > 0, "No steps generated"
|
|
|
|
print("✓ Executive planning test passed")
|
|
print(f" Plan summary: {plan['summary']}")
|
|
print(f" Steps: {len(plan['steps'])}")
|
|
print(f" Complexity: {plan.get('estimated_complexity', 'unknown')}")
|
|
|
|
return plan
|
|
|
|
|
|
def test_self_state_persistence():
|
|
"""Test self-state loads and updates."""
|
|
print("\n" + "="*60)
|
|
print("TEST 3: Self-State Persistence")
|
|
print("="*60)
|
|
|
|
state1 = load_self_state()
|
|
assert "mood" in state1, "Missing mood field"
|
|
assert "energy" in state1, "Missing energy field"
|
|
assert "interaction_count" in state1, "Missing interaction_count"
|
|
|
|
initial_count = state1.get("interaction_count", 0)
|
|
print(f" Initial interaction count: {initial_count}")
|
|
|
|
update_self_state(
|
|
mood_delta=0.1,
|
|
energy_delta=-0.05,
|
|
new_focus="testing"
|
|
)
|
|
|
|
state2 = load_self_state()
|
|
assert state2["interaction_count"] == initial_count + 1, "Interaction count not incremented"
|
|
assert state2["focus"] == "testing", "Focus not updated"
|
|
|
|
print("✓ Self-state persistence test passed")
|
|
print(f" New interaction count: {state2['interaction_count']}")
|
|
print(f" New focus: {state2['focus']}")
|
|
print(f" New energy: {state2['energy']:.2f}")
|
|
|
|
return state2
|
|
|
|
|
|
async def test_end_to_end_flow():
|
|
"""Test complete flow from monologue through planning."""
|
|
print("\n" + "="*60)
|
|
print("TEST 4: End-to-End Flow")
|
|
print("="*60)
|
|
|
|
# Step 1: Monologue detects complex query
|
|
mono = InnerMonologue()
|
|
mono_result = await mono.process({
|
|
"user_message": "Design a scalable ML pipeline with CI/CD integration",
|
|
"session_id": "test_e2e",
|
|
"self_state": load_self_state(),
|
|
"context_summary": {}
|
|
})
|
|
|
|
print(f" Monologue intent: {mono_result.get('intent')}")
|
|
print(f" Consult executive: {mono_result.get('consult_executive')}")
|
|
|
|
# Step 2: If executive requested, generate plan
|
|
if mono_result.get("consult_executive"):
|
|
plan = await plan_execution(
|
|
user_prompt="Design a scalable ML pipeline with CI/CD integration",
|
|
intent=mono_result.get("intent", "unknown"),
|
|
context_state={"tools_available": ["CODEBRAIN", "WEB"]},
|
|
identity_block={}
|
|
)
|
|
|
|
assert plan is not None, "Plan should be generated"
|
|
print(f" Executive plan generated: {len(plan.get('steps', []))} steps")
|
|
|
|
# Step 3: Update self-state
|
|
update_self_state(
|
|
energy_delta=-0.1, # Complex task is tiring
|
|
new_focus="ml_pipeline_design",
|
|
confidence_delta=0.05
|
|
)
|
|
|
|
state = load_self_state()
|
|
assert state["focus"] == "ml_pipeline_design", "Focus should be updated"
|
|
|
|
print("✓ End-to-end flow test passed")
|
|
print(f" Final state: {state['mood']}, energy={state['energy']:.2f}")
|
|
|
|
return True
|
|
|
|
|
|
async def run_all_tests():
|
|
"""Run all Phase 1 tests."""
|
|
print("\n" + "="*60)
|
|
print("PHASE 1 AUTONOMY TESTS")
|
|
print("="*60)
|
|
|
|
try:
|
|
# Test 1: Monologue
|
|
mono_result = await test_monologue_integration()
|
|
|
|
# Test 2: Executive Planning
|
|
plan_result = await test_executive_planning()
|
|
|
|
# Test 3: Self-State
|
|
state_result = test_self_state_persistence()
|
|
|
|
# Test 4: End-to-End
|
|
await test_end_to_end_flow()
|
|
|
|
print("\n" + "="*60)
|
|
print("ALL TESTS PASSED ✓")
|
|
print("="*60)
|
|
|
|
print("\nSummary:")
|
|
print(f" - Monologue: {mono_result.get('intent')} ({mono_result.get('tone')})")
|
|
print(f" - Executive: {plan_result.get('estimated_complexity')} complexity")
|
|
print(f" - Self-state: {state_result.get('interaction_count')} interactions")
|
|
|
|
return True
|
|
|
|
except Exception as e:
|
|
print("\n" + "="*60)
|
|
print(f"TEST FAILED: {e}")
|
|
print("="*60)
|
|
import traceback
|
|
traceback.print_exc()
|
|
return False
|
|
|
|
|
|
if __name__ == "__main__":
|
|
success = asyncio.run(run_all_tests())
|
|
sys.exit(0 if success else 1)
|