跳到主要内容

存储

AISCouncil 将所有数据本地存储在您的浏览器中。没有任何内容上传到任何服务器。存储系统使用两个层级 —— localStorage 用于启动时需要的小型同步读取,IndexedDB 用于大型异步数据,如机器人配置文件和聊天历史。

两层存储架构

层级API容量用例
localStorage同步约 5-10 MB主题、API 密钥、设置 —— 页面加载时即时需要的数据
IndexedDB异步约 100 MB - 1 GB+机器人配置文件、聊天历史、插件清单 —— 大数据

这种分离存在是因为 localStorage 快速但大小有限,而 IndexedDB 实际上无限制但需要异步访问。关键的启动时值(主题、API 密钥、登录状态)存在于 localStorage 中,以便应用程序可以立即渲染而无需等待异步读取。

localStorage 键

所有 localStorage 键使用 ais- 前缀:

类型描述
ais-themestring当前主题(lightdarksystem
ais-apikey-anthropicstringAnthropic API 密钥
ais-apikey-openaistringOpenAI API 密钥
ais-apikey-xaistringxAI API 密钥
ais-apikey-geministringGoogle Gemini API 密钥
ais-apikey-openrouterstringOpenRouter API 密钥
ais-apikey-deepseekstringDeepSeek API 密钥
ais-apikey-groqstringGroq API 密钥
ais-apikey-mistralstringMistral API 密钥
ais-userJSON登录用户信息(姓名、邮箱、头像、提供商)
ais-idb-migratedstring指示 localStorage 到 IndexedDB 迁移完成的标志
ais-ollama-endpointstring自定义 Ollama 端点 URL(默认:http://localhost:11434
ais-custom-providersJSON用户定义的自定义提供商配置数组
aiscouncil-settingsJSON全局设置(主题、字体大小、能力等)
aiscouncil-usageJSON使用跟踪数据(token、每个提供商的成本)
注意

localStorage 中的 API 密钥可被同一来源上运行的任何 JavaScript 访问。这是浏览器应用的标准,但意味着您不应安装不受信任的浏览器扩展。密钥从不包含在 URL 导出或数据备份中。

IndexedDB 键

IndexedDB 将数据存储在名为 ais-db 的数据库内的键值对象存储中(或登录时的每用户数据库):

键模式类型描述
ais-botsarray所有机器人会话元数据(ID、名称、配置、创建日期)
ais-profilesarray所有保存的配置文件(单个和委员会)
ais-chat-{botId}array特定机器人会话的聊天消息历史
ais-addon-manifestsarray安装的插件/插件清单
ais-miniprogram-*varies安装的小程序数据

每个机器人会话都有自己的聊天键(ais-chat-abc123),因此聊天历史是隔离的,可以独立加载。

自动迁移

首次启动时,AIS.Storage.init() 检查 localStorage 中是否存在旧版本的数据,并自动将其迁移到 IndexedDB。ais-idb-migrated 标志防止后续加载时重复迁移。

如果 IndexedDB 不可用(某些隐私浏览器会阻止它),存储层会透明地回退到 localStorage。应用程序继续工作,但有约 5-10 MB 的存储限制。

可选 SQLite WASM 层

对于涉及大型二进制数据(图像、附件)的高级用例,存储系统可以加载可选的 SQLite WASM 模块。SQLite 与 IndexedDB 并发运行,并将数据存储在浏览器的源私有文件系统 (OPFS) 中。

SQLite 按需加载 —— 除非明确请求或需要用于 blob 存储,否则永远不会加载。要启用它,请转到设置 > 通用 > 存储后端并选择 SQLite。

功能IndexedDBSQLite WASM
键值存储
二进制 blob 存储有限优化
SQL 查询
持久性浏览器管理OPFS(基于文件)
加载立即延迟(首次使用时)

AIS.Storage API

AIS.Storage 模块提供统一的 API,无论活动后端如何都能工作:

核心操作

// 初始化存储(启动时调用一次)
await AIS.Storage.init();

// 获取值
const bots = await AIS.Storage.get("ais-bots");

// 设置值
await AIS.Storage.set("ais-bots", updatedBots);

// 删除键
await AIS.Storage.delete("ais-chat-abc123");

// 列出所有键
const allKeys = await AIS.Storage.keys();

// 获取所有键值对
const everything = await AIS.Storage.getAll();

// 清除所有数据
await AIS.Storage.clear();

Blob 存储 (SQLite)

// 存储二进制 blob
await AIS.Storage.putBlob("image-001", arrayBuffer, "image/png");

// 检索 blob
const blob = await AIS.Storage.getBlob("image-001");
// { data: Uint8Array, mime: 'image/png', size: 12345 }

实用函数

// 同步 localStorage 助手(用于启动时读取)
const theme = AIS.Storage.loadJSON("ais-theme");
AIS.Storage.saveJSON("ais-theme", "dark");

// TTL 缓存工厂(用于注册表缓存)
const cache = AIS.Storage.cache("ais-models-cache", "ais-models-ts", 86400000); // 24h TTL
const data = cache.load(); // 读取缓存数据
cache.save(newData); // 更新缓存
const stale = cache.isStale(); // 检查缓存是否过期

状态属性

AIS.Storage.isIDB; // 如果 IndexedDB 处于活动状态则为 true
AIS.Storage.hasSQLite; // 如果 SQLite WASM 已加载则为 true

导出和导入

导出数据

转到设置 > 隐私 > 导出所有数据或使用 API:

const backup = await AIS.Storage.exportData();
// 返回: { bcz_version: "1.0.0", exported: "2026-02-19T...", data: {...} }

导出包括所有机器人配置文件、聊天历史、设置和插件清单。它明确排除

  • API 密钥(从不导出)
  • 配置文件中的每成员 API 密钥(剥离到只有提供商/模型)

导出保存为 ais-backup-YYYY-MM-DD.json

SQLite Blob

如果您激活了 SQLite blob 存储,导出还会生成一个单独的 ais-blobs-YYYY-MM-DD.db 文件,包含 SQLite 数据库。

导入数据

转到设置 > 隐私 > 导入数据或使用 API:

const count = await AIS.Storage.importData(jsonBackup);
// 返回: 导入的项目数

导入接受:

  • .json 文件(标准备份格式)
  • .db 文件(SQLite 数据库)

即使文件中存在 API 密钥,也不会导入。

存储配额

浏览器存储配额因平台而异:

浏览器IndexedDB 配额具有持久存储
Chrome/Edge磁盘空间的约 60%相同,但不会被驱逐
Firefox磁盘空间的约 50%提示用户授予权限
Safari初始约 1 GB,用户可以授予更多相同

AISCouncil 在初始化时通过 navigator.storage.persist() 请求持久存储。当被授予时,当存储空间不足时,浏览器不会自动驱逐您的数据。

检查存储使用情况

打开浏览器的开发者工具,转到应用程序 > 存储,查找来源 aiscouncil.net 以查看当前存储使用情况和配额。

隐私

所有数据都保留在您的设备上:

  • 无服务器上传 —— 机器人配置、聊天历史和设置永远不会发送到任何服务器
  • 无分析 —— 不传输任何使用数据
  • 无 cookie —— 应用程序使用 localStorage 和 IndexedDB,而不是跟踪 cookie(ais-auth cookie 仅用于跨子域身份验证检测)
  • 无第三方存储 —— 数据仅存储在 aiscouncil.net 来源下

清除数据

要清除所有存储的数据:

  1. 设置 > 隐私 > 清除所有数据 —— 删除所有 IndexedDB 数据、配置文件和聊天历史
  2. 浏览器开发者工具 > 应用程序 > 清除存储 —— 核选项,删除包括 localStorage 在内的所有内容
  3. 单独聊天删除 —— 在侧边栏中右键点击机器人并选择删除
危险

清除所有数据是不可逆的。如果您想要备份,请先导出数据。通过浏览器开发者工具清除时,存储在 localStorage 中的 API 密钥也会被删除。

小程序的每机器人存储

每个安装的小程序都有自己的隔离存储命名空间。小程序通过 ais.storage SDK API 访问存储,该 API 映射到 IndexedDB 中每应用前缀的键。一个小程序无法访问另一个的数据。

// 在小程序内部
await ais.storage.set("my-key", "my-value");
const val = await ais.storage.get("my-key");
const keys = await ais.storage.keys();
await ais.storage.remove("my-key");

卸载小程序时会删除小程序的存储。