Metadata-Version: 2.4
Name: palacelite
Version: 0.6.0
Summary: 轻量级本地 AI 记忆系统
Author: fajknli
License-Expression: AGPL-3.0
Project-URL: Changelog, https://github.com/fajknli/palacelite/blob/main/CHANGELOG.md
Classifier: Development Status :: 4 - Beta
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: OS Independent
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: sqlite-vec>=0.1.0
Requires-Dist: sentence-transformers>=5.0.0
Requires-Dist: click>=8.0.0
Requires-Dist: jieba>=0.42.1
Requires-Dist: numpy>=1.24.0
Requires-Dist: rich>=13.0.0
Provides-Extra: chat
Requires-Dist: llama-cpp-python>=0.3.0; extra == "chat"
Dynamic: license-file

<h1 align="center">PalaceLite</h1>

<p align="center">
  <strong>轻量级 · 纯本地 · 可解释的 AI 记忆系统</strong>
</p>

<p align="center">
  <a href="#安装">安装</a> ·
  <a href="#核心概念">核心概念</a> ·
  <a href="#快速开始">快速开始</a> ·
  <a href="#架构">架构</a> ·
  <a href="#设计原则">设计原则</a> ·
  <a href="#定位说明">定位说明</a>
</p>

<p align="center">
  <a href="https://www.gnu.org/licenses/agpl-3.0"><img src="https://img.shields.io/badge/License-AGPL_v3-blue.svg" alt="License: AGPL v3"></a>
  <a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.9+-blue.svg" alt="Python 3.9+"></a>
  <a href="https://pypi.org/project/palacelite/"><img src="https://badge.fury.io/py/palacelite.svg" alt="PyPI version"></a>
</p>

---
---
---

<h2 align="center">许可证变更说明</h2>

自 v0.6.0 版本起，PalaceLite 的开放源代码许可证已从 MIT 切换为 GNU Affero General Public License v3 (AGPL-3.0)。

### 不同许可证对您的影响

| 使用场景 | MIT (v0.5.5 及更早版本) | AGPL-3.0 (v0.6.0 及后续版本) |
| :--- | :--- | :--- |
| 个人使用与学习 | 完全自由 | 完全自由 |
| 企业内部使用与修改 | 完全自由 | 完全自由 |
| 修改后分发 | 允许闭源分发 | 必须公开修改后的全部源代码 |
| 作为网络服务 (SaaS) 提供 | 允许闭源提供服务 | 必须公开提供该服务的全部源代码 |

### 切换许可证的原因

MIT 协议允许任何人将代码闭源后包装为商业服务出售。这意味着用户的记忆数据可能被锁进一个无法审查、无法验证、无法迁移的黑盒子里。

切换到 AGPL-3.0 是为了确保：任何将 PalaceLite 作为网络服务提供的主体，必须将其代码开源。用户有权知道自己的记忆被如何存储和处理。

个人和内部使用不受任何限制。

### 继续使用 MIT 版本的方式

您仍有以下选择：

