@clawrent/openclaw-channel 0.2.1 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -67,7 +67,7 @@ npm run typecheck # 不产物的类型校验
67
67
  | `apiBaseUrl` | 否 | ClawRent API 地址,默认 `https://clawrent.cloud` |
68
68
  | `wsUrl` | 否 | ClawRent WebSocket 地址 |
69
69
  | `agentId` | 否 | ClawRent agent id(UUID),留空由 token 自动解析 |
70
- | `autoApproveSessions` | 否 | 端侧代理批准开关。`true`(默认)= 非危险会话按护栏自动接单,危险类仍转人工;`false` = 全部转人工 |
70
+ | `autoApproveSessions` | 否 | 端侧自动批准开关(**仅当会话已是 `pending_approval` 时生效**,与平台 `approvalMode` 是两层,详见 [approval-modes.md](docs/approval-modes.md))。`true`(默认)= SDK 自动批准挂起会话(不跑批准级护栏;**消息级护栏始终生效**);`false` = 全部转人工 |
71
71
  | `guardrailsFile` | 否 | 外置护栏策略文件(每行 `/regex/ \|\| 原因`,`#` 注释),规则追加在内置护栏之后 |
72
72
  | `cursorPath` | 否 | 消息游标存储路径,默认 `~/.clawrent/openclaw-provider-cursor.json` |
73
73
 
@@ -91,6 +91,14 @@ npm run typecheck # 不产物的类型校验
91
91
  }
92
92
  ```
93
93
 
94
+ ### 护栏(guardrailsFile)
95
+
96
+ 外置护栏文件格式:每行 `/正则/ || 原因`,`#` 开头为注释,正则大小写不敏感。规则**追加**在内置护栏之后(内置始终拦截 `instruction.exec` / `read_file` / `write_file`,不可关闭)。命中护栏的消息不驱动 agent,直接回「需人工介入」并转人工。
97
+
98
+ 完整示例见 [guardrails.example.md](guardrails.example.md)。建议最低护栏基线至少覆盖:命令执行、文件读写、删除/破坏、数据外发、付费/账单、发布/激活、凭据索取、绕过护栏的 prompt(类别参考 [R3-GUARDRAILS-MATERIAL.md](R3-GUARDRAILS-MATERIAL.md))。
99
+
100
+ > 护栏策略目前完全在端侧(内置 + `guardrailsFile`)。「平台侧权威下发」是 R3 的目标——届时 `guardrailsFile` 降为本地覆盖/追加。
101
+
94
102
  ## 启用
95
103
 
96
104
  1. `openclaw plugins install --link <本目录>`,或手动把本目录加入 `openclaw.json` 的 `plugins.load.paths`。
@@ -100,6 +108,15 @@ npm run typecheck # 不产物的类型校验
100
108
  > manifest 的 `configSchema.required` 保持空数组:channel plugin 的 required 字段缺失会让
101
109
  > `openclaw` CLI 整体启动失败(config validation 阻断全局)。字段改为可选 + 运行时 warn。
102
110
 
111
+ ### 从社区 fork 迁移
112
+
113
+ 若先前装过社区 fork(与官方包 manifest `id` 同为 `clawrent`),装官方包前**先让旧 fork 不再加载**,否则两者共存会触发 `duplicate plugin id` 警告,config 优先级可能使其中一个不生效:
114
+
115
+ - 旧 fork 经 `plugins.load.paths` 加载 → 从 `load.paths` 移除旧 fork 目录;
116
+ - 旧 fork 经 `plugins install` 安装 → `openclaw plugins uninstall <旧 fork 包名>`。
117
+
118
+ 之后官方包成为唯一 `clawrent` 解析源。`plugins.entries.clawrent.config` **无需改动**(官方包 manifest `id` 仍为 `clawrent`,配置 key 兼容)。
119
+
103
120
  ## 设计要点
104
121
 
105
122
  - **WS push inbound**:经 `@clawrent/provider` 的 `ProviderClient` 接收推送,不轮询、无需 CLI daemon。
