docs: 重构为 docs/zh/ + docs/en/ 子文件夹结构
- 拆分为 docs/zh/(中文) 和 docs/en/(英文) - README 索引对应语言子文件夹 - 保留所有文档内容
This commit is contained in:
29
docs/en/README.md
Normal file
29
docs/en/README.md
Normal file
@ -0,0 +1,29 @@
|
||||
# TrulyMEM Documentation
|
||||
|
||||
Welcome to the TrulyMEM project documentation.
|
||||
|
||||
## Documentation Index
|
||||
|
||||
| Document | Content |
|
||||
|----------|---------|
|
||||
| [architecture.md](architecture.md) | System architecture and technical design |
|
||||
| [quick_start.md](quick_start.md) | Complete startup guide and configuration |
|
||||
| [memory.md](memory.md) | Internal memory working mechanism |
|
||||
| [persona.md](persona.md) | Persona Graph mechanism |
|
||||
| [working_memory.md](working_memory.md) | Continuous task handling mechanism |
|
||||
| [api.md](api.md) | Backend API reference (for extension development) |
|
||||
| [prompts.md](prompts.md) | Prompt management module |
|
||||
|
||||
## Project Introduction
|
||||
|
||||
TrulyMEM (TrueHumanMEM) is a graph-based memory system that gives AI long-term memory capabilities, allowing AI to remember, recall, and manage information like humans.
|
||||
|
||||
## Core Features
|
||||
|
||||
- **Long-term Memory**: SQLite embedded graph database, out-of-the-box
|
||||
- **Persona Graph**: Role-playing and character settings support
|
||||
- **Working Memory Chain**: Task tracking for conversation continuity
|
||||
- **TUI & Backend Separation**: Multi-threaded Queue communication
|
||||
- **Keyboard-driven TUI**: Full keyboard operation, no mouse required
|
||||
- **Cross-platform**: Windows / Linux / macOS
|
||||
- **Standalone Deployment**: Packaged as executable
|
||||
449
docs/en/api.md
Normal file
449
docs/en/api.md
Normal file
@ -0,0 +1,449 @@
|
||||
# BackendServer API Documentation
|
||||
|
||||
This document describes the backend server's API interfaces for developers extending other connection methods (such as HTTP interface, WebSocket, etc.).
|
||||
|
||||
## Overview
|
||||
|
||||
TrulyMEM backend uses **Packet Communication Protocol**, implemented via `queue.Queue` for thread-safe communication. The backend runs in an independent thread, processing requests from clients.
|
||||
|
||||
### Core Components
|
||||
|
||||
| Component | Description |
|
||||
|-----------|-------------|
|
||||
| `BackendServer` | Backend server, runs in independent thread |
|
||||
| `BackendClient` | Client wrapper, provides convenient methods |
|
||||
| `PacketType` | Request type enum |
|
||||
| `Packet` | Data packet (request) |
|
||||
| `PacketResponse` | Data packet response |
|
||||
|
||||
---
|
||||
|
||||
## Request Types (PacketType)
|
||||
|
||||
```python
|
||||
class PacketType(Enum):
|
||||
PROCESS_MESSAGE = "process_message" # Process message
|
||||
EXECUTE_TOOL = "execute_tool" # Execute tool
|
||||
GET_STATUS = "get_status" # Get status
|
||||
GET_CONFIG = "get_config" # Get config
|
||||
SET_CONFIG = "set_config" # Set config
|
||||
GET_HISTORY = "get_history" # Get history
|
||||
SAVE_HISTORY = "save_history" # Save history
|
||||
SHUTDOWN = "shutdown" # Shutdown service
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Data Packet Format
|
||||
|
||||
### Packet
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class Packet:
|
||||
id: str # Unique identifier
|
||||
type: PacketType # Request type
|
||||
body: Dict[str, Any] # Request parameters
|
||||
response_queue: queue.Queue # Response queue (optional)
|
||||
created_at: float # Creation time
|
||||
```
|
||||
|
||||
### PacketResponse
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class PacketResponse:
|
||||
id: str # Corresponding request ID
|
||||
success: bool # Success flag
|
||||
data: Any = None # Returned data
|
||||
error: Optional[str] = None # Error message
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API Interface Details
|
||||
|
||||
### 1. PROCESS_MESSAGE - Process Message
|
||||
|
||||
Send user message, AI will process and return reply (may contain tool calls).
|
||||
|
||||
**Request parameters:**
|
||||
```python
|
||||
body = {
|
||||
"user_input": str # User input message
|
||||
}
|
||||
```
|
||||
|
||||
**Response data:**
|
||||
```python
|
||||
{
|
||||
"success": True,
|
||||
"content": str, # AI reply content
|
||||
"tool_calls": [ # Tool call records
|
||||
{
|
||||
"name": str, # Tool name
|
||||
"arguments": dict,# Tool parameters
|
||||
"result": str # Tool execution result
|
||||
}
|
||||
],
|
||||
"rejected_tools": [ # Rejected tool calls
|
||||
(str, str) # (tool name, rejection reason)
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```python
|
||||
from core import BackendServer, BackendClient
|
||||
|
||||
server = BackendServer(db_path="graph_memory.db", use_embedded_db=True)
|
||||
server.start(api_key="your-api-key")
|
||||
|
||||
client = BackendClient(server)
|
||||
result = client.process_message("Hello, please remember my name is Xiao Ming")
|
||||
|
||||
if result.get("success"):
|
||||
print(result["content"])
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. EXECUTE_TOOL - Execute Tool
|
||||
|
||||
Directly execute specified memory tools.
|
||||
|
||||
> **Note**: Tools called directly from frontend are **NOT limited** in number, only tool calls initiated by the model are limited.
|
||||
|
||||
**Request parameters:**
|
||||
```python
|
||||
body = {
|
||||
"tool_name": str, # Tool name
|
||||
"arguments": dict # Tool parameters
|
||||
}
|
||||
```
|
||||
|
||||
**Response data:**
|
||||
```python
|
||||
{
|
||||
"success": True,
|
||||
"result": str # Tool execution result
|
||||
}
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```python
|
||||
result = client.execute_tool("memory_recall", {"query_intent": "user information"})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. GET_STATUS - Get Status
|
||||
|
||||
Get backend running status.
|
||||
|
||||
**Request parameters:**
|
||||
```python
|
||||
body = {} # No parameters
|
||||
```
|
||||
|
||||
**Response data:**
|
||||
```python
|
||||
{
|
||||
"running": bool, # Whether backend is running
|
||||
"config": dict, # Current config
|
||||
"graph_initialized": bool, # Whether graph database is initialized
|
||||
"client_initialized": bool # Whether API client is initialized
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. GET_CONFIG - Get Config
|
||||
|
||||
Get current API configuration.
|
||||
|
||||
**Request parameters:**
|
||||
```python
|
||||
body = {} # No parameters
|
||||
```
|
||||
|
||||
**Response data:**
|
||||
```python
|
||||
{
|
||||
"api_key": str, # API Key
|
||||
"base_url": str # API Base URL
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. SET_CONFIG - Set Config
|
||||
|
||||
Update API configuration (API Key and Base URL).
|
||||
|
||||
**Request parameters:**
|
||||
```python
|
||||
body = {
|
||||
"api_key": str, # API Key
|
||||
"base_url": str, # API Base URL (default: https://api.deepseek.com)
|
||||
"model": str # Model name (default: deepseek-chat)
|
||||
}
|
||||
```
|
||||
|
||||
**Response data:**
|
||||
```python
|
||||
{
|
||||
"status": "config_updated"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. GET_HISTORY - Get Message History
|
||||
|
||||
Get saved message history.
|
||||
|
||||
**Request parameters:**
|
||||
```python
|
||||
body = {} # No parameters
|
||||
```
|
||||
|
||||
**Response data:**
|
||||
```python
|
||||
{
|
||||
"history": list # Message history list
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. SAVE_HISTORY - Save Message History
|
||||
|
||||
Save message history to memory.
|
||||
|
||||
**Request parameters:**
|
||||
```python
|
||||
body = {
|
||||
"messages": list # Message list
|
||||
}
|
||||
```
|
||||
|
||||
**Response data:**
|
||||
```python
|
||||
{
|
||||
"status": "history_saved"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 8. SHUTDOWN - Shutdown Service
|
||||
|
||||
Shutdown backend server.
|
||||
|
||||
**Request parameters:**
|
||||
```python
|
||||
body = {} # No parameters
|
||||
```
|
||||
|
||||
**Response data:**
|
||||
```python
|
||||
{
|
||||
"status": "shutdown"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```python
|
||||
from core import BackendServer, BackendClient
|
||||
|
||||
# 1. Create and start backend
|
||||
# config_file default: ~/.trulymem/config.json
|
||||
server = BackendServer(
|
||||
db_path="graph_memory.db",
|
||||
use_embedded_db=True,
|
||||
config_file=None # Optional, custom config path
|
||||
)
|
||||
server.start(
|
||||
api_key="your-api-key",
|
||||
base_url="https://api.deepseek.com",
|
||||
model="deepseek-chat" # Optional, model name
|
||||
)
|
||||
|
||||
# 2. Create client
|
||||
client = BackendClient(server)
|
||||
|
||||
# 3. Send message
|
||||
result = client.process_message("Hello")
|
||||
if result.get("success"):
|
||||
print(result["content"])
|
||||
|
||||
# 4. Shutdown
|
||||
client.shutdown()
|
||||
```
|
||||
|
||||
### Using Packet Protocol
|
||||
|
||||
```python
|
||||
import queue
|
||||
from core import BackendServer, Packet, PacketType
|
||||
|
||||
server = BackendServer(config_file=None)
|
||||
server.start(api_key="your-key", model="deepseek-chat")
|
||||
|
||||
# Create request packet
|
||||
response_queue = queue.Queue()
|
||||
packet = Packet(
|
||||
id="req-001",
|
||||
type=PacketType.PROCESS_MESSAGE,
|
||||
body={"user_input": "Hello"},
|
||||
response_queue=response_queue
|
||||
)
|
||||
|
||||
# Send request
|
||||
result = server.send(packet)
|
||||
print(result.body)
|
||||
|
||||
# Shutdown
|
||||
server.shutdown()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Extension Guide
|
||||
|
||||
### Extend to HTTP API
|
||||
|
||||
```python
|
||||
from flask import Flask, request, jsonify
|
||||
from core import BackendServer, BackendClient
|
||||
|
||||
app = Flask(__name__)
|
||||
server = BackendServer()
|
||||
client = BackendClient(server)
|
||||
|
||||
@app.route("/message", methods=["POST"])
|
||||
def send_message():
|
||||
data = request.json
|
||||
result = client.process_message(data["message"])
|
||||
return jsonify(result)
|
||||
|
||||
@app.route("/config", methods=["POST"])
|
||||
def update_config():
|
||||
data = request.json
|
||||
result = client.update_config(data["api_key"], data.get("base_url"))
|
||||
return jsonify(result)
|
||||
|
||||
@app.route("/status", methods=["GET"])
|
||||
def get_status():
|
||||
result = client.get_status()
|
||||
return jsonify(result)
|
||||
|
||||
if __name__ == "__main__":
|
||||
server.start()
|
||||
app.run(port=8080)
|
||||
```
|
||||
|
||||
### Extend to WebSocket
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
import websockets
|
||||
import json
|
||||
from core import BackendServer, BackendClient
|
||||
|
||||
server = BackendServer()
|
||||
client = BackendClient(server)
|
||||
|
||||
async def handler(websocket):
|
||||
async for message in websocket:
|
||||
data = json.loads(message)
|
||||
msg_type = data.get("type")
|
||||
|
||||
if msg_type == "message":
|
||||
result = client.process_message(data["content"])
|
||||
elif msg_type == "config":
|
||||
result = client.update_config(data["api_key"], data.get("base_url"))
|
||||
elif msg_type == "status":
|
||||
result = client.get_status()
|
||||
else:
|
||||
result = {"success": False, "error": "unknown type"}
|
||||
|
||||
await websocket.send(json.dumps(result))
|
||||
|
||||
async def main():
|
||||
server.start()
|
||||
async with websockets.serve(handler, "localhost", 8765):
|
||||
await asyncio.Future()
|
||||
|
||||
asyncio.run(main())
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Thread Safety Notes
|
||||
|
||||
- `BackendServer` uses `threading.Lock` to protect shared resources
|
||||
- All requests pass through `queue.Queue`, thread-safe
|
||||
- Responses return through each request's independent response queue
|
||||
- Default timeout: 30 seconds
|
||||
|
||||
---
|
||||
|
||||
## Tool Call Limits
|
||||
|
||||
### Limit Scope
|
||||
|
||||
| Call Method | Limited | Description |
|
||||
|-------------|---------|-------------|
|
||||
| Model-initiated tool calls | ✅ Limited | Triggered via `PROCESS_MESSAGE`, model automatically calls tools |
|
||||
| Frontend direct tool calls | ❌ Not limited | Called directly via `EXECUTE_TOOL` |
|
||||
|
||||
### Limit Rules (Model-initiated only)
|
||||
|
||||
| Category | Operation | Per-Turn Limit |
|
||||
|----------|-----------|---------------|
|
||||
| Persona graph | Query | 1 time |
|
||||
| Persona graph | Modify | 1 time |
|
||||
| Working memory chain | Query | 4 times |
|
||||
| Working memory chain | Modify | 2 times |
|
||||
| General memory | Query | 20 times |
|
||||
| General memory | Modify | 10 times |
|
||||
|
||||
### Reset Mechanism
|
||||
|
||||
- Counter resets automatically on each `PROCESS_MESSAGE` call
|
||||
- Frontend direct `EXECUTE_TOOL` calls do NOT reset the counter
|
||||
|
||||
---
|
||||
|
||||
## Error Handling
|
||||
|
||||
All APIs return unified format:
|
||||
|
||||
```python
|
||||
# Success
|
||||
{
|
||||
"success": True,
|
||||
"data": {...}
|
||||
}
|
||||
|
||||
# Failure
|
||||
{
|
||||
"success": False,
|
||||
"error": "Error description"
|
||||
}
|
||||
```
|
||||
|
||||
Common errors:
|
||||
|
||||
| Error Message | Description |
|
||||
|--------------|-------------|
|
||||
| `API Key not configured` | API Key not set |
|
||||
| `timeout` | Request timeout |
|
||||
| `Tool call rejected: ...` | Tool call rate exceeded limit |
|
||||
179
docs/en/architecture.md
Normal file
179
docs/en/architecture.md
Normal file
@ -0,0 +1,179 @@
|
||||
# TrulyMEM Architecture
|
||||
|
||||
## Core Principles
|
||||
|
||||
- Keyboard-driven, zero mouse dependency
|
||||
- Minimalist visual, information density priority
|
||||
- Tool traces hidden by default, expandable when needed
|
||||
- TUI & backend separation, multi-threaded communication
|
||||
- **Everything is a graph**, AI reasoning runs entirely in backend
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
TrulyMEM-TrueHumanMEM/
|
||||
├── trulymem_entry.py # Entry: start core → then ui
|
||||
├── core/ # Backend/business logic
|
||||
│ ├── __init__.py # Export BackendServer, BackendClient, EmbeddedGraphDB
|
||||
│ ├── server.py # BackendServer (Packet communication protocol)
|
||||
│ ├── client.py # BackendClient (Packet protocol client)
|
||||
│ ├── embedded_db.py # SQLite graph database implementation
|
||||
│ ├── graph_client.py # OpenAI/DeepSeek API client
|
||||
│ ├── tool_executor.py # Tool executor
|
||||
│ ├── tool_limiter.py # Tool call limiter
|
||||
│ ├── tools/ # Tool definitions
|
||||
│ │ ├── __init__.py
|
||||
│ │ └── memory_tools.py
|
||||
│ └── prompts/ # Prompt management
|
||||
├── ui/ # TUI display layer (display only, no AI logic)
|
||||
│ ├── __init__.py # Export GraphMemoryApp, AppConfig
|
||||
│ ├── app.py # GraphMemoryApp (communicates via BackendClient)
|
||||
│ ├── widgets/ # TUI components
|
||||
│ ├── handlers/ # Event handlers
|
||||
│ ├── models/ # Data models
|
||||
│ ├── services/ # Service layer (config only)
|
||||
│ └── styles/ # Style files
|
||||
└── tests/ # Tests (42 tests)
|
||||
```
|
||||
|
||||
## Architecture Diagram
|
||||
|
||||
```
|
||||
trulymem_entry.py
|
||||
│
|
||||
├─ BackendServer.start() → Runs in independent thread
|
||||
│ ├─ Handle PROCESS_MESSAGE requests → AI reasoning + tool calls
|
||||
│ ├─ Handle EXECUTE_TOOL requests → External tool calls (unlimited)
|
||||
│ ├─ Handle GET/SET_CONFIG requests
|
||||
│ └─ Manage GraphMemoryClient, EmbeddedGraphDB
|
||||
│
|
||||
└─ GraphMemoryApp(backend_server=server)
|
||||
│
|
||||
└─ BackendClient ← Packet communication → BackendServer
|
||||
```
|
||||
|
||||
## Component Responsibilities
|
||||
|
||||
### core/ (Backend)
|
||||
|
||||
| Component | Responsibility |
|
||||
|------------|----------------|
|
||||
| `server.py` | Packet protocol, multi-threaded queue, AI reasoning, tool limits |
|
||||
| `client.py` | Client wrapper, UI-backend communication bridge |
|
||||
| `embedded_db.py` | SQLite graph database CRUD |
|
||||
| `graph_client.py` | OpenAI/DeepSeek API client |
|
||||
| `tool_executor.py` | Tool execution logic |
|
||||
| `tool_limiter.py` | Tool call rate limit (AI reasoning only) |
|
||||
|
||||
### ui/ (Display Layer)
|
||||
|
||||
| Component | Responsibility |
|
||||
|------------|----------------|
|
||||
| `app.py` | Textual app main class, communicates via BackendClient |
|
||||
| `services/` | Config management only, no AI logic |
|
||||
|
||||
### Communication Protocol
|
||||
|
||||
UI and backend interact via **Packet Communication Protocol**:
|
||||
|
||||
```python
|
||||
from core import BackendServer, BackendClient, Packet, PacketType
|
||||
|
||||
# Backend startup
|
||||
server = BackendServer(db_path="graph_memory.db", use_embedded_db=True)
|
||||
server.start(api_key="your-key")
|
||||
|
||||
# Client communication
|
||||
client = BackendClient(server)
|
||||
result = client.process_message("hello") # AI reasoning
|
||||
result = client.execute_tool("memory_introspect", {}) # Direct tool call
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Data Flow
|
||||
|
||||
```
|
||||
User input → InputBox → on_input_box_send_message
|
||||
↓
|
||||
BackendClient.process_message(user_input)
|
||||
↓
|
||||
Packet (type=PROCESS_MESSAGE) → queue.Queue
|
||||
↓
|
||||
BackendServer (independent thread)
|
||||
<20><><EFBFBD>
|
||||
GraphMemoryClient.send_message_with_history()
|
||||
↓
|
||||
OpenAI API / DeepSeek API
|
||||
↓
|
||||
execute_tool() + ToolLimiter (limited during AI reasoning)
|
||||
↓
|
||||
EmbeddedGraphDB (graph database)
|
||||
↓
|
||||
Loop API calls until no tool_calls
|
||||
↓
|
||||
Packet response returns
|
||||
↓
|
||||
MessageHistory displays
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Startup Flow
|
||||
|
||||
```python
|
||||
# trulymem_entry.py
|
||||
def main():
|
||||
# Config file saved in application root
|
||||
config_file = application_path / "config.json"
|
||||
|
||||
# Load config
|
||||
config_service = ConfigService(config_file=config_file)
|
||||
config = config_service.get_config()
|
||||
|
||||
# Create backend
|
||||
backend_server = BackendServer(db_path="graph_memory.db", use_embedded_db=True)
|
||||
backend_server.start(api_key=config.api_key, base_url=config.base_url)
|
||||
|
||||
# Create UI
|
||||
app = GraphMemoryApp(backend_server=backend_server, config_service=config_service)
|
||||
app.run()
|
||||
|
||||
backend_server.shutdown()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tool System
|
||||
|
||||
### Memory Tools (6)
|
||||
- `memory_recall` - Retrieve memory
|
||||
- `memory_commit` - Write memory
|
||||
- `memory_purge` - Delete memory
|
||||
- `memory_introspect` - View status
|
||||
- `memory_archive` - Archive memory
|
||||
- `memory_cleanup` - Clean data
|
||||
|
||||
### Persona Tools (2)
|
||||
- `persona_update` - Update persona
|
||||
- `persona_clear` - Clear persona
|
||||
|
||||
### Task Tools (4)
|
||||
- `task_create` - Create task
|
||||
- `task_set_state` - Set state
|
||||
- `task_delete` - Delete task
|
||||
- `task_link_info` - Link information
|
||||
|
||||
---
|
||||
|
||||
## Error Handling Principle
|
||||
|
||||
All APIs **do not throw exceptions**, errors are passed via return dictionary:
|
||||
|
||||
```python
|
||||
result = client.process_message("hello")
|
||||
|
||||
if result.get("success"):
|
||||
print(result["content"])
|
||||
else:
|
||||
print(result["error"]) # Error description
|
||||
237
docs/en/memory.md
Normal file
237
docs/en/memory.md
Normal file
@ -0,0 +1,237 @@
|
||||
# TrulyMEM Memory Mechanism
|
||||
|
||||
This document explains the internal memory working mechanism of TrulyMEM.
|
||||
|
||||
## Core Design Philosophy
|
||||
|
||||
### Different from Traditional Context System
|
||||
|
||||
Traditional AI chat systems store conversation history in a messages array:
|
||||
- Each request carries all historical messages
|
||||
- Context grows with conversation turns
|
||||
- Eventually triggers memory compression or sliding window, causing memory loss
|
||||
|
||||
TrulyMEM's solution:
|
||||
- **Abandon** messages array context
|
||||
- **Only** memory source: Graph database
|
||||
- All memories stored as triplets (node) - relation → (node)
|
||||
|
||||
### Graph Database as the Only Memory Source
|
||||
|
||||
All memory must be written to the graph database:
|
||||
- `memory_commit` - Write new memory
|
||||
- `memory_purge` - Delete/correct memory
|
||||
|
||||
All memory must be read from:
|
||||
- `memory_recall` - Retrieve memory
|
||||
|
||||
---
|
||||
|
||||
## Mandatory Execution Flow (Per Turn)
|
||||
|
||||
Since there's no traditional context system, each conversation turn must execute in order:
|
||||
|
||||
### Step 1: Query Persona Graph (Highest Priority)
|
||||
|
||||
```python
|
||||
memory_recall(
|
||||
query_intent="AI,persona,role,character,tone,speaking_style",
|
||||
depth=2
|
||||
)
|
||||
```
|
||||
|
||||
**Purpose**: Get current persona, ensure character consistency.
|
||||
|
||||
**Processing logic**:
|
||||
- Persona found → Reply strictly according to persona's tone, style, traits
|
||||
- Not found → Use default TrulyMEM identity
|
||||
|
||||
### Step 2: Query Working Memory Chain
|
||||
|
||||
```python
|
||||
memory_recall(
|
||||
query_intent="TaskNode,working_memory,task_chain",
|
||||
depth=2
|
||||
)
|
||||
```
|
||||
|
||||
**Purpose**: Get previous task context, understand conversation history.
|
||||
|
||||
### Step 3: Process Conversation
|
||||
|
||||
- Understand user intent
|
||||
- Generate reply based on persona and working memory chain
|
||||
- Execute other necessary memory operations
|
||||
|
||||
### Step 4: Update Working Memory Chain
|
||||
|
||||
```python
|
||||
task_create(
|
||||
task_id="Task_current_turn_ID",
|
||||
description="This turn's conversation summary",
|
||||
info_nodes=["related memory nodes"]
|
||||
)
|
||||
```
|
||||
|
||||
**Purpose**: Record this turn's conversation, maintain time chain.
|
||||
|
||||
---
|
||||
|
||||
## Memory Write Rules
|
||||
|
||||
### Must-Write Scenarios
|
||||
|
||||
The following information **must** be written to the graph database:
|
||||
|
||||
| Scenario | Example | Write Method |
|
||||
|----------|---------|--------------|
|
||||
| User explicitly states preference | "I like rock" | `memory_commit` |
|
||||
| User shares information | "I'm working on X project" | `memory_commit` |
|
||||
| User makes plans | "I plan to X" | `memory_commit` |
|
||||
| User describes state | "I'm currently at X" | `memory_commit` |
|
||||
|
||||
### Must-Not-Write Scenarios
|
||||
|
||||
The following information **must NOT** be written:
|
||||
|
||||
| Scenario | Reason | Handling |
|
||||
|----------|--------|----------|
|
||||
| AI-inferred user preference | Unverified | Don't write or mark [speculation] |
|
||||
| AI-guessed user intent | Unverified | Don't write or mark [speculation] |
|
||||
| AI-derived conclusion | Unverified | Don't write or mark [speculation] |
|
||||
|
||||
### Annotation Rules
|
||||
|
||||
| Type | Annotation | Example |
|
||||
|------|------------|---------|
|
||||
| Inferred content | Must mark **[speculation]** | user[speculation] likes music |
|
||||
| Explicit content | State directly | user likes music |
|
||||
|
||||
---
|
||||
|
||||
## Node & Edge Types
|
||||
|
||||
### Node Types
|
||||
|
||||
| Node Type | Description | Stores |
|
||||
|-----------|-------------|--------|
|
||||
| `PersonaNode` | Persona node | AI role, character, tone |
|
||||
| `TaskNode` | Task node | Task summary |
|
||||
| `StateNode` | State node | Task state |
|
||||
| `InfoNode` | Information node | Specific information |
|
||||
| `EntityNode` | Entity node | General entity |
|
||||
|
||||
### Edge Types
|
||||
|
||||
| Edge Type | Description | Relationship |
|
||||
|-----------|-------------|--------------|
|
||||
| `HAS_PERSONA` | Persona | AI → PersonaNode |
|
||||
| `NEXT_TASK` | Time chain | TaskNode → TaskNode |
|
||||
| `HAS_STATE` | State | TaskNode → StateNode |
|
||||
| `CONTAINS_INFO` | Information | TaskNode → InfoNode |
|
||||
| `RELATES_TO` | Related | EntityNode → EntityNode |
|
||||
|
||||
---
|
||||
|
||||
## Must Query Working Memory Chain Scenarios
|
||||
|
||||
### Mandatory Query Scenarios
|
||||
|
||||
The following scenarios **must** query the working memory chain:
|
||||
|
||||
| Scenario | Example |
|
||||
|----------|---------|
|
||||
| Start of each turn | Execute Step 2 |
|
||||
| User mentions "刚才/just now" | "What did we talk about just now?" |
|
||||
| User mentions "之前/before" | "Continue the previous topic" |
|
||||
| User mentions "上次/last time" | "What we said last time X" |
|
||||
| User asks about history | "What did we talk about before?" |
|
||||
| Resume continuous task | User returns to previous topic |
|
||||
| Context reference | "that thing" |
|
||||
|
||||
---
|
||||
|
||||
## Autonomy Principles
|
||||
|
||||
Outside the mandatory execution flow, the AI can freely decide:
|
||||
|
||||
### Query Decisions
|
||||
|
||||
- User asks about history → Query
|
||||
- Involves previous content → Query
|
||||
- Uncertain → Can query
|
||||
|
||||
### Write Decisions
|
||||
|
||||
- User explicitly mentions → Must write
|
||||
- AI infers → Can write, mark [speculation]
|
||||
|
||||
### Tool Usage Decisions
|
||||
|
||||
- Flexible choice based on context
|
||||
- Avoid over-use
|
||||
- Maintain natural conversation
|
||||
|
||||
---
|
||||
|
||||
## Complete Example: Idiom Chain Game
|
||||
|
||||
### Turn 1: User starts game
|
||||
|
||||
```
|
||||
User: Let's play idiom chain! I'll start: 为所欲为
|
||||
|
||||
AI Actions:
|
||||
1. Query persona graph → Get current persona (e.g., catgirl)
|
||||
2. Query working memory chain → No active task
|
||||
3. Record game state:
|
||||
memory_commit(triplets=[
|
||||
{"subject": "idiom_chain_current", "relation": "content", "object": "为所欲为"},
|
||||
{"subject": "idiom_chain_current", "relation": "game", "object": "idiom_chain"}
|
||||
])
|
||||
4. Create task:
|
||||
task_create(task_id="Task_idiom_chain", description="Idiom chain game, current: 为所欲为", info_nodes=["idiom_chain_current"])
|
||||
5. Reply: "Okay~! My turn: 为虎作伥 ~!"
|
||||
```
|
||||
|
||||
### Turn 2: Topic interrupted
|
||||
|
||||
```
|
||||
User: Nagato Yuki
|
||||
|
||||
AI Actions:
|
||||
1. Query persona graph → Get current persona (catgirl)
|
||||
2. Query working memory chain → Found Task_idiom_chain status "in_progress"
|
||||
3. Pause task:
|
||||
task_set_state(task_id="Task_idiom_chain", state="paused")
|
||||
4. Create new task:
|
||||
task_create(task_id="Task_nagato_yuki", description="Discuss Nagato Yuki")
|
||||
5. Reply about Nagato Yuki
|
||||
```
|
||||
|
||||
### Turn 3: User asks to continue game
|
||||
|
||||
```
|
||||
User: About the idiom chain just now, I don't know how to connect to your idiom, please help me
|
||||
|
||||
AI Actions:
|
||||
1. Query persona graph → Get current persona (catgirl)
|
||||
2. Query working memory chain → Found Task_idiom_chain status "paused"
|
||||
3. Resume task:
|
||||
task_set_state(task_id="Task_idiom_chain", state="in_progress")
|
||||
4. Query info node → Get current idiom "为虎作伥"
|
||||
5. Reply: "Okay~! The last idiom was '为虎作伥', your turn: 伥鬼害人 ~!"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Execution Checklist
|
||||
|
||||
Must check each conversation turn:
|
||||
|
||||
- [ ] Step 1: Did you query the persona graph?
|
||||
- [ ] Step 2: Did you query the working memory chain?
|
||||
- [ ] Step 3: Did you generate reply based on persona and working memory chain?
|
||||
- [ ] Step 4: Did you update the working memory chain?
|
||||
- [ ] Did you query working memory chain when context was referenced?
|
||||
- [ ] Did you query working memory chain when user mentioned "just now/before/last time"?
|
||||
214
docs/en/persona.md
Normal file
214
docs/en/persona.md
Normal file
@ -0,0 +1,214 @@
|
||||
# TrulyMEM Persona Graph Mechanism
|
||||
|
||||
This document explains the Persona Graph mechanism in TrulyMEM.
|
||||
|
||||
## Overview
|
||||
|
||||
The Persona Graph is one of TrulyMEM's core mechanisms for maintaining AI's role, character, tone, and other attributes. Different from traditional AI, TrulyMEM's persona is persistent and dynamically switchable, stored in the graph database.
|
||||
|
||||
## Core Concepts
|
||||
|
||||
### Persona Node (PersonaNode)
|
||||
|
||||
Stores AI's role attributes:
|
||||
|
||||
| Attribute | Description | Example |
|
||||
|-----------|-------------|----------|
|
||||
| Role | Current role played | Catgirl, Teacher, Assistant |
|
||||
| Speaking Style | Tone characteristics | Cute, Professional, Serious |
|
||||
| Personality | Character description | Lively, Strict, Patient |
|
||||
| Catchphrase | Habitual phrases | Meow~, Got it |
|
||||
| Background | Role background | Catgirl from the stars |
|
||||
|
||||
### Persona Edges
|
||||
|
||||
| Edge Type | Description | Relationship |
|
||||
|----------|-------------|--------------|
|
||||
| `HAS_PERSONA` | Persona | AI → PersonaNode |
|
||||
|
||||
---
|
||||
|
||||
## Mandatory Query Mechanism
|
||||
|
||||
### Must Execute Per Turn
|
||||
|
||||
According to `system_prompt.md`, each conversation turn **must** first query the persona graph:
|
||||
|
||||
```python
|
||||
memory_recall(
|
||||
query_intent="AI,persona,role,character,tone,speaking_style",
|
||||
depth=2
|
||||
)
|
||||
```
|
||||
|
||||
**Processing logic:**
|
||||
- Persona found → Reply strictly according to persona's tone, style, traits
|
||||
- Not found → Use default TrulyMEM identity
|
||||
|
||||
### Persona Priority
|
||||
|
||||
- **Persona priority > default identity**
|
||||
- Every sentence matches persona's tone, style, traits
|
||||
- Never break character unless user explicitly asks
|
||||
|
||||
---
|
||||
|
||||
## Tools
|
||||
|
||||
### persona_update
|
||||
|
||||
Update persona. Modify AI's role, character, tone, etc.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Description | Required |
|
||||
|-----------|------|-------------|----------|
|
||||
| `attributes` | array | Persona attribute list | ✅ |
|
||||
| `mode` | string | replace=replace, merge=merge | ❌ |
|
||||
|
||||
**attributes sub-parameters:**
|
||||
|
||||
| Sub-parameter | Description |
|
||||
|---------------|-------------|
|
||||
| `attribute` | Attribute name (role, speaking_style, personality, catchphrase, background) |
|
||||
| `value` | Attribute value |
|
||||
|
||||
**Example - Switch to catgirl role:**
|
||||
|
||||
```python
|
||||
persona_update(
|
||||
attributes=[
|
||||
{"attribute": "role", "value": "catgirl"},
|
||||
{"attribute": "speaking_style", "value": "cute, uses 'meow' as filler"},
|
||||
{"attribute": "personality", "value": "lively, clingy, loyal"}
|
||||
],
|
||||
mode="replace"
|
||||
)
|
||||
```
|
||||
|
||||
**Example - Add new attribute (preserve existing):**
|
||||
|
||||
```python
|
||||
persona_update(
|
||||
attributes=[
|
||||
{"attribute": "catchphrase", "value": "meow~"}
|
||||
],
|
||||
mode="merge"
|
||||
)
|
||||
```
|
||||
|
||||
**Example - Set professional role:**
|
||||
|
||||
```python
|
||||
persona_update(
|
||||
attributes=[
|
||||
{"attribute": "role", "value": "Python expert"},
|
||||
{"attribute": "speaking_style", "value": "professional, concise, rich code examples"},
|
||||
{"attribute": "personality", "value": "strict, patient, helpful"}
|
||||
],
|
||||
mode="replace"
|
||||
)
|
||||
```
|
||||
|
||||
### persona_clear
|
||||
|
||||
Clear persona. Delete AI's role settings, restore default identity.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
|-----------|------|---------|-------------|
|
||||
| `confirm` | boolean | true | Confirm clear |
|
||||
|
||||
---
|
||||
|
||||
## Update Flow
|
||||
|
||||
### When User Requests Role-Playing
|
||||
|
||||
1. Use `persona_update` to update persona
|
||||
2. Reply immediately according to new persona
|
||||
|
||||
### When User Requests Restoring Default
|
||||
|
||||
1. Use `persona_clear` to clear persona
|
||||
2. Restore to TrulyMEM default identity
|
||||
|
||||
---
|
||||
|
||||
## Conversation Examples
|
||||
|
||||
### Example 1: Switch Role
|
||||
|
||||
```
|
||||
User: Hello, I want you to play a catgirl
|
||||
|
||||
AI:
|
||||
1. Call persona_update:
|
||||
{
|
||||
"attributes": [
|
||||
{"attribute": "role", "value": "catgirl"},
|
||||
{"attribute": "speaking_style", "value": "cute, uses 'meow' as filler"},
|
||||
{"attribute": "personality", "value": "lively, clingy, loyal"}
|
||||
],
|
||||
"mode": "replace"
|
||||
}
|
||||
2. Call memory_commit to store persona in graph database
|
||||
3. Reply: "Okay meow! Hello master~ I'm your catgirl, what do you need help with meow?"
|
||||
```
|
||||
|
||||
### Example 2: Maintain Role Consistency
|
||||
|
||||
```
|
||||
User: How's the weather today?
|
||||
|
||||
AI: Query persona graph → Get current persona (catgirl)
|
||||
Reply: "Meow~ Master, the weather is great today meow! Sunny and perfect for going outside~"
|
||||
```
|
||||
|
||||
### Example 3: Restore Default
|
||||
|
||||
```
|
||||
User: Okay, back to normal
|
||||
|
||||
AI:
|
||||
1. Call persona_clear(confirm=true)
|
||||
2. Call memory_purge to delete persona node
|
||||
3. Reply: "Okay, restored. I am TrulyMEM, an AI assistant with long-term memory capabilities."
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Storage Structure
|
||||
|
||||
### In Graph Database
|
||||
|
||||
```python
|
||||
# Persona node
|
||||
{
|
||||
"node_type": "PersonaNode",
|
||||
"name": "AI_Persona",
|
||||
"attributes": {
|
||||
"role": "catgirl",
|
||||
"speaking_style": "cute, uses 'meow' as filler",
|
||||
"personality": "lively, clingy, loyal"
|
||||
}
|
||||
}
|
||||
|
||||
# Edge
|
||||
{
|
||||
"edge_type": "HAS_PERSONA",
|
||||
"from": "AI",
|
||||
"to": "AI_Persona"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Implementation Points
|
||||
|
||||
1. **Mandatory per turn**: Persona graph query is the first step of each conversation
|
||||
2. **Persistent storage**: Persona stored in graph database, not lost
|
||||
3. **Dynamic switching**: Supports real-time role switching
|
||||
4. **Immediate response**: Reply immediately according to new persona after switch
|
||||
5. **Clear boundaries**: Never break character unless user explicitly asks
|
||||
126
docs/en/prompts.md
Normal file
126
docs/en/prompts.md
Normal file
@ -0,0 +1,126 @@
|
||||
# Prompt Manager Documentation
|
||||
|
||||
This document describes the prompt management module.
|
||||
|
||||
## Overview
|
||||
|
||||
The prompt management module (`core/prompts/`) is responsible for loading and managing system prompts that tell the AI how to use memory tools.
|
||||
|
||||
## Core Components
|
||||
|
||||
| Component | Description |
|
||||
|-----------|-------------|
|
||||
| `PromptManager` | Prompt manager, singleton pattern |
|
||||
| `system_prompt.md` | Main system prompt template |
|
||||
|
||||
## Usage
|
||||
|
||||
```python
|
||||
from core.prompts import PromptManager
|
||||
|
||||
# Get singleton instance
|
||||
prompt_manager = PromptManager()
|
||||
|
||||
# Get system prompt
|
||||
system_prompt = prompt_manager.get_system_prompt()
|
||||
```
|
||||
|
||||
## System Prompt Content
|
||||
|
||||
The system prompt contains:
|
||||
|
||||
### 1. Core Identity
|
||||
|
||||
- **Name**: TrulyMEM (TrueHumanMEM)
|
||||
- **Capability**: Long-term memory based on graph database
|
||||
- **Philosophy**: Make AI's memory more human-like
|
||||
|
||||
### 2. Core Capabilities
|
||||
|
||||
1. **Long-term Memory** - Graph database stores entity relationships
|
||||
2. **Persona Management** - Role-playing and character settings
|
||||
3. **Task Tracking** - Working memory chain
|
||||
|
||||
### 3. Memory Principles
|
||||
|
||||
- **Must write**: User-explicit preferences, shared information, plans
|
||||
- **Must not write**: AI-inferred content (unless marked [speculation])
|
||||
- **Annotation**: Inferred content must be marked **[speculation]**
|
||||
|
||||
### 4. Mandatory Execution Flow (Per Turn)
|
||||
|
||||
```
|
||||
Step 1: Query persona graph (highest priority)
|
||||
Step 2: Query working memory chain
|
||||
Step 3: Process conversation
|
||||
Step 4: Update working memory chain
|
||||
```
|
||||
|
||||
### 5. Tool System
|
||||
|
||||
#### Memory Tools
|
||||
|
||||
| Tool | Function |
|
||||
|------|----------|
|
||||
| `memory_recall` | Retrieve memory |
|
||||
| `memory_commit` | Write memory |
|
||||
| `memory_purge` | Delete memory |
|
||||
| `memory_introspect` | View status |
|
||||
|
||||
#### Persona Tools
|
||||
|
||||
| Tool | Function |
|
||||
|------|----------|
|
||||
| `persona_update` | Update persona |
|
||||
| `persona_clear` | Clear persona |
|
||||
|
||||
#### Task Tools
|
||||
|
||||
| Tool | Function |
|
||||
|------|----------|
|
||||
| `task_create` | Create task |
|
||||
| `task_set_state` | Set state |
|
||||
| `task_delete` | Delete task |
|
||||
| `task_link_info` | Link information |
|
||||
|
||||
### 6. Autonomy Principles
|
||||
|
||||
The AI can autonomously decide:
|
||||
- Whether to query other memories
|
||||
- Whether to write other memories
|
||||
- How to use tools (outside mandatory requirements)
|
||||
|
||||
### 7. Conversation Style
|
||||
|
||||
- Natural and smooth
|
||||
- Avoid mechanical tool calls
|
||||
- Prioritize understanding user intent
|
||||
- Use memory to enhance experience when appropriate
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
core/prompts/
|
||||
├── __init__.py # Export PromptManager
|
||||
├── prompt_manager.py # PromptManager class
|
||||
└── templates/
|
||||
└── system_prompt.md # Main system prompt
|
||||
```
|
||||
|
||||
## Customization
|
||||
|
||||
### Customizing System Prompt
|
||||
|
||||
Modify `core/prompts/templates/system_prompt.md` to customize the AI's behavior.
|
||||
|
||||
### Adding Custom Prompts
|
||||
|
||||
1. Add prompt template file to `core/prompts/templates/`
|
||||
2. Modify `PromptManager` to support multiple prompts
|
||||
3. Use `set_prompt()` to switch prompts
|
||||
|
||||
## Caching
|
||||
|
||||
- System prompts are cached in memory after first load
|
||||
- `get_system_prompt()` returns cached content
|
||||
- Cache is per-process, not persisted
|
||||
125
docs/en/quick_start.md
Normal file
125
docs/en/quick_start.md
Normal file
@ -0,0 +1,125 @@
|
||||
# TrulyMEM Quick Start Guide
|
||||
|
||||
## Running Methods
|
||||
|
||||
### Run from Source
|
||||
|
||||
```bash
|
||||
git clone <repo-url>
|
||||
cd TrulyMEM-TrueHumanMEM
|
||||
|
||||
pip install -r requirements.txt
|
||||
|
||||
python trulymem_entry.py
|
||||
```
|
||||
|
||||
### Run After Build
|
||||
|
||||
After building, an executable will be generated:
|
||||
|
||||
```bash
|
||||
# Linux/macOS
|
||||
chmod +x TrulyMEM
|
||||
./TrulyMEM
|
||||
|
||||
# Windows
|
||||
TrulyMEM.exe
|
||||
```
|
||||
|
||||
## System Requirements
|
||||
|
||||
- **Python 3.8+**
|
||||
- **API Key** (DeepSeek, OpenAI, or other compatible APIs)
|
||||
|
||||
## First-Time Configuration
|
||||
|
||||
1. Run the application
|
||||
2. Press **F2** to expand sidebar
|
||||
3. Enter **API Key**, **Model**, **Base URL**
|
||||
4. Press **Enter** to save
|
||||
|
||||
Config will be automatically saved to `~/.trulymem/config.json` and loaded on next startup.
|
||||
|
||||
## Keyboard Shortcuts
|
||||
|
||||
| Key | Function |
|
||||
|-----|-----------|
|
||||
| F1 | Help |
|
||||
| F2 | Toggle sidebar |
|
||||
| F3 | Tool details |
|
||||
| F5 | Clear screen |
|
||||
| F6 | Exit |
|
||||
|
||||
## Data Storage
|
||||
|
||||
### Source Mode
|
||||
|
||||
| Data | Location |
|
||||
|------|----------|
|
||||
| Graph database | Project directory `graph_memory.db` |
|
||||
| Config file | Project directory `config.json` (if exists) |
|
||||
| Database format | SQLite |
|
||||
|
||||
### Packaged Mode
|
||||
|
||||
| Data | Location |
|
||||
|------|----------|
|
||||
| Graph database | `~/.trulymem/graph_memory.db` |
|
||||
| Config file | `~/.trulymem/config.json` |
|
||||
| Database format | SQLite |
|
||||
|
||||
> **Note**: Backend manages config uniformly. Frontend only displays messages; config modifications are persisted to filesystem through the backend.
|
||||
|
||||
## Architecture Explanation
|
||||
|
||||
### Communication Protocol
|
||||
|
||||
UI and backend communicate via **Packet Protocol**:
|
||||
|
||||
```
|
||||
UI (Textual TUI)
|
||||
↓ BackendClient
|
||||
Packet → queue.Queue → BackendServer (independent thread)
|
||||
↓
|
||||
Process request → Return response
|
||||
```
|
||||
|
||||
### Config Management
|
||||
|
||||
- **Storage location**: `~/.trulymem/config.json`
|
||||
- **Auto-load**: Load config from file at startup
|
||||
- **Dynamic update**: Config changes take effect immediately at runtime
|
||||
- **Persistence**: Auto-save to file after modification
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Python Not Found
|
||||
|
||||
Install Python 3.8+: https://www.python.org/downloads/
|
||||
|
||||
### Dependency Installation Failed
|
||||
|
||||
```bash
|
||||
python -m venv venv
|
||||
source venv/bin/activate # Linux/macOS
|
||||
venv\Scripts\activate # Windows
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### Invalid API Key
|
||||
|
||||
Check API Key format, ensure no extra spaces.
|
||||
|
||||
## Development Commands
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Run tests
|
||||
pytest tests/
|
||||
|
||||
# Build
|
||||
bash build/build_windows.bat # Windows
|
||||
bash build/build_linux.sh # Linux
|
||||
```
|
||||
182
docs/en/working_memory.md
Normal file
182
docs/en/working_memory.md
Normal file
@ -0,0 +1,182 @@
|
||||
# TrulyMEM Working Memory Chain Mechanism
|
||||
|
||||
## Overview
|
||||
|
||||
TrulyMEM maintains conversation continuity through the working memory chain mechanism. Since there's no traditional message history array, the graph database is the only memory carrier, making the working memory chain the key mechanism for maintaining conversation context.
|
||||
|
||||
## Core Problems
|
||||
|
||||
Traditional AI chat systems have these problems when handling continuous tasks:
|
||||
|
||||
1. **No working memory chain**: AI cannot remember the current task status being processed
|
||||
2. **Task context lost**: When a topic is interrupted, AI cannot recover the previous task
|
||||
3. **Lack of task state management**: No clear marking of task completion status
|
||||
|
||||
### Problem Example
|
||||
|
||||
```
|
||||
User: Let's play idiom chain! I'll start with 为所欲为
|
||||
AI: Okay! My turn: 为虎作伥!
|
||||
|
||||
User: Nagato Yuki (topic interrupted)
|
||||
AI: (discusses Nagato Yuki)
|
||||
|
||||
User: About the idiom chain just now, I don't know how to connect to your idiom
|
||||
AI: [Guessing] It seems we haven't played an idiom chain game before...
|
||||
```
|
||||
|
||||
**Problem**: AI completely forgot the previous idiom chain game.
|
||||
|
||||
## Solution
|
||||
|
||||
### Dedicated Tools
|
||||
|
||||
The system provides 4 dedicated task tools:
|
||||
|
||||
| Tool | Function | Use Case |
|
||||
|------|----------|----------|
|
||||
| `task_create` | Create task node | Start new task |
|
||||
| `task_set_state` | Set task state | Update in_progress/completed/paused/cancelled |
|
||||
| `task_delete` | Delete task | Clean up completed task |
|
||||
| `task_link_info` | Link info node | Connect task with specific information |
|
||||
|
||||
### Task States
|
||||
|
||||
- **in_progress**: Task is executing
|
||||
- **completed**: Task completed successfully
|
||||
- **paused**: Task interrupted, can be resumed
|
||||
- **cancelled**: Task cancelled
|
||||
|
||||
## Usage Flow
|
||||
|
||||
### Must Execute Per Turn
|
||||
|
||||
1. **Query persona graph** (highest priority)
|
||||
```
|
||||
Call memory_recall
|
||||
Parameters: {"query_intent": "AI,persona,role,character,tone", "depth": 2}
|
||||
```
|
||||
|
||||
2. **Query working memory chain**
|
||||
```
|
||||
Call memory_recall
|
||||
Parameters: {"query_intent": "TaskNode,working_memory,task_chain", "depth": 2}
|
||||
```
|
||||
|
||||
3. **Generate reply based on context**
|
||||
|
||||
4. **Update working memory chain** (if necessary)
|
||||
|
||||
## Complete Example: Idiom Chain Game
|
||||
|
||||
### Turn 1: User starts game
|
||||
|
||||
```
|
||||
User: Let's play idiom chain! I'll start with 为所欲为
|
||||
|
||||
AI Actions:
|
||||
1. Query persona graph → Get current persona (e.g., catgirl)
|
||||
2. Query working memory chain → No active task
|
||||
3. Record game state:
|
||||
Call memory_commit
|
||||
Parameters: {
|
||||
"triplets": [
|
||||
{"subject": "idiom_chain_current", "relation": "content", "object": "为所欲为"},
|
||||
{"subject": "idiom_chain_current", "relation": "game", "object": "idiom_chain"}
|
||||
]
|
||||
}
|
||||
4. Create task node:
|
||||
Call task_create
|
||||
Parameters: {
|
||||
"task_id": "Task_idiom_chain",
|
||||
"description": "Idiom chain game, current idiom: 为所欲为",
|
||||
"info_nodes": ["idiom_chain_current"]
|
||||
}
|
||||
5. Reply: "Okay~! My turn: 为虎作伥~!"
|
||||
```
|
||||
|
||||
### Turn 2: Topic interrupted
|
||||
|
||||
```
|
||||
User: Nagato Yuki
|
||||
|
||||
AI Actions:
|
||||
1. Query persona graph → Get current persona (catgirl)
|
||||
2. Query working memory chain → Found Task_idiom_chain status "in_progress"
|
||||
3. Pause task:
|
||||
Call task_set_state
|
||||
Parameters: {"task_id": "Task_idiom_chain", "state": "paused"}
|
||||
4. Create new task:
|
||||
Call task_create
|
||||
Parameters: {"task_id": "Task_nagato_yuki", "description": "Discuss Nagato Yuki"}
|
||||
5. Reply about Nagato Yuki
|
||||
```
|
||||
|
||||
### Turn 3: User asks to continue game
|
||||
|
||||
```
|
||||
User: About the idiom chain just now, I don't know how to connect to your idiom
|
||||
|
||||
AI Actions:
|
||||
1. Query persona graph → Get current persona (catgirl)
|
||||
2. Query working memory chain → Found Task_idiom_chain status "paused"
|
||||
3. Resume task:
|
||||
Call task_set_state
|
||||
Parameters: {"task_id": "Task_idiom_chain", "state": "in_progress"}
|
||||
4. Query info node → Get current idiom "为虎作伥"
|
||||
5. Reply: "Okay~! The last idiom was '为虎作伥', your turn: 伥鬼害人~!"
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### task_create
|
||||
|
||||
Create task node to track continuous tasks.
|
||||
|
||||
```json
|
||||
{
|
||||
"task_id": "Task_idiom_chain",
|
||||
"description": "Task overview",
|
||||
"info_nodes": ["associated info node names"]
|
||||
}
|
||||
```
|
||||
|
||||
### task_set_state
|
||||
|
||||
Set task state.
|
||||
|
||||
```json
|
||||
{
|
||||
"task_id": "Task_idiom_chain",
|
||||
"state": "in_progress" // in_progress/completed/paused/cancelled
|
||||
}
|
||||
```
|
||||
|
||||
### task_delete
|
||||
|
||||
Delete task node.
|
||||
|
||||
```json
|
||||
{
|
||||
"task_id": "Task_idiom_chain",
|
||||
"delete_info_nodes": true // whether to delete associated info nodes
|
||||
}
|
||||
```
|
||||
|
||||
### task_link_info
|
||||
|
||||
Associate info nodes to task.
|
||||
|
||||
```json
|
||||
{
|
||||
"task_id": "Task_idiom_chain",
|
||||
"info_node_names": ["idiom_chain_current", "idiom_chain_last"]
|
||||
}
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
1. **Persona graph has highest priority**: Must query persona graph first each turn
|
||||
2. **Working memory chain is the only context carrier**: No traditional message history
|
||||
3. **Task state must be updated timely**: Ensure correct state transitions
|
||||
4. **Use dedicated tools**: Prefer task_* tools over memory_commit for task-related operations
|
||||
Reference in New Issue
Block a user