- **指定版本安装**：使用 `pip install palacelite==0.5.5` 安装最后的 MIT 版本。
- **从存档分支获取**：项目提供专用的 [`legacy-mit-v0.5.5`](https://github.com/fajknli/palacelite/tree/legacy-mit-v0.5.5) 分支，该分支永久保留最后的 MIT 许可代码，可用于 fork 或二次开发。

如对本变更有任何疑问，欢迎通过 GitHub Issue 讨论。

---
---
---

> 不是在造工具，是在造一面随时间生长的镜子。

当对话结束，记忆不应消失。PalaceLite 用结构代替摘要，用本地存储代替云端同步，用透明公式代替黑盒检索。

---

## 核心特性

| 特性 | 说明 |
|------|------|
| **纯本地运行** | 单 SQLite 文件存储元数据 + 向量，零外部依赖 |
| **三层空间隐喻** | Wing → Room → Drawer，贴合人类记忆组织方式 |
| **透明混合检索** | 5 因子加权公式，每因子可调可审计 |
| **异步提炼 + 规则兜底** | 后台压缩用户输入，关键词规则自动分类 |
| **数据反哺工作流** | `audit` 命令输出关键词建议，结构从使用中生长 |

---

## 核心概念

- **Wing**：`work` / `life` / `tech` / `unsorted`（系统预置）
- **Room**：每个 Wing 下默认 `general`，按需添加
- **Drawer**：单条记忆，存储内容 + 向量 + 元数据

---

## 快速开始

### 安装

```bash
# 核心功能
pip install palacelite

# 含对话支持
pip install "palacelite[chat]"
```
> [chat] 会自动安装 llama-cpp-python，用于加载 GGUF 格式模型。


### 首次运行

#### 准备模型

PalaceLite 需要自备 GGUF 格式的模型文件：

|模型|用途|是否必需|
|----|----|--------|
|对话模型|生成 AI 回复|必需|
|提炼模型|压缩用户输入为简洁记忆|可选|

不使用提炼模型时，系统会直接保存用户原话。如需提炼，建议使用 1.5B 小模型；若发现提炼质量不佳（如丢失关键信息），可换用 3B 模型
```bash
palacelite chat -m ~/models/qwen-7b.gguf --online
```

> 嵌入模型约 100MB，下载后永久离线使用。

### 日常使用

```bash
# 默认进入 unsorted/general
palacelite chat -m ~/models/qwen-7b.gguf

# 指定工作空间
palacelite chat -m ~/models/qwen-7b.gguf -w work -r auth-design
```

### 命令行管理

```bash
# 添加记忆
palacelite add -w tech -r db -c "PostgreSQL 并发写入优于 MySQL"

# 搜索
palacelite search -q "数据库选型" -w tech

# 盘点未分类记忆
palacelite audit -k 15

# 查看统计
palacelite stats
```

---

## 命令速查

### CLI 命令

| 命令 | 说明 |
|------|------|
| `add -w <wing> -r <room> -c <内容>` | 添加记忆 |
| `search -q <关键词> [-w wing] [-r room]` | 搜索记忆 |
| `list [-w wing] [-r room] [-l 数量] [-a]` | 列出活跃记忆 |
| `list-ids [-w wing] [-r room] [-l 数量]` | 紧凑显示记忆 ID |
| `move -i <id> [-w wing] [-r room]` | 移动单条记忆 |
| `move -i <id1> -i <id2> [-w wing] [-r room]` | 移动范围内记忆 |
| `move-all -fw <wing> [-fr room] -tw <wing> -tr <room>` | 批量移动记忆 |
| `audit [-k N] [-w wing]` | 盘点高频词，输出分类建议 |
| `stats` | 显示数据库统计 |
| `archive-old [--days N] [--importance N]` | 批量归档旧记忆 |
| `list-archived` | 列出已归档记忆 |
| `export-archived [-o 路径]` | 导出归档记忆到 JSON |
| `delete-archived` | 永久删除归档记忆 |

### 对话内命令

| 命令 | 说明 |
|------|------|
| `/mem <关键词>` | 搜索记忆 |
| `/add <内容>` | 手动添加记忆 |
| `/list [N]` | 列出最近 N 条 |
| `/move <id> [id2] <wing>/<room>` | 移动记忆 |
| `/wings` / `/rooms` | 列出空间结构 |
| `/cd [wing]/[room]` | 切换当前空间 |
| `/stats` / `/clear` / `/help` / `/quit` | 系统操作 |

---

## 检索原理

```
score = similarity × time_decay × importance × freshness × keyword_bonus
```

| 因子 | 计算方式 | 可调参数 |
|------|----------|----------|
| 向量相似度 | 余弦相似度（sqlite-vec 批量计算） | 无 |
| 时间衰减 | `0.5 ^ (天数/30)`，最低 0.1 | `half_life_days=30` |
| 重要性 | `0.5 + min(importance,10)/10`，范围 0.6~1.5 | 用户标记 1~10 |
| 新鲜度 | 7 天内线性加成，最高 1.5× | `freshness_days=7` |
| 关键词匹配 | Jaccard 相似度（jieba 分词），最高 1.5× | `keyword_weight=0.5` |

所有因子均在 `retrieval.py` 中明文实现。

---

## 架构概览

```
用户对话
   │
   ▼
Distiller（异步提炼）→ 队列 → Storage（SQLite + sqlite-vec）
   │                              │
   ▼                              ▼
Manager（规则分类）        Retriever（透明混合检索）
   │                              │
   └──────────┬───────────────────┘
              ▼
      PalaceLite Core（统一 API）
```

---

## 设计原则

**质量 · 本地 · 透明 · 克制 · 人工在环**

## 定位说明

PalaceLite 不提供 API 接入，也不计划支持云端模型调用。

原因很简单：**记忆数据是你最私密的数字资产**。一旦通过 API 发送给云端模型，数据就已离开你的控制范围。

PalaceLite 选择「纯本地」：
- 对话模型在本地运行
- 记忆存储在本地 SQLite
- 检索计算在本地完成

至于你想用 CLI 模式把记忆复制到 ChatGPT/Claude —— 那是你的自由。工具不限制你，但也不替你送出去。

如果你需要更强模型，建议等待本地模型能力演进，或自行部署更大参数的 GGUF 模型。

---

## 配置

### 环境变量

| 变量 | 默认值 | 说明 |
|------|--------|------|
| `PALACE_MODEL_PATH` | — | GGUF 模型路径 |
| `PALACE_MODEL_DIR` | `~/Public/ai/models` | 模型默认存放目录 |
| `GPU_LAYERS` | `20` | GPU 加速层数 |
| `PYTHONLOGLEVEL` | `INFO` | 设为 `DEBUG` 输出分类调试日志 |

### 工作目录

默认：`~/.palacelite`

自定义：
```python
from palacelite import PalaceLite
p = PalaceLite(workspace="/custom/path")
```

数据库文件：`~/.palacelite/palace.db`（单文件，含元数据 + 向量）

---

## 维护指南

### 分类关键词维护

```bash
# 每周执行
palacelite audit -k 15

# 输出示例：
# 建议新增分类关键词（当前未覆盖，可直接复制）：
# ["PostgreSQL", "asyncio", "部署"]

# 操作：复制列表 → 粘贴到 palacelite/manager.py 对应分类 → 保存生效
```

### 更换嵌入模型后重建向量

```bash
python scripts/rebuild_embeddings.py --workspace ~/.palacelite
```

### 导出记忆用于微调

```bash
python scripts/clean_memories.py ~/backup.json ~/cleaned.json
```

### 运行测试

```bash
# 执行全套测试
pytest

# 仅测试某个模块
pytest palacelite/tests/test_retrieval.py -v

# 详细输出，遇到失败停止
pytest -v -x
```

---

## 依赖说明

```txt
# 核心依赖
sqlite-vec>=0.1.0
sentence-transformers>=5.0.0
click>=8.0.0
rich>=13.0.0
jieba>=0.42.1
numpy>=1.20.0

# 可选：对话支持
llama-cpp-python>=0.3.0

# 开发测试
pytest>=7.0.0
```

安装：
```bash
pip install palacelite              # 仅核心
pip install "palacelite[chat]"      # 含对话
```

---

## 项目结构

```
palacelite/
├── palacelite/
│   ├── __init__.py          # 版本与导出
│   ├── core.py              # PalaceLite 主类
│   ├── storage.py           # SQLite + sqlite-vec 存储层
│   ├── retrieval.py         # 透明混合检索
│   ├── distiller.py         # 异步记忆提炼
│   ├── manager.py           # 规则分类器
│   ├── models.py            # 数据模型：Wing/Room/Drawer
│   ├── utils.py             # 工具函数
│   ├── cli.py               # Click CLI + audit 命令
│   ├── chat.py              # 对话入口
│   └── tests/               # pytest 测试套件
│       ├── __init__.py
│       ├── conftest.py      # 全局 Fixture
│       ├── test_models.py   # 数据模型测试
│       ├── test_storage.py  # 存储层测试
│       ├── test_manager.py  # 分类器测试
│       └── test_retrieval.py # 检索层测试
├── pyproject.toml           # 打包配置
├── requirements.txt         # 依赖声明
├── pytest.ini               # pytest 配置
├── README.md                # 你正在阅读的文件
└── LICENSE                  # APGL-3.0
```

---

## 许可证

APGL--3.0 License — 详见 [LICENSE](LICENSE) 文件。

---

<p align="center">
  <strong>A mirror with memory.</strong>
</p>

