Skip to content

AgentOS

The AgentOS is designed for the autonomation and orchestration of software agents within the Eidolon framework. In the following documentation, we will delve into the systems-level agent management, resource registry, and I/O communication processes that establish AgentOS as a vital component of the Eidolon platform.

System memory

Systems-Level Agent Management

AgentOS orchestrates the execution and administration of AgentPrograms within the Eidolon environment. Agent programs are registered with FastAPI and can be started, stopped, and managed through the AgentOS. The endpoints for these operations are automatically generated by FastAPI and can be accessed through the Eidolon API.

@register_program

Each Agent method registered using the “@register_program” decorator represents a new “process” in the AgentOS. Calls to these methods are assigned a new process ID and a thread ID which are used to track the execution of a conversation.

The following code snippet illustrates how create a new Agent with two programs:

from typing import Annotated
from fastapi import UploadFile, Body, File
from pydantic import BaseModel
from eidolon_ai_sdk.agent.agent import register_program
class HelloWorld:
@register_program()
async def execute(self, name: Annotated[str, Body(description="Your name", embed=True)]) -> str:
return f"Hello, World {name}!"
@register_program()
async def describe_image(
self,
question: str = Body(..., embed=True, description="Your question about the image"),
image: UploadFile = File(..., description="The image to describe"),
) -> IdleStateRepresentation:
return f"Hello, World {question}! File name is {image.filename}. file length is {image.size} bytes. content type is {image.content_type}"

The first program, “execute”, takes a name as input and returns a greeting. The second program, “describe_image”, takes a question and an image as input and returns a description of the image file.

Both of these methods are registered with FastAPI and can be accessed through the Eidolon API. Since the method doesn’t return a state to transition to, both methods also transition directly to the “terminated” state after execution meaning that they are not long-running processes.

Before we can communicate with a program or action, we need to start a process. Process are created by sending a POST request to the “/agents/{agent_name}/processes” endpoint with no body.

The return from the API call is the output of the program follows the following JSON format:

{
"process_id": "string",
"state": "string",
"available_actions": ["string"]
}

The “process_id” is the ID of the process that was created to execute the program. The “state” is the state of the process, in this case it is always “initialized”. The “available_actions” are the next set of actions that can be executed in the current state. These are the programs that are registered for that Agent.

In FASTAPI, program are actions that can be started from the “initialize” state and are registered as POST endpoints under the URL “/agents/{agent_name}/processes/{process_id}/actions/{program_name}” and the body of the request is the input to the program, in JSON format. The return from the API call is the output of the program follows the following JSON format:

{
"process_id": "string",
"state": "string",
"available_actions": ["string"],
"data": json
}

The “process_id” is the ID of the process that was created to execute the program. The “state” is the state that the process transitioned to after execution. The “available_actions” are the next set of actions that can be executed in the current state. The “data” is the output of the program, in JSON format with the schema derived from the return of the method.

@register_action

The “@register_action” decorator is used to register an action with the AgentOS. Actions are followup states that a program transitions into after execution. Actions are used to create long-running processes that are be monitored and controlled by the AgentOS and are used to implement the Eidolon conversation model.

The following code snippet illustrates how to create a new Agent with a long-running conversational program:

from typing import Annotated
from fastapi import UploadFile, Body, File
from pydantic import BaseModel
from eidolon_ai_sdk.agent.agent import register_program, register_action, AgentState
class HelloWorld:
@register_program()
@register_action("idle")
async def execute(self, name: Annotated[str, Body(description="Your name", embed=True)]) -> AgentState[str]:
return AgentState(name="idle", data=f"Hello, World {name}!")

In this example, the “@register_program” decorator on the “execute” method is used to register the method as a program. The “@register_action” decorator is used to register the “execute” method as an action as well, specifically for the “idle” state. Notice the return type of the “execute” method is now “AgentState” instead of “str”. This is because the “execute” method now returns a state to transition to the “idle” state instead of the “terminated” state. This one method now implements the Eidolon conversation model and can be used to create a conversational agent.

In general the “@register_action” decorator is used to register a method as an action for a specific state. The return type of the method should be “AgentState” and the method should return the state to transition to.

In FASTAPI, actions are registered as POST endpoints under the URL “/agents/{agent_name}/processes/{process_id}/actions/{action_name}” and the body of the request is the input to the program, in JSON format.

The return from the API call is the output of the program follows the following JSON format:

{
"process_id": "string",
"state": "string",
"available_actions": ["string"],
"data": json
}

The “process_id” is the ID of the process that was created to execute the program. The “state” is the state that the process transitioned to after execution. The “available_actions” are the next set of actions that can be executed in the current state. The “data” is the output of the program, in JSON format with the schema derived from the return of the method.

Recap

The AgentOS uses the “@register_program” and “@register_action” decorators to register the methods of an agent with FastAPI. Methods decorated with “@register_program” are registered as programs and methods decorated with “@register_action” are registered as actions for a specific state.

