docs: 重构为 docs/zh/ + docs/en/ 子文件夹结构

- 拆分为 docs/zh/(中文) 和 docs/en/(英文)
- README 索引对应语言子文件夹
- 保留所有文档内容
This commit is contained in:
root
2026-04-14 13:25:53 +08:00
parent dd685485b5
commit 29d15707f5
18 changed files with 16 additions and 16 deletions

29
docs/en/README.md Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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