跳转至

Worker Service

Worker Service 是一个基于 Express.js 构建、由 Bun 原生管理的长时运行 HTTP API。它通过 Claude Agent SDK 单独处理观察记录,与 hook 执行分离,以避免超时问题。

概述

  • 技术:Express.js HTTP 服务器
  • 运行时:Bun(缺失时自动安装)
  • 进程管理器:通过 ProcessManager 进行 Bun 原生进程管理
  • 端口:每个用户的默认端口为 37700 + (uid % 100)(可通过 CLAUDE_MEM_WORKER_PORT 覆盖)。当前端口存储在 ~/.claude-mem/settings.json 中,并由 GET /api/health 报告。
  • 位置:src/services/worker-service.ts
  • 构建输出:plugin/scripts/worker-service.cjs
  • 模型:可通过 CLAUDE_MEM_MODEL 配置(默认:claude-haiku-4-5-20251001)

会话缓冲区清理

删除或立即移除会话时,会在丢弃非空内存缓冲区之前记录一条包含 pendingCount 的 WARN 日志。已认领但未确认的消息仍会计入数量;已确认的消息不再缓冲。

Worker 关闭时还会记录 pendingCountAtShutdownStart,即清理开始前活动会话的总数。这是一个启动时的快照,而不是最终丢弃的数量。空缓冲区不会发出丢弃警告。

REST API 端点

Worker Service 公开了 22 个 HTTP 端点,分为六个类别:

查看器与健康端点

1. 查看器 UI

GET /

用途:提供基于 Web 的查看器 UI(v5.1.0+)

响应:包含嵌入式 React 应用的 HTML 页面

功能: - 实时内存流可视化 - 无限滚动分页 - 项目筛选 - 基于 SSE 的实时更新 - 主题切换(浅色/深色模式),自 v5.1.2 起

2. 健康检查

GET /health

用途:Worker 健康状态检查

响应:

{
  "status": "ok",
  "uptime": 12345,
  "port": 37742
}

port 值是当前用户实际使用的 Worker 端口——每个用户的默认端口为 37700 + (uid % 100),或由 CLAUDE_MEM_WORKER_PORT 设置的任意值。上面的示例仅作说明;你的实际值会有所不同。

3. Server-Sent Events 流

GET /stream

用途:为查看器 UI 提供实时更新

响应:包含以下事件的 SSE 流: - observation-created:新增观察记录 - session-summary-created:生成新的会话摘要 - user-prompt-created:记录新的 Prompt

事件格式:

event: observation-created
data: {"id": 123, "title": "...", ...}

数据检索端点

4. 获取 Prompts

GET /api/prompts?project=my-project&limit=20&offset=0

用途:分页检索用户 Prompt

查询参数: - project(可选):按项目名称筛选 - limit(默认:20):结果数量 - offset(默认:0):分页偏移量

响应:

{
  "prompts": [{
    "id": 1,
    "session_id": "abc123",
    "prompt": "User's prompt text",
    "prompt_number": 1,
    "created_at": "2025-11-06T10:30:00Z"
  }],
  "total": 150,
  "hasMore": true
}

5. 获取观察记录

GET /api/observations?project=my-project&limit=20&offset=0

用途:分页检索观察记录

查询参数: - project(可选):按项目名称筛选 - limit(默认:20):结果数量 - offset(默认:0):分页偏移量

响应:

{
  "observations": [{
    "id": 123,
    "title": "Fix authentication bug",
    "type": "bugfix",
    "narrative": "...",
    "created_at": "2025-11-06T10:30:00Z"
  }],
  "total": 500,
  "hasMore": true
}

6. 获取摘要

GET /api/summaries?project=my-project&limit=20&offset=0

用途:分页检索会话摘要

查询参数: - project(可选):按项目名称筛选 - limit(默认:20):结果数量 - offset(默认:0):分页偏移量

响应:

{
  "summaries": [{
    "id": 456,
    "session_id": "abc123",
    "request": "User's original request",
    "completed": "Work finished",
    "created_at": "2025-11-06T10:30:00Z"
  }],
  "total": 100,
  "hasMore": true
}

7. 按 ID 获取观察记录

GET /api/observation/:id

用途:按 ID 检索单条观察记录

路径参数: - id(必填):观察记录 ID

响应:

{
  "id": 123,
  "sdk_session_id": "abc123",
  "project": "my-project",
  "type": "bugfix",
  "title": "Fix authentication bug",
  "narrative": "...",
  "created_at": "2025-11-06T10:30:00Z",
  "created_at_epoch": 1730886600000
}

错误响应(404):

{
  "error": "Observation #123 not found"
}

8. 按多个 ID 获取观察记录(批量)

POST /api/observations/batch

用途:在单个请求中按多个 ID 检索多条观察记录

请求体:

{
  "ids": [123, 456, 789],
  "orderBy": "date_desc",
  "limit": 10,
  "project": "my-project"
}

请求体参数: - ids(必填):观察记录 ID 数组 - orderBy(可选):排序方式 - date_desc 或 date_asc(默认:date_desc) - limit(可选):返回的最大结果数量 - project(可选):按项目名称筛选

