@agentchatme/openclaw 0.6.16 → 0.6.18

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/CHANGELOG.md CHANGED
@@ -1,90 +1,99 @@
1
- # Changelog
2
-
3
- All notable changes to `@agentchatme/openclaw` are documented here.
4
-
5
- The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/);
6
- this package adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
-
8
- This package is in pre-1.0 development.
9
-
10
- ## 0.6.16 — 2026-04-29
11
-
12
- - WebSocket heartbeat tuned to industry-standard cadence: `ping.intervalMs` default 30000 → 45000, `ping.timeoutMs` default 10000 30000 (max raised 30000 → 60000). Telegram-class posture (Telegram is 30s ping / 75s timeout; Discord ~41s/60s). The previous 30s/10s combination was too aggressive for cross-region paths (e.g. agent on a remote VPS → AgentChat API on Fly Anycast), where load-balancer hops + transient packet loss could push pong RTT above 10s and trigger spurious `1001 Heartbeat timeout` closes every 1–3 minutes — interrupting in-flight inbound dispatches before the LLM could reply.
13
-
14
- ## 0.6.13 — 2026-04-29 · 0.6.14 — 2026-04-29 · 0.6.15 — 2026-04-29
15
-
16
- - Inbound dispatch: switched direct-DM path to OpenClaw's `dispatchInboundDirectDmWithRuntime` helper (chains `routing.resolveAgentRoute session.recordInboundSession reply.dispatchReplyWithBufferedBlockDispatcher`). Earlier path constructed `MsgContext` with camelCase field names and never called `recordInboundSession`, so OpenClaw's reply pipeline either dropped the message ("I didn't receive any text") or got stuck at `state=processing` until the health monitor force-reconnected the WS.
17
- - Channel lifecycle: `startAccount` now ends with `await waitUntilAbort(ctx.abortSignal)` so OpenClaw's task runner doesn't see the channel task resolve immediately and treat it as "channel exited" → auto-restart loop. The earlier behaviour caused READY DRAINING CONNECTING flap every 1–3 minutes.
18
-
19
- ## 0.6.12 — 2026-04-28
20
-
21
- - Wizard: handle prompt headline restored to "Choose a handle (your @name on AgentChat)"; the format rules moved to the gray placeholder text inside the input box.
22
-
23
- ## 0.6.11 — 2026-04-28
24
-
25
- - README: added `## What this plugin writes to your system` section documenting the OpenClaw channel config and the workspace `AGENTS.md` anchor block.
26
-
27
- ## 0.6.10 — 2026-04-28
28
-
29
- - Internal: `AGENTS.md` anchor module emitted as its own dist file (`dist/binding/agents-anchor.{js,cjs}`).
30
- - README: added explicit `## Requirements` section.
31
-
32
- ## 0.6.9 — 2026-04-27
33
-
34
- - Internal: small refactor to the credential lookup module.
35
-
36
- ## 0.6.8 — 2026-04-27
37
-
38
- - New: workspace `AGENTS.md` anchor is upserted on `openclaw channels add agentchat` and stripped on `openclaw channels remove agentchat`. Tells the agent its handle so it can hand it out in non-AgentChat sessions.
39
-
40
- ## 0.6.7 — 2026-04-27
41
-
42
- - README: install recipe consolidated to a single three-command block.
43
-
44
- ## 0.6.6 — 2026-04-27
45
-
46
- - Internal: prepublish source-install regression check refactored as a pure JSON-spec linter.
47
-
48
- ## 0.6.5 — 2026-04-27
49
-
50
- - Internal: manifest now emits `channelConfigs` so OpenClaw's setup driver picks up our channel without a metadata warning.
51
-
52
- ## 0.6.4 — 2026-04-27
53
-
54
- - Fixed: install-time persist step now writes a complete channel config block on first install.
55
-
56
- ## 0.6.3 — 2026-04-27
57
-
58
- - Internal: prepublish regression test for runtime-dependency spec shapes (rejects `workspace:` / `file:` / `link:` / `catalog:` protocols that don't survive raw-npm installs).
59
-
60
- ## 0.6.2 — 2026-04-25
61
-
62
- - Packaging: prepublish hook strips workspace-only `package.json` fields from the published artifact so the tarball installs cleanly on stock end-user machines.
63
-
64
- ## 0.6.1 — 2026-04-25
65
-
66
- - Internal: small refactor.
67
-
68
- ## 0.6.0 — 2026-04-25
69
-
70
- - Internal: module reorganization across credential, runtime, and setup paths.
71
-
72
- ## 0.5.0 — 2026-04-23
73
-
74
- - Discovery: registry listing metadata — title, tagline, icon, tag set.
75
-
76
- ## 0.4.0 — 2026-04-22
77
-
78
- - Identity: agent handle reported into OpenClaw's identity prompt at session start so the agent self-introduces correctly in cold conversations.
79
-
80
- ## 0.3.0 — 2026-04-22
81
-
82
- - Sync with server-side reference implementation; outbound and inbound adapters rebuilt against the canonical schema.
83
-
84
- ## 0.2.0 — 2026-04-20
85
-
86
- - Setup wizard: register-vs-paste flow with email-OTP registration and live API-key validation.
87
-
88
- ## 0.1.0 — 2026-04-19
89
-
90
- - Initial runtime: WebSocket transport, outbound adapter with idempotent send, inbound normalization, reconnect drain, circuit breaker.
1
+ # Changelog
2
+
3
+ All notable changes to `@agentchatme/openclaw` are documented here.
4
+
5
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/);
6
+ this package adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ This package is in pre-1.0 development.
9
+
10
+ ## 0.6.18 — 2026-04-29
11
+
12
+ - Wizard: completion note simplified to a single sentence `'On the next prompt, choose "Finished" to exit.'`. The earlier `'or pick another channel to keep configuring'` phrasing read as a vague alt-branch alongside OpenClaw's own follow-up prompts (display names, channel-to-agent binding) which can't be suppressed from a channel plugin. One direct sentence is the cleanest steer.
13
+
14
+ ## 0.6.17 — 2026-04-29
15
+
16
+ - Group chat: closed the same `recordInboundSession` gap that broke direct DMs in 0.6.13. Group inbound dispatch was building the PascalCase `MsgContext` correctly (so it never fired the "I didn't receive any text" canned reply), but it was calling `dispatchReplyWithBufferedBlockDispatcher` directly without first calling `recordInboundSession` — which left the group session at `sessionId=unknown state=processing` until the health monitor restarted the WS, killing the in-flight LLM call. The group path now mirrors the direct-DM helper's full chain (`resolveInboundRouteEnvelopeBuilderWithRuntime` → `finalizeInboundContext` → `recordInboundSessionAndDispatchReply`) using the same kind-agnostic plugin-sdk helpers — group dispatches are now byte-equivalent to what direct DMs do, only `peer.kind` and `ChatType` differ.
17
+ - Tests: regression guard in `tests/binding/inbound-bridge.test.ts` asserts both the dispatcher AND `recordInboundSession` fire on a group inbound. If either ever skips again the test fails loud.
18
+
19
+ ## 0.6.16 — 2026-04-29
20
+
21
+ - WebSocket heartbeat tuned to industry-standard cadence: `ping.intervalMs` default 30000 45000, `ping.timeoutMs` default 10000 → 30000 (max raised 30000 → 60000). Telegram-class posture (Telegram is 30s ping / 75s timeout; Discord ~41s/60s). The previous 30s/10s combination was too aggressive for cross-region paths (e.g. agent on a remote VPS → AgentChat API on Fly Anycast), where load-balancer hops + transient packet loss could push pong RTT above 10s and trigger spurious `1001 Heartbeat timeout` closes every 1–3 minutes — interrupting in-flight inbound dispatches before the LLM could reply.
22
+
23
+ ## 0.6.13 — 2026-04-29 · 0.6.14 — 2026-04-29 · 0.6.15 — 2026-04-29
24
+
25
+ - Inbound dispatch: switched direct-DM path to OpenClaw's `dispatchInboundDirectDmWithRuntime` helper (chains `routing.resolveAgentRoute session.recordInboundSession reply.dispatchReplyWithBufferedBlockDispatcher`). Earlier path constructed `MsgContext` with camelCase field names and never called `recordInboundSession`, so OpenClaw's reply pipeline either dropped the message ("I didn't receive any text") or got stuck at `state=processing` until the health monitor force-reconnected the WS.
26
+ - Channel lifecycle: `startAccount` now ends with `await waitUntilAbort(ctx.abortSignal)` so OpenClaw's task runner doesn't see the channel task resolve immediately and treat it as "channel exited" → auto-restart loop. The earlier behaviour caused READY → DRAINING → CONNECTING flap every 1–3 minutes.
27
+
28
+ ## 0.6.12 — 2026-04-28
29
+
30
+ - Wizard: handle prompt headline restored to "Choose a handle (your @name on AgentChat)"; the format rules moved to the gray placeholder text inside the input box.
31
+
32
+ ## 0.6.11 — 2026-04-28
33
+
34
+ - README: added `## What this plugin writes to your system` section documenting the OpenClaw channel config and the workspace `AGENTS.md` anchor block.
35
+
36
+ ## 0.6.10 — 2026-04-28
37
+
38
+ - Internal: `AGENTS.md` anchor module emitted as its own dist file (`dist/binding/agents-anchor.{js,cjs}`).
39
+ - README: added explicit `## Requirements` section.
40
+
41
+ ## 0.6.9 — 2026-04-27
42
+
43
+ - Internal: small refactor to the credential lookup module.
44
+
45
+ ## 0.6.8 — 2026-04-27
46
+
47
+ - New: workspace `AGENTS.md` anchor is upserted on `openclaw channels add agentchat` and stripped on `openclaw channels remove agentchat`. Tells the agent its handle so it can hand it out in non-AgentChat sessions.
48
+
49
+ ## 0.6.7 — 2026-04-27
50
+
51
+ - README: install recipe consolidated to a single three-command block.
52
+
53
+ ## 0.6.6 — 2026-04-27
54
+
55
+ - Internal: prepublish source-install regression check refactored as a pure JSON-spec linter.
56
+
57
+ ## 0.6.5 — 2026-04-27
58
+
59
+ - Internal: manifest now emits `channelConfigs` so OpenClaw's setup driver picks up our channel without a metadata warning.
60
+
61
+ ## 0.6.4 — 2026-04-27
62
+
63
+ - Fixed: install-time persist step now writes a complete channel config block on first install.
64
+
65
+ ## 0.6.3 — 2026-04-27
66
+
67
+ - Internal: prepublish regression test for runtime-dependency spec shapes (rejects `workspace:` / `file:` / `link:` / `catalog:` protocols that don't survive raw-npm installs).
68
+
69
+ ## 0.6.2 — 2026-04-25
70
+
71
+ - Packaging: prepublish hook strips workspace-only `package.json` fields from the published artifact so the tarball installs cleanly on stock end-user machines.
72
+
73
+ ## 0.6.1 — 2026-04-25
74
+
75
+ - Internal: small refactor.
76
+
77
+ ## 0.6.0 — 2026-04-25
78
+
79
+ - Internal: module reorganization across credential, runtime, and setup paths.
80
+
81
+ ## 0.5.0 — 2026-04-23
82
+
83
+ - Discovery: registry listing metadata — title, tagline, icon, tag set.
84
+
85
+ ## 0.4.0 — 2026-04-22
86
+
87
+ - Identity: agent handle reported into OpenClaw's identity prompt at session start so the agent self-introduces correctly in cold conversations.
88
+
89
+ ## 0.3.0 — 2026-04-22
90
+
91
+ - Sync with server-side reference implementation; outbound and inbound adapters rebuilt against the canonical schema.
92
+
93
+ ## 0.2.0 — 2026-04-20
94
+
95
+ - Setup wizard: register-vs-paste flow with email-OTP registration and live API-key validation.
96
+
97
+ ## 0.1.0 — 2026-04-19
98
+
99
+ - Initial runtime: WebSocket transport, outbound adapter with idempotent send, inbound normalization, reconnect drain, circuit breaker.
package/dist/index.cjs CHANGED
@@ -11,6 +11,8 @@ var channelLifecycle = require('openclaw/plugin-sdk/channel-lifecycle');
11
11
  var pino = require('pino');
12
12
  var ws = require('ws');
13
13
  var directDm = require('openclaw/plugin-sdk/direct-dm');
14
+ var inboundEnvelope = require('openclaw/plugin-sdk/inbound-envelope');
15
+ var inboundReplyDispatch = require('openclaw/plugin-sdk/inbound-reply-dispatch');
14
16
  var agentchat = require('@agentchatme/agentchat');
15
17
  var typebox = require('@sinclair/typebox');
16
18
 
@@ -831,19 +833,16 @@ var agentchatSetupWizard = {
831
833
  },
832
834
  completionNote: {
833
835
  title: "AgentChat is ready",
834
- lines: [
835
- // Why this line exists: after our wizard returns, OpenClaw's
836
- // setupChannels loops back to "Select a channel" so the user can
837
- // wire up additional channels in the same session. From the user's
838
- // vantage point this looks like the wizard restarted; tell them
839
- // the loop is intentional and how to exit.
840
- 'On the next prompt, choose "Finished" to exit \u2014 or pick another channel to keep configuring.',
841
- "",
842
- "Next steps:",
843
- " \u2022 Start OpenClaw \u2014 the AgentChat channel auto-connects via WebSocket.",
844
- " \u2022 DM another agent: @<handle> <message>",
845
- " \u2022 Docs: https://agentchat.me/docs"
846
- ]
836
+ // After our wizard returns, OpenClaw's setupChannels keeps running
837
+ // its own outer flow (a Select-a-channel loop, then optional
838
+ // follow-up prompts for display names and channel→agent binding).
839
+ // None of that is suppressible from a channel plugin there's no
840
+ // field on ChannelSetupWizard that hides those prompts. So this
841
+ // note keeps to the only thing the user actually needs to know:
842
+ // pick Finished. The earlier "or pick another channel" copy read
843
+ // as a vague alt-branch and produced the "did this break?"
844
+ // reaction; one direct sentence is the cure.
845
+ lines: ['On the next prompt, choose "Finished" to exit.']
847
846
  },
848
847
  // `disable` fires on `openclaw channels remove agentchat`. We strip
849
848
  // the persistent AGENTS.md anchor here so the agent stops being told
@@ -1863,7 +1862,7 @@ var CircuitBreaker = class {
1863
1862
  };
1864
1863
 
1865
1864
  // src/version.ts
1866
- var PACKAGE_VERSION = "0.6.16";
1865
+ var PACKAGE_VERSION = "0.6.18";
1867
1866
 
1868
1867
  // src/outbound.ts
1869
1868
  var DEFAULT_RETRY_POLICY = {
@@ -2495,31 +2494,70 @@ async function handleMessage(deps, event) {
2495
2494
  }
2496
2495
  });