Processes are created by sending a POST request to the “/agents/{agent_name}/processes” endpoint with no body.

In the OpenAPI documentation, all operations are registered as POST endpoints under the URL “/agents/{agent_name}/processes/{process_id}/actions/{action_name}” and the body of the request is the input to the action, in JSON format.

Resource Registry and its Role

The Resource Registry in AgentOS is similar to the concept of resource models found in Kubernetes. It acts as a centralized registry that keeps track of all resources utilized by agents, such as defined AgentPrograms, memories, machine definition, and more. Resources are the generic way every object is defined in Eidolon.

Resources can be defined in code or, more commonly, in YAML files. Following in as example of a resource definition in YAML:

apiVersion: eidolon/v1
kind: CPU
metadata:
name: frugal
implementation: "eidolon_ai_sdk.cpu.conversational_agent_cpu.ConversationalAgentCPU"
spec:
cpu:
spec:
llm_unit:
spec:
force_json: 'True'
max_tokens: '3000'
model: gpt-3.5-turbo-1106
temperature: '.1'
max_num_function_calls: '20'

This resource definition defines a CPU resource named “frugal” that uses the “ConversationalAgentCPU” implementation. The LLM for this CPU is configured to use the GPT-3.5-Turbo-1106 model with a temperature of 0.1 and a max number of tokens of 3000.

This resource is registered with the AgentOS and can be accessed by agents in their definition in the following way:

apiVersion: eidolon/v1
kind: GenericAgent
metadata:
name: qa
spec:
cpu: "CPU.frugal"

The “CPU.frugal” resource is referenced in the agent definition and the AgentOS will automatically inject the resource into the agent when it is created. References are of the form “kind.name” where “kind” is the kind of resource and “name” is the name of the resource.

Any object that is defined in Eidolon is a resource and can be referenced in this way. For example, you could define a LogicUnit resource and reference it in many agent definitions.

I/O and Agent Communication

As mentioned previously, the AgentOS registers all Agent endpoints with FastAPI; therefore, all communication with agents is over HTTP in a RESTful manner. Communication with an agent is as simple as sending a POST request to the agent’s endpoint with the appropriate data.

The published API for an agent is automatically generated by FastAPI and is documented in the OpenAPI documentation allowing for easy discovery and integration with other systems. This simple communication model allows agents to be integrated into any system that can make HTTP requests creating a powerful and flexible communication model.

Agent-to-Agent Communication

An agent can define the set of other agents that it can communicate with. This is done by setting the “agent_refs” property in the agent specification. For example:

apiVersion: eidolon/v1
kind: Agent
metadata:
name: qa
implementation: eidolon_examples.getting_started.2_custom_agents.qa.QualityAssurance
spec:
agent_refs: ["hello_world"]
cpu: "CPU.frugal"

This agent definition defines an agent that can communicate with the “hello_world” agent. The parameters of an agent_ref is actually a URL, however, in this since the agent is locally defined the URL is just the name of the agent.

The AgentOS will automatically create LogicUnits to handle the communication between agents. Every program defined in an agent is automatically registered as a tool function in the created LogicUnit. After a program is executed, the legal next set of actions for a program are followed by the LogicUnit, restricting the next set of tools that can be executed to the next set of legal actions defined by the Agent. This allows agents to communicate with each other in a structured and controlled manner where the definition of the Agent dictates the “flow” of the conversation.

Summary

The AgentOS is an integral part of the Eidolon platform, designed to automate and orchestrate software agents through robust system-level management, resource registry, and communication processes. It facilitates the execution and administration of AgentPrograms, allowing them to be started, stopped, and managed with ease. AgentOS interfaces with FastAPI to enable automatic generation of endpoints, making the deployment of agents in the Eidolon environment streamlined. With decorators like @register_program and @register_action, developers can quickly create new agents or extend functionalities with new processes or actions. This modular approach simplifies the process of building powerful and complex systems by abstracting agent management and interaction details.

AgentOS boasts a Resource Registry, akin to Kubernetes resource models, which centrally tracks resources such as AgentPrograms and machine definitions. Resources can be defined in code or YAML, as demonstrated by a CPU resource example, and incorporate comprehensive specifications for various implementation details. Agents utilize these well-defined resources through references in their definitions, promoting a cohesive and organized structure for resource management. This feature enables precise control and efficient utilization of all the components within the AgentOS ecosystem, contributing to a robust and harmonious operation of the agents.

Communication in AgentOS is facilitated via RESTful HTTP, using FastAPI to register agent endpoints. This allows simple and flexible interaction with any system capable of sending HTTP requests. OpenAPI documentation is automatically generated, enhancing the discoverability and integration possibilities of agents. Additionally, AgentOS permits structured Agent-to-Agent communication through defined references, ensuring conversations are tightly regulated according to the conversation model inherent to the agents’ designs. The logical flow of agent interactions is thus directed by their explicit definitions within AgentOS.