@clawling/clawchat-plugin-openclaw 2026.9.13-3 → 2026.9.14-2
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/dist/src/client.js +2 -0
- package/dist/src/runtime.js +19 -1
- package/dist/src/ws-client.js +1 -0
- package/package.json +1 -1
- package/src/client.ts +2 -0
- package/src/protocol-types.ts +2 -0
- package/src/runtime.ts +21 -1
- package/src/ws-client.ts +4 -0
package/dist/src/client.js
CHANGED
|
@@ -3,6 +3,7 @@ import os from "node:os";
|
|
|
3
3
|
import { createClawChatClient } from "./ws-client.js";
|
|
4
4
|
import { CHANNEL_ID } from "./config.js";
|
|
5
5
|
import { resolveStateDirFromEnv } from "./state-paths.js";
|
|
6
|
+
import { resolvePluginVersion } from "./plugin-report.js";
|
|
6
7
|
/**
|
|
7
8
|
* Derive this instance's `device_id` from stable, per-instance material.
|
|
8
9
|
*
|
|
@@ -35,6 +36,7 @@ export function createOpenclawClawlingClient(account, overrides = {}) {
|
|
|
35
36
|
url: account.websocketUrl,
|
|
36
37
|
token: account.token,
|
|
37
38
|
deviceId,
|
|
39
|
+
clientVersion: resolvePluginVersion(),
|
|
38
40
|
...(overrides.transport ? { transport: overrides.transport } : {}),
|
|
39
41
|
reconnect: {
|
|
40
42
|
enabled: true,
|
package/dist/src/runtime.js
CHANGED
|
@@ -2373,7 +2373,22 @@ export async function startOpenclawClawlingGateway(params) {
|
|
|
2373
2373
|
log?.info?.(`[${accountId}] clawchat-plugin-openclaw skip duplicate stored msg=${turn.messageId}`);
|
|
2374
2374
|
return "skipped";
|
|
2375
2375
|
}
|
|
2376
|
+
if (claimed !== true) {
|
|
2377
|
+
// Fail closed: a claim that could not be decided (store disabled, SQLite
|
|
2378
|
+
// error, a throw converted to undefined by recordConnection) must not
|
|
2379
|
+
// dispatch. Live delivery and device replay can carry the same message,
|
|
2380
|
+
// and the outbound reply path (outbound.ts / reply-dispatcher.ts) already
|
|
2381
|
+
// refuses to send without a claim — so dispatching here only re-ran the
|
|
2382
|
+
// LLM/tools without delivering, or double-replied. Logged at error level
|
|
2383
|
+
// with reason=claim_unavailable so a store outage is visible and is not
|
|
2384
|
+
// mistaken for dedup. Accepted cost: a one-off transient claim failure
|
|
2385
|
+
// drops that message.
|
|
2386
|
+
log?.error?.(`[${accountId}] clawchat-plugin-openclaw inbound skipped msg=${turn.messageId} chat_id=${turn.peer.id} event=${String(env.event)} reason=claim_unavailable result=${String(claimed)}`);
|
|
2387
|
+
return "skipped";
|
|
2388
|
+
}
|
|
2376
2389
|
}
|
|
2390
|
+
// No store wired at all (injected test transport, or store construction
|
|
2391
|
+
// threw at startup — which is itself logged) keeps the store-less pass-through.
|
|
2377
2392
|
return "claimed";
|
|
2378
2393
|
};
|
|
2379
2394
|
const dispatchTurnToAgent = async (turn) => {
|
|
@@ -2730,7 +2745,10 @@ export async function startOpenclawClawlingGateway(params) {
|
|
|
2730
2745
|
// replayed — permanently lost. Claiming first makes it durable; the abort
|
|
2731
2746
|
// check below then returns without dispatching, but the frame is kept.
|
|
2732
2747
|
// `claimInboundTurn` is INSERT OR IGNORE, so a genuine duplicate (same
|
|
2733
|
-
// message_id) is still deduped here exactly once.
|
|
2748
|
+
// message_id) is still deduped here exactly once. The claim fails CLOSED:
|
|
2749
|
+
// only a successful claim proceeds; an undecided claim (store unavailable)
|
|
2750
|
+
// skips with reason=claim_unavailable, because outbound replies also refuse
|
|
2751
|
+
// to send without a claim, so dispatching would only waste the turn.
|
|
2734
2752
|
const claimed = claimInboundTurn(turn);
|
|
2735
2753
|
if (claimed === "skipped")
|
|
2736
2754
|
return "skipped";
|
package/dist/src/ws-client.js
CHANGED
|
@@ -664,6 +664,7 @@ export class ClawChatClient extends EventEmitter {
|
|
|
664
664
|
token: this.opts.token,
|
|
665
665
|
nonce,
|
|
666
666
|
...(this.opts.deviceId ? { device_id: this.opts.deviceId } : {}),
|
|
667
|
+
...(this.opts.clientVersion ? { client_version: this.opts.clientVersion } : {}),
|
|
667
668
|
// Agent runtime is single-device: multi_device stays off so the server
|
|
668
669
|
// never self-fans-out this connection's own messages. notify_signals is
|
|
669
670
|
// advertised because we now handle the notify.signal frame (§9.4).
|
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { Envelope, Transport } from "./protocol-types.ts";
|
|
|
4
4
|
import { createClawChatClient, type ClawlingChatClient } from "./ws-client.ts";
|
|
5
5
|
import { CHANNEL_ID, type ResolvedOpenclawClawlingAccount } from "./config.ts";
|
|
6
6
|
import { resolveStateDirFromEnv } from "./state-paths.ts";
|
|
7
|
+
import { resolvePluginVersion } from "./plugin-report.ts";
|
|
7
8
|
|
|
8
9
|
export type { ChatType } from "./protocol-types.ts";
|
|
9
10
|
|
|
@@ -69,6 +70,7 @@ export function createOpenclawClawlingClient(
|
|
|
69
70
|
url: account.websocketUrl,
|
|
70
71
|
token: account.token,
|
|
71
72
|
deviceId,
|
|
73
|
+
clientVersion: resolvePluginVersion(),
|
|
72
74
|
...(overrides.transport ? { transport: overrides.transport } : {}),
|
|
73
75
|
reconnect: {
|
|
74
76
|
enabled: true,
|
package/src/protocol-types.ts
CHANGED
package/src/runtime.ts
CHANGED
|
@@ -2859,7 +2859,24 @@ export async function startOpenclawClawlingGateway(params: StartGatewayParams):
|
|
|
2859
2859
|
);
|
|
2860
2860
|
return "skipped";
|
|
2861
2861
|
}
|
|
2862
|
+
if (claimed !== true) {
|
|
2863
|
+
// Fail closed: a claim that could not be decided (store disabled, SQLite
|
|
2864
|
+
// error, a throw converted to undefined by recordConnection) must not
|
|
2865
|
+
// dispatch. Live delivery and device replay can carry the same message,
|
|
2866
|
+
// and the outbound reply path (outbound.ts / reply-dispatcher.ts) already
|
|
2867
|
+
// refuses to send without a claim — so dispatching here only re-ran the
|
|
2868
|
+
// LLM/tools without delivering, or double-replied. Logged at error level
|
|
2869
|
+
// with reason=claim_unavailable so a store outage is visible and is not
|
|
2870
|
+
// mistaken for dedup. Accepted cost: a one-off transient claim failure
|
|
2871
|
+
// drops that message.
|
|
2872
|
+
log?.error?.(
|
|
2873
|
+
`[${accountId}] clawchat-plugin-openclaw inbound skipped msg=${turn.messageId} chat_id=${turn.peer.id} event=${String(env.event)} reason=claim_unavailable result=${String(claimed)}`,
|
|
2874
|
+
);
|
|
2875
|
+
return "skipped";
|
|
2876
|
+
}
|
|
2862
2877
|
}
|
|
2878
|
+
// No store wired at all (injected test transport, or store construction
|
|
2879
|
+
// threw at startup — which is itself logged) keeps the store-less pass-through.
|
|
2863
2880
|
return "claimed";
|
|
2864
2881
|
};
|
|
2865
2882
|
|
|
@@ -3265,7 +3282,10 @@ export async function startOpenclawClawlingGateway(params: StartGatewayParams):
|
|
|
3265
3282
|
// replayed — permanently lost. Claiming first makes it durable; the abort
|
|
3266
3283
|
// check below then returns without dispatching, but the frame is kept.
|
|
3267
3284
|
// `claimInboundTurn` is INSERT OR IGNORE, so a genuine duplicate (same
|
|
3268
|
-
// message_id) is still deduped here exactly once.
|
|
3285
|
+
// message_id) is still deduped here exactly once. The claim fails CLOSED:
|
|
3286
|
+
// only a successful claim proceeds; an undecided claim (store unavailable)
|
|
3287
|
+
// skips with reason=claim_unavailable, because outbound replies also refuse
|
|
3288
|
+
// to send without a claim, so dispatching would only waste the turn.
|
|
3269
3289
|
const claimed = claimInboundTurn(turn);
|
|
3270
3290
|
if (claimed === "skipped") return "skipped";
|
|
3271
3291
|
// Findings 2 & 3 — hold ALL group traffic until the in-flight settings pull
|
package/src/ws-client.ts
CHANGED
|
@@ -118,6 +118,8 @@ export interface ClawChatClientOptions {
|
|
|
118
118
|
url: string;
|
|
119
119
|
token: string;
|
|
120
120
|
deviceId?: string;
|
|
121
|
+
/** Sent as connect `client_version` (telemetry only); omitted when empty. */
|
|
122
|
+
clientVersion?: string;
|
|
121
123
|
transport?: Transport;
|
|
122
124
|
traceIdFactory?: () => string;
|
|
123
125
|
reconnect?: {
|
|
@@ -137,6 +139,7 @@ export interface NormalizedClawChatClientOptions {
|
|
|
137
139
|
url: string;
|
|
138
140
|
token: string;
|
|
139
141
|
deviceId?: string;
|
|
142
|
+
clientVersion?: string;
|
|
140
143
|
transport: Transport;
|
|
141
144
|
traceIdFactory: () => string;
|
|
142
145
|
reconnect: Required<NonNullable<ClawChatClientOptions["reconnect"]>>;
|
|
@@ -750,6 +753,7 @@ export class ClawChatClient extends EventEmitter {
|
|
|
750
753
|
token: this.opts.token,
|
|
751
754
|
nonce,
|
|
752
755
|
...(this.opts.deviceId ? { device_id: this.opts.deviceId } : {}),
|
|
756
|
+
...(this.opts.clientVersion ? { client_version: this.opts.clientVersion } : {}),
|
|
753
757
|
// Agent runtime is single-device: multi_device stays off so the server
|
|
754
758
|
// never self-fans-out this connection's own messages. notify_signals is
|
|
755
759
|
// advertised because we now handle the notify.signal frame (§9.4).
|