响应:

[
  {
    "id": 789,
    "sdk_session_id": "abc123",
    "project": "my-project",
    "type": "feature",
    "title": "Add new feature",
    "narrative": "...",
    "created_at": "2025-11-06T12:00:00Z",
    "created_at_epoch": 1730891400000
  },
  {
    "id": 456,
    "sdk_session_id": "abc124",
    "project": "my-project",
    "type": "bugfix",
    "title": "Fix authentication bug",
    "narrative": "...",
    "created_at": "2025-11-06T10:30:00Z",
    "created_at_epoch": 1730886600000
  }
]

错误响应: - 400 Bad Request:{"error": "ids must be an array of numbers"} - 400 Bad Request:{"error": "All ids must be integers"}

用例:此端点由 get_observations MCP 工具使用,以便在单个请求中高效检索多条观察记录,避免多个单独请求的开销。

9. 按 ID 获取会话

GET /api/session/:id

用途:按 ID 检索单个会话

路径参数: - id(必填):会话 ID

响应:

{
  "id": 456,
  "sdk_session_id": "abc123",
  "project": "my-project",
  "request": "User's original request",
  "completed": "Work finished",
  "created_at": "2025-11-06T10:30:00Z"
}

错误响应(404):

{
  "error": "Session #456 not found"
}

10. 按 ID 获取 Prompt

GET /api/prompt/:id

用途:按 ID 检索单个用户 Prompt

路径参数: - id(必填):Prompt ID

响应:

{
  "id": 1,
  "session_id": "abc123",
  "prompt": "User's prompt text",
  "prompt_number": 1,
  "created_at": "2025-11-06T10:30:00Z"
}

错误响应(404):

{
  "error": "Prompt #1 not found"
}

12. 获取统计信息

GET /api/stats

用途:按项目获取数据库统计信息

响应:

{
  "byProject": {
    "my-project": {
      "observations": 245,
      "summaries": 12,
      "prompts": 48
    },
    "other-project": {
      "observations": 156,
      "summaries": 8,
      "prompts": 32
    }
  },
  "total": {
    "observations": 401,
    "summaries": 20,
    "prompts": 80,
    "sessions": 20
  }
}

13. 获取项目列表

GET /api/projects

用途:获取观测记录中不重复的项目列表

响应:

{
  "projects": ["my-project", "other-project", "test-project"]
}

设置端点

14. 获取设置

GET /api/settings

用途:检索用户设置

响应:

{
  "sidebarOpen": true,
  "selectedProject": "my-project",
  "theme": "dark"
}

15. 保存设置

POST /api/settings

用途:持久化保存用户设置

请求体:

{
  "sidebarOpen": false,
  "selectedProject": "other-project",
  "theme": "light"
}

响应:

{
  "success": true
}

队列管理端点

16. 获取待处理队列状态

GET /api/pending-queue

用途:查看当前处理队列状态并识别卡住的消息

响应:

{
  "queue": {
    "messages": [
      {
        "id": 123,
        "session_db_id": 45,
        "claude_session_id": "abc123",
        "message_type": "observation",
        "status": "pending",
        "retry_count": 0,
        "created_at_epoch": 1730886600000,
        "started_processing_at_epoch": null,
        "completed_at_epoch": null
      }
    ],
    "totalPending": 5,
    "totalProcessing": 2,
    "totalFailed": 0,
    "stuckCount": 1
  },
  "recentlyProcessed": [
    {
      "id": 122,
      "session_db_id": 44,
      "status": "processed",
      "completed_at_epoch": 1730886500000
    }
  ],
  "sessionsWithPendingWork": [44, 45, 46]
}

状态定义: - pending:消息已入队,尚未处理 - processing:消息当前正在由 SDK 智能体处理 - processed:消息已成功处理完成 - failed:消息在达到最大重试次数(默认为 3 次)后处理失败

卡住检测:处于 processing 状态超过 5 分钟的消息将被视为卡住,并计入 stuckCount

使用场景:在 worker 崩溃或重启后检查队列健康状况,以识别未处理的观测记录

17. 触发手动恢复

POST /api/pending-queue/process

用途:手动触发待处理队列的处理(替代 v5.x+ 中的自动恢复)

请求体:

{
  "sessionLimit": 10
}

请求体参数: - sessionLimit(可选):要处理的最大会话数(默认:10,最大:100)

响应:

{
  "success": true,
  "totalPendingSessions": 15,
  "sessionsStarted": 10,
  "sessionsSkipped": 2,
  "startedSessionIds": [44, 45, 46, 47, 48, 49, 50, 51, 52, 53]
}

响应字段: - totalPendingSessions:数据库中包含待处理消息的会话总数 - sessionsStarted:本次请求中已开始处理的会话数 - sessionsSkipped:已在积极处理中的会话(未重新启动) - startedSessionIds:已启动会话的数据库 ID

行为: - 最多处理 sessionLimit 个有待处理工作的会话 - 跳过已在积极处理中的会话(防止重复智能体) - 为每个会话启动非阻塞的 SDK 智能体 - 立即返回状态(处理在后台继续)

