New web interface, move llm engine to separate process

This commit is contained in:
2025-05-20 09:43:17 +02:00
parent 895a533e01
commit d4a4902b94
137 changed files with 4850 additions and 3503 deletions

View File

@@ -10,10 +10,9 @@ from sia.web_io_buffer import WebIOBuffer
from sia.working_memory import WorkingMemory
from sia.system_metrics import SystemMetrics
from sia.llm_engine import LlmEngine
from sia.xml_validator import XMLValidator
from sia.response_parser import ResponseParser
from sia.iteration_logger import IterationLogger
from sia.web_agent import WebAgent, LlmState
from sia.web_agent import WebAgent, AgentState
from sia.command import Command
from sia.command_result import CommandResult
from sia.entry.reasoning_entry import ReasoningEntry
@@ -22,7 +21,7 @@ from sia.entry import Entry
from sia.response_buffer import ResponseBuffer
from pathlib import Path
class MockLlmEngine(LlmEngine):
class MockLlmEngine:
"""Mock LLM engine for testing."""
def __init__(self, output: str = "<reasoning>test reasoning</reasoning>"):
@@ -67,14 +66,10 @@ class WebAgentTest(unittest.TestCase):
'default': MockLlmEngine(),
'alternative': MockLlmEngine("<reasoning>alternative reasoning</reasoning>")
}
self.mock_validator = Mock(spec=XMLValidator)
self.io_buffer = WebIOBuffer()
self.working_memory = WorkingMemory()
self.work_dir = Path("/tmp") # Use temp directory for tests
# Mock validator to pass by default
self.mock_validator.validate.return_value = None
# Create parser with IO buffer
self.parser = ResponseParser(self.work_dir, self.io_buffer)
@@ -98,7 +93,6 @@ class WebAgentTest(unittest.TestCase):
working_memory=self.working_memory,
metrics=self.mock_metrics,
llms=self.mock_llms,
validator=self.mock_validator,
parser=self.parser,
iteration_logger=self.mock_iteration_logger
)
@@ -107,7 +101,7 @@ class WebAgentTest(unittest.TestCase):
self.llm_state_changes = []
self.context_changes = []
def llm_change_handler(self, llm_name: str, state: LlmState):
def llm_change_handler(self, llm_name: str, state: AgentState):
"""Track LLM state changes for verification."""
self.llm_state_changes.append((llm_name, state))
@@ -124,23 +118,11 @@ class WebAgentTest(unittest.TestCase):
# Check LLM states
llm_states = self.agent.llms
self.assertEqual(len(llm_states), 2)
self.assertEqual(llm_states['default'], LlmState.IDLE)
self.assertEqual(llm_states['alternative'], LlmState.IDLE)
self.assertEqual(llm_states['default'], AgentState.IDLE)
self.assertEqual(llm_states['alternative'], AgentState.IDLE)
# Check response buffer
self.assertIsInstance(self.agent.response_buffer, ResponseBuffer)
def test_handler_registration(self):
"""Test adding state and context change handlers."""
self.agent.add_llm_change_handler(self.llm_change_handler)
self.agent.add_context_change_handler(self.context_change_handler)
# Adding same handler twice should not duplicate
self.agent.add_llm_change_handler(self.llm_change_handler)
self.agent.add_context_change_handler(self.context_change_handler)
self.assertEqual(len(self.agent._llm_change_handlers), 1)
self.assertEqual(len(self.agent._context_change_handlers), 1)
def test_run_inference(self):
"""Test running inference."""
@@ -153,8 +135,8 @@ class WebAgentTest(unittest.TestCase):
# Check state changes
self.assertEqual(len(self.llm_state_changes), 2) # IDLE -> INFERENCE -> IDLE
self.assertEqual(self.llm_state_changes[0], ('default', LlmState.INFERENCE))
self.assertEqual(self.llm_state_changes[1], ('default', LlmState.IDLE))
self.assertEqual(self.llm_state_changes[0], ('default', AgentState.INFERENCE))
self.assertEqual(self.llm_state_changes[1], ('default', AgentState.IDLE))
# Verify LLM was called
self.assertTrue(self.mock_llms['default'].infer_called)
@@ -171,7 +153,7 @@ class WebAgentTest(unittest.TestCase):
def test_run_inference_busy_llm(self):
"""Test running inference on a busy LLM."""
# Set LLM state to INFERENCE
with patch.object(self.agent, '_llm_states', {'default': LlmState.INFERENCE}):
with patch.object(self.agent, '_llm_states', {'default': AgentState.INFERENCE}):
with self.assertRaises(RuntimeError):
self.agent.run_inference('default')
@@ -187,7 +169,6 @@ class WebAgentTest(unittest.TestCase):
working_memory=WorkingMemory(),
metrics=self.mock_metrics,
llms={'test': mock_engine},
validator=self.mock_validator,
parser=self.parser,
iteration_logger=self.mock_iteration_logger
)
@@ -224,7 +205,6 @@ class WebAgentTest(unittest.TestCase):
working_memory=WorkingMemory(),
metrics=self.mock_metrics,
llms=self.mock_llms,
validator=self.mock_validator,
parser=self.parser,
iteration_logger=self.mock_iteration_logger
)
@@ -254,7 +234,6 @@ class WebAgentTest(unittest.TestCase):
working_memory=WorkingMemory(),
metrics=self.mock_metrics,
llms=self.mock_llms,
validator=self.mock_validator,
parser=self.parser,
iteration_logger=self.mock_iteration_logger
)
@@ -290,7 +269,7 @@ class WebAgentTest(unittest.TestCase):
self.assertTrue(mock_command.executed)
# Check command result was stored
self.assertEqual(self.agent.command_result, command_result)
self.assertEqual(self.agent._command_result, command_result)
# Verify iteration was logged
self.mock_iteration_logger.log_iteration.assert_called_once()
@@ -329,7 +308,6 @@ class WebAgentTest(unittest.TestCase):
working_memory=test_memory,
metrics=self.mock_metrics,
llms=self.mock_llms,
validator=self.mock_validator,
parser=self.parser,
iteration_logger=self.mock_iteration_logger
)