Skip to content

opensolon/solonclaw

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

90 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SolonClaw

English

置顶说明
本项目的基础架构思路学习和参考了开源项目 HKUDS/nanobot
SolonClaw 不是对 nanobot 的直接移植,而是基于 Solon + Solon AI + 文件工作区 + 多渠道适配 的本地化实现。理解项目时,请以当前仓库代码与测试为准。

SolonClaw 是一个基于 Solon 3.9.5 构建的轻量级 Agent 服务。它把模型调用、会话历史、子任务编排、工作区工具、定时任务、调试页和钉钉渠道统一到同一套运行时中。

适合用来做这些事情:

  • 🤖 构建一个可持续运行的个人/团队 AI 助手
  • 💬 同时接本地 Debug Web 与钉钉机器人
  • 🧠 让 Agent 基于工作区文件获得记忆、身份和行为约束
  • 🛠️ 让 Agent 通过工具读写工作区、通过 CLI 技能执行命令、管理任务
  • 🧩 把复杂问题拆成多个子任务并回流父会话
  • ⏰ 创建持久化定时任务,让 Agent 定期执行工作

核心特性

  • 🚀 统一运行时 所有消息都会先进入 AgentRuntimeService,统一完成去重、会话落盘、调度、模型执行与渠道回发。

  • 🔀 会话级并发 并发控制按 sessionKey 生效,而不是全局串行。当前默认单会话最大并发数为 4

  • 🧵 子任务编排 Agent 可以通过 spawn_task 派生独立子任务;子任务完成后会回流父会话,并支持按 batchKey 聚合状态。

  • 🔔 主动通知 Agent 在一次运行中可以主动向当前外部会话发送通知,而不必等最终回复。

  • 🗂️ 工作区驱动提示词 AGENTS.md / SOUL.md / IDENTITY.md / USER.md / TOOLS.md / HEARTBEAT.md / MEMORY.md / memory/YYYY-MM-DD.md 会自动参与系统提示词拼装。

  • 🧰 内置工具与技能 支持文件读写、片段编辑、任务查询、定时任务管理,并可从 workspace/skills 挂载 CLI 技能池 @skills

  • 🧪 本地调试友好 自带 Debug Web 页面,可直接查看 run 状态、流式事件、子任务列表与聚合摘要。

  • 📁 文件持久化 会话、运行、去重标记、路由状态和任务定义都可以直接在工作区中看到。

当前架构

Inbound Message
  -> ChannelAdapter / Debug Web / System Job
  -> AgentRuntimeService
  -> RuntimeStoreService (dedup + conversation events + run events + reply target)
  -> ConversationScheduler (per sessionKey concurrency)
  -> SolonAiConversationAgent
     -> ChatModel
     -> Workspace Tools
     -> Runtime Tools
     -> Job Tools
     -> CLI Skills (@skills)
  -> OutboundEnvelope
  -> ChannelRegistry
  -> DingTalk / Debug Web

核心模块:

  • agent/runtime 统一运行时、调度器、心跳、子任务与通知能力。

  • agent/store 统一文件落盘与历史重建。

  • agent/workspace 工作区路径边界、模板初始化、提示词拼装。

  • agent/tool 工作区工具、运行时工具、定时任务工具。

  • agent/job 持久化定时任务与恢复机制。

  • channel/dingtalk 钉钉 Stream 入站与机器人 OpenAPI 出站。

  • web Debug Web 页面与调试 API。

目录与持久化

默认工作区根目录为 ./workspace

运行后常见文件结构如下:

workspace/
  AGENTS.md
  SOUL.md
  IDENTITY.md
  USER.md
  TOOLS.md
  HEARTBEAT.md
  MEMORY.md
  memory/
  skills/
  jobs.json
  runtime/
    runs/
    conversations/
    dedup/
    meta/
    media/