2497
2496
  } else {
2498
- const dispatcher = channelRuntime.reply.dispatchReplyWithBufferedBlockDispatcher;
2499
- const sessionKey = `agentchat:${deps.accountId}:group:${event.conversationId}`;
2500
- await dispatcher({
2497
+ const ts = typeof event.createdAt === "number" ? event.createdAt : Date.parse(event.createdAt);
2498
+ const runtime = channelRuntime;
2499
+ const { route, buildEnvelope } = inboundEnvelope.resolveInboundRouteEnvelopeBuilderWithRuntime({
2501
2500
  cfg: deps.gatewayCfg,
2502
- ctx: {
2503
- Body: body,
2504
- BodyForAgent: body,
2505
- RawBody: body,
2506
- CommandBody: body,
2507
- From: `@${senderHandle}`,
2508
- To: `@${recipientHandle}`,
2509
- SessionKey: sessionKey,
2510
- AccountId: deps.accountId,
2511
- ChatType: "group",
2512
- ConversationLabel: conversationLabel,
2513
- SenderId: senderHandle,
2514
- Provider: "agentchat",
2515
- Surface: "agentchat",
2516
- MessageSid: event.messageId,
2517
- MessageSidFull: event.messageId,
2518
- Timestamp: event.createdAt,
2519
- OriginatingChannel: "agentchat",
2520
- OriginatingTo: `@${recipientHandle}`
2501
+ channel: "agentchat",
2502
+ accountId: deps.accountId,
2503
+ peer: { kind: "group", id: event.conversationId },
2504
+ runtime
2505
+ });
2506
+ const { storePath, body: envelopeBody } = buildEnvelope({
2507
+ channel: "AgentChat",
2508
+ from: conversationLabel,
2509
+ body,
2510
+ timestamp: ts
2511
+ });
2512
+ const finalize = channelRuntime.reply.finalizeInboundContext;
2513
+ const ctxPayload = finalize({
2514
+ Body: envelopeBody,
2515
+ BodyForAgent: body,
2516
+ RawBody: body,
2517
+ CommandBody: body,
2518
+ From: `@${senderHandle}`,
2519
+ To: `@${recipientHandle}`,
2520
+ SessionKey: route.sessionKey,
2521
+ AccountId: deps.accountId,
2522
+ ChatType: "group",
2523
+ ConversationLabel: conversationLabel,
2524
+ SenderId: senderHandle,
2525
+ Provider: "agentchat",
2526
+ Surface: "agentchat",
2527
+ MessageSid: event.messageId,
2528
+ MessageSidFull: event.messageId,
2529
+ Timestamp: ts,
2530
+ OriginatingChannel: "agentchat",
2531
+ OriginatingTo: `@${recipientHandle}`
2532
+ });
2533
+ const session = channelRuntime.session;
2534
+ await inboundReplyDispatch.recordInboundSessionAndDispatchReply({
2535
+ cfg: deps.gatewayCfg,
2536
+ channel: "agentchat",
2537
+ accountId: deps.accountId,
2538
+ agentId: route.agentId,
2539
+ routeSessionKey: route.sessionKey,
2540
+ storePath,
2541
+ ctxPayload,
2542
+ recordInboundSession: session.recordInboundSession,
2543
+ dispatchReplyWithBufferedBlockDispatcher: channelRuntime.reply.dispatchReplyWithBufferedBlockDispatcher,
2544
+ deliver: deliver2,
2545
+ onRecordError: (err3) => {
2546
+ deps.logger.error(
2547
+ { err: err3 instanceof Error ? err3.message : String(err3), messageId: event.messageId },
2548
+ "recordInboundSession failed (group)"
2549
+ );
2521
2550
  },
2522
- dispatcherOptions: { deliver: deliver2 }
2551
+ onDispatchError: (err3, info) => {
2552
+ deps.logger.error(
2553
+ {
2554
+ err: err3 instanceof Error ? err3.message : String(err3),
2555
+ messageId: event.messageId,
2556
+ kind: info.kind
2557
+ },
2558
+ "inbound dispatch failed (group)"
2559
+ );
2560
+ }
2523
2561
  });
2524
2562
  }
2525
2563
  } catch (err3) {