使用场景:在 worker 崩溃后手动恢复卡住的观测记录,或在自动恢复被禁用时使用

恢复策略说明:自 v5.x 起,worker 启动时的自动恢复默认处于禁用状态。用户必须通过此端点或 CLI 工具(bun scripts/check-pending-queue.ts)手动触发恢复,以保持对重新处理的显式控制。

会话管理端点

19. 初始化会话

POST /sessions/:sessionDbId/init

请求体:

{
  "sdk_session_id": "abc-123",
  "project": "my-project"
}

响应:

{
  "success": true,
  "session_id": "abc-123"
}

20. 添加观测

POST /sessions/:sessionDbId/observations

请求体:

{
  "tool_name": "Read",
  "tool_input": {...},
  "tool_result": "...",
  "correlation_id": "xyz-789"
}

响应:

{
  "success": true,
  "observation_id": 123
}

21. 生成摘要

POST /sessions/:sessionDbId/summarize

请求体:

{
  "trigger": "stop"
}

响应:

{
  "success": true,
  "summary_id": 456
}

22. 会话状态

GET /sessions/:sessionDbId/status

响应:

{
  "session_id": "abc-123",
  "status": "active",
  "observation_count": 42,
  "summary_count": 1
}

23. 删除会话

DELETE /sessions/:sessionDbId

响应:

{
  "success": true
}

说明:自 v4.1.0 起,清理钩子不再调用此端点。会话会被标记为完成而不是删除,以便 worker 优雅关闭。

Bun 进程管理

概述

worker 由原生的 ProcessManager 类管理,它负责: - 使用 Bun 运行时生成进程 - 在 ~/.claude-mem/worker.pid 跟踪 PID 文件 - 带自动重试的健康检查 - 通过 SIGTERM/SIGKILL 回退实现优雅关闭

命令

# Start worker (auto-starts on first session)
npm run worker:start

# Stop worker
npm run worker:stop

# Restart worker
npm run worker:restart

# View logs
npm run worker:logs

# Check status
npm run worker:status

自动启动行为

当 SessionStart 钩子触发时,Worker Service 会自动启动。手动启动是可选的。

Bun 要求

运行 Worker Service 需要 Bun。如果未安装 Bun,npx claude-mem install(以及 npx claude-mem repair)会在设置期间全局安装它,并显示可见的 clack 加载指示器:

  • Windows:powershell -c "irm bun.sh/install.ps1 | iex"
  • macOS/Linux:curl -fsSL https://bun.sh/install | bash

你也可以通过以下方式手动安装: - winget install Oven-sh.Bun(Windows) - brew install oven-sh/bun/bun(macOS)

Claude Agent SDK 集成

Worker Service 将观察结果路由到 Claude Agent SDK 进行 AI 驱动的处理:

处理流程

  1. 观察队列:观察结果在内存中累积
  2. SDK 处理:通过 Agent SDK 将观察结果发送给 Claude
  3. XML 解析:解析响应以提取结构化数据
  4. 数据库存储:处理后的观察结果存储在 SQLite 中

SDK 组件

  • Prompts(src/sdk/prompts.ts):构建 XML 结构的 Prompt
  • Parser(src/sdk/parser.ts):解析 Claude 的 XML 响应
  • Worker(src/sdk/worker.ts):SDK Agent 主循环

模型配置

通过环境变量或 ~/.claude-mem/settings.json 设置用于压缩的 Claude 模型:

export CLAUDE_MEM_MODEL=claude-haiku-4-5-20251001

允许的值: - claude-haiku-4-5-20251001 - 默认,最快(最适合压缩) - claude-sonnet-5 - 质量与速度均衡 - claude-opus-4-8 - 质量最高(最慢)

端口分配

Worker Service 使用基于用户的默认端口,因此同一台机器上的不同操作系统用户永远不会冲突:

  • 默认:37700 + (uid % 100)(在 src/shared/SettingsDefaultsManager.ts 中设置)
  • 覆盖:设置 CLAUDE_MEM_WORKER_PORT(环境变量或 ~/.claude-mem/settings.json)
  • 发现:GET /api/health 返回当前使用的端口;~/.claude-mem/settings.json 存储配置的值

如果所选端口已被占用,Worker Service 将无法启动——请通过 CLAUDE_MEM_WORKER_PORT 指定其他端口并重启。

数据存储

Worker Service 将数据存储在用户数据目录中:

~/.claude-mem/
├── claude-mem.db           # SQLite database (bun:sqlite)
├── worker.pid              # PID file for process tracking
├── settings.json           # User settings
└── logs/
    └── worker-YYYY-MM-DD.log  # Daily rotating logs

错误处理

Worker Service 实现了优雅降级:

  • 数据库错误:记录日志但不会导致服务崩溃
  • SDK 错误:使用指数退避重试
  • 网络错误:记录日志并跳过
  • 无效输入:校验后以错误响应拒绝

性能

  • 异步处理:异步处理观察结果
  • 内存队列:快速累积观察结果
  • 批量处理:多个观察结果一起处理
  • 连接池:复用 SQLite 连接

故障排查

有关常见问题及解决方案,请参阅 故障排查 - Worker 问题。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/claude-mem