其中:

  • workspace/runtime/runs 保存 run 明细与 run 事件。

  • workspace/runtime/conversations 保存会话事件和会话元数据。

  • workspace/runtime/meta 保存最近一次外部回复路由等状态。

  • workspace/jobs.json 保存定时任务定义。

当前已实现的渠道

1. Debug Web

本地调试页默认可用,访问根路径即可进入:

  • GET /
  • POST /api/debug/chat
  • GET /api/debug/runs/{runId}
  • GET /api/debug/runs/{runId}/events
  • GET /api/debug/runs/{runId}/children

特性:

  • 与钉钉共用同一个运行时
  • debug-web 会话与外部渠道隔离
  • 可查看流式事件、最终回复、子任务和聚合摘要

2. DingTalk

当前钉钉接入方式:

  • 入站:DingTalkStreamTopics.BOT_MESSAGE_TOPIC
  • 出站:机器人 OpenAPI
  • 群聊:orgGroupSend
  • 私聊:batchSendOTO
  • 输出格式:markdown 文本

当前行为边界:

  • 群聊与私聊会使用不同 sessionKey
  • 回复目标完全依赖 ReplyTarget
  • 附件暂时只做文本化降级
  • 白名单为空时默认允许;一旦配置白名单,则只允许命中项通过

Agent 当前能力

当前 Agent 可以使用的核心工具包括:

  • read_file
  • write_file
  • edit_file
  • notify_user
  • spawn_task
  • list_child_runs
  • get_run_status
  • get_child_summary
  • list_jobs
  • get_job
  • add_job
  • remove_job
  • start_job
  • stop_job

能力特点:

  • 文件读写受工作区边界保护
  • 命令执行走 CLI TerminalSkillbash 能力
  • TerminalSkill 默认启用沙盒模式,可通过 solonclaw.agent.tools.sandboxMode 控制
  • 定时任务会绑定最近一次外部会话路由
  • 心跳检查会读取 HEARTBEAT.md 并触发静默内部运行

sandboxMode 规则:

  • true:CLI 的 bash / ls / read / grep / glob 等能力只允许工作区相对路径、~/@skills 逻辑路径
  • true:禁止绝对路径,禁止通过 ../ 等方式越出工作区
  • true@skills 逻辑路径可读、可执行,但仍是只读挂载池
  • false:放开绝对路径访问,CLI 能力进入更开放模式

快速开始

1. 环境要求

  • JDK 8
  • Maven 3.9+
  • 推荐本地安装并启动 Ollama

2. 配置模型

开发环境可直接使用 src/main/resources/app-dev.yml 中的 Ollama 示例配置。

生产或本地自定义配置建议参考:

可在项目根目录创建 config.yml,注入你的模型与钉钉配置。

3. 编译与测试

mvn -q -DskipTests compile
mvn -q test

说明:

  • ChatModelConfigTest 在本地 Ollama 不可达时会自动跳过真实调用测试。

4. 启动应用

java -jar target/solonclaw.jar

或开发模式:

java -jar target/solonclaw.jar --env=dev

默认端口:

  • 12345

启动后可打开:

5. 一键复制的启动命令

如果你希望 README 里直接给出“先设置变量,再启动”的现成命令,可以直接使用下面这些示例。

PowerShell:

$env:APP_JAR="target/solonclaw.jar"
$env:APP_ENV="dev"
$env:APP_PORT="12345"
$env:APP_WORKSPACE="./workspace"
$env:APP_XMS="256m"
$env:APP_XMX="512m"

java `
  "-Xms$env:APP_XMS" `
  "-Xmx$env:APP_XMX" `
  "-Dserver.port=$env:APP_PORT" `
  "-Dsolonclaw.workspace=$env:APP_WORKSPACE" `
  -jar $env:APP_JAR `
  --env=$env:APP_ENV

Bash:

export APP_JAR="target/solonclaw.jar"
export APP_ENV="dev"
export APP_PORT="12345"
export APP_WORKSPACE="./workspace"
export JAVA_OPTS="-Xms256m -Xmx512m"

