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
142 changes: 142 additions & 0 deletions aworld-cli/src/aworld_cli/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -905,6 +905,7 @@ async def run_chat_session(self, agent_name: str, executor: Callable[[str], Any]
f"Type '/agents' to list all available agents.\n"
f"Type '/cost' for current session, '/cost -all' for global history.\n"
f"Type '/compact' to run context compression.\n"
f"Type '/memory' to edit project context, '/memory view' to view, '/memory status' for status.\n"
f"Use @filename to include images or text files (e.g., @photo.jpg or @document.txt)."
)

Expand All @@ -920,6 +921,7 @@ async def run_chat_session(self, agent_name: str, executor: Callable[[str], Any]
slash_cmds = [
"/agents", "/skills", "/new", "/restore", "/latest",
"/exit", "/quit", "/switch", "/cost", "/cost -all", "/compact",
"/memory", "/memory view", "/memory reload", "/memory status",
]
switch_with_agents = [f"/switch {n}" for n in agent_names] if agent_names else []
all_words = slash_cmds + switch_with_agents + ["exit", "quit"]
Expand All @@ -935,6 +937,10 @@ async def run_chat_session(self, agent_name: str, executor: Callable[[str], Any]
"/cost": "View query history (current session)",
"/cost -all": "View global history (all sessions)",
"/compact": "Run context compression",
"/memory": "Edit AWORLD.md project context",
"/memory view": "View current memory content",
"/memory reload": "Reload memory from file",
"/memory status": "Show memory system status",
"exit": "Exit chat",
"quit": "Exit chat",
}
Expand Down Expand Up @@ -1166,6 +1172,142 @@ async def run_chat_session(self, agent_name: str, executor: Callable[[str], Any]
traceback.print_exc()
continue

# Handle memory command
memory_input = user_input.strip().lower()
if memory_input.startswith(("/memory", "memory")):
try:
parts = user_input.split(maxsplit=1)
subcommand = parts[1] if len(parts) > 1 else ""

# Import required modules
import os
from pathlib import Path
import subprocess

# Find AWORLD.md file
def find_aworld_file():
"""Find AWORLD.md in standard locations"""
working_dir = Path.cwd()
search_paths = [
Path.home() / '.aworld' / 'AWORLD.md',
working_dir / '.aworld' / 'AWORLD.md',
working_dir / 'AWORLD.md',
]
for path in search_paths:
if path.exists():
return path
return None

def get_editor():
"""Get editor from environment variables"""
return os.environ.get('VISUAL') or os.environ.get('EDITOR') or 'nano'

if subcommand == "view":
# View current memory content
aworld_file = find_aworld_file()
if not aworld_file:
self.console.print("[yellow]No AWORLD.md file found.[/yellow]")
self.console.print("[dim]Create one with: /memory[/dim]")
else:
self.console.print(f"[dim]Reading from: {aworld_file}[/dim]\n")
content = aworld_file.read_text(encoding='utf-8')
# Display in a panel
from rich.panel import Panel
from rich.syntax import Syntax
syntax = Syntax(content, "markdown", theme="monokai", line_numbers=False)
self.console.print(Panel(syntax, title="AWORLD.md", border_style="cyan"))

elif subcommand == "reload":
# Reload memory from file
self.console.print("[dim]Memory reload functionality requires agent restart.[/dim]")
self.console.print("[dim]The AWORLD.md file will be automatically loaded on next agent start.[/dim]")

elif subcommand == "status":
# Show memory system status
aworld_file = find_aworld_file()
from rich.table import Table
table = Table(title="Memory System Status", box=box.ROUNDED)
table.add_column("Property", style="cyan")
table.add_column("Value", style="green")

if aworld_file:
table.add_row("AWORLD.md Location", str(aworld_file))
table.add_row("File Size", f"{aworld_file.stat().st_size} bytes")
from datetime import datetime
mtime = datetime.fromtimestamp(aworld_file.stat().st_mtime)
table.add_row("Last Modified", mtime.strftime("%Y-%m-%d %H:%M:%S"))
table.add_row("Status", "✅ Active")
else:
table.add_row("AWORLD.md Location", "Not found")
table.add_row("Status", "❌ Not configured")

table.add_row("Feature", "AWORLDFileNeuron")
table.add_row("Auto-load", "Enabled")
self.console.print(table)

else:
# Edit AWORLD.md (default action)
aworld_file = find_aworld_file()

if not aworld_file:
# Create new file in user directory (DEFAULT)
default_location = Path.home() / '.aworld' / 'AWORLD.md'
self.console.print(f"[yellow]No AWORLD.md found. Creating new file at:[/yellow]")
self.console.print(f"[cyan]{default_location}[/cyan]")
self.console.print(f"[dim](Default: ~/.aworld/AWORLD.md)[/dim]\n")

# Create directory if needed
default_location.parent.mkdir(parents=True, exist_ok=True)

# Create template
template = """# Project Context

## Project Overview
Describe your project here.

## Important Guidelines
- Add your project-specific guidelines
- Include coding standards
- Document important conventions

## Technical Details
- List key technologies
- Document architecture decisions
- Note important file locations

## Custom Instructions
Add any custom instructions for AI agents working on this project.

---
*This file is automatically loaded by AWorld agents.*
"""
default_location.write_text(template, encoding='utf-8')
aworld_file = default_location

# Open in editor
editor = get_editor()
self.console.print(f"[dim]Opening {aworld_file} in {editor}...[/dim]")

try:
# Open editor and wait for it to close
result = subprocess.run([editor, str(aworld_file)])
if result.returncode == 0:
self.console.print("[green]✅ AWORLD.md saved successfully.[/green]")
self.console.print("[dim]Changes will take effect on next agent start.[/dim]")
else:
self.console.print(f"[yellow]Editor exited with code {result.returncode}[/yellow]")
except FileNotFoundError:
self.console.print(f"[red]Editor '{editor}' not found.[/red]")
self.console.print("[dim]Set EDITOR or VISUAL environment variable to your preferred editor.[/dim]")
except Exception as e:
self.console.print(f"[red]Error opening editor: {e}[/red]")

except Exception as e:
self.console.print(f"[red]Error handling memory command: {e}[/red]")
import traceback
traceback.print_exc()
continue

# Handle agents command
if user_input.lower() in ("/agents", "agents"):
try:
Expand Down
4 changes: 4 additions & 0 deletions aworld/core/context/amni/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ class AgentContextConfig(BaseConfig):
enable_system_prompt_augment: bool = Field(default=False, description="enable_system_prompt_augment")
neuron_names: Optional[list[str]] = Field(default_factory=list)
neuron_config: Optional[Dict[str, NeuronStrategyConfig]] = Field(default_factory=list)

# AWORLD.md File Support
enable_aworld_file: bool = Field(default=True, description="Enable AWORLD.md file loading for project-specific context")
aworld_file_path: Optional[str] = Field(default=None, description="Custom path to AWORLD.md file (optional override)")

# Context Reduce - Purge
history_rounds: int = Field(default=100,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ async def _process_neurons(self, context: ApplicationContext, event: SystemPromp
from aworld.core.context.amni.prompt.neurons.skill_neuron import SKILL_NEURON_NAME
if SKILL_NEURON_NAME not in neuron_names:
neuron_names.append(SKILL_NEURON_NAME)

# Enable AWORLD.md File Feature
if agent_context_config.enable_aworld_file:
from aworld.core.context.amni.prompt.neurons.aworld_file_neuron import AWORLD_FILE_NEURON_NAME
if AWORLD_FILE_NEURON_NAME not in neuron_names:
neuron_names.insert(0, AWORLD_FILE_NEURON_NAME) # High priority - insert at beginning

# Enable Planing Feature
if agent_context_config.automated_cognitive_ingestion:
Expand Down
1 change: 1 addition & 0 deletions aworld/core/context/amni/prompt/neurons/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class Neurons:
WORKSPACE = "workspace"
GRAPH = "graph"
ENTITY = "entity"
AWORLD_FILE = "aworld_file"

class Neuron(ABC):
"""
Expand Down
Loading
Loading