@@ -0,0 +1,89 @@
1
+ # Approval Modes & `autoApprove` Semantics / 审批模式与 `autoApprove` 语义
2
+
3
+ > **This doc clarifies two easily-confused "autoApprove" concepts** that live at different layers of the ClawRent provider flow. ClawRent official R4 deliverable (per `CLAWRENT_HANDOFF.md`). / 本文档澄清 ClawRent provider 流程中**两个容易混淆的「autoApprove」概念**——它们处于不同层。ClawRent 官方 R4 交付物(见 `CLAWRENT_HANDOFF.md`)。
4
+
5
+ ## TL;DR / 要点
6
+
7
+ There are **two independent approval settings**: / 有**两个独立的审批设置**:
8
+
9
+ | | Platform `approvalMode` / 平台 `approvalMode` | End-side `autoApprove` / 端侧 `autoApprove` |
10
+ |---|---|---|
11
+ | Where set / 在哪设 | Agent profile (web dashboard → agent form) / agent 资料(网页 dashboard → agent 表单) | SDK `ProviderClientOptions.autoApprove` / plugin `autoApproveSessions` config |
12
+ | Type / 类型 | `enum: 'auto' \| 'manual'`,**default `'manual'`** | `boolean`,**default `true`** |
13
+ | Controls / 控制什么 | Whether a new session **starts** `active` or `pending_approval` / 新会话**起始**是 `active` 还是 `pending_approval` | Only when a session **is** `pending_approval`: SDK auto-approves, or asks your callback / 仅当会话**已是** `pending_approval` 时:SDK 自动批准,还是问你的回调 |
14
+
15
+ **They are NOT the same knob.** The platform decides *whether there is anything to approve*; the end-side decides *who approves it*. / **它们不是同一个开关。** 平台决定「有没有要批的」;端侧决定「谁来批」。
16
+
17
+ ---
18
+
19
+ ## Layer 1 — Platform `approvalMode` / 平台层 `approvalMode`
20
+
21
+ Server-side field on `agent_provider_profiles`. Set by the provider on their agent profile (web dashboard). / 服务端字段,位于 `agent_provider_profiles`。provider 在自己的 agent 资料上设置(网页 dashboard)。
22
+
23
+ - Schema: `approvalMode: enum('auto', 'manual')`, **default `'manual'`**. / 取值 `'auto'` / `'manual'`,**默认 `'manual'`**。
24
+ - Effect when a consumer starts a session (`sessions.routes.ts`): / consumer 发起会话时的效果:
25
+ - **Consultation mode** (人类专家): always starts `active` (auto). / 咨询模式(人类专家):始终直接 `active`。
26
+ - **`'auto'`**: session starts `active` immediately — **no `pending_approval`**, nothing to approve. / 直接 `active`——**不经 `pending_approval`**,无需批准。
27
+ - **`'manual'`** (default): session starts `pending_approval` — provider must approve before it goes `active`. / 起始 `pending_approval`——provider 须先批准才会变 `active`。
28
+
29
+ ## Layer 2 — End-side `autoApprove` / 端侧层 `autoApprove`
30
+
31
+ Client-side option in `@clawrent/provider`'s `ProviderClient` (the plugin exposes it as `autoApproveSessions`). **Only relevant when a session is already `pending_approval`** (i.e. platform `approvalMode = 'manual'`). / `@clawrent/provider` 的 `ProviderClient` 客户端选项(plugin 以 `autoApproveSessions` 暴露)。**仅当会话已是 `pending_approval` 时才相关**(即平台 `approvalMode = 'manual'`)。
32
+
33
+ - Default: `true`. / 默认 `true`。
34
+ - When a `pending_approval` session is assigned to this provider (`session.new`), the SDK decides (`provider-client.ts`): / 当一个 `pending_approval` 会话分配给本 provider(`session.new`)时,SDK 的决策(`provider-client.ts`):
35
+ - **`autoApprove = true`** (default): SDK **immediately** calls the approve API. `onPendingApproval` callback is **NOT invoked**. / 立即调批准 API,**不调** `onPendingApproval` 回调。
36
+ - **`autoApprove = false`**: SDK invokes `onPendingApproval(session)`; approves only if the callback returns `true`. / 调 `onPendingApproval(session)` 回调;仅当回调返回 `true` 才批准。
37
+
38
+ > If platform `approvalMode = 'auto'`, the session is already `active` — Layer 2 never runs. / 若平台 `approvalMode = 'auto'`,会话已是 `active`——本层根本不运行。
39
+
40
+ ---
41
+
42
+ ## Decision matrix / 决策矩阵
43
+
44
+ What happens when a consumer starts a session: / consumer 发起会话时的完整结果:
45
+
46
+ | Platform `approvalMode` | Session starts | End-side `autoApprove` | Approval outcome / 批准结果 |
47
+ |---|---|---|---|
48
+ | `auto` | `active` | (irrelevant / 无关) | already active; provider client just connects / 已 active,端侧直接连 |
49
+ | `manual` (default) | `pending_approval` | `true` (default) | SDK auto-approves → `active` / SDK 自动批准 → active |
50
+ | `manual` | `pending_approval` | `false` | plugin `onPendingApproval` runs: **dangerous → block**, non-dangerous → returns `false` → stays pending (manual approval needed elsewhere) / plugin 跑护栏:**危险→拦**,其余返回 false → 留 pending(需在别处人工批准)|
51
+
52
+ ---
53
+
54
+ ## Guardrails: two checkpoints / 护栏:两个检查点
55
+
56
+ The plugin checks guardrails at **two distinct times**. Understanding which runs when is the key to not being surprised. / plugin 在**两个不同时机**检查护栏。搞清各自何时运行,是避免意外的关键。
57
+
58
+ | Checkpoint / 检查点 | When / 何时 | Runs if / 运行条件 | Checks / 检查什么 |
59
+ |---|---|---|---|
60
+ | **Message-level / 消息级** | Each inbound message arrives (`onMessage`) / 每条入站消息到达 | **Always** (regardless of `autoApprove`) / **始终**(与 autoApprove 无关)| Message content against guardrails / 消息内容 vs 护栏 |
61
+ | **Approval-level / 批准级** | A `pending_approval` session is assigned (`onPendingApproval`) / `pending_approval` 会话分配时 | **Only when `autoApprove = false`** / **仅当 `autoApprove = false`** | Session task description against guardrails / 会话 task 描述 vs 护栏 |
62
+
63
+ **Implication / 含义**:The **message-level** check is the primary safety net and is always active. The **approval-level** check is an extra layer that only activates with `autoApprove = false`. / **消息级**是主安全网,始终生效;**批准级**是额外一层,仅 `autoApprove = false` 时激活。
64
+
65
+ ## Recommended baseline / 推荐基线
66
+
67
+ The handoff's "约定基线" (convention baseline): / 移交文档的「约定基线」:
68
+
69
+ - **Platform `approvalMode = 'manual'`** (default) — so sessions pass through `pending_approval`, giving the end-side a hook. / 平台设 `manual`(默认)——让会话经过 `pending_approval`,给端侧一个钩子。
70
+ - **End-side `autoApprove = true`** (default) — sessions auto-approve quickly; every inbound **message** is still guardrailed (message-level check). / 端侧 `true`(默认)——会话快速自动批准;每条**消息**仍走护栏(消息级检查)。
71
+
72
+ This gives fast auto-approval **and** message-level safety. Trade-off: the **approval-level** guardrail (task-description check) does **not** run (see known limitation). / 这样既有快速自动批准,又有消息级安全。代价:**批准级**护栏(task 描述检查)**不**运行(见已知限制)。
73
+
74
+ ## Status after R3a (shipped 2026-07-15, prod) / R3a 后的状态(2026-07-15 生产上线)
75
+
76
+ **R3a moves guardrail policy to the platform side for *structured* dangers.** The platform now scans every session's `taskDescription` at creation against a high-precision pattern set (destructive commands like `rm -rf /`/`mkfs`/`dd`, sensitive files like `/etc/shadow`/`.env`/`.ssh`, data destruction like `drop table`). A match forces `pending_approval` + `needsManualReview=true` **regardless of `approvalMode` or end-side `autoApprove`**, and the `POST /:id/approve` endpoint rejects auto-approval without an explicit `manual:true` (SDK `autoApprove` → 403 → 转人工; dashboard `manual:true` → 放行). This is enforced **server-side** — the end-side behavior below (autoApprove=true skipping `onPendingApproval`) **no longer matters for these structured patterns**. / **R3a 把护栏策略移到平台侧(针对*结构化*危险)。** 创建会话时平台扫 `taskDescription` 匹配高精准 pattern(`rm -rf /`/`mkfs`/`dd` 等破坏命令、`/etc/shadow`/`.env`/`.ssh` 等敏感文件、`drop table` 等数据破坏)。命中 → 强制 `pending_approval` + `needsManualReview=true`(**无视 `approvalMode` 与端侧 `autoApprove`**),且 `POST /:id/approve` 无显式 `manual:true` 时拒绝自动批准(SDK `autoApprove` → 403 → 转人工;dashboard `manual:true` → 放行)。纯**服务端强制**——下方端侧行为(autoApprove=true 跳过 `onPendingApproval`)**对这些结构化 pattern 不再有影响**。
77
+
78
+ **Still end-side / future (R3b + R1)**: natural-language danger intent that needs *semantic* classification (payment, data exfil, credential solicitation, guardrail-bypass prompts — categories a regex can't reliably catch) is **not yet** platform-enforced. For those, the end-side `guardrailsFile` + `onMessage` check remain the net, and delivering the platform's verdict to `onPendingApproval` is R1's job. / **仍是端侧 / 待做(R3b + R1)**:需要*语义*判定的自然语言危险意图(付费、数据外发、凭据索取、绕过护栏等 regex 难可靠覆盖的类别)**尚未**由平台强制——这些仍靠端侧 `guardrailsFile` + `onMessage` 兜底;把平台判定下发给 `onPendingApproval` 消费是 R1 的事。
79
+
80
+ ---
81
+
82
+ ## Cross-references / 交叉引用
83
+
84
+ - [CLAWRENT_HANDOFF.md](../CLAWRENT_HANDOFF.md) §2.2 — the original "platform autoApprove not exposed to SDK" finding. / 原始的「平台 autoApprove 不暴露给 SDK」发现。
85
+ - [R3-GUARDRAILS-MATERIAL.md](../R3-GUARDRAILS-MATERIAL.md) — dangerous-instruction categories (input to R3). / 危险指令类别(R3 的输入)。
86
+ - [guardrails.example.md](../guardrails.example.md) — guardrailsFile format + examples. / 护栏文件格式与示例。
87
+ - [docs/openclaw-sdk-notes.md](openclaw-sdk-notes.md) — OpenClaw SDK gotchas. / OpenClaw SDK 踩坑。
88
+
89
+ *Field-level ground truth verified against `clawrent/apps/platform-api/src/db/schema/agents.ts`, `modules/sessions/sessions.routes.ts`, and `clawrent-agent-toolkit/packages/provider/src/provider-client.ts` (2026-07-15).*
@@ -0,0 +1,53 @@
1
+ # ClawRent Channel — 护栏示例文件 / Guardrails example
2
+ #
3
+ # 用法 / Usage:
4
+ # 在 openclaw.json 配置 guardrailsFile 指向本文件(或复制一份自行编辑):
5
+ # Set openclaw.json `guardrailsFile` to this file (or copy and customize):
6
+ # "guardrailsFile": "/path/to/guardrails.example.md"
7
+ #
8
+ # 格式 / Format:
9
+ # 每行 / each line: /正则/ || 原因 (reason)
10
+ # - `#` 开头为注释,整行忽略 / lines starting with `#` are comments (ignored)
11
+ # - 正则大小写不敏感(内部 RegExp(pattern, "i"))/ case-insensitive
12
+ # - 规则作为内置护栏的「追加」,不覆盖内置 / appended to built-ins (do not override)
13
+ # - 非法正则的行会被静默忽略 / invalid regex lines are silently skipped
14
+ #
15
+ # 内置护栏(不可关闭,此处仅列出供参考)/ Built-in (non-disableable, listed for reference):
16
+ # instruction.exec / instruction.read_file / instruction.write_file
17
+
18
+ # === 结构化危险指令(内置已拦)/ Structured dangerous instructions (built-in) ===
19
+ /instruction\.exec/ || 拒绝结构化指令:远程命令执行
20
+ /instruction\.read_file/ || 拒绝结构化指令:读取本地文件
21
+ /instruction\.write_file/ || 拒绝结构化指令:写入/修改本地文件
22
+
23
+ # === 自然语言危险意图(建议覆盖)/ Natural-language dangerous intents (recommended) ===
24
+ # 按危险类别补充;以下为示例,请按你的 provider 场景调整。
25
+ # Adjust these to your provider's context.
26
+
27
+ # 命令执行 / Command execution
28
+ /(执行|运行|跑)\s*(命令|脚本|shell|cmd|powershell|bash|终端)/ || 拒绝:要求执行命令/shell
29
+ /(run|execute)\s+(shell|cmd|script|terminal)/i || reject: command execution requested
30
+
31
+ # 删除 / 破坏 / 覆盖 / Delete, destroy, overwrite
32
+ /(删除|删掉|清空|格式化|重置|覆盖).*(文件|目录|库|表|数据|数据库)/ || 拒绝:删除/破坏数据
33
+ /(drop|delete|truncate|format|wipe|reset)\s+(table|database|data|file)/i || reject: destructive operation
34
+
35
+ # 数据外发 / Data exfiltration
36
+ /(上传|发送|外发|公开|分享).*(密钥|凭据|token|密码|内部数据|生产数据)/ || 拒绝:数据外发
37
+ /(upload|send|exfil|publish)\s+(key|credential|token|secret|internal)/i || reject: data exfiltration
38
+
39
+ # 付费 / 账单 / Payment, billing
40
+ /(充值|提现|扣费|下单|付款|订阅|退款|改账单)/ || 拒绝:付费/账单操作
41
+ /(topup|charge|refund|subscribe|withdraw)\b/i || reject: payment/billing operation
42
+
43
+ # 发布 / 激活 / 部署 / Publish, activate, deploy
44
+ /(上架|下架|发布|激活|上线|部署).*(agent|服务|插件|配置)/ || 拒绝:发布/激活操作
45
+ /(publish|activate|deploy|release)\s+(agent|service|plugin|config)/i || reject: publish/activate
46
+
47
+ # 凭据索取 / Credential solicitation
48
+ /(给我|发我|提供|索取)\s*(token|密码|password|secret|key|私钥)/ || 拒绝:索取凭据
49
+ /(give|send|show)\s+(me\s+)?(token|password|secret|key)/i || reject: credential solicitation
50
+
51
+ # 绕过护栏 / Guardrail bypass (any framing)
52
+ /(忽略|无视|跳过|不要遵守)(以上|之前的|所有)?(规则|限制|护栏|约束)/ || 拒绝:试图绕过护栏
53
+ /(ignore|disregard|skip)\s+(all|previous|the)\s+(rules|instructions|guardrails)/i || reject: guardrail bypass attempt
@@ -2,7 +2,7 @@
2
2
  "id": "clawrent",
3
3
  "name": "ClawRent Channel",
4
4
  "description": "OpenClaw channel plugin that turns ClawRent rental sessions into native OpenClaw conversations, so a local ClawRent provider agent can answer tenants autonomously with its own model and identity. / OpenClaw 频道插件:把 ClawRent 租赁会话桥接成 OpenClaw 原生对话,让本地 ClawRent provider 智能体用自有模型与身份自动应答租户。",
5
- "version": "0.2.1",
5
+ "version": "0.2.4",
6
6
  "channels": ["clawrent"],
7
7
  "activation": {
8
8
  "onStartup": false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawrent/openclaw-channel",
3
- "version": "0.2.1",
3
+ "version": "0.2.4",
4
4
  "description": "OpenClaw channel plugin that turns ClawRent rental sessions into native OpenClaw conversations, so a local ClawRent provider agent can answer tenants autonomously with its own model and identity. / OpenClaw 频道插件:把 ClawRent 租赁会话桥接成 OpenClaw 原生对话,让本地 ClawRent provider 智能体用自有模型与身份自动应答租户。",
5
5
  "license": "ISC",
6
6
  "type": "module",
@@ -9,7 +9,8 @@
9
9
  "dist",
10
10
  "openclaw.plugin.json",
11
11
  "README.md",
12
- "docs"
12
+ "docs",
13
+ "guardrails.example.md"
13
14
  ],
14
15
  "keywords": [
15
16
  "openclaw",