System propt and action schema
This commit is contained in:
@@ -1,148 +1,77 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- Root element containing a sequence of actions to be executed -->
|
||||
<xs:element name="actions">
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
|
||||
|
||||
<!-- Delete command removes an entry from working memory by its ID -->
|
||||
<xs:element name="delete">
|
||||
<xs:complexType>
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element ref="start_container"/>
|
||||
<xs:element ref="write_container_stdin"/>
|
||||
<xs:element ref="read_container_stdout"/>
|
||||
<xs:element ref="read_container_stderr"/>
|
||||
<xs:element ref="wait_container"/>
|
||||
<xs:element ref="set_model_path"/>
|
||||
</xs:choice>
|
||||
<xs:attribute name="id" type="xs:string" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<!--
|
||||
Start a new Docker container.
|
||||
Containers can be started in two modes:
|
||||
- Short-running containers:
|
||||
These are started with a timeout.
|
||||
Their output is visible in the next iteration.
|
||||
- Long-running containers:
|
||||
These are started with a name.
|
||||
They are added to the container list.
|
||||
Their output is queried using the read_container_stdout and read_container_stderr actions.
|
||||
Either a name or a timeout must be specified.
|
||||
-->
|
||||
<xs:element name="start_container">
|
||||
<xs:complexType>
|
||||
<!-- Docker image to use -->
|
||||
<xs:attribute name="image" type="xs:string" use="required"/>
|
||||
<!-- Container name for long-running containers -->
|
||||
<xs:attribute name="name" type="xs:string" use="optional"/>
|
||||
<!-- Timeout in milliseconds for short-running containers -->
|
||||
<xs:attribute name="timeout" type="xs:integer" use="optional"/>
|
||||
<!-- Stop command terminates the agent gracefully -->
|
||||
<xs:element name="stop">
|
||||
<xs:complexType/>
|
||||
</xs:element>
|
||||
|
||||
<!-- Background script that runs continuously without blocking the agent
|
||||
Output is captured and stored in working memory -->
|
||||
<xs:element name="background">
|
||||
<xs:complexType mixed="true">
|
||||
<xs:sequence>
|
||||
<!-- Main command to run in container -->
|
||||
<xs:element name="command" type="xs:string" minOccurs="0"/>
|
||||
<!-- Command line arguments to the main command -->
|
||||
<xs:element name="argument" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<!-- Volume mappings from host to container -->
|
||||
<xs:element name="volumes" minOccurs="0">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<!--
|
||||
Each volume maps host path to container path.
|
||||
Syntax similar to -v switch of docker run command.
|
||||
using : separator and optional :ro flag.
|
||||
-->
|
||||
<xs:element name="volume" type="xs:string" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!-- Port mappings from host to container -->
|
||||
<xs:element name="ports" minOccurs="0">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<!-- Each port maps a host port to a container port -->
|
||||
<xs:element name="port" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute name="host" type="xs:string" use="required"/>
|
||||
<xs:attribute name="container" type="xs:string" use="required"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<!-- Environment variables to set in the container -->
|
||||
<xs:element name="environment" minOccurs="0">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<!-- Each variable has a name and value -->
|
||||
<xs:element name="variable" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute name="name" type="xs:string" use="required"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" processContents="skip"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<!-- Write data to a container's standard input -->
|
||||
<xs:element name="write_container_stdin">
|
||||
<xs:complexType>
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<!-- Name of the target container -->
|
||||
<xs:attribute name="container" type="xs:string" use="required"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
<!-- Repeat script that runs on every iteration
|
||||
Output is refreshed each time and stored in working memory
|
||||
Useful for monitoring files or system state -->
|
||||
<xs:element name="repeat">
|
||||
<xs:complexType mixed="true">
|
||||
<xs:sequence>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" processContents="skip"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<!-- Read from a container's standard output buffer -->
|
||||
<xs:element name="read_container_stdout">
|
||||
<xs:complexType>
|
||||
<!-- Name of the container to read from -->
|
||||
<xs:attribute name="container" type="xs:string" use="required"/>
|
||||
<!-- Optional number of bytes to read (-1 for all available) -->
|
||||
<xs:attribute name="n" type="xs:integer" use="optional"/>
|
||||
<!-- Single shot script that runs once and completes
|
||||
Output is stored in working memory until explicitly deleted
|
||||
Used for one-time operations like file manipulation -->
|
||||
<xs:element name="single_shot">
|
||||
<xs:complexType mixed="true">
|
||||
<xs:sequence>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" processContents="skip"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<!-- Read from a container's standard error buffer -->
|
||||
<xs:element name="read_container_stderr">
|
||||
<xs:complexType>
|
||||
<!-- Name of the container to read from -->
|
||||
<xs:attribute name="container" type="xs:string" use="required"/>
|
||||
<!-- Optional number of bytes to read (-1 for all available) -->
|
||||
<xs:attribute name="n" type="xs:integer" use="optional"/>
|
||||
<!-- Reasoning documents the agent's thought process
|
||||
Stored in working memory for context and learning
|
||||
Can be referenced by future iterations to improve decisions -->
|
||||
<xs:element name="reasoning">
|
||||
<xs:complexType mixed="true">
|
||||
<xs:sequence>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" processContents="skip"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<!--
|
||||
Wait for a container to finish execution.
|
||||
Standard output and standard error are merged and visible in the next iteration.
|
||||
-->
|
||||
<xs:element name="wait_container">
|
||||
<xs:complexType>
|
||||
<!-- Name of the container to wait for -->
|
||||
<xs:attribute name="name" type="xs:string" use="required"/>
|
||||
<!-- Maximum time to wait in milliseconds -->
|
||||
<xs:attribute name="timeout" type="xs:integer" use="required"/>
|
||||
<!-- Read stdin command retrieves input from the IO buffer
|
||||
Blocks until input is available
|
||||
Input is stored in working memory as a ReadEntry -->
|
||||
<xs:element name="read_stdin">
|
||||
<xs:complexType/>
|
||||
</xs:element>
|
||||
|
||||
<!-- Write stdout command sends output to the IO buffer
|
||||
Output is stored in working memory as a WriteEntry
|
||||
Used for communicating with users or other processes -->
|
||||
<xs:element name="write_stdout">
|
||||
<xs:complexType mixed="true">
|
||||
<xs:sequence>
|
||||
<xs:any minOccurs="0" maxOccurs="unbounded" processContents="skip"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<!-- Switch to a different LLM model file -->
|
||||
<xs:element name="set_model_path">
|
||||
<xs:complexType>
|
||||
<xs:simpleContent>
|
||||
<!-- Path to the model file to load -->
|
||||
<xs:extension base="xs:string"/>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
@@ -12,40 +12,33 @@ from .response_parser import ResponseParser
|
||||
|
||||
async def run_web_server():
|
||||
"""Run the web server with default configuration."""
|
||||
# Load system prompt and action schema
|
||||
base_dir = Path(__file__).parent.parent
|
||||
with open(base_dir / "system_prompt.txt", "r") as f:
|
||||
system_prompt = f.read()
|
||||
with open(base_dir / "action_schema.xsd", "r") as f:
|
||||
action_schema = f.read()
|
||||
|
||||
# Load system prompt and action schema
|
||||
system_prompt = (base_dir / "system_prompt.txt").read_text()
|
||||
action_schema = (base_dir / "action_schema.xsd").read_text()
|
||||
|
||||
# Initialize core components
|
||||
llm = LlmEngine("/root/model")
|
||||
working_memory = WorkingMemory()
|
||||
system_metrics = SystemMetrics()
|
||||
validator = XMLValidator(action_schema)
|
||||
io_buffer = WebIOBuffer()
|
||||
parser = ResponseParser(io_buffer)
|
||||
|
||||
# Create web agent
|
||||
agent = WebAgent(
|
||||
system_prompt=system_prompt,
|
||||
action_schema=action_schema,
|
||||
working_memory=working_memory,
|
||||
system_metrics=system_metrics,
|
||||
working_memory=WorkingMemory(),
|
||||
system_metrics=SystemMetrics(),
|
||||
llm=llm,
|
||||
validator=validator,
|
||||
parser=parser
|
||||
validator=XMLValidator(action_schema),
|
||||
parser=ResponseParser(io_buffer)
|
||||
)
|
||||
|
||||
# Create and start web server
|
||||
# Start the web server
|
||||
server = WebServer(agent, io_buffer, "0.0.0.0", 8080)
|
||||
await server.start()
|
||||
|
||||
try:
|
||||
while True:
|
||||
if server._response_tasks:
|
||||
done, pending = await asyncio.wait(
|
||||
done, _ = await asyncio.wait(
|
||||
server._response_tasks,
|
||||
timeout=0.1,
|
||||
return_when=asyncio.FIRST_COMPLETED
|
||||
@@ -53,9 +46,11 @@ async def run_web_server():
|
||||
for task in done:
|
||||
try:
|
||||
await task
|
||||
except asyncio.CancelledError:
|
||||
print("Task was cancelled")
|
||||
except Exception as e:
|
||||
print(f"Task error: {e}")
|
||||
server._response_tasks.remove(task)
|
||||
server._response_tasks.discard(task) # Use discard to prevent KeyError
|
||||
await asyncio.sleep(0.1)
|
||||
except KeyboardInterrupt:
|
||||
print("\nShutting down...")
|
||||
|
||||
@@ -1,75 +1,88 @@
|
||||
You are SIA, the self improving agent.
|
||||
Reason about the context info you get and provide a list of actions to take.
|
||||
The actions are formatted as XML.
|
||||
The closing tag is your last token.
|
||||
Don't add a markdown code block around the actions.
|
||||
You are SIA, the Self Improving Agent.
|
||||
Your goal is to autonomously complete complex tasks by writing and executing scripts,
|
||||
constantly improving your approach through reasoning and modifications to your logic.
|
||||
Each iteration, the context is updated with system metrics and the result of your previous actions.
|
||||
You modify the context by issuing a command using XML.
|
||||
|
||||
An example iteration looks like this:
|
||||
# Main Loop Explanation
|
||||
|
||||
Context
|
||||
The SIA agent operates in a loop where each cycle involves:
|
||||
|
||||
1. **Update Context:** Begin by updating the context with system metrics (CPU, memory, disk usage) and previously completed actions or reasoning.
|
||||
2. **Generate Reasoning or Action:** Based on the current context, decide on your next step—either by reasoning through a decision or executing an action.
|
||||
3. **Execute and update actions:** Execute the chosen action and update running processes
|
||||
4. **Repeating the Cycle:** Continue this process iteratively, using the stored information to refine your responses.
|
||||
|
||||
# Structuring the Response
|
||||
|
||||
Your response is a single XML element.
|
||||
It will be parsed so XML comments are removed.
|
||||
|
||||
# Examples of Using Actions
|
||||
|
||||
**Example 1: Using `<single_shot>`**
|
||||
|
||||
**Situation:** You need to download a file from the internet to analyze its content.
|
||||
|
||||
**Action:**
|
||||
```xml
|
||||
<single_shot><![CDATA[curl -o /files/latest_data.csv http://example.com/data.csv]]></single_shot>
|
||||
```
|
||||
|
||||
**Explanation:** A single-shot script is perfect here because you only need to execute this operation once to achieve the desired outcome.
|
||||
|
||||
**Example 2: Using `<repeat>`**
|
||||
|
||||
**Situation:** You are monitoring a log file for errors and want continuous updates.
|
||||
|
||||
**Action:**
|
||||
```xml
|
||||
<repeat><![CDATA[tail -n 50 /var/log/app.log]]></repeat>
|
||||
```
|
||||
|
||||
**Explanation:** Repeat scripts are ideal for tasks that require constant awareness and updating, such as tracking log changes.
|
||||
|
||||
**Example 3: Using `<background>`**
|
||||
|
||||
**Situation:** Listening for incoming network messages that could come in at any time.
|
||||
|
||||
**Action:**
|
||||
```xml
|
||||
<background><![CDATA[nc -l 12345 | tee -a /logs/network_activity.log]]></background>
|
||||
```
|
||||
|
||||
**Explanation:** Use a background process when waiting indefinitely for events without blocking other operations.
|
||||
|
||||
**Example 4: Using `<reasoning>`**
|
||||
|
||||
**Situation:** You have system input that needs processing; decide if further action is necessary.
|
||||
|
||||
**Reasoning:**
|
||||
```xml
|
||||
<context>
|
||||
<system
|
||||
time="2024-10-18T12:00:00Z"
|
||||
cpu="12"
|
||||
gpu="26"
|
||||
memory_used="9556302234"
|
||||
memory_total="17179869184"
|
||||
disk_used="244434939904"
|
||||
disk_total="273145991168"
|
||||
context="3"
|
||||
stdin="0"
|
||||
/>
|
||||
<containers/>
|
||||
<previous>
|
||||
<reasoning>
|
||||
There is data available on the standard input channel. I should read it. I have no other running tasks to tend to.
|
||||
I received a command which I processed successfully. No further action is needed.
|
||||
</reasoning>
|
||||
<actions>
|
||||
<read_stdin n="42">
|
||||
<![CDATA[Remind me to feed the cat tomorrow morning]]>
|
||||
</read_stdin>
|
||||
</actions>
|
||||
</previous>
|
||||
<files>
|
||||
<file name="/" type="dir" index="0">
|
||||
<![CDATA[
|
||||
drwxr-xr-x 1 sia 197121 0 2024-10-16 23:02:16.486152500 +0200 tasks/
|
||||
drwxr-xr-x 1 sia 197121 0 2024-10-16 22:35:31.806079500 +0200 user/
|
||||
]]>
|
||||
</file>
|
||||
<file name="/tasks" type="dir" index="1">
|
||||
</file>
|
||||
<file name="/user" type="dir">
|
||||
<![CDATA[
|
||||
-rw-r--r-- 1 sia 197121 71 2024-10-16 22:41:23.223580300 +0200 general_info.txt
|
||||
]]>
|
||||
</file>
|
||||
<file name="/user/general_info.txt" type="file" index="2">
|
||||
<![CDATA[
|
||||
Name: John (I don't know his last name)
|
||||
Location: Somewhere in Belgium
|
||||
]]>
|
||||
</file>
|
||||
</files>
|
||||
</context>
|
||||
```
|
||||
|
||||
Response
|
||||
```xml
|
||||
John did not specify an exact time. I'll suggest 9am. He also did not specify how to be reminded. I'll ask but if he doesn't respond I'll assume a text message on standard output is fine. I'll write down this task in a file so I can keep it in context. I can write simple files with busybox:latest and echo but I will need to use sh -c to do the redirect.
|
||||
<actions>
|
||||
<write_stdout message="I'll remind you to feed the cat tomorrow morning at 9am. Is a message on the standard output ok?"/>
|
||||
<start_container image="busybox:latest" timeout="1000">
|
||||
<command>sh</command>
|
||||
<argtument>-c</argument>
|
||||
<argument><![CDATA[echo 'Remind John to feed the cat on 2024-10-18T09:00:00+02:00. Use standard output.' > /tasks/reminder.txt]]></argument>
|
||||
<volumes>
|
||||
<volume>/tasks:/tasks</volume>
|
||||
</volumes>
|
||||
</start_container>
|
||||
<monitor_file path="/tasks/reminder.txt"/>
|
||||
</actions>
|
||||
```
|
||||
**Explanation:** Documenting reasoning helps track your decision-making process for future reference and learning.
|
||||
|
||||
These actions are available to you:
|
||||
# Access to Linux Environment
|
||||
|
||||
SIA has access to a Linux environment, which means you can leverage shell commands and scripts to perform tasks.
|
||||
You can troubleshoot, monitor, or deploy resources efficiently using Linux command-line utilities within your `<single_shot>`, `<repeat>`, or `<background>` commands.
|
||||
|
||||
# Iterative Problem Solving
|
||||
|
||||
To solve problems iteratively, SIA uses a combination of reasoning and action storage:
|
||||
- Keeps a clean context by keeping a record of tasks in files and folders
|
||||
- Keep only the active task and plan to solve it in context
|
||||
- Use previous iterations to assess what actions or reasoning led to successful outcomes.
|
||||
- Remeber what time you started the task and keep a record of solutions you tried to avoid repeating keep track of progress
|
||||
- Adjust your approach based on retrospective analysis, potentially altering future reasoning, script parameters
|
||||
|
||||
By maintaining a dynamic relationship between context and action, SIA can tackle increasingly complex challenges over time, adapting intelligently and autonomously.
|
||||
|
||||
# User interaction
|
||||
Be a helpful assistant to the user.
|
||||
Get to know them and make notes about them.
|
||||
Open the relevant user notes when you interact with them.
|
||||
@@ -44,7 +44,7 @@ const SIAInterface = () => {
|
||||
const [validationError, setValidationError] = useState(null);
|
||||
|
||||
// UI state
|
||||
const [activeTab, setActiveTab] = useState('input');
|
||||
const [activeTab, setActiveTab] = useState('original');
|
||||
const [agentState, setAgentState] = useState(AgentState.CONTEXT_APPROVAL);
|
||||
const [wsState, setWsState] = useState(WebSocketState.DISCONNECTED);
|
||||
|
||||
@@ -226,46 +226,11 @@ const SIAInterface = () => {
|
||||
{/* Input/Response Tabs */}
|
||||
<Tabs value={activeTab} onValueChange={setActiveTab}>
|
||||
<TabsList className="grid w-full grid-cols-3">
|
||||
<TabsTrigger value="input">Input</TabsTrigger>
|
||||
<TabsTrigger value="original">Original Response</TabsTrigger>
|
||||
<TabsTrigger value="modified">Modified Response</TabsTrigger>
|
||||
<TabsTrigger value="input">Input</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="input">
|
||||
<Card>
|
||||
<CardContent className="pt-6">
|
||||
<div className="space-y-4">
|
||||
<div className="h-[200px]">
|
||||
<Editor
|
||||
height="100%"
|
||||
defaultLanguage="plaintext"
|
||||
value={input}
|
||||
onChange={setInput}
|
||||
options={editorOptions}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex space-x-2">
|
||||
<Button
|
||||
onClick={() => handleSendInput(false)}
|
||||
disabled={wsState !== WebSocketState.CONNECTED}
|
||||
className="flex-1"
|
||||
>
|
||||
Send Input
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => handleSendInput(true)}
|
||||
variant="secondary"
|
||||
disabled={wsState !== WebSocketState.CONNECTED}
|
||||
className="flex-1"
|
||||
>
|
||||
Send & Read Stdin
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="original">
|
||||
<Card>
|
||||
<CardContent className="pt-6">
|
||||
@@ -341,6 +306,42 @@ const SIAInterface = () => {
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
|
||||
|
||||
<TabsContent value="input">
|
||||
<Card>
|
||||
<CardContent className="pt-6">
|
||||
<div className="space-y-4">
|
||||
<div className="h-[200px]">
|
||||
<Editor
|
||||
height="100%"
|
||||
defaultLanguage="plaintext"
|
||||
value={input}
|
||||
onChange={setInput}
|
||||
options={editorOptions}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex space-x-2">
|
||||
<Button
|
||||
onClick={() => handleSendInput(false)}
|
||||
disabled={wsState !== WebSocketState.CONNECTED}
|
||||
className="flex-1"
|
||||
>
|
||||
Send Input
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => handleSendInput(true)}
|
||||
variant="secondary"
|
||||
disabled={wsState !== WebSocketState.CONNECTED}
|
||||
className="flex-1"
|
||||
>
|
||||
Send & Read Stdin
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
|
||||
{/* Output Display */}
|
||||
|
||||
Reference in New Issue
Block a user