diff --git a/diagrams/SIA_Component_Model.puml b/diagrams/SIA_Component_Model.puml
index 5c7cc32..c92030d 100644
--- a/diagrams/SIA_Component_Model.puml
+++ b/diagrams/SIA_Component_Model.puml
@@ -2,10 +2,11 @@
skinparam componentStyle uml2
-package "SIA System" {
+package "SIA System" as SS {
[LLM Engine] as LLM
- [Agent Core] as AC
[Context Template] as CT
+
+ [Agent Core] as AC
package "Modules" {
[Process Module] as PM
@@ -20,25 +21,26 @@ cloud "Docker Engine" as DE {
}
database "File System" as FS {
- database "Git Repository" as GR
+ database "Git Repository" as GIT
}
-AC -> LLM : Context
-LLM -> AC : Reasoning and actions
+AC -d-> LLM : Context
+LLM -u-> AC : Reasoning and actions
-CT --> AC : Context
-AC --> Modules : Commands to execute
-Modules --> CT : Data
+AC -u-> CT : Context data
+CT -d-> AC : Context
-DM -> DE : Container management
-DM <--> FS : Mount volumes
-RLM --> FS : Store trained models
-PM --> GR : SIA update
+AC -r-> Modules : Commands to execute
+Modules -l-> AC : Context data
-Instances --> GR : Modifies
-Instances --> Images : Create
+DM -d-> DE : Container management
+DM <-d-> FS : Mount volumes
+RLM -d-> FS : Store trained models
+PM -d-> GIT : SIA update
-FS -> CT : Monitored files
-FS -> LLM : Load models
+Instances -u-> GIT : Modifies
+Instances -r-> Images : Create
+
+FS ----u-> LLM : Model weights
@enduml
\ No newline at end of file
diff --git a/diagrams/SIA_Component_Model.svg b/diagrams/SIA_Component_Model.svg
index 4cbdc51..2b5c34b 100644
--- a/diagrams/SIA_Component_Model.svg
+++ b/diagrams/SIA_Component_Model.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/readme.md b/readme.md
index ec9f20a..e9cdd23 100644
--- a/readme.md
+++ b/readme.md
@@ -116,7 +116,7 @@ An overview of the key components and their interactions.
### Modules
-Modules execute core commands and provide data for the main context.
+Modules execute core commands and provide data for the context template.
- Process Module
- standard I/O operations
@@ -134,15 +134,11 @@ Modules execute core commands and provide data for the main context.
The Agent Core runs the SIA main loop.
-- request main context from the Context Manager
+- template the context
- run the LLM
- parse the LLM output
- execute the appropriate actions using the relevant modules
-### Context Template
-
-The Context Template collects information from the modules and creates the input for the LLM.
-
### LLM Engine
The LLM Engine is responsible for:
@@ -173,6 +169,12 @@ It also simplifies escaping of command line arguments.
Action results are added in the context as text nodes after the last parameter.
+### Context Template
+
+A Handlerbars template is used to create the context for the LLM.
+A ContextTemplate object is created for each iteration of the main loop.
+The template is filled with data by the Agent Core.
+
### Training datasets
A training dataset is a folder with these files:
diff --git a/sia/context_template.py b/sia/context_template.py
new file mode 100644
index 0000000..f099c39
--- /dev/null
+++ b/sia/context_template.py
@@ -0,0 +1,40 @@
+from typing import List, Dict
+import xml.etree.ElementTree as ET
+
+def generate_context(containers: List[Dict[str, any]]) -> str:
+ """Generate full context XML string.
+
+ Args:
+ containers: List of container status dictionaries
+
+ Returns:
+ Formatted context XML string
+ """
+ context_elem = ET.Element("context")
+ context_elem.append(format_containers_xml(containers))
+ ET.indent(context_elem, space="\t")
+ return ET.tostring(context_elem, encoding='unicode')
+
+def format_containers_xml(containers: List[Dict[str, any]]) -> ET.Element:
+ """Format container statuses as XML string.
+
+ Args:
+ containers: List of dictionaries containing container information
+
+ Returns:
+ ElementTree.Element representing the containers
+ """
+ containers_elem = ET.Element("containers")
+
+ for container in containers:
+ container_elem = ET.SubElement(containers_elem, "container")
+ container_elem.set("name", container['name'])
+ container_elem.set("status", container['status'])
+ container_elem.set("started_at", container['started_at'])
+ container_elem.set("stdout", str(container['stdout_size']))
+ container_elem.set("stderr", str(container['stderr_size']))
+ if 'exit_code' in container.keys():
+ container_elem.set("exit_code", str(container['exit_code']))
+ if 'error' in container.keys():
+ container_elem.set("error", container['error'])
+ return containers_elem
diff --git a/sia/docker_module.py b/sia/docker_module.py
index 5ea712a..ebbda42 100644
--- a/sia/docker_module.py
+++ b/sia/docker_module.py
@@ -269,3 +269,12 @@ class DockerModule:
except Exception as e:
self.logger.error(f"Error getting status for container {name}: {str(e)}")
raise
+
+ def get_all_container_statuses(self) -> List[Dict[str, any]]:
+ """Get current status information for all containers.
+ Returns:
+ List of dictionaries with container status information
+ """
+ statuses = []
+ for name, (container, socket) in self.containers.items():
+ statuses.append(self.get_container_status(name))
\ No newline at end of file
diff --git a/test/context_template_test.py b/test/context_template_test.py
new file mode 100644
index 0000000..32f82c4
--- /dev/null
+++ b/test/context_template_test.py
@@ -0,0 +1,34 @@
+import unittest
+from datetime import datetime
+from sia.context_template import generate_context
+
+class TestContextTemplate(unittest.TestCase):
+ def test_empty_containers(self):
+ """Test context generation with no containers."""
+ context = generate_context([])
+ self.assertIn("", context)
+ self.assertIn("", context)
+ self.assertIn("", context)
+
+ def test_single_container(self):
+ """Test context generation with a single container."""
+ container_status = {
+ 'name': 'test-container',
+ 'status': 'running',
+ 'started_at': '2024-10-25T10:00:00Z',
+ 'stdout_size': 100,
+ 'stderr_size': 50
+ }
+ context = generate_context([container_status])
+ print(f"context: {context}")
+ self.assertIn("", context)
+ self.assertIn("", context)
+
+if __name__ == '__main__':
+ unittest.main()