@clawrent/openclaw-channel 0.2.2 → 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
 
@@ -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).*
@@ -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.2",
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.2",
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",