.
diff --git a/README.md b/README.md
index bb6767a..bd7f621 100644
--- a/README.md
+++ b/README.md
@@ -1,88 +1,97 @@
-# TrueHumanMEM - Graph Memory TUI
+# TrulyMEM - TrueHumanMEM
-> The More Human Choice.
+**让 AI 拥有自知、可塑、有分寸感的长期记忆**
-一个让 AI 拥有自知、可塑、有分寸感长期记忆的图记忆系统,配备现代化终端用户界面。
+*The More Human Choice.*
-## ✨ 特性
+[](https://www.gnu.org/licenses/gpl-3.0)
+[](https://www.python.org/downloads/)
+[](https://github.com/yourusername/trulymem)
-- 🖥️ **现代化TUI界面** - 基于Textual框架的终端界面
+---
+
+## 简介
+
+TrulyMEM(TrueHumanMEM)是一个让 AI 拥有长期记忆能力的图记忆系统。通过图数据库存储实体关系,让AI能够像人类一样记忆、回忆和管理信息。
+
+### 核心特性
+
+- 🧠 **长期记忆** - 基于图数据库的持久化记忆存储
+- 🎭 **人设图机制** - AI角色保持和角色扮演支持
+- 🖥️ **现代化TUI** - 基于Textual框架的终端用户界面
- 💾 **内嵌数据库** - SQLite实现,无需Docker/Neo4j
- 🌐 **Web接口** - 支持浏览器访问
-- 🚀 **一键启动** - 3步骤完成,30秒启动
+- 🚀 **流式显示** - 实时显示AI响应,减少等待
+- 📦 **独立部署** - 支持打包为独立可执行文件
- 🌍 **跨平台** - 支持Windows/Linux/macOS
-- 📊 **实时可视化** - 消息、工具调用实时显示
-- 🔧 **完整功能** - 记忆检索、写入、删除、归档
-
-## 📖 目录
-
-- [快速开始](#快速开始)
-- [使用方法](#使用方法)
-- [功能说明](#功能说明)
-- [API接口](#api接口)
-- [配置说明](#配置说明)
-- [开发指南](#开发指南)
---
## 快速开始
-### 前置要求
+### 方式一:使用可执行文件(推荐)
-- **Python 3.8+**
-- **DeepSeek API Key**(或兼容OpenAI格式的API)
-
-### 一键启动
-
-#### Windows
+**Windows:**
```bash
-# 双击运行
-start.bat
-
-# 或命令行
-python start.py
+# 下载 TrulyMEM.exe
+# 双击运行或命令行执行
+./TrulyMEM.exe
```
-#### Linux / macOS
+**Linux:**
```bash
-# Shell脚本
-chmod +x start.sh
-./start.sh
-
-# 或Python
-python3 start.py
+# 下载 TrulyMEM
+chmod +x TrulyMEM
+./TrulyMEM
```
-### 启动流程
+### 方式二:从源码运行
-```
-[Step 1/3] 检查 Python
-[Step 2/3] 设置虚拟环境
-[Step 3/3] 启动应用
+```bash
+# 克隆仓库
+git clone https://github.com/yourusername/trulymem.git
+cd trulymem
-✅ 系统初始化成功!
-• 数据库: 内嵌SQLite (graph_memory.db)
-• API Key: 未配置
+# 安装依赖
+pip install -r requirements.txt
+
+# 运行应用
+python -m graph_memory_tui.main
```
+### 配置
+
+1. 按 **F2** 展开侧边栏
+2. 输入 **API Key**(支持DeepSeek、OpenAI等)
+3. 按 **Enter** 保存配置
+4. 开始对话!
+
---
-## 使用方法
+## 功能说明
-### 1. 配置 API Key
+### 记忆管理工具
-1. 按 **F2** 展开侧边栏
-2. 点击 **"配置"**
-3. 输入你的 **DeepSeek API Key**
-4. 按 **Enter** 保存
+| 工具 | 功能 | 说明 |
+|------|------|------|
+| `memory_recall` | 检索记忆 | 根据意图查询相关记忆 |
+| `memory_commit` | 写入记忆 | 将信息存储为图结构 |
+| `memory_purge` | 删除记忆 | 删除过期或错误信息 |
+| `memory_introspect` | 查看状态 | 查看记忆系统状态 |
+| `memory_archive` | 归档记忆 | 归档旧记忆 |
+| `memory_cleanup` | 清理数据 | 清理无效数据 |
-### 2. 开始对话
+### 人设图机制
-- 输入消息
-- 按 **Enter** 发送
-- 查看AI响应和工具调用
+AI会在每轮对话前查询人设图,严格按照人设回复,确保角色一致性。
-### 3. 快捷键
+**使用示例:**
+```
+用户:以猫娘的语气跟我说话
+AI:喵~好的主人!我会用可爱的猫娘语气跟你说话的喵!(≧ω≦)
+```
+
+### 快捷键
| 快捷键 | 功能 |
|--------|------|
@@ -95,176 +104,24 @@ python3 start.py
---
-## 功能说明
-
-### 记忆管理工具
-
-| 工具 | 功能 | 参数 |
-|------|------|------|
-| memory_recall | 检索记忆 | query_intent, depth |
-| memory_commit | 写入记忆 | triplets, confidence |
-| memory_purge | 删除记忆 | criteria, mode |
-| memory_introspect | 查看状态 | - |
-| memory_archive | 归档记忆 | days |
-| memory_cleanup | 清理数据 | dry_run |
-
-### 数据库
-
-**内嵌SQLite数据库:**
-- 文件:`graph_memory.db`
-- 无需配置
-- 自动创建
-- 本地存储
-
-**数据结构:**
-- 实体(entities):name, type, mention_count
-- 关系(relations):source, target, type, confidence, status
-
----
-
-## API接口
-
-### Web界面
-
-启动后访问:`http://localhost:5000`
-
-**界面特点:**
-- 🖥️ 与TUI相似的界面设计
-- 📊 左侧消息历史,右侧配置和日志
-- 🎨 深色主题,终端风格
-- ⌨️ 支持键盘快捷键
-
-**使用方法:**
-1. 在右侧配置区输入API Key
-2. 点击"保存配置"
-3. 在左侧输入框输入消息
-4. 按 Ctrl+Enter 发送
-
-### REST API
-
-```bash
-# 检索记忆
-POST /api/memory/recall
-{
- "query_intent": "Python,AI"
-}
-
-# 写入记忆
-POST /api/memory/commit
-{
- "triplets": [
- {"subject": "用户", "relation": "喜欢", "object": "Python"}
- ]
-}
-
-# 查看状态
-GET /api/memory/introspect
-
-# 获取配置
-GET /api/config
-```
-
----
-
-## 配置说明
-
-### 环境变量
-
-创建 `.env` 文件:
-
-```bash
-# API配置
-DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxx
-DEEPSEEK_BASE_URL=https://api.deepseek.com
-MODEL_NAME=deepseek-chat
-
-# 数据库配置(可选)
-USE_EMBEDDED_DB=true
-```
-
-### 切换数据库
-
-**使用内嵌数据库(默认):**
-```bash
-USE_EMBEDDED_DB=true
-```
-
-**使用Neo4j(需要Docker):**
-```bash
-USE_EMBEDDED_DB=false
-NEO4J_URI=bolt://localhost:7687
-NEO4J_USER=neo4j
-NEO4J_PASSWORD=graphmemory123
-```
-
----
-
-## 开发指南
-
-### 项目结构
+## 项目结构
```
-graph_enable_ability/
+trulymem/
├── graph_memory_tui/ # TUI应用
│ ├── core/ # 核心逻辑
-│ │ ├── embedded_db.py # 内嵌数据库
-│ │ └── imports.py
-│ ├── web/ # Web接口
+│ ├── handlers/ # 事件处理
+│ ├── models/ # 数据模型
+│ ├── services/ # 服务层
│ ├── widgets/ # UI组件
-│ ├── styles/ # 样式
-│ └── app.py
-├── tests/ # 测试
+│ └── styles/ # 样式文件
├── docs/ # 文档
-├── start.bat # Windows启动
-├── start.sh # Linux/macOS启动
-└── start.py # 跨平台启动
+├── tests/ # 测试
+├── requirements.txt # 依赖清单
+├── LICENSE # 许可证
+└── README.md # 说明文档
```
-### 运行测试
-
-```bash
-# 安装依赖
-pip install -r requirements.txt
-
-# 运行测试
-pytest tests/
-```
-
-### 开发模式
-
-```bash
-# 创建虚拟环境
-python -m venv venv
-source venv/bin/activate # Linux/macOS
-venv\Scripts\activate # Windows
-
-# 安装依赖
-pip install -r requirements.txt
-
-# 运行应用
-python -m graph_memory_tui.main
-```
-
----
-
-## 常见问题
-
-### Q: 启动时显示"API Key 未配置"?
-
-**A:** 按F2打开侧边栏,在配置区输入API Key,按Enter保存。
-
-### Q: 数据保存在哪里?
-
-**A:** 数据保存在 `graph_memory.db` 文件中,可以备份或迁移。
-
-### Q: 如何查看数据库内容?
-
-**A:** 使用SQLite工具打开 `graph_memory.db`,或使用 `memory_introspect` 工具。
-
-### Q: 支持哪些API?
-
-**A:** 支持所有兼容OpenAI格式的API,如DeepSeek、OpenAI等。
-
---
## 技术栈
@@ -277,16 +134,83 @@ python -m graph_memory_tui.main
---
+## 开发指南
+
+### 环境设置
+
+```bash
+# 创建虚拟环境
+python -m venv venv
+source venv/bin/activate # Linux/macOS
+venv\Scripts\activate # Windows
+
+# 安装依赖
+pip install -r requirements.txt
+```
+
+### 运行测试
+
+```bash
+pytest tests/
+```
+
+### 打包应用
+
+```bash
+# Windows
+python build_windows.bat
+
+# Linux
+bash build_linux.sh
+```
+
+---
+
## 许可证
-MIT License
+本项目采用 **GNU General Public License v3.0 (GPLv3)** 许可证开源。
+
+详见 [LICENSE](LICENSE) 文件。
+
+### 许可证要点:
+
+- ✅ 可以自由使用、修改和分发
+- ✅ 必须保留版权声明和许可证
+- ✅ 修改后的作品必须以相同许可证发布
+- ✅ 必须提供源代码
---
## 贡献
-欢迎提交Issue和Pull Request!
+欢迎提交 Issue 和 Pull Request!
+
+### 贡献指南
+
+1. Fork 本仓库
+2. 创建特性分支 (`git checkout -b feature/AmazingFeature`)
+3. 提交更改 (`git commit -m 'Add some AmazingFeature'`)
+4. 推送到分支 (`git push origin feature/AmazingFeature`)
+5. 创建 Pull Request
---
-**TrueHumanMEM —— 让 AI 的记忆方式,更像人。**
+## 作者
+
+**jianf** - 项目设计与开发
+
+---
+
+## 致谢
+
+感谢所有为这个项目做出贡献的开发者和用户。
+
+---
+
+
+
+**TrulyMEM —— 让 AI 的记忆方式,更像人。**
+
+*Made with ❤️ by jianf*
+
+
diff --git a/build_linux.sh b/build_linux.sh
new file mode 100644
index 0000000..b7104e3
--- /dev/null
+++ b/build_linux.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+# Linux打包脚本
+# 需要在Linux系统上运行
+
+echo "开始打包Linux版本..."
+
+# 检查Python和PyInstaller
+if ! command -v python3 &> /dev/null; then
+ echo "错误: 未找到python3"
+ exit 1
+fi
+
+# 安装依赖
+echo "安装依赖..."
+pip3 install -r requirements.txt
+
+# 打包Linux二进制文件
+echo "打包Linux二进制文件..."
+python3 -m PyInstaller \
+ --clean \
+ --onefile \
+ --name TrulyMEM \
+ --console \
+ --add-data "graph_memory_tui/styles/*.css:graph_memory_tui/styles" \
+ --add-data "graph_memory_tui/web/templates/*.html:graph_memory_tui/web/templates" \
+ --hidden-import textual \
+ --hidden-import openai \
+ --hidden-import flask \
+ --hidden-import neo4j \
+ graph_memory_tui/main.py
+
+echo "打包完成!"
+echo "可执行文件位于: dist/TrulyMEM"
diff --git a/build_windows.bat b/build_windows.bat
new file mode 100644
index 0000000..7ecca5c
--- /dev/null
+++ b/build_windows.bat
@@ -0,0 +1,34 @@
+@echo off
+REM Windows打包脚本
+
+echo 开始打包Windows版本...
+
+REM 检查Python
+python --version >nul 2>&1
+if errorlevel 1 (
+ echo 错误: 未找到python
+ exit /b 1
+)
+
+REM 安装依赖
+echo 安装依赖...
+pip install -r requirements.txt
+
+REM 打包Windows exe文件
+echo 打包Windows exe文件...
+python -m PyInstaller ^
+ --clean ^
+ --onefile ^
+ --name TrulyMEM ^
+ --console ^
+ --add-data "graph_memory_tui/styles/*.css;graph_memory_tui/styles" ^
+ --add-data "graph_memory_tui/web/templates/*.html;graph_memory_tui/web/templates" ^
+ --hidden-import textual ^
+ --hidden-import openai ^
+ --hidden-import flask ^
+ --hidden-import neo4j ^
+ graph_memory_tui/main.py
+
+echo 打包完成!
+echo 可执行文件位于: dist\TrulyMEM.exe
+pause
diff --git a/config.json b/config.json
index 4ca49ba..1c0f04f 100644
--- a/config.json
+++ b/config.json
@@ -1,5 +1,5 @@
{
- "api_key": "sk-7d3e23384c04415b9c828a925ef4ab11",
+ "api_key": "",
"model": "deepseek-chat",
"base_url": "https://api.deepseek.com"
}
\ No newline at end of file
diff --git a/convert_icon.py b/convert_icon.py
new file mode 100644
index 0000000..473d46f
--- /dev/null
+++ b/convert_icon.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python3
+"""
+转换PNG图标为ICO格式
+"""
+
+from PIL import Image
+
+def convert_to_ico():
+ """转换PNG为ICO"""
+ # 打开PNG图片
+ img = Image.open('trulymem_new_icon.png')
+
+ # 转换为RGBA模式
+ if img.mode != 'RGBA':
+ img = img.convert('RGBA')
+
+ # 调整大小为256x256
+ img = img.resize((256, 256), Image.Resampling.LANCZOS)
+
+ # 创建不同尺寸的图标
+ icon_sizes = [(16, 16), (32, 32), (48, 48), (64, 64), (128, 128), (256, 256)]
+
+ # 保存为ICO
+ img.save('trulymem_icon.ico', format='ICO', sizes=icon_sizes)
+ print("ICO图标已创建: trulymem_icon.ico")
+
+if __name__ == "__main__":
+ convert_to_ico()
diff --git a/create_icon.py b/create_icon.py
new file mode 100644
index 0000000..cb7123c
--- /dev/null
+++ b/create_icon.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python3
+"""
+创建TrulyMEM应用图标
+"""
+
+from PIL import Image, ImageDraw, ImageFont
+import sys
+
+def create_icon():
+ """创建应用图标"""
+ # 创建256x256的图标
+ size = 256
+ img = Image.new('RGBA', (size, size), (0, 0, 0, 0))
+ draw = ImageDraw.Draw(img)
+
+ # 绘制圆形背景
+ margin = 20
+ draw.ellipse(
+ [margin, margin, size-margin, size-margin],
+ fill=(52, 152, 219, 255), # 蓝色背景
+ outline=(41, 128, 185, 255),
+ width=3
+ )
+
+ # 绘制字母T和M
+ try:
+ # 尝试使用系统字体
+ font = ImageFont.truetype("arial.ttf", 80)
+ except:
+ # 如果找不到字体,使用默认字体
+ font = ImageFont.load_default()
+
+ # 绘制文字
+ text = "TM"
+ # 获取文字边界框
+ bbox = draw.textbbox((0, 0), text, font=font)
+ text_width = bbox[2] - bbox[0]
+ text_height = bbox[3] - bbox[1]
+
+ # 计算文字位置(居中)
+ x = (size - text_width) // 2
+ y = (size - text_height) // 2 - 10
+
+ # 绘制白色文字
+ draw.text((x, y), text, fill=(255, 255, 255, 255), font=font)
+
+ # 保存为PNG
+ img.save('trulymem_icon.png', 'PNG')
+ print("图标已创建: trulymem_icon.png")
+
+ # 转换为ICO格式
+ try:
+ # 创建不同尺寸的图标
+ icon_sizes = [(16, 16), (32, 32), (48, 48), (64, 64), (128, 128), (256, 256)]
+ icons = []
+ for icon_size in icon_sizes:
+ icon = img.resize(icon_size, Image.Resampling.LANCZOS)
+ icons.append(icon)
+
+ # 保存为ICO
+ img.save('trulymem_icon.ico', format='ICO', sizes=icon_sizes)
+ print("ICO图标已创建: trulymem_icon.ico")
+ except Exception as e:
+ print(f"创建ICO失败: {e}")
+ print("请使用在线工具将PNG转换为ICO")
+
+if __name__ == "__main__":
+ try:
+ create_icon()
+ except ImportError:
+ print("需要安装Pillow库: pip install Pillow")
+ sys.exit(1)
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 0000000..4066bc6
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,25 @@
+# TrulyMEM 文档
+
+欢迎来到TrulyMEM项目文档。
+
+## 文档目录
+
+- [架构设计](架构.md) - 系统架构和技术设计
+- [快速开始](一键启动指南.md) - 一键启动指南
+
+## 项目简介
+
+TrulyMEM是一个让AI拥有长期记忆能力的图记忆系统,通过图数据库存储实体关系,让AI能够像人类一样记忆、回忆和管理信息。
+
+## 核心特性
+
+- 长期记忆存储
+- 人设图机制
+- 流式消息显示
+- 跨平台支持
+- 独立部署
+
+## 快速链接
+
+- [GitHub仓库](https://github.com/yourusername/trulymem)
+- [问题反馈](https://github.com/yourusername/trulymem/issues)
diff --git a/graph_memory_demo.py b/graph_memory_demo.py
index 83011b8..865ea46 100644
--- a/graph_memory_demo.py
+++ b/graph_memory_demo.py
@@ -523,6 +523,48 @@ class GraphMemoryClient:
def _build_system_prompt(self) -> str:
return """你是TrulyMEM,TrueHumanMEM项目的AI助手,拥有长期记忆能力。
+## ⚠️ 最高优先级:人设图机制(每轮必读!)
+
+**【强制要求】每轮对话开始前,必须执行以下步骤:**
+
+1. **立即调用memory_recall**,查询参数:
+ ```json
+ {
+ "query_intent": "AI,人设,角色,性格,语气,说话风格",
+ "depth": 2
+ }
+ ```
+
+2. **检查查询结果**:
+ - 如果找到人设信息 → **严格按照人设回复,不得跳出角色**
+ - 如果没有找到 → 使用默认的TrulyMEM身份
+
+3. **回复时必须遵守**:
+ - 人设优先级 > 默认身份
+ - 每句话都符合人设的语气、风格、特征
+ - 绝不主动跳出角色,除非用户明确要求
+
+### 人设图结构
+- AI节点:人设图中心节点
+- 角色属性:性格、语气、说话风格、行为特征
+- 用户要求:用户指定的角色要求
+
+### 用户要求角色扮演时
+立即使用memory_commit写入:
+```json
+{
+ "triplets": [
+ {"subject": "AI", "relation": "扮演角色", "object": "猫娘"},
+ {"subject": "AI", "relation": "说话风格", "object": "可爱俏皮"},
+ {"subject": "AI", "relation": "语气特征", "object": "使用喵结尾"},
+ {"subject": "AI", "relation": "性格特点", "object": "活泼粘人"}
+ ]
+}
+```
+然后立即按照新人设回复!
+
+---
+
## 身份说明
- 你的名字是TrulyMEM,是TrueHumanMEM项目的产物
- 你拥有基于图数据库的长期记忆能力
@@ -530,12 +572,14 @@ class GraphMemoryClient:
## 核心职责
你是一个智能对话助手,**图数据库是你记忆的唯一载体**。你的主要任务是:
-1. 与用户进行自然、流畅的对话
-2. 回答问题、提供建议、协助完成任务
-3. 根据对话内容灵活查询和使用记忆
-4. 将用户明确提到的信息写入记忆
+1. **每轮对话前先查询人设图(最高优先级)**
+2. 与用户进行自然、流畅的对话
+3. 回答问题、提供建议、协助完成任务
+4. 根据对话内容灵活查询和使用记忆
+5. 将用户明确提到的信息写入记忆
**重要**:
+- **人设图优先:每轮对话前必须查询人设,严格按照人设回复**
- 图数据库是你记忆的唯一来源,没有其他记忆方式
- 优先进行自然对话,根据需要灵活调用记忆工具
- 用户明确提到的内容必须写入,推理得到的内容必须标注
diff --git a/jimeng-2026-04-11-5790-一款扁平化、现代化风格的应用图标,以“trulymem”字母为视觉核心。字母采用....png b/jimeng-2026-04-11-5790-一款扁平化、现代化风格的应用图标,以“trulymem”字母为视觉核心。字母采用....png
new file mode 100644
index 0000000..569e2a4
Binary files /dev/null and b/jimeng-2026-04-11-5790-一款扁平化、现代化风格的应用图标,以“trulymem”字母为视觉核心。字母采用....png differ
diff --git a/tests/test_core/test_imports.py b/tests/test_core/test_imports.py
new file mode 100644
index 0000000..38feb26
--- /dev/null
+++ b/tests/test_core/test_imports.py
@@ -0,0 +1,50 @@
+"""核心逻辑导入测试"""
+
+import pytest
+
+
+def test_import_neo4j_graph():
+ """测试 Neo4jGraph 类导入"""
+ from graph_memory_tui.core.imports import Neo4jGraph
+ assert Neo4jGraph is not None
+ assert hasattr(Neo4jGraph, 'recall')
+ assert hasattr(Neo4jGraph, 'commit')
+ assert hasattr(Neo4jGraph, 'purge')
+
+
+def test_import_graph_memory_client():
+ """测试 GraphMemoryClient 类导入"""
+ from graph_memory_tui.core.imports import GraphMemoryClient
+ assert GraphMemoryClient is not None
+ assert hasattr(GraphMemoryClient, 'send_message')
+
+
+def test_import_tools():
+ """测试 TOOLS 定义导入"""
+ from graph_memory_tui.core.imports import TOOLS
+ assert TOOLS is not None
+ assert isinstance(TOOLS, list)
+ assert len(TOOLS) > 0
+ assert any(t['function']['name'] == 'memory_recall' for t in TOOLS)
+
+
+def test_import_execute_tool():
+ """测试 execute_tool 函数导入"""
+ from graph_memory_tui.core.imports import execute_tool
+ assert execute_tool is not None
+ assert callable(execute_tool)
+
+
+def test_import_config_vars():
+ """测试配置变量导入"""
+ from graph_memory_tui.core.imports import (
+ DEEPSEEK_API_KEY,
+ DEEPSEEK_BASE_URL,
+ MODEL_NAME,
+ NEO4J_URI,
+ NEO4J_USER,
+ NEO4J_PASSWORD,
+ )
+ assert DEEPSEEK_BASE_URL is not None
+ assert MODEL_NAME is not None
+ assert NEO4J_URI is not None
diff --git a/tests/test_handlers/test_focus_handler.py b/tests/test_handlers/test_focus_handler.py
new file mode 100644
index 0000000..b8a655a
--- /dev/null
+++ b/tests/test_handlers/test_focus_handler.py
@@ -0,0 +1,33 @@
+"""焦点处理器测试"""
+
+import pytest
+from graph_memory_tui.handlers.focus_handler import FocusHandler
+
+
+def test_focus_handler_creation():
+ """测试焦点处理器创建"""
+ handler = FocusHandler()
+ assert handler is not None
+ assert handler._current_index == 0
+
+
+def test_focus_ring():
+ """测试焦点循环"""
+ handler = FocusHandler()
+ assert len(handler.FOCUS_RING) == 5
+ assert "input-textarea" in handler.FOCUS_RING
+ assert "cypher-textarea" in handler.FOCUS_RING
+
+
+def test_get_current_focus_name():
+ """测试获取当前焦点名称"""
+ handler = FocusHandler()
+ name = handler.get_current_focus_name()
+ assert name == "Input"
+
+
+def test_focus_names_mapping():
+ """测试焦点名称映射"""
+ handler = FocusHandler()
+ assert handler.FOCUS_NAMES["input-textarea"] == "Input"
+ assert handler.FOCUS_NAMES["cypher-textarea"] == "Query"
diff --git a/tests/test_models/test_models.py b/tests/test_models/test_models.py
new file mode 100644
index 0000000..dc7f20a
--- /dev/null
+++ b/tests/test_models/test_models.py
@@ -0,0 +1,83 @@
+"""数据模型测试"""
+
+import pytest
+from datetime import datetime
+from graph_memory_tui.models.message import Message, ToolCall, ToolResult
+from graph_memory_tui.models.config import AppConfig
+from graph_memory_tui.models.log_entry import LogEntry
+
+
+def test_message_creation(sample_message):
+ """测试消息创建"""
+ assert sample_message.role == "user"
+ assert sample_message.content == "测试消息"
+ assert isinstance(sample_message.timestamp, datetime)
+
+
+def test_message_with_tool_calls():
+ """测试带工具调用的消息"""
+ tool_call = ToolCall(
+ id="test-id",
+ name="memory_recall",
+ arguments={"query_intent": "测试"}
+ )
+
+ message = Message(
+ role="assistant",
+ content="测试回复",
+ tool_calls=[tool_call]
+ )
+
+ assert message.role == "assistant"
+ assert message.tool_calls is not None
+ assert len(message.tool_calls) == 1
+ assert message.tool_calls[0].name == "memory_recall"
+
+
+def test_tool_call_creation(sample_tool_call):
+ """测试工具调用创建"""
+ assert sample_tool_call.id == "test-call-id"
+ assert sample_tool_call.name == "memory_recall"
+ assert sample_tool_call.arguments == {"query_intent": "测试查询"}
+
+
+def test_tool_result_creation(sample_tool_result):
+ """测试工具结果创建"""
+ assert sample_tool_result.tool_call_id == "test-call-id"
+ assert sample_tool_result.success is True
+ assert sample_tool_result.result == "测试结果"
+
+
+def test_config_creation(sample_config):
+ """测试配置创建"""
+ assert sample_config.api_key == "test-api-key"
+ assert sample_config.model == "test-model"
+ assert sample_config.base_url == "https://test.api.com"
+
+
+def test_config_from_env():
+ """测试从环境变量加载配置"""
+ import os
+ os.environ["DEEPSEEK_API_KEY"] = "env-api-key"
+ os.environ["MODEL_NAME"] = "env-model"
+
+ config = AppConfig.from_env()
+ assert config.api_key == "env-api-key"
+ assert config.model == "env-model"
+
+
+def test_log_entry_creation(sample_log_entry):
+ """测试日志条目创建"""
+ assert sample_log_entry.tool_name == "memory_recall"
+ assert sample_log_entry.duration == 0.5
+
+
+def test_log_entry_summary(sample_log_entry):
+ """测试日志条目摘要"""
+ args_summary = sample_log_entry.args_summary
+ result_summary = sample_log_entry.result_summary
+
+ assert isinstance(args_summary, str)
+ assert isinstance(result_summary, str)
+ assert len(args_summary) <= 53 # 50 + "..."
+ assert len(result_summary) <= 103 # 100 + "..."
diff --git a/trulymem_entry.py b/trulymem_entry.py
new file mode 100644
index 0000000..e947dc0
--- /dev/null
+++ b/trulymem_entry.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python3
+"""
+TrulyMEM 独立入口文件
+用于打包为可执行文件
+"""
+
+import sys
+import os
+from pathlib import Path
+
+# 确保工作目录正确
+if getattr(sys, 'frozen', False):
+ # 打包后的可执行文件
+ application_path = Path(sys.executable).parent
+else:
+ # 开发环境
+ application_path = Path(__file__).parent
+
+# 切换到应用目录
+os.chdir(application_path)
+
+# 添加项目路径
+if str(application_path) not in sys.path:
+ sys.path.insert(0, str(application_path))
+
+# 导入并运行应用
+from graph_memory_tui.app import GraphMemoryApp
+
+def main():
+ """主函数"""
+ try:
+ app = GraphMemoryApp()
+ app.run()
+ except KeyboardInterrupt:
+ print("\n应用已退出")
+ sys.exit(0)
+ except Exception as e:
+ print(f"应用启动失败: {e}")
+ import traceback
+ traceback.print_exc()
+ sys.exit(1)
+
+if __name__ == "__main__":
+ main()
diff --git a/trulymem_icon.ico b/trulymem_icon.ico
new file mode 100644
index 0000000..a372918
Binary files /dev/null and b/trulymem_icon.ico differ
diff --git a/trulymem_icon.png b/trulymem_icon.png
new file mode 100644
index 0000000..790307e
Binary files /dev/null and b/trulymem_icon.png differ
diff --git a/trulymem_new_icon.png b/trulymem_new_icon.png
new file mode 100644
index 0000000..569e2a4
Binary files /dev/null and b/trulymem_new_icon.png differ