java ${JAVA_OPTS} \
  -Dserver.port="${APP_PORT}" \
  -Dsolonclaw.workspace="${APP_WORKSPACE}" \
  -jar "${APP_JAR}" \
  --env="${APP_ENV}"

生产环境示例:

export APP_JAR="target/solonclaw.jar"
export APP_ENV="prod"
export APP_PORT="12345"
export APP_WORKSPACE="./workspace"
export JAVA_OPTS="-Xms512m -Xmx1024m"

java ${JAVA_OPTS} \
  -Dserver.port="${APP_PORT}" \
  -Dsolonclaw.workspace="${APP_WORKSPACE}" \
  -jar "${APP_JAR}" \
  --env="${APP_ENV}"

配置说明

主配置文件:

  • src/main/resources/app.yml

当前关键项:

  • solonclaw.workspace=./workspace
  • solonclaw.agent.scheduler.maxConcurrentPerConversation=4
  • solonclaw.agent.scheduler.ackWhenBusy=false
  • solonclaw.agent.tools.sandboxMode=true
  • solonclaw.agent.heartbeat.enabled=true
  • solonclaw.agent.heartbeat.intervalSeconds=1800
  • solonclaw.channels.dingtalk.*

注意:

  • 仓库内不提交生产密钥
  • prod 环境默认追加加载根目录 ./config.yml

Docker 部署

仓库现在已经提供:

1. 构建镜像

docker build -t solonclaw:latest .

2. 准备宿主机文件

建议在项目根目录准备:

  • config.yml
  • workspace/

其中:

  • config.yml 用来放生产环境密钥、模型配置、钉钉配置
  • workspace/ 用来持久化运行时数据、记忆文件、技能和任务定义

可先参考:

3. 直接用 docker run 启动

docker run -d \
  --name solonclaw \
  -p 12345:12345 \
  -e JAVA_OPTS="-Xms256m -Xmx512m" \
  -e APP_ARGS="--env=prod" \
  -v "$(pwd)/workspace:/app/workspace" \
  -v "$(pwd)/config.yml:/app/config.yml:ro" \
  solonclaw:latest

Windows PowerShell:

docker run -d `
  --name solonclaw `
  -p 12345:12345 `
  -e JAVA_OPTS="-Xms256m -Xmx512m" `
  -e APP_ARGS="--env=prod" `
  -v "${PWD}/workspace:/app/workspace" `
  -v "${PWD}/config.yml:/app/config.yml:ro" `
  solonclaw:latest

说明:

  • 容器工作目录固定为 /app
  • APP_ARGS="--env=prod" 会启用 app.yml 中的 prod 段,并加载 /app/config.yml
  • workspace 目录挂载后,运行数据不会随容器删除而丢失

4. 使用 Docker Compose 启动

docker compose up -d --build

停止:

docker compose down

查看日志:

docker compose logs -f solonclaw

当前 docker-compose.yml 默认会:

  • 暴露端口 12345
  • 挂载 ./workspace/app/workspace
  • 挂载 ./config.yml/app/config.yml
  • --env=prod 启动应用

5. Docker Compose 文件说明

如果你需要自定义 JVM 参数或启动参数,可以直接修改 docker-compose.yml 里的环境变量:

  • JAVA_OPTS
  • APP_ARGS

例如:

environment:
  JAVA_OPTS: "-Xms512m -Xmx1024m"
  APP_ARGS: "--env=prod"

6. 容器部署建议

  • 生产环境务必挂载独立的 workspace 目录
  • 生产环境不要把真实密钥写进镜像
  • 如果使用本地 Ollama,请确保容器能访问你的模型服务地址
  • 如果要接钉钉,请在 config.yml 中补齐 clientIdclientSecretrobotCode

测试覆盖

当前测试已覆盖这些方向:

  • Solon 启动与 ChatModel 装配
  • 工作区模板初始化与提示词拼装
  • 工作区工具路径边界
  • 运行时文件落盘
  • 会话并发与忙时回执
  • 子任务派生、回流、聚合与按批次查询
  • 主动通知
  • 心跳静默执行
  • 钉钉入站转换与 markdown 发送参数
  • 定时任务持久化

开发约束

  • 新增渠道先抽象成 ChannelAdapter
  • 回复必须来自 ReplyTarget
  • 会话历史只能通过 RuntimeStoreService 维护
  • 长时资源优先接入 Solon 生命周期
  • 新增配置优先并入 SolonClawProperties
  • 调试能力优先复用现有 Debug Web
  • 不要把系统退回成全局串行队列
  • 实体类、DTO、事件载荷、结果对象、配置承载对象优先使用 Lombok 管理字段访问器;明确适合的类优先使用 @Data
  • 无参构造优先交给 Lombok 管理,这类数据类默认优先使用 @NoArgsConstructor
  • 需要持久化、序列化传输、缓存或作为稳定数据载体的类,应按需实现 Serializable
  • 尽量避免新增内部类;配置承载对象优先拆成独立类维护

PR 规范

建议所有 Pull Request 默认包含这些内容:

  • 背景
  • 改动内容
  • 影响范围
  • 验证方式
  • 风险与回滚

推荐模板:

## 背景
- 为什么要做这次修改

## 改动内容
- 这次具体改了什么

## 影响范围
- 涉及哪些模块、接口、配置或部署方式

## 验证方式
- 执行了哪些测试
- 做了哪些人工验证

## 风险与回滚
- 潜在风险是什么
- 出现问题如何回滚

附加要求:

  • 一个 PR 尽量只做一类改动
  • PR 标题与提交信息建议使用中英双语
  • 改动涉及配置或行为变化时,要同步更新文档

Commit 规范

提交信息默认采用 Conventional Commits 风格:

<type>(<scope>): <subject>

说明:

  • 冒号 : 后必须有一个空格
  • scope 选填,表示 commit 的作用范围,可以写模块名、目录名,或 runtimeworkspaceweb 这类职责范围
  • subject 必填,用于简短描述本次提交内容,建议使用中英双语

type 必填,允许值如下:

  • feat:新功能 feature
  • fix:修复 bug
  • docs:文档注释
  • style:代码格式(不影响代码运行的变动)
  • refactor:重构、优化(既不增加新功能,也不是修复 bug)
  • perf:性能优化
  • test:增加测试
  • chore:构建过程或辅助工具的变动
  • revert:回退
  • build:打包

推荐示例:

feat(agent): 增加了子任务聚合能力 (Add child-run aggregation)
docs(readme): 补充了提交信息格式说明 (Add commit message format notes)
fix(runtime): 修复了 continuation 丢失问题 (Fix continuation dispatch issue)

额外约定:

  • 默认按职责拆分 commit,优先拆成“提示词与上下文 / 运行时治理 / 配置默认值与注释 / 测试”这类最小修改单元
  • 尽量做到一个 commit 只解决一类问题,避免把无关改动混在一起

AI 辅助开发说明

本项目允许使用 AI 辅助编写代码和文档。

但需要明确:

  • AI 可以参与实现,不可以替代开发者责任
  • 所有 AI 参与生成的代码,都必须由开发者人工阅读
  • 所有待合并改动,都必须经过开发者人工测试和验证
  • 不能因为使用了 AI,就跳过 Review、测试或关键链路回归

建议至少完成与风险等级匹配的人工验证:

  • 本地编译
  • 单元测试或集成测试
  • 关键功能手工验证
  • 配置与部署检查

结论很简单:

  • 允许使用 AI 写代码
  • 不允许未经开发者人工测试和验证直接合并

更完整的仓库协作说明请阅读:

参考入口

License

当前仓库未单独声明许可证时,请以仓库实际发布方式和作者说明为准。

About

Java impl version of "OpenClaw(Clawdbot,Moltbot)"

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors