Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,27 @@ jobs:

- name: Validate EC600 protocol template (draft)
run: |
TEMPLATE_FILE="$(find local-docs -maxdepth 3 -type f -name 'EC600_PROTOCOL_MAPPING_TEMPLATE.md' | head -n 1)"
if [ -z "${TEMPLATE_FILE}" ]; then
echo "No EC600 protocol template found under local-docs/, skip draft validation."
exit 0
fi
python -m opencane.hardware.validate_protocol \
--mapping local-docs/nanobot-legacy/EC600_PROTOCOL_MAPPING_TEMPLATE.md \
--mapping "${TEMPLATE_FILE}" \
--stage draft

- name: Validate EC600 frozen mapping (freeze gate)
run: |
TEMPLATE_FILE="$(find local-docs -maxdepth 3 -type f -name 'EC600_PROTOCOL_MAPPING_TEMPLATE.md' | head -n 1)"
DEFERRED_FILE="$(find local-docs -maxdepth 3 -type f -name 'HARDWARE_JOINT_DEBUG_DEFERRED.md' | head -n 1)"
if [ -f "EC600_PROTOCOL_MAPPING_V1.md" ]; then
python -m opencane.hardware.validate_protocol \
--mapping EC600_PROTOCOL_MAPPING_V1.md \
--stage freeze
elif grep -q "当前状态:\`Frozen\`" local-docs/nanobot-legacy/EC600_PROTOCOL_MAPPING_TEMPLATE.md; then
elif [ -n "${TEMPLATE_FILE}" ] && grep -q "当前状态:\`Frozen\`" "${TEMPLATE_FILE}"; then
echo "Template is Frozen but EC600_PROTOCOL_MAPPING_V1.md is missing."
exit 1
elif grep -q "状态:\`Deferred\`" local-docs/nanobot-legacy/HARDWARE_JOINT_DEBUG_DEFERRED.md; then
elif [ -n "${DEFERRED_FILE}" ] && grep -q "状态:\`Deferred\`" "${DEFERRED_FILE}"; then
echo "Freeze gate deferred by HARDWARE_JOINT_DEBUG_DEFERRED.md"
else
echo "EC600 freeze gate requires EC600_PROTOCOL_MAPPING_V1.md or an explicit Deferred marker."
Expand Down
34 changes: 14 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,20 +75,17 @@ opencane hardware serve --adapter mock --logs
- Security Baseline: `docs/security.md`
- Roadmap: `docs/roadmap.md`

### NanoBot Compatibility and Migration
### OpenCane Runtime Conventions

- Primary CLI command is `opencane`, with `nanobot` alias compatibility
- Project branding and product docs are now OpenCane
- Python package/import path uses `opencane` (no longer supports `from nanobot...`)
- Default data directory is `~/.opencane`, with backward-compatible reads from `~/.nanobot`
- Migration guide: `docs/migration-from-nanobot.md`
- Legacy nanobot docs are archived at: `local-docs/nanobot-legacy/`
- Archive README: `local-docs/nanobot-legacy/README.md`
- Primary CLI command: `opencane`
- Python package/import path: `opencane`
- Default data directory: `~/.opencane`
- Local internal docs directory: `local-docs/`

### Acknowledgement

OpenCane is continuously developed based on [HKUDS/nanobot](https://github.com/HKUDS/nanobot).
Thanks to HKUDS for the open-source foundation.
OpenCane is continuously evolved from an upstream open-source foundation by HKUDS.
Thanks to HKUDS for the original engineering base.

---

Expand Down Expand Up @@ -164,17 +161,14 @@ opencane hardware serve --adapter mock --logs
- 安全基线:`docs/security.md`
- 路线图:`docs/roadmap.md`

### NanoBot 兼容与迁移
### OpenCane 运行约定

- CLI 主命令为 `opencane`,并兼容 `nanobot` 别名
- 项目品牌与产品文档已切换为 OpenCane
- Python 包与导入路径:使用 `opencane`(不再支持 `from nanobot...`)
- 数据目录:默认 `~/.opencane`,兼容读取历史 `~/.nanobot`
- 迁移说明:`docs/migration-from-nanobot.md`
- 旧版 nanobot 历史文档已归档到:`local-docs/nanobot-legacy/`
- 归档说明见:`local-docs/nanobot-legacy/README.md`
- CLI 主命令:`opencane`
- Python 包与导入路径:`opencane`
- 默认数据目录:`~/.opencane`
- 本地内部文档目录:`local-docs/`

### 致谢

本项目基于 [HKUDS/nanobot](https://github.com/HKUDS/nanobot) 进行持续开发与场景化演进
感谢 HKUDS 团队开源 nanobot,为 OpenCane 的落地提供了坚实基础
本项目基于 HKUDS 的上游开源基础进行持续开发与场景化演进
感谢 HKUDS 团队提供的原始工程基础
9 changes: 4 additions & 5 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
## 当前状态(2026-02-21)

- 代码包名已完成迁移:`opencane`
- CLI 主命令:`opencane`(兼容 `nanobot` 别名)
- 默认数据目录:`~/.opencane`(兼容读取 `~/.nanobot`)
- 历史文档已归档到本地目录:`../local-docs/nanobot-legacy/`
- CLI 主命令:`opencane`
- 默认数据目录:`~/.opencane`
- 历史文档已归档到本地目录:`../local-docs/`

## 阅读顺序

Expand Down Expand Up @@ -36,8 +36,7 @@
- 运维手册: `operations-runbook.md`
- 安全基线: `security.md`
- 路线图: `roadmap.md`
- 迁移说明: `migration-from-nanobot.md`

## 历史文档归档

- 旧版 nanobot 文档: `../local-docs/nanobot-legacy/`
- 本地历史文档目录: `../local-docs/`
53 changes: 0 additions & 53 deletions docs/migration-from-nanobot.md

This file was deleted.

13 changes: 4 additions & 9 deletions docs/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,13 @@ OpenCane 是“AI Agent 平台能力 + 智能盲杖后端能力”的统一工
- OTA 固件发布平台
- 多租户控制平面 SaaS

## 3. 运行接口与兼容边界
## 3. 运行接口

项目品牌已切换为 OpenCane,但以下运行接口仍保持兼容
当前运行接口如下

- Python 包/导入:`opencane`
- CLI:`opencane ...`(兼容 `nanobot` 别名)
- 默认配置路径:`~/.opencane/config.json`(兼容读取 `~/.nanobot/config.json`)

不在兼容范围内:

- `python -m nanobot`
- `from nanobot...` 导入路径
- CLI:`opencane ...`
- 默认配置路径:`~/.opencane/config.json`

## 4. 文档使用方式

Expand Down
4 changes: 1 addition & 3 deletions docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ pip install -e .
opencane onboard
```

如本机已有旧版 `~/.nanobot/config.json`,运行时会自动兼容读取。

生成默认配置后,建议直接应用预设模板:

```bash
Expand Down Expand Up @@ -74,7 +72,7 @@ opencane hardware serve --adapter generic_mqtt --logs

说明:

- `opencane` 为主命令;`nanobot` 作为 CLI 别名可继续使用
- `opencane` 为主命令
- Python 包导入路径请统一使用 `opencane`

## 7. 常用调试命令
Expand Down
Binary file removed nanobot_arch.png
Binary file not shown.
Binary file removed nanobot_logo.png
Binary file not shown.
12 changes: 6 additions & 6 deletions opencane/channels/dingtalk.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@
ChatbotMessage = None # type: ignore[assignment,misc]


class NanobotDingTalkHandler(CallbackHandler):
class OpenCaneDingTalkHandler(CallbackHandler):
"""
Standard DingTalk Stream SDK Callback Handler.
Parses incoming messages and forwards them to the Nanobot channel.
Parses incoming messages and forwards them to the OpenCane channel.
"""

def __init__(self, channel: "DingTalkChannel"):
Expand Down Expand Up @@ -67,7 +67,7 @@ async def process(self, message: CallbackMessage):

logger.info(f"Received DingTalk message from {sender_name} ({sender_id}): {content}")

# Forward to Nanobot via _on_message (non-blocking).
# Forward to OpenCane via _on_message (non-blocking).
# Store reference to prevent GC before task completes.
task = asyncio.create_task(
self.channel._on_message(content, sender_id, sender_name)
Expand Down Expand Up @@ -132,7 +132,7 @@ async def start(self) -> None:
self._client = DingTalkStreamClient(credential)

# Register standard handler
handler = NanobotDingTalkHandler(self)
handler = OpenCaneDingTalkHandler(self)
self._client.register_callback_handler(ChatbotMessage.TOPIC, handler)

logger.info("DingTalk bot started with Stream Mode")
Expand Down Expand Up @@ -207,7 +207,7 @@ async def send(self, msg: OutboundMessage) -> None:
"msgKey": "sampleMarkdown",
"msgParam": json.dumps({
"text": msg.content,
"title": "Nanobot Reply",
"title": "OpenCane Reply",
}),
}

Expand All @@ -225,7 +225,7 @@ async def send(self, msg: OutboundMessage) -> None:
logger.error(f"Error sending DingTalk message: {e}")

async def _on_message(self, content: str, sender_id: str, sender_name: str) -> None:
"""Handle incoming message (called by NanobotDingTalkHandler).
"""Handle incoming message (called by OpenCaneDingTalkHandler).

Delegates to BaseChannel._handle_message() which enforces allow_from
permission checks before publishing to the bus.
Expand Down
2 changes: 1 addition & 1 deletion scripts/run_control_api_smoke_ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ set -euo pipefail
CONTROL_API_HOST="${CONTROL_API_HOST:-127.0.0.1}"
CONTROL_API_PORT="${CONTROL_API_PORT:-18792}"
CONTROL_API_BASE="http://${CONTROL_API_HOST}:${CONTROL_API_PORT}"
SERVER_LOG="${SERVER_LOG:-/tmp/nanobot_mock_control_api.log}"
SERVER_LOG="${SERVER_LOG:-/tmp/opencane_mock_control_api.log}"

echo "starting mock control api server at ${CONTROL_API_BASE}"
python3 scripts/mock_control_api_server.py \
Expand Down