openclaw-lark-multi-agent 1.4.4 → 1.4.6
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 +33 -15
- package/README.zh-CN.md +8 -0
- package/dist/cli.js +4 -4
- package/dist/compact-progress.d.ts +4 -4
- package/dist/compact-progress.js +5 -5
- package/dist/feishu-bot.d.ts +19 -9
- package/dist/feishu-bot.js +214 -94
- package/dist/openclaw-client.d.ts +35 -25
- package/dist/openclaw-client.js +400 -158
- package/package.json +2 -2
- package/plugins/lma-steer/README.md +23 -30
- package/dist/session-file-compactor.d.ts +0 -39
- package/dist/session-file-compactor.js +0 -176
package/README.md
CHANGED
|
@@ -99,22 +99,20 @@ On Windows, install [NSSM](https://nssm.cc/download), make sure `nssm.exe` is in
|
|
|
99
99
|
lma install-windows-service
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
-
###
|
|
102
|
+
### Real-time steering
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
When the agent is mid-run and a new message arrives, the bridge submits it via
|
|
105
|
+
OpenClaw's public `chat.send` API with `queueMode: "steer"`. The RPC
|
|
106
|
+
acknowledgment is provisional: LMA retains its durable pending trigger until a
|
|
107
|
+
matching `session.message` proves transcript commitment/consumption, and only
|
|
108
|
+
then switches Feishu from Typing to Get. Async `error`/`aborted` terminals are
|
|
109
|
+
routed by run id, while unconsumed input remains available for normal queue
|
|
110
|
+
fallback. This replaces the deprecated synchronous plugin primitive whose
|
|
111
|
+
boolean could not represent later runtime rejection.
|
|
106
112
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
systemctl --user restart openclaw-gateway.service
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
When the agent is mid-run and a new message arrives, the bridge injects it into
|
|
114
|
-
the active run at the next tool-call boundary (Feishu shows the "Get" reaction).
|
|
115
|
-
Without the plugin, the bridge falls back to queuing the message until the run
|
|
116
|
-
finishes — everything still works, just without real-time steering. See
|
|
117
|
-
`plugins/lma-steer/README.md` for details.
|
|
113
|
+
OpenClaw 2026.8+ no longer requires the bundled `lma-steer` plugin. The
|
|
114
|
+
`install-steer-plugin` command remains temporarily for older installations but
|
|
115
|
+
current LMA releases do not call its private Gateway method.
|
|
118
116
|
|
|
119
117
|
Useful CLI commands:
|
|
120
118
|
|
|
@@ -124,7 +122,7 @@ lma doctor
|
|
|
124
122
|
lma start [config]
|
|
125
123
|
lma init [--state-dir DIR] [--force]
|
|
126
124
|
lma install-systemd [--user|--system] [--state-dir DIR]
|
|
127
|
-
lma install-steer-plugin [--no-force]
|
|
125
|
+
lma install-steer-plugin [--no-force] # legacy; not needed on OpenClaw 2026.8+
|
|
128
126
|
```
|
|
129
127
|
|
|
130
128
|
## Quick start from source
|
|
@@ -450,6 +448,26 @@ Assistant replies are sent as Feishu CardKit v2 cards. Markdown is preprocessed
|
|
|
450
448
|
|
|
451
449
|
For generated files/images/documents, agents should use the bridge attachment marker protocol instead of calling Feishu messaging tools directly. The bridge strips the marker from the visible reply, validates the file path under the configured attachment directory, uploads/sends the attachment, and records it in local context. Markdown documents can be converted into Feishu cloud documents through this path.
|
|
452
450
|
|
|
451
|
+
## OpenClaw 2026.8 compatibility
|
|
452
|
+
|
|
453
|
+
LMA targets Gateway protocol 4 and is built/tested against `openclaw@2026.8.2`.
|
|
454
|
+
OpenClaw 2026.8 moves active session rows and transcripts into the per-agent
|
|
455
|
+
SQLite database. LMA never opens that database or rewrites archived JSONL:
|
|
456
|
+
`/compact` first requests semantic `sessions.compact`, then uses the same
|
|
457
|
+
Gateway RPC with a bounded `maxLines` tail only if semantic compaction cannot
|
|
458
|
+
run. Set `OPENCLAW_LARK_MULTI_AGENT_COMPACT_FALLBACK_MAX_LINES` to change the
|
|
459
|
+
default tail size (`200`, minimum `20`).
|
|
460
|
+
|
|
461
|
+
OpenClaw 2026.8 also separates model metadata from the override allowlist. Every
|
|
462
|
+
model configured in LMA must be permitted by `agents.defaults.modelPolicy.allow`
|
|
463
|
+
when that list is non-empty. Exact refs and `provider/*` wildcards are accepted.
|
|
464
|
+
LMA now surfaces a model-policy rejection instead of logging a false “model
|
|
465
|
+
ensured” success.
|
|
466
|
+
|
|
467
|
+
Mid-run messages use the public `chat.send { queueMode: "steer" }` path. LMA
|
|
468
|
+
keeps the durable trigger until `session.message` confirms consumption; this is
|
|
469
|
+
also the signal for the visible Typing-to-Get transition.
|
|
470
|
+
|
|
453
471
|
## Live status
|
|
454
472
|
|
|
455
473
|
In non-verbose mode, each run shows a single self-updating Feishu interactive
|
package/README.zh-CN.md
CHANGED
|
@@ -408,6 +408,14 @@ v1 行为边界:如果消息已经进入 OpenClaw 正在处理,暂不 abort
|
|
|
408
408
|
|
|
409
409
|
如果 Agent 需要发送生成的文件、图片或文档,应使用 bridge attachment marker 协议,而不是直接调用飞书消息工具。桥接层会从可见回复中剥离 marker,校验文件路径位于配置的附件目录下,然后上传/发送附件,并写入本地上下文。Markdown 文档也可以通过这个路径转换成飞书云文档。
|
|
410
410
|
|
|
411
|
+
## OpenClaw 2026.8 兼容性
|
|
412
|
+
|
|
413
|
+
LMA 以 Gateway protocol 4 为基线,并使用 `openclaw@2026.8.2` 构建和测试。OpenClaw 2026.8 把活动 session row 与 transcript 迁入每个 Agent 的 SQLite 数据库。LMA 不再直接查找或改写 JSONL:`/compact` 先调用语义化 `sessions.compact`,如果语义压缩无法执行,再通过同一个 Gateway RPC 的 `maxLines` 安全保留最近一段转录。可用 `OPENCLAW_LARK_MULTI_AGENT_COMPACT_FALLBACK_MAX_LINES` 调整默认保留数量(默认 `200`,最小 `20`)。
|
|
414
|
+
|
|
415
|
+
新版把模型元数据与模型覆盖允许列表分开。如果 `agents.defaults.modelPolicy.allow` 非空,LMA 配置中的每个模型都必须被该列表的精确模型引用或 `provider/*` 通配符允许。遇到拒绝时,LMA 会直接报告 model policy 错误,不再错误记录“模型已确保”。
|
|
416
|
+
|
|
417
|
+
执行中插入的消息改用公开的 `chat.send { queueMode: "steer" }`。RPC 成功返回只是暂时接受;LMA 会继续保留本地 pending trigger,只有匹配的 `session.message` 确认消息已写入转录并被消费后才清除,同时把飞书标记从 Typing 切换为 Get。异步 `error`/`aborted` 按 runId 投递,未消费的输入仍由普通队列兜底。这样不再依赖无法表达后续异步拒绝的旧同步插件原语。
|
|
418
|
+
|
|
411
419
|
## Live Status 与最终回复
|
|
412
420
|
|
|
413
421
|
非 verbose 模式下,执行过程显示一张可更新的 live status 卡片。运行中显示最近活动和耗时;完成后收缩为“累计工具调用次数 + 总耗时”。
|
package/dist/cli.js
CHANGED
|
@@ -206,12 +206,12 @@ function runCapture(cmd, args) {
|
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
208
|
/**
|
|
209
|
-
* Install the bundled lma-steer
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
* ships inside this package under plugins/lma-steer (built to dist).
|
|
209
|
+
* Install the legacy bundled lma-steer plugin. Current LMA uses OpenClaw's
|
|
210
|
+
* public `chat.send { queueMode: "steer" }` API and does not call this plugin;
|
|
211
|
+
* the command remains only for operators maintaining older LMA deployments.
|
|
213
212
|
*/
|
|
214
213
|
function cmdInstallSteerPlugin(args) {
|
|
214
|
+
console.warn("Note: current LMA releases use native chat.send queueMode=steer; this legacy plugin is not required on OpenClaw 2026.8+.");
|
|
215
215
|
// Default to --force so reinstalling an updated bundled plugin overwrites the
|
|
216
216
|
// previously installed copy. Pass --no-force to keep an existing install.
|
|
217
217
|
const noForce = hasFlag(args, "--no-force");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Coarse phase of the compaction flow, drives the card's primary line. */
|
|
2
|
-
export type CompactPhase = "native" | "
|
|
2
|
+
export type CompactPhase = "native" | "transcript-trim";
|
|
3
3
|
/** Terminal outcome used by the renderer to pick color/emoji. */
|
|
4
4
|
export type CompactState = "running" | "done" | "failed" | "noop";
|
|
5
5
|
/** Structured snapshot the renderer turns into a Feishu interactive card. */
|
|
@@ -27,7 +27,7 @@ export type CompactProgressOptions = {
|
|
|
27
27
|
tickMs?: number;
|
|
28
28
|
};
|
|
29
29
|
/**
|
|
30
|
-
* Lifecycle: start() → (optional)
|
|
30
|
+
* Lifecycle: start() → (optional) toTranscriptTrim() when native gives up → one of
|
|
31
31
|
* done()/noop()/fail(). The card is created lazily after `delayMs` so a fast
|
|
32
32
|
* compaction that finishes first never shows a card at all. All terminal calls
|
|
33
33
|
* are idempotent and safe even if the card was never created.
|
|
@@ -50,8 +50,8 @@ export declare class CompactProgressController {
|
|
|
50
50
|
get id(): string | undefined;
|
|
51
51
|
/** Begin the flow; schedules lazy card creation after delayMs. */
|
|
52
52
|
start(): void;
|
|
53
|
-
/** Native compaction gave up
|
|
54
|
-
|
|
53
|
+
/** Native compaction gave up; switch to Gateway-owned transcript-tail trim. */
|
|
54
|
+
toTranscriptTrim(): Promise<void>;
|
|
55
55
|
/** Finished successfully; patch the card to the done state with a detail line. */
|
|
56
56
|
done(detail?: string): Promise<void>;
|
|
57
57
|
/** Nothing to compact; patch the card to a neutral "no-op" state. */
|
package/dist/compact-progress.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
const DEFAULT_DELAY_MS = Number(process.env.OPENCLAW_LARK_MULTI_AGENT_COMPACT_STATUS_DELAY_MS || 500);
|
|
11
11
|
const DEFAULT_TICK_MS = Number(process.env.OPENCLAW_LARK_MULTI_AGENT_COMPACT_STATUS_TICK_MS || 1000);
|
|
12
12
|
/**
|
|
13
|
-
* Lifecycle: start() → (optional)
|
|
13
|
+
* Lifecycle: start() → (optional) toTranscriptTrim() when native gives up → one of
|
|
14
14
|
* done()/noop()/fail(). The card is created lazily after `delayMs` so a fast
|
|
15
15
|
* compaction that finishes first never shows a card at all. All terminal calls
|
|
16
16
|
* are idempotent and safe even if the card was never created.
|
|
@@ -45,11 +45,11 @@ export class CompactProgressController {
|
|
|
45
45
|
}, this.opts.delayMs ?? DEFAULT_DELAY_MS);
|
|
46
46
|
this.createTimer.unref?.();
|
|
47
47
|
}
|
|
48
|
-
/** Native compaction gave up
|
|
49
|
-
async
|
|
50
|
-
if (this.finalized || this.phase === "
|
|
48
|
+
/** Native compaction gave up; switch to Gateway-owned transcript-tail trim. */
|
|
49
|
+
async toTranscriptTrim() {
|
|
50
|
+
if (this.finalized || this.phase === "transcript-trim")
|
|
51
51
|
return;
|
|
52
|
-
this.phase = "
|
|
52
|
+
this.phase = "transcript-trim";
|
|
53
53
|
await this.refresh();
|
|
54
54
|
}
|
|
55
55
|
/** Finished successfully; patch the card to the done state with a detail line. */
|
package/dist/feishu-bot.d.ts
CHANGED
|
@@ -46,8 +46,15 @@ export declare class FeishuBot {
|
|
|
46
46
|
private lastRealDeliveryAt;
|
|
47
47
|
/** Per-chat: whether we've already sent the high-context alert this cycle. */
|
|
48
48
|
private contextAlerted;
|
|
49
|
-
/** Active
|
|
49
|
+
/** Active pre-admission target for the current chat operation. */
|
|
50
50
|
private activeDeliveryTargets;
|
|
51
|
+
/** Stable targets for concurrent runs in one chat. A steer admission can
|
|
52
|
+
* become an ordinary run while another run remains active. */
|
|
53
|
+
private deliveryTargetsByRun;
|
|
54
|
+
/** Provisional native-steer correlations keyed by durable message row. If the
|
|
55
|
+
* message falls back to a normal run, cancel these before submission so a
|
|
56
|
+
* later identical steer cannot consume the stale observer/correlation. */
|
|
57
|
+
private pendingSteerCleanups;
|
|
51
58
|
private adminOpenId;
|
|
52
59
|
private locale;
|
|
53
60
|
private configPath?;
|
|
@@ -181,6 +188,9 @@ export declare class FeishuBot {
|
|
|
181
188
|
*/
|
|
182
189
|
private autoRetryUntilComplete;
|
|
183
190
|
private cancelDelayedFailure;
|
|
191
|
+
private deliveryRunTargetKey;
|
|
192
|
+
private bindRunDeliveryTarget;
|
|
193
|
+
private releaseRunDeliveryTargetAfter;
|
|
184
194
|
private setActiveDeliveryTarget;
|
|
185
195
|
private scheduleDelayedFailure;
|
|
186
196
|
private deliverySessionKey;
|
|
@@ -305,14 +315,14 @@ export declare class FeishuBot {
|
|
|
305
315
|
* Handle /compact command: compress session context.
|
|
306
316
|
*/
|
|
307
317
|
/**
|
|
308
|
-
* Compact a session with a fallback chain:
|
|
309
|
-
* 1.
|
|
310
|
-
* 2. If
|
|
311
|
-
*
|
|
312
|
-
*
|
|
313
|
-
*
|
|
314
|
-
*
|
|
315
|
-
*
|
|
318
|
+
* Compact a session with a Gateway-owned fallback chain:
|
|
319
|
+
* 1. Semantic compaction through `sessions.compact`.
|
|
320
|
+
* 2. If summarization cannot run, ask the same RPC to retain only a bounded
|
|
321
|
+
* transcript tail via `maxLines`. This works with legacy JSONL and the
|
|
322
|
+
* SQLite session store introduced in OpenClaw 2026.8.x, and preserves
|
|
323
|
+
* OpenClaw's write locks, transcript invariants, and migration ownership.
|
|
324
|
+
*
|
|
325
|
+
* LMA deliberately never opens or rewrites OpenClaw transcript storage.
|
|
316
326
|
*/
|
|
317
327
|
private compactWithFallback;
|
|
318
328
|
private handleCompactCommand;
|