Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,32 @@ jobs:
- name: Install Cerebrum
run: |
python -m pip install -e aios_root/Cerebrum/
# Create AIOS kernel config if missing
- name: Create AIOS kernel config
run: |
mkdir -p aios_root/aios/config
if [ ! -f aios_root/aios/config/config.yaml ]; then
cat > aios_root/aios/config/config.yaml << 'EOF'
llm:
max_gpu_memory: null
kernel_max_new_tokens: 512
memory:
auto_extract: true
auto_inject: true
relevance_threshold: 0.3
max_injected_memories: 10
max_memory_tokens: 2000
storage:
root_dir: root
server:
hostname: localhost
port: 8000
EOF
echo "Created default config.yaml"
else
echo "config.yaml already exists"
fi

# Run AIOS kernel
- name: Run AIOS kernel in background
run: |
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -204,4 +204,7 @@ next-env.d.ts
metagpt
workspace

cache
cache

# Kiro
/.kiro
35 changes: 35 additions & 0 deletions cerebrum/llm/apis.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,30 @@ def llm_chat(
"backend": "openai"
}]
)

# Using an Ollama model
response = llm_chat(
"agent1",
messages=[
{"role": "user", "content": "Summarize this article."}
],
llms=[{"name": "qwen2.5:7b", "backend": "ollama"}]
)
```

Kernel Personalization:
When the kernel is configured with the ``mem0`` memory provider and
``auto_inject: true``, the kernel may prepend a system message
containing relevant memories to the messages list before processing.
When ``auto_extract: true`` is set, the kernel stores conversation
turns as memories after each chat call. This injection is performed
by the kernel and does not modify the SDK request payload.

Ollama Dynamic Discovery:
Ollama models installed on the Ollama server are automatically
discovered by the kernel and do not require pre-registration in the
kernel's ``config.yaml``. Simply specify the model name and
``"backend": "ollama"`` in the ``llms`` configuration list.
"""
query = LLMQuery(
llms=llms,
Expand Down Expand Up @@ -329,6 +352,10 @@ def llm_chat_with_json_output(
}
)
```

Kernel Personalization:
Personalization memory injection does not apply to
``chat_with_json_output`` action types.
"""
query = LLMQuery(
llms=llms,
Expand Down Expand Up @@ -411,6 +438,14 @@ def llm_chat_with_tool_call_output(
}]
)
```

Kernel Personalization:
When the kernel is configured with the ``mem0`` memory provider and
``auto_inject: true``, the kernel may prepend a system message
containing relevant memories to the messages list before processing.
Note that conversation extraction does not occur for this action
type — only context injection applies. This injection is performed
by the kernel and does not modify the SDK request payload.
"""
query = LLMQuery(
llms=llms,
Expand Down
93 changes: 88 additions & 5 deletions cerebrum/memory/apis.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,32 @@
"""Memory API module for AIOS kernel memory operations.

Provides functions to create, read, update, delete, and search agent memories
through the AIOS kernel.

Kernel-Side Memory Configuration:
The following fields are configured in the kernel's ``config.yaml`` under
the ``memory`` section. They are **not** configurable through the SDK.

memory.provider : str
Memory backend to use. Accepts ``"in-house"``, ``"mem0"``, or ``"zep"``.
memory.auto_extract : bool
When true, the kernel automatically stores conversation turns as
memories after each chat LLM call.
memory.auto_inject : bool
When true, the kernel retrieves and injects relevant memories before
each chat LLM call.
memory.relevance_threshold : float
Minimum similarity score a memory must meet to be eligible for
injection.
memory.max_injected_memories : int
Maximum number of memories injected per LLM call.
memory.max_memory_tokens : int
Token budget for the injected memory block.

``memory.mem0.*`` and ``memory.zep.*`` contain provider-specific kernel
configuration and are not set from the SDK.
"""

from pydantic import BaseModel, Field
from typing import List, Dict, Optional, Any, Union
from typing_extensions import Literal
Expand Down Expand Up @@ -56,7 +85,8 @@ def create_memory(agent_name: str,
Args:
agent_name: Name of the agent to handle the request
content: Content of the memory
metadata: Optional metadata (keywords, context, tags, etc.)
metadata: Optional metadata (keywords, context, tags, etc.).
Provider-specific keys can be passed through this dict.
base_url: Base URL for the API server

Returns:
Expand All @@ -68,6 +98,18 @@ def create_memory(agent_name: str,
>>> response = create_memory("agent1", "Meeting notes: Discussed Q1 goals", metadata)
>>> print(response.memory_id) # "mem_123abc"
>>> print(response.success) # True

Provider-Specific Metadata Keys:
mem0:
``user_id`` (str): Scopes memory to a specific user.
``agent_id`` (str): Scopes memory to a specific agent.
Falls back to kernel config defaults if not provided.
zep:
``session_id`` (str): Scopes memory to a session.
``user_id`` (str): Scopes memory to a user.
Falls back to kernel config defaults if not provided.
in-house:
No provider-specific metadata keys required.
"""
query = MemoryQuery(
operation_type="add_memory",
Expand All @@ -79,12 +121,13 @@ def create_agentic_memory(agent_name: str,
content: str,
metadata: Optional[Dict[str, Any]] = None,
base_url: str = aios_kernel_url) -> MemoryResponse:
"""Create a new memory note.
"""Create a new agentic memory note.

Args:
agent_name: Name of the agent to handle the request
content: Content of the memory
metadata: Optional metadata (keywords, context, tags, etc.)
metadata: Optional metadata (keywords, context, tags, etc.).
Provider-specific keys can be passed through this dict.
base_url: Base URL for the API server

Returns:
Expand All @@ -93,9 +136,21 @@ def create_agentic_memory(agent_name: str,
Example:
>>> # Create a memory with content and metadata
>>> metadata = {"tags": ["important", "meeting"], "priority": "high"}
>>> response = create_memory("agent1", "Meeting notes: Discussed Q1 goals", metadata)
>>> response = create_agentic_memory("agent1", "Meeting notes: Discussed Q1 goals", metadata)
>>> print(response.memory_id) # "mem_123abc"
>>> print(response.success) # True

Provider-Specific Metadata Keys:
mem0:
``user_id`` (str): Scopes memory to a specific user.
``agent_id`` (str): Scopes memory to a specific agent.
Falls back to kernel config defaults if not provided.
zep:
``session_id`` (str): Scopes memory to a session.
``user_id`` (str): Scopes memory to a user.
Falls back to kernel config defaults if not provided.
in-house:
No provider-specific metadata keys required.
"""
query = MemoryQuery(
operation_type="add_agentic_memory",
Expand Down Expand Up @@ -139,7 +194,8 @@ def update_memory(agent_name: str,
agent_name: Name of the agent to handle the request
memory_id: ID of the memory to update
content: Optional new content
metadata: Optional new metadata
metadata: Optional new metadata.
Provider-specific keys can be passed through this dict.
base_url: Base URL for the API server

Returns:
Expand All @@ -155,6 +211,18 @@ def update_memory(agent_name: str,
... metadata=new_metadata
... )
>>> print(response.success) # True

Provider-Specific Metadata Keys:
mem0:
``user_id`` (str): Scopes memory to a specific user.
``agent_id`` (str): Scopes memory to a specific agent.
Falls back to kernel config defaults if not provided.
zep:
``session_id`` (str): Scopes memory to a session.
``user_id`` (str): Scopes memory to a user.
Falls back to kernel config defaults if not provided.
in-house:
No provider-specific metadata keys required.
"""
params = {"memory_id": memory_id}
if metadata is not None:
Expand Down Expand Up @@ -218,6 +286,21 @@ def search_memories(agent_name: str,
# Memory ID: mem_123abc
# Content: Meeting notes: Discussed Q1 goals
# Score: 0.92

Provider-Specific Metadata Keys:
These keys can be used to scope search results when passed via
the ``metadata`` parameter of memory creation functions.

mem0:
``user_id`` (str): Scopes memory to a specific user.
``agent_id`` (str): Scopes memory to a specific agent.
Falls back to kernel config defaults if not provided.
zep:
``session_id`` (str): Scopes memory to a session.
``user_id`` (str): Scopes memory to a user.
Falls back to kernel config defaults if not provided.
in-house:
No provider-specific metadata keys required.
"""
query = MemoryQuery(
operation_type="retrieve_memory",
Expand Down
14 changes: 13 additions & 1 deletion cerebrum/storage/apis.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ def retrieve_file(
def create_file(
agent_name: str,
file_path: str,
file_name: Optional[str] = None,
base_url: str = aios_kernel_url
) -> StorageResponse:
"""
Expand All @@ -163,6 +164,9 @@ def create_file(
Args:
agent_name: Name of the agent
file_path: Path where to create the file
file_name: Optional[str] — Custom file name for the created file.
When provided, the kernel uses this name instead of deriving it
from the file path. Defaults to None.
base_url: API base URL

Returns:
Expand All @@ -176,10 +180,18 @@ def create_file(
print(f"File created at {file_path}")
else:
print(f"Failed to create file: {response.error}")

# Create a file with a custom file name
response = create_file("agent1", "src/", file_name="report.txt")
if response.finished:
print("File created with custom name")
```
"""
params = {"file_path": file_path}
if file_name is not None:
params["file_name"] = file_name
query = StorageQuery(
params={"file_path": file_path},
params=params,
operation_type="create_file"
)
return send_request(agent_name, query, base_url)
Expand Down
Loading