@openclaw/crabline 0.1.14 → 0.1.16

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.
Files changed (31) hide show
  1. package/dist/src/index.d.ts +2 -2
  2. package/dist/src/index.js +1 -1
  3. package/dist/src/index.js.map +1 -1
  4. package/dist/src/openclaw/bridges/discord.js +17 -4
  5. package/dist/src/openclaw/bridges/discord.js.map +1 -1
  6. package/dist/src/openclaw/bridges/matrix.js +4 -2
  7. package/dist/src/openclaw/bridges/matrix.js.map +1 -1
  8. package/dist/src/openclaw/bridges/mattermost.js +70 -23
  9. package/dist/src/openclaw/bridges/mattermost.js.map +1 -1
  10. package/dist/src/openclaw/bridges/signal.js +10 -3
  11. package/dist/src/openclaw/bridges/signal.js.map +1 -1
  12. package/dist/src/openclaw/bridges/slack.js +5 -3
  13. package/dist/src/openclaw/bridges/slack.js.map +1 -1
  14. package/dist/src/openclaw/bridges/telegram.js +50 -27
  15. package/dist/src/openclaw/bridges/telegram.js.map +1 -1
  16. package/dist/src/openclaw/bridges/whatsapp.js +5 -3
  17. package/dist/src/openclaw/bridges/whatsapp.js.map +1 -1
  18. package/dist/src/openclaw/bridges/zalo.js +4 -3
  19. package/dist/src/openclaw/bridges/zalo.js.map +1 -1
  20. package/dist/src/openclaw/private-file.d.ts +8 -0
  21. package/dist/src/openclaw/private-file.js +99 -8
  22. package/dist/src/openclaw/private-file.js.map +1 -1
  23. package/dist/src/openclaw/shared.d.ts +48 -4
  24. package/dist/src/openclaw/shared.js +68 -9
  25. package/dist/src/openclaw/shared.js.map +1 -1
  26. package/dist/src/openclaw.d.ts +10 -4
  27. package/dist/src/openclaw.js +31 -11
  28. package/dist/src/openclaw.js.map +1 -1
  29. package/dist/src/servers/mattermost.js +42 -14
  30. package/dist/src/servers/mattermost.js.map +1 -1
  31. package/package.json +1 -1
@@ -9,7 +9,7 @@ export { startTelegramServer } from "./servers/telegram.js";
9
9
  export { startWhatsAppServer } from "./servers/whatsapp.js";
10
10
  export { startZaloServer } from "./servers/zalo.js";
11
11
  export { CRABLINE_SERVER_CHANNELS, isCrablineServerChannel, startCrablineServer, } from "./servers/index.js";
12
- export { createOpenClawCrablineAgentDelivery, createOpenClawCrablineChannelReportNotes, createOpenClawCrablineProviderBinding, createOpenClawCrablineInbound, createOpenClawCrablineOutboundFromRecorderEvent, OPENCLAW_CRABLINE_ARTIFACT_POINTER_PATH, OPENCLAW_CRABLINE_ARTIFACT_STORE_DIRECTORY, OPENCLAW_CRABLINE_CHANNEL_CAPABILITY_MATRIX_PATH, OPENCLAW_CRABLINE_PROVIDER_READINESS_PATH, OPENCLAW_CRABLINE_DEFAULT_CHANNEL, OPENCLAW_CRABLINE_MANIFEST_PATH, probeOpenClawCrablineProvider, resolveOpenClawCrablineChannel, resolveOpenClawCrablineChannelDriverSelection, runOpenClawCrablineProviderReadiness, startOpenClawCrablineAdapter, } from "./openclaw.js";
12
+ export { createOpenClawCrablineAgentDelivery, createOpenClawCrablineChannelReportNotes, createOpenClawCrablineProviderBinding, createOpenClawCrablineInbound, createOpenClawCrablineOutboundFromRecorderEvent, createOpenClawCrablineOutboundObservation, OPENCLAW_CRABLINE_ARTIFACT_POINTER_PATH, OPENCLAW_CRABLINE_ARTIFACT_STORE_DIRECTORY, OPENCLAW_CRABLINE_CHANNEL_CAPABILITY_MATRIX_PATH, OPENCLAW_CRABLINE_PROVIDER_READINESS_PATH, OPENCLAW_CRABLINE_DEFAULT_CHANNEL, OPENCLAW_CRABLINE_MANIFEST_PATH, probeOpenClawCrablineProvider, resolveOpenClawCrablineChannel, resolveOpenClawCrablineChannelDriverSelection, runOpenClawCrablineProviderReadiness, startOpenClawCrablineAdapter, } from "./openclaw.js";
13
13
  export { BUILTIN_ADAPTERS, FIXTURE_MODES, INBOUND_AUTHORS, INBOUND_NONCE_MODES, INBOUND_STRATEGIES, ManifestSchema, PROVIDER_PLATFORMS, ProviderConfigSchema, } from "./config/schema.js";
14
14
  export { OPENCLAW_SUPPORT_CATALOG } from "./providers/catalog.js";
15
15
  export { createRegistry } from "./providers/registry.js";
@@ -28,4 +28,4 @@ export type { StartedTelegramServer, StartTelegramServerParams, TelegramServerMa
28
28
  export type { StartedWhatsAppServer, StartWhatsAppServerParams, WhatsAppBaileysMessage, WhatsAppServerManifest, } from "./servers/whatsapp.js";
29
29
  export type { StartedZaloServer, StartZaloServerParams, ZaloServerManifest, } from "./servers/zalo.js";
30
30
  export type { CrablineServerChannel, CrablineServerManifest, StartedCrablineServer, StartCrablineServerParams, } from "./servers/index.js";
31
- export type { OpenClawCrablineAgentDelivery, OpenClawCrablineChannelDriverSelection, OpenClawCrablineProviderReadinessResult, OpenClawCrablineConversation, OpenClawCrablineGatewayBinding, OpenClawCrablineInbound, OpenClawCrablineInboundInput, OpenClawCrablineOutboundMessage, StartedOpenClawCrablineAdapter, StartOpenClawCrablineAdapterParams, } from "./openclaw.js";
31
+ export type { OpenClawCrablineAgentDelivery, OpenClawCrablineChannelDriverSelection, OpenClawCrablineCorrelatedAgentDelivery, OpenClawCrablineProviderReadinessResult, OpenClawCrablineConversation, OpenClawCrablineGatewayBinding, OpenClawCrablineInbound, OpenClawCrablineInboundInput, OpenClawCrablineOutboundMessage, OpenClawCrablineOutboundObservation, StartedOpenClawCrablineAdapter, StartedOpenClawCrablineCorrelatedAdapter, StartOpenClawCrablineAdapterParams, } from "./openclaw.js";
package/dist/src/index.js CHANGED
@@ -9,7 +9,7 @@ export { startTelegramServer } from "./servers/telegram.js";
9
9
  export { startWhatsAppServer } from "./servers/whatsapp.js";
10
10
  export { startZaloServer } from "./servers/zalo.js";
11
11
  export { CRABLINE_SERVER_CHANNELS, isCrablineServerChannel, startCrablineServer, } from "./servers/index.js";
12
- export { createOpenClawCrablineAgentDelivery, createOpenClawCrablineChannelReportNotes, createOpenClawCrablineProviderBinding, createOpenClawCrablineInbound, createOpenClawCrablineOutboundFromRecorderEvent, OPENCLAW_CRABLINE_ARTIFACT_POINTER_PATH, OPENCLAW_CRABLINE_ARTIFACT_STORE_DIRECTORY, OPENCLAW_CRABLINE_CHANNEL_CAPABILITY_MATRIX_PATH, OPENCLAW_CRABLINE_PROVIDER_READINESS_PATH, OPENCLAW_CRABLINE_DEFAULT_CHANNEL, OPENCLAW_CRABLINE_MANIFEST_PATH, probeOpenClawCrablineProvider, resolveOpenClawCrablineChannel, resolveOpenClawCrablineChannelDriverSelection, runOpenClawCrablineProviderReadiness, startOpenClawCrablineAdapter, } from "./openclaw.js";
12
+ export { createOpenClawCrablineAgentDelivery, createOpenClawCrablineChannelReportNotes, createOpenClawCrablineProviderBinding, createOpenClawCrablineInbound, createOpenClawCrablineOutboundFromRecorderEvent, createOpenClawCrablineOutboundObservation, OPENCLAW_CRABLINE_ARTIFACT_POINTER_PATH, OPENCLAW_CRABLINE_ARTIFACT_STORE_DIRECTORY, OPENCLAW_CRABLINE_CHANNEL_CAPABILITY_MATRIX_PATH, OPENCLAW_CRABLINE_PROVIDER_READINESS_PATH, OPENCLAW_CRABLINE_DEFAULT_CHANNEL, OPENCLAW_CRABLINE_MANIFEST_PATH, probeOpenClawCrablineProvider, resolveOpenClawCrablineChannel, resolveOpenClawCrablineChannelDriverSelection, runOpenClawCrablineProviderReadiness, startOpenClawCrablineAdapter, } from "./openclaw.js";
13
13
  export { BUILTIN_ADAPTERS, FIXTURE_MODES, INBOUND_AUTHORS, INBOUND_NONCE_MODES, INBOUND_STRATEGIES, ManifestSchema, PROVIDER_PLATFORMS, ProviderConfigSchema, } from "./config/schema.js";
14
14
  export { OPENCLAW_SUPPORT_CATALOG } from "./providers/catalog.js";
15
15
  export { createRegistry } from "./providers/registry.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,iCAAiC,CAAC;AAC/E,OAAO,EAAE,4BAA4B,EAAE,MAAM,iCAAiC,CAAC;AAC/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EACL,wBAAwB,EACxB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,mCAAmC,EACnC,wCAAwC,EACxC,qCAAqC,EACrC,6BAA6B,EAC7B,+CAA+C,EAC/C,uCAAuC,EACvC,0CAA0C,EAC1C,gDAAgD,EAChD,yCAAyC,EACzC,iCAAiC,EACjC,+BAA+B,EAC/B,6BAA6B,EAC7B,8BAA8B,EAC9B,6CAA6C,EAC7C,oCAAoC,EACpC,4BAA4B,GAC7B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC","sourcesContent":["export { resolveTelegramAdapterConfig } from \"./providers/builtin/telegram.js\";\nexport { resolveWhatsAppAdapterConfig } from \"./providers/builtin/whatsapp.js\";\nexport { startDiscordServer } from \"./servers/discord.js\";\nexport { startMattermostServer } from \"./servers/mattermost.js\";\nexport { startMatrixServer } from \"./servers/matrix.js\";\nexport { startSignalServer } from \"./servers/signal.js\";\nexport { startSlackServer } from \"./servers/slack.js\";\nexport { startTelegramServer } from \"./servers/telegram.js\";\nexport { startWhatsAppServer } from \"./servers/whatsapp.js\";\nexport { startZaloServer } from \"./servers/zalo.js\";\nexport {\n CRABLINE_SERVER_CHANNELS,\n isCrablineServerChannel,\n startCrablineServer,\n} from \"./servers/index.js\";\nexport {\n createOpenClawCrablineAgentDelivery,\n createOpenClawCrablineChannelReportNotes,\n createOpenClawCrablineProviderBinding,\n createOpenClawCrablineInbound,\n createOpenClawCrablineOutboundFromRecorderEvent,\n OPENCLAW_CRABLINE_ARTIFACT_POINTER_PATH,\n OPENCLAW_CRABLINE_ARTIFACT_STORE_DIRECTORY,\n OPENCLAW_CRABLINE_CHANNEL_CAPABILITY_MATRIX_PATH,\n OPENCLAW_CRABLINE_PROVIDER_READINESS_PATH,\n OPENCLAW_CRABLINE_DEFAULT_CHANNEL,\n OPENCLAW_CRABLINE_MANIFEST_PATH,\n probeOpenClawCrablineProvider,\n resolveOpenClawCrablineChannel,\n resolveOpenClawCrablineChannelDriverSelection,\n runOpenClawCrablineProviderReadiness,\n startOpenClawCrablineAdapter,\n} from \"./openclaw.js\";\nexport {\n BUILTIN_ADAPTERS,\n FIXTURE_MODES,\n INBOUND_AUTHORS,\n INBOUND_NONCE_MODES,\n INBOUND_STRATEGIES,\n ManifestSchema,\n PROVIDER_PLATFORMS,\n ProviderConfigSchema,\n} from \"./config/schema.js\";\nexport { OPENCLAW_SUPPORT_CATALOG } from \"./providers/catalog.js\";\nexport { createRegistry } from \"./providers/registry.js\";\nexport type { CatalogEntry } from \"./providers/catalog.js\";\nexport type { Registry } from \"./providers/registry.js\";\nexport type { ServerRequestEvent } from \"./servers/http.js\";\nexport type { ServerEventObserver } from \"./servers/recorder.js\";\nexport type {\n DiscordServerManifest,\n StartedDiscordServer,\n StartDiscordServerParams,\n} from \"./servers/discord.js\";\nexport type {\n BuiltinAdapterId,\n FixtureDefinition,\n FixtureMode,\n ManifestDefinition,\n ProviderConfig,\n ProviderPlatform,\n} from \"./config/schema.js\";\nexport type {\n InboundEnvelope,\n NormalizedTarget,\n ProbeResult,\n ProviderAdapter,\n ProviderContext,\n ProviderSupportStatus,\n SendContext,\n SendResult,\n WaitContext,\n WatchContext,\n} from \"./providers/types.js\";\nexport type {\n MattermostServerManifest,\n StartedMattermostServer,\n StartMattermostServerParams,\n} from \"./servers/mattermost.js\";\nexport type {\n MatrixServerManifest,\n StartedMatrixServer,\n StartMatrixServerParams,\n} from \"./servers/matrix.js\";\nexport type {\n SignalServerManifest,\n StartedSignalServer,\n StartSignalServerParams,\n} from \"./servers/signal.js\";\nexport type {\n SlackServerManifest,\n StartedSlackServer,\n StartSlackServerParams,\n} from \"./servers/slack.js\";\nexport type {\n StartedTelegramServer,\n StartTelegramServerParams,\n TelegramServerManifest,\n} from \"./servers/telegram.js\";\nexport type {\n StartedWhatsAppServer,\n StartWhatsAppServerParams,\n WhatsAppBaileysMessage,\n WhatsAppServerManifest,\n} from \"./servers/whatsapp.js\";\nexport type {\n StartedZaloServer,\n StartZaloServerParams,\n ZaloServerManifest,\n} from \"./servers/zalo.js\";\nexport type {\n CrablineServerChannel,\n CrablineServerManifest,\n StartedCrablineServer,\n StartCrablineServerParams,\n} from \"./servers/index.js\";\nexport type {\n OpenClawCrablineAgentDelivery,\n OpenClawCrablineChannelDriverSelection,\n OpenClawCrablineProviderReadinessResult,\n OpenClawCrablineConversation,\n OpenClawCrablineGatewayBinding,\n OpenClawCrablineInbound,\n OpenClawCrablineInboundInput,\n OpenClawCrablineOutboundMessage,\n StartedOpenClawCrablineAdapter,\n StartOpenClawCrablineAdapterParams,\n} from \"./openclaw.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,iCAAiC,CAAC;AAC/E,OAAO,EAAE,4BAA4B,EAAE,MAAM,iCAAiC,CAAC;AAC/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EACL,wBAAwB,EACxB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,mCAAmC,EACnC,wCAAwC,EACxC,qCAAqC,EACrC,6BAA6B,EAC7B,+CAA+C,EAC/C,yCAAyC,EACzC,uCAAuC,EACvC,0CAA0C,EAC1C,gDAAgD,EAChD,yCAAyC,EACzC,iCAAiC,EACjC,+BAA+B,EAC/B,6BAA6B,EAC7B,8BAA8B,EAC9B,6CAA6C,EAC7C,oCAAoC,EACpC,4BAA4B,GAC7B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC","sourcesContent":["export { resolveTelegramAdapterConfig } from \"./providers/builtin/telegram.js\";\nexport { resolveWhatsAppAdapterConfig } from \"./providers/builtin/whatsapp.js\";\nexport { startDiscordServer } from \"./servers/discord.js\";\nexport { startMattermostServer } from \"./servers/mattermost.js\";\nexport { startMatrixServer } from \"./servers/matrix.js\";\nexport { startSignalServer } from \"./servers/signal.js\";\nexport { startSlackServer } from \"./servers/slack.js\";\nexport { startTelegramServer } from \"./servers/telegram.js\";\nexport { startWhatsAppServer } from \"./servers/whatsapp.js\";\nexport { startZaloServer } from \"./servers/zalo.js\";\nexport {\n CRABLINE_SERVER_CHANNELS,\n isCrablineServerChannel,\n startCrablineServer,\n} from \"./servers/index.js\";\nexport {\n createOpenClawCrablineAgentDelivery,\n createOpenClawCrablineChannelReportNotes,\n createOpenClawCrablineProviderBinding,\n createOpenClawCrablineInbound,\n createOpenClawCrablineOutboundFromRecorderEvent,\n createOpenClawCrablineOutboundObservation,\n OPENCLAW_CRABLINE_ARTIFACT_POINTER_PATH,\n OPENCLAW_CRABLINE_ARTIFACT_STORE_DIRECTORY,\n OPENCLAW_CRABLINE_CHANNEL_CAPABILITY_MATRIX_PATH,\n OPENCLAW_CRABLINE_PROVIDER_READINESS_PATH,\n OPENCLAW_CRABLINE_DEFAULT_CHANNEL,\n OPENCLAW_CRABLINE_MANIFEST_PATH,\n probeOpenClawCrablineProvider,\n resolveOpenClawCrablineChannel,\n resolveOpenClawCrablineChannelDriverSelection,\n runOpenClawCrablineProviderReadiness,\n startOpenClawCrablineAdapter,\n} from \"./openclaw.js\";\nexport {\n BUILTIN_ADAPTERS,\n FIXTURE_MODES,\n INBOUND_AUTHORS,\n INBOUND_NONCE_MODES,\n INBOUND_STRATEGIES,\n ManifestSchema,\n PROVIDER_PLATFORMS,\n ProviderConfigSchema,\n} from \"./config/schema.js\";\nexport { OPENCLAW_SUPPORT_CATALOG } from \"./providers/catalog.js\";\nexport { createRegistry } from \"./providers/registry.js\";\nexport type { CatalogEntry } from \"./providers/catalog.js\";\nexport type { Registry } from \"./providers/registry.js\";\nexport type { ServerRequestEvent } from \"./servers/http.js\";\nexport type { ServerEventObserver } from \"./servers/recorder.js\";\nexport type {\n DiscordServerManifest,\n StartedDiscordServer,\n StartDiscordServerParams,\n} from \"./servers/discord.js\";\nexport type {\n BuiltinAdapterId,\n FixtureDefinition,\n FixtureMode,\n ManifestDefinition,\n ProviderConfig,\n ProviderPlatform,\n} from \"./config/schema.js\";\nexport type {\n InboundEnvelope,\n NormalizedTarget,\n ProbeResult,\n ProviderAdapter,\n ProviderContext,\n ProviderSupportStatus,\n SendContext,\n SendResult,\n WaitContext,\n WatchContext,\n} from \"./providers/types.js\";\nexport type {\n MattermostServerManifest,\n StartedMattermostServer,\n StartMattermostServerParams,\n} from \"./servers/mattermost.js\";\nexport type {\n MatrixServerManifest,\n StartedMatrixServer,\n StartMatrixServerParams,\n} from \"./servers/matrix.js\";\nexport type {\n SignalServerManifest,\n StartedSignalServer,\n StartSignalServerParams,\n} from \"./servers/signal.js\";\nexport type {\n SlackServerManifest,\n StartedSlackServer,\n StartSlackServerParams,\n} from \"./servers/slack.js\";\nexport type {\n StartedTelegramServer,\n StartTelegramServerParams,\n TelegramServerManifest,\n} from \"./servers/telegram.js\";\nexport type {\n StartedWhatsAppServer,\n StartWhatsAppServerParams,\n WhatsAppBaileysMessage,\n WhatsAppServerManifest,\n} from \"./servers/whatsapp.js\";\nexport type {\n StartedZaloServer,\n StartZaloServerParams,\n ZaloServerManifest,\n} from \"./servers/zalo.js\";\nexport type {\n CrablineServerChannel,\n CrablineServerManifest,\n StartedCrablineServer,\n StartCrablineServerParams,\n} from \"./servers/index.js\";\nexport type {\n OpenClawCrablineAgentDelivery,\n OpenClawCrablineChannelDriverSelection,\n OpenClawCrablineCorrelatedAgentDelivery,\n OpenClawCrablineProviderReadinessResult,\n OpenClawCrablineConversation,\n OpenClawCrablineGatewayBinding,\n OpenClawCrablineInbound,\n OpenClawCrablineInboundInput,\n OpenClawCrablineOutboundMessage,\n OpenClawCrablineOutboundObservation,\n StartedOpenClawCrablineAdapter,\n StartedOpenClawCrablineCorrelatedAdapter,\n StartOpenClawCrablineAdapterParams,\n} from \"./openclaw.js\";\n"]}
@@ -86,10 +86,22 @@ export const DISCORD_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineP
86
86
  if (parsed.threadId) {
87
87
  const threadId = discordId(parsed.threadId, "Discord thread");
88
88
  const to = `channel:${threadId}`;
89
- return { channel: "discord", replyChannel: "discord", replyTo: to, to };
89
+ return {
90
+ channel: "discord",
91
+ providerTargetKey: providerTargetKey(threadId),
92
+ replyChannel: "discord",
93
+ replyTo: to,
94
+ to,
95
+ };
90
96
  }
91
97
  const to = `${parsed.kind === "direct" ? "user" : "channel"}:${id}`;
92
- return { channel: "discord", replyChannel: "discord", replyTo: to, to };
98
+ return {
99
+ channel: "discord",
100
+ providerTargetKey: providerTargetKey(parsed.kind === "direct" ? discordDirectChannelId(discord.botUserId, id) : id),
101
+ replyChannel: "discord",
102
+ replyTo: to,
103
+ to,
104
+ };
93
105
  },
94
106
  createInbound(input) {
95
107
  const conversationId = discordId(input.conversation.id, "Discord conversation");
@@ -121,7 +133,7 @@ export const DISCORD_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineP
121
133
  ...(threadId ? { threadId } : {}),
122
134
  };
123
135
  },
124
- createOutboundFromRecorderEvent({ event, targetByProviderTarget }) {
136
+ createOutboundObservation({ event }) {
125
137
  if (!isRecord(event) ||
126
138
  event.type !== "api" ||
127
139
  event.method !== "POST" ||
@@ -140,7 +152,8 @@ export const DISCORD_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineP
140
152
  senderId: discord.botUserId,
141
153
  senderName: "OpenClaw QA",
142
154
  text,
143
- to: targetByProviderTarget.get(providerTargetKey(channelId)) ?? channelId,
155
+ providerTargetKeys: [providerTargetKey(channelId)],
156
+ fallbackTarget: channelId,
144
157
  };
145
158
  },
146
159
  };
@@ -1 +1 @@
1
- {"version":3,"file":"discord.js","sourceRoot":"","sources":["../../../../src/openclaw/bridges/discord.ts"],"names":[],"mappings":"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","sourcesContent":["import { discordDirectChannelId } from \"../../servers/discord.js\";\nimport {\n createAdminInboundRequest,\n createOpenClawCrablineProviderBridge,\n DEFAULT_ACCOUNT_ID,\n isRecord,\n qaTargetForInbound,\n readNonBlankString,\n readString,\n} from \"../shared.js\";\nimport { throwProbeHttpError } from \"./probe-response.js\";\n\nconst DISCORD_ID_PATTERN = /^\\d{17,20}$/u;\n\nfunction discordId(value: string, label: string): string {\n const id = value.trim();\n if (!DISCORD_ID_PATTERN.test(id)) {\n throw new Error(`${label} must be a Discord snowflake.`);\n }\n return id;\n}\n\nfunction providerTargetKey(channelId: string): string {\n return channelId;\n}\n\nexport const DISCORD_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProviderBridge({\n provider: \"discord\",\n createAdapter(discord) {\n return {\n async probe(signal) {\n const response = await fetch(`${discord.endpoints.apiRoot}/v10/users/@me`, {\n headers: { authorization: `Bot ${discord.botToken}` },\n ...(signal ? { signal } : {}),\n });\n if (!response.ok) {\n await throwProbeHttpError(\n response,\n `Crabline Discord users/@me probe failed with HTTP ${response.status}.`,\n );\n }\n const payload: unknown = await response.json();\n if (\n !isRecord(payload) ||\n readString(payload.id) !== discord.botUserId ||\n payload.bot !== true ||\n !readNonBlankString(payload.username)\n ) {\n throw new Error(\"Crabline Discord users/@me probe returned an unexpected bot user.\");\n }\n return payload;\n },\n createBinding() {\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n channel: \"discord\",\n createProviderReadinessEnv: (env) => ({ ...env, ...discord.env }),\n createGatewayConfig: (openclawConfig = {}) => {\n const channels = isRecord(openclawConfig.channels) ? openclawConfig.channels : {};\n const discordConfig = isRecord(channels.discord) ? channels.discord : {};\n const guilds = isRecord(discordConfig.guilds) ? discordConfig.guilds : {};\n const wildcardGuild = isRecord(guilds[\"*\"]) ? guilds[\"*\"] : {};\n const wildcardChannels = isRecord(wildcardGuild.channels) ? wildcardGuild.channels : {};\n const wildcardChannel = isRecord(wildcardChannels[\"*\"]) ? wildcardChannels[\"*\"] : {};\n return {\n ...openclawConfig,\n channels: {\n ...channels,\n discord: {\n ...discordConfig,\n applicationId: discord.applicationId,\n dm: { enabled: true },\n dmPolicy: \"open\",\n enabled: true,\n groupPolicy: \"open\",\n guilds: {\n ...guilds,\n \"*\": {\n ...wildcardGuild,\n channels: {\n ...wildcardChannels,\n \"*\": {\n ...wildcardChannel,\n enabled: true,\n requireMention: false,\n },\n },\n },\n },\n replyToMode: \"all\",\n streaming: { mode: \"off\" },\n token: discord.botToken,\n voice: { enabled: false },\n },\n },\n };\n },\n requiredPluginIds: [\"discord\"],\n };\n },\n createAgentDelivery(parsed) {\n const id = discordId(parsed.id, \"Discord target\");\n if (parsed.threadId) {\n const threadId = discordId(parsed.threadId, \"Discord thread\");\n const to = `channel:${threadId}`;\n return { channel: \"discord\", replyChannel: \"discord\", replyTo: to, to };\n }\n const to = `${parsed.kind === \"direct\" ? \"user\" : \"channel\"}:${id}`;\n return { channel: \"discord\", replyChannel: \"discord\", replyTo: to, to };\n },\n createInbound(input) {\n const conversationId = discordId(input.conversation.id, \"Discord conversation\");\n const senderId = discordId(input.senderId, \"Discord sender\");\n const threadId = input.threadId ? discordId(input.threadId, \"Discord thread\") : undefined;\n if (input.conversation.kind === \"direct\" && threadId) {\n throw new Error(\"Discord direct messages do not support thread targets.\");\n }\n const channelId =\n input.conversation.kind === \"direct\"\n ? discordDirectChannelId(discord.botUserId, senderId)\n : (threadId ?? conversationId);\n return {\n ...createAdminInboundRequest(discord),\n providerBody: {\n channelId,\n content: input.text,\n ...(input.conversation.kind === \"group\"\n ? {\n guildId: \"135000000000000099\",\n ...(threadId ? { parentChannelId: conversationId } : {}),\n }\n : {}),\n senderId,\n ...(input.senderName ? { senderName: input.senderName } : {}),\n },\n providerTargetKey: providerTargetKey(channelId),\n qaTarget: qaTargetForInbound(input),\n stateConversation: { id: conversationId, kind: input.conversation.kind },\n ...(threadId ? { threadId } : {}),\n };\n },\n createOutboundFromRecorderEvent({ event, targetByProviderTarget }) {\n if (\n !isRecord(event) ||\n event.type !== \"api\" ||\n event.method !== \"POST\" ||\n typeof event.path !== \"string\" ||\n !isRecord(event.body)\n ) {\n return null;\n }\n const match = /^\\/api\\/v10\\/channels\\/(\\d{17,20})\\/messages$/u.exec(event.path);\n const channelId = match?.[1];\n const text = readNonBlankString(event.body.content);\n if (!channelId || !text) {\n return null;\n }\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n senderId: discord.botUserId,\n senderName: \"OpenClaw QA\",\n text,\n to: targetByProviderTarget.get(providerTargetKey(channelId)) ?? channelId,\n };\n },\n };\n },\n});\n"]}
1
+ {"version":3,"file":"discord.js","sourceRoot":"","sources":["../../../../src/openclaw/bridges/discord.ts"],"names":[],"mappings":"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","sourcesContent":["import { discordDirectChannelId } from \"../../servers/discord.js\";\nimport {\n createAdminInboundRequest,\n createOpenClawCrablineProviderBridge,\n DEFAULT_ACCOUNT_ID,\n isRecord,\n qaTargetForInbound,\n readNonBlankString,\n readString,\n} from \"../shared.js\";\nimport { throwProbeHttpError } from \"./probe-response.js\";\n\nconst DISCORD_ID_PATTERN = /^\\d{17,20}$/u;\n\nfunction discordId(value: string, label: string): string {\n const id = value.trim();\n if (!DISCORD_ID_PATTERN.test(id)) {\n throw new Error(`${label} must be a Discord snowflake.`);\n }\n return id;\n}\n\nfunction providerTargetKey(channelId: string): string {\n return channelId;\n}\n\nexport const DISCORD_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProviderBridge({\n provider: \"discord\",\n createAdapter(discord) {\n return {\n async probe(signal) {\n const response = await fetch(`${discord.endpoints.apiRoot}/v10/users/@me`, {\n headers: { authorization: `Bot ${discord.botToken}` },\n ...(signal ? { signal } : {}),\n });\n if (!response.ok) {\n await throwProbeHttpError(\n response,\n `Crabline Discord users/@me probe failed with HTTP ${response.status}.`,\n );\n }\n const payload: unknown = await response.json();\n if (\n !isRecord(payload) ||\n readString(payload.id) !== discord.botUserId ||\n payload.bot !== true ||\n !readNonBlankString(payload.username)\n ) {\n throw new Error(\"Crabline Discord users/@me probe returned an unexpected bot user.\");\n }\n return payload;\n },\n createBinding() {\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n channel: \"discord\",\n createProviderReadinessEnv: (env) => ({ ...env, ...discord.env }),\n createGatewayConfig: (openclawConfig = {}) => {\n const channels = isRecord(openclawConfig.channels) ? openclawConfig.channels : {};\n const discordConfig = isRecord(channels.discord) ? channels.discord : {};\n const guilds = isRecord(discordConfig.guilds) ? discordConfig.guilds : {};\n const wildcardGuild = isRecord(guilds[\"*\"]) ? guilds[\"*\"] : {};\n const wildcardChannels = isRecord(wildcardGuild.channels) ? wildcardGuild.channels : {};\n const wildcardChannel = isRecord(wildcardChannels[\"*\"]) ? wildcardChannels[\"*\"] : {};\n return {\n ...openclawConfig,\n channels: {\n ...channels,\n discord: {\n ...discordConfig,\n applicationId: discord.applicationId,\n dm: { enabled: true },\n dmPolicy: \"open\",\n enabled: true,\n groupPolicy: \"open\",\n guilds: {\n ...guilds,\n \"*\": {\n ...wildcardGuild,\n channels: {\n ...wildcardChannels,\n \"*\": {\n ...wildcardChannel,\n enabled: true,\n requireMention: false,\n },\n },\n },\n },\n replyToMode: \"all\",\n streaming: { mode: \"off\" },\n token: discord.botToken,\n voice: { enabled: false },\n },\n },\n };\n },\n requiredPluginIds: [\"discord\"],\n };\n },\n createAgentDelivery(parsed) {\n const id = discordId(parsed.id, \"Discord target\");\n if (parsed.threadId) {\n const threadId = discordId(parsed.threadId, \"Discord thread\");\n const to = `channel:${threadId}`;\n return {\n channel: \"discord\",\n providerTargetKey: providerTargetKey(threadId),\n replyChannel: \"discord\",\n replyTo: to,\n to,\n };\n }\n const to = `${parsed.kind === \"direct\" ? \"user\" : \"channel\"}:${id}`;\n return {\n channel: \"discord\",\n providerTargetKey: providerTargetKey(\n parsed.kind === \"direct\" ? discordDirectChannelId(discord.botUserId, id) : id,\n ),\n replyChannel: \"discord\",\n replyTo: to,\n to,\n };\n },\n createInbound(input) {\n const conversationId = discordId(input.conversation.id, \"Discord conversation\");\n const senderId = discordId(input.senderId, \"Discord sender\");\n const threadId = input.threadId ? discordId(input.threadId, \"Discord thread\") : undefined;\n if (input.conversation.kind === \"direct\" && threadId) {\n throw new Error(\"Discord direct messages do not support thread targets.\");\n }\n const channelId =\n input.conversation.kind === \"direct\"\n ? discordDirectChannelId(discord.botUserId, senderId)\n : (threadId ?? conversationId);\n return {\n ...createAdminInboundRequest(discord),\n providerBody: {\n channelId,\n content: input.text,\n ...(input.conversation.kind === \"group\"\n ? {\n guildId: \"135000000000000099\",\n ...(threadId ? { parentChannelId: conversationId } : {}),\n }\n : {}),\n senderId,\n ...(input.senderName ? { senderName: input.senderName } : {}),\n },\n providerTargetKey: providerTargetKey(channelId),\n qaTarget: qaTargetForInbound(input),\n stateConversation: { id: conversationId, kind: input.conversation.kind },\n ...(threadId ? { threadId } : {}),\n };\n },\n createOutboundObservation({ event }) {\n if (\n !isRecord(event) ||\n event.type !== \"api\" ||\n event.method !== \"POST\" ||\n typeof event.path !== \"string\" ||\n !isRecord(event.body)\n ) {\n return null;\n }\n const match = /^\\/api\\/v10\\/channels\\/(\\d{17,20})\\/messages$/u.exec(event.path);\n const channelId = match?.[1];\n const text = readNonBlankString(event.body.content);\n if (!channelId || !text) {\n return null;\n }\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n senderId: discord.botUserId,\n senderName: \"OpenClaw QA\",\n text,\n providerTargetKeys: [providerTargetKey(channelId)],\n fallbackTarget: channelId,\n };\n },\n };\n },\n});\n"]}
@@ -151,6 +151,7 @@ export const MATRIX_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablinePr
151
151
  const to = `room:${roomId}`;
152
152
  return {
153
153
  channel: "matrix",
154
+ providerTargetKey: roomId,
154
155
  replyChannel: "matrix",
155
156
  replyTo: to,
156
157
  to,
@@ -180,7 +181,7 @@ export const MATRIX_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablinePr
180
181
  ...(threadId ? { threadId } : {}),
181
182
  };
182
183
  },
183
- createOutboundFromRecorderEvent({ event, targetByProviderTarget }) {
184
+ createOutboundObservation({ event }) {
184
185
  if (!isRecord(event) ||
185
186
  event.type !== "api" ||
186
187
  event.method !== "PUT" ||
@@ -227,7 +228,8 @@ export const MATRIX_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablinePr
227
228
  senderId: matrix.botUserId,
228
229
  senderName: "OpenClaw QA",
229
230
  text,
230
- to: targetByProviderTarget.get(targetKey(roomId, threadId)) ?? targetKey(roomId, threadId),
231
+ providerTargetKeys: [targetKey(roomId, threadId)],
232
+ fallbackTarget: targetKey(roomId, threadId),
231
233
  };
232
234
  },
233
235
  };
@@ -1 +1 @@
1
- {"version":3,"file":"matrix.js","sourceRoot":"","sources":["../../../../src/openclaw/bridges/matrix.ts"],"names":[],"mappings":"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","sourcesContent":["import { isIP } from \"node:net\";\nimport { isMatrixEventId } from \"../../matrix-ids.js\";\nimport {\n canonicalConversationIdForInbound,\n createAdminInboundRequest,\n createOpenClawCrablineProviderBridge,\n DEFAULT_ACCOUNT_ID,\n isRecord,\n qaTargetForInbound,\n readNonBlankString,\n readString,\n} from \"../shared.js\";\nimport { throwProbeHttpError } from \"./probe-response.js\";\n\nconst MAX_MATRIX_IDENTIFIER_BYTES = 255;\n\nfunction isMatrixIpv4Address(value: string): boolean {\n const octets = value.split(\".\");\n return (\n octets.length === 4 && octets.every((octet) => /^\\d{1,3}$/u.test(octet) && Number(octet) <= 255)\n );\n}\n\nfunction isMatrixServerName(value: string): boolean {\n const ipv6 = /^\\[([^\\]]+)\\](?::(\\d{1,5}))?$/u.exec(value);\n if (ipv6) {\n return isIP(ipv6[1]!) === 6;\n }\n const hostAndPort = /^([^:]+?)(?::(\\d{1,5}))?$/u.exec(value);\n if (!hostAndPort) {\n return false;\n }\n const hostname = hostAndPort[1]!;\n if (isMatrixIpv4Address(hostname)) {\n return true;\n }\n if (/^\\d+\\.\\d+\\.\\d+\\.\\d+$/u.test(hostname)) {\n return false;\n }\n return hostname.length <= 255 && /^[A-Za-z0-9.-]+$/u.test(hostname);\n}\n\nfunction hasLoneSurrogate(value: string): boolean {\n for (let index = 0; index < value.length; index += 1) {\n const code = value.charCodeAt(index);\n if (code >= 0xd800 && code <= 0xdbff) {\n const next = value.charCodeAt(index + 1);\n if (next < 0xdc00 || next > 0xdfff) {\n return true;\n }\n index += 1;\n } else if (code >= 0xdc00 && code <= 0xdfff) {\n return true;\n }\n }\n return false;\n}\n\nfunction isMatrixRoomId(value: string): boolean {\n if (!value.startsWith(\"!\") || Buffer.byteLength(value, \"utf8\") > MAX_MATRIX_IDENTIFIER_BYTES) {\n return false;\n }\n const separator = value.indexOf(\":\");\n if (separator >= 2) {\n const localpart = value.slice(1, separator);\n return (\n !localpart.includes(\"\\0\") &&\n !hasLoneSurrogate(localpart) &&\n isMatrixServerName(value.slice(separator + 1))\n );\n }\n const opaqueId = value.slice(1);\n if (!/^[A-Za-z0-9_-]{43}$/u.test(opaqueId)) {\n return false;\n }\n const decoded = Buffer.from(opaqueId, \"base64url\");\n return decoded.length === 32 && decoded.toString(\"base64url\") === opaqueId;\n}\n\nfunction matrixRoomId(value: string): string {\n const trimmed = value.trim();\n if (!isMatrixRoomId(trimmed)) {\n throw new Error(\"Matrix targets must be native room IDs.\");\n }\n return trimmed;\n}\n\nfunction targetKey(roomId: string, threadId?: string): string {\n return threadId ? `${roomId}:thread:${threadId}` : roomId;\n}\n\nfunction matrixThreadId(value: string): string {\n const trimmed = value.trim();\n if (!isMatrixEventId(trimmed)) {\n throw new Error(\"Matrix thread IDs must be native event IDs.\");\n }\n return trimmed;\n}\n\nfunction eventThreadId(content: Record<string, unknown>): string | null | undefined {\n const relation = isRecord(content[\"m.relates_to\"]) ? content[\"m.relates_to\"] : undefined;\n if (relation?.rel_type !== \"m.thread\") {\n return undefined;\n }\n const eventId = readString(relation.event_id);\n return eventId && isMatrixEventId(eventId) ? eventId : null;\n}\n\nconst MAX_DELIVERED_MATRIX_TRANSACTIONS = 1_000;\n\nexport const MATRIX_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProviderBridge({\n provider: \"matrix\",\n createAdapter(matrix) {\n const deliveredTransactions = new Set<string>();\n return {\n async probe(signal) {\n const response = await fetch(`${matrix.endpoints.clientApiRoot}/account/whoami`, {\n headers: { authorization: `Bearer ${matrix.accessToken}` },\n ...(signal ? { signal } : {}),\n });\n if (!response.ok) {\n await throwProbeHttpError(\n response,\n `Crabline Matrix probe failed with HTTP ${response.status}.`,\n );\n }\n const payload: unknown = await response.json();\n if (!isRecord(payload) || readString(payload.user_id) !== matrix.botUserId) {\n throw new Error(\"Crabline Matrix whoami probe returned an unexpected user.\");\n }\n return payload;\n },\n createBinding() {\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n channel: \"matrix\",\n createProviderReadinessEnv: (env) => ({ ...env, ...matrix.env }),\n createGatewayConfig: (openclawConfig = {}) => {\n const channels = isRecord(openclawConfig.channels) ? openclawConfig.channels : {};\n const matrixConfig = isRecord(channels.matrix) ? channels.matrix : {};\n const dmConfig = isRecord(matrixConfig.dm) ? matrixConfig.dm : {};\n return {\n ...openclawConfig,\n channels: {\n ...channels,\n matrix: {\n ...matrixConfig,\n accessToken: matrix.accessToken,\n dm: {\n ...dmConfig,\n allowFrom: [\"*\"],\n policy: \"open\",\n },\n enabled: true,\n encryption: false,\n groupAllowFrom: [\"*\"],\n groupPolicy: \"open\",\n homeserver: matrix.baseUrl,\n network: { dangerouslyAllowPrivateNetwork: true },\n streaming: {\n mode: \"off\",\n block: { enabled: false },\n },\n userId: matrix.botUserId,\n },\n },\n };\n },\n requiredPluginIds: [\"matrix\"],\n };\n },\n createAgentDelivery(parsed) {\n if (parsed.threadId) {\n throw new Error(\"Matrix thread targets require OpenClaw QA thread forwarding.\");\n }\n const roomId = matrixRoomId(parsed.id);\n const to = `room:${roomId}`;\n return {\n channel: \"matrix\",\n replyChannel: \"matrix\",\n replyTo: to,\n to,\n };\n },\n createInbound(input) {\n const roomId = matrixRoomId(canonicalConversationIdForInbound(input));\n const rawThreadId = input.threadId?.trim();\n const threadId = rawThreadId ? matrixThreadId(rawThreadId) : undefined;\n const direct = input.conversation.kind === \"direct\";\n return {\n ...createAdminInboundRequest(matrix),\n providerBody: {\n roomId,\n direct,\n senderId: input.senderId,\n ...(input.senderName ? { senderName: input.senderName } : {}),\n text: input.text,\n ...(threadId ? { threadId } : {}),\n },\n providerTargetKey: targetKey(roomId, threadId),\n qaTarget: qaTargetForInbound(input),\n stateConversation: {\n id: roomId,\n kind: direct ? \"direct\" : \"group\",\n },\n ...(threadId ? { threadId } : {}),\n };\n },\n createOutboundFromRecorderEvent({ event, targetByProviderTarget }) {\n if (\n !isRecord(event) ||\n event.type !== \"api\" ||\n event.method !== \"PUT\" ||\n event.replayed === true ||\n !isRecord(event.body)\n ) {\n return null;\n }\n const match =\n /^\\/_matrix\\/client\\/(?:v3|r0)\\/rooms\\/([^/]+)\\/send\\/([^/]+)\\/([^/]+)$/u.exec(\n readString(event.path) ?? \"\",\n );\n if (!match) {\n return null;\n }\n let roomId: string;\n let eventType: string;\n let transactionId: string;\n try {\n roomId = decodeURIComponent(match[1]!);\n eventType = decodeURIComponent(match[2]!);\n transactionId = decodeURIComponent(match[3]!);\n } catch {\n return null;\n }\n if (eventType !== \"m.room.message\") {\n return null;\n }\n const text = readNonBlankString(event.body.body);\n if (!text) {\n return null;\n }\n const transactionKey = JSON.stringify([roomId, eventType, transactionId]);\n if (deliveredTransactions.has(transactionKey)) {\n return null;\n }\n const threadId = eventThreadId(event.body);\n if (threadId === null) {\n return null;\n }\n deliveredTransactions.add(transactionKey);\n if (deliveredTransactions.size > MAX_DELIVERED_MATRIX_TRANSACTIONS) {\n deliveredTransactions.delete(deliveredTransactions.values().next().value!);\n }\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n senderId: matrix.botUserId,\n senderName: \"OpenClaw QA\",\n text,\n to:\n targetByProviderTarget.get(targetKey(roomId, threadId)) ?? targetKey(roomId, threadId),\n };\n },\n };\n },\n});\n"]}
1
+ {"version":3,"file":"matrix.js","sourceRoot":"","sources":["../../../../src/openclaw/bridges/matrix.ts"],"names":[],"mappings":"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","sourcesContent":["import { isIP } from \"node:net\";\nimport { isMatrixEventId } from \"../../matrix-ids.js\";\nimport {\n canonicalConversationIdForInbound,\n createAdminInboundRequest,\n createOpenClawCrablineProviderBridge,\n DEFAULT_ACCOUNT_ID,\n isRecord,\n qaTargetForInbound,\n readNonBlankString,\n readString,\n} from \"../shared.js\";\nimport { throwProbeHttpError } from \"./probe-response.js\";\n\nconst MAX_MATRIX_IDENTIFIER_BYTES = 255;\n\nfunction isMatrixIpv4Address(value: string): boolean {\n const octets = value.split(\".\");\n return (\n octets.length === 4 && octets.every((octet) => /^\\d{1,3}$/u.test(octet) && Number(octet) <= 255)\n );\n}\n\nfunction isMatrixServerName(value: string): boolean {\n const ipv6 = /^\\[([^\\]]+)\\](?::(\\d{1,5}))?$/u.exec(value);\n if (ipv6) {\n return isIP(ipv6[1]!) === 6;\n }\n const hostAndPort = /^([^:]+?)(?::(\\d{1,5}))?$/u.exec(value);\n if (!hostAndPort) {\n return false;\n }\n const hostname = hostAndPort[1]!;\n if (isMatrixIpv4Address(hostname)) {\n return true;\n }\n if (/^\\d+\\.\\d+\\.\\d+\\.\\d+$/u.test(hostname)) {\n return false;\n }\n return hostname.length <= 255 && /^[A-Za-z0-9.-]+$/u.test(hostname);\n}\n\nfunction hasLoneSurrogate(value: string): boolean {\n for (let index = 0; index < value.length; index += 1) {\n const code = value.charCodeAt(index);\n if (code >= 0xd800 && code <= 0xdbff) {\n const next = value.charCodeAt(index + 1);\n if (next < 0xdc00 || next > 0xdfff) {\n return true;\n }\n index += 1;\n } else if (code >= 0xdc00 && code <= 0xdfff) {\n return true;\n }\n }\n return false;\n}\n\nfunction isMatrixRoomId(value: string): boolean {\n if (!value.startsWith(\"!\") || Buffer.byteLength(value, \"utf8\") > MAX_MATRIX_IDENTIFIER_BYTES) {\n return false;\n }\n const separator = value.indexOf(\":\");\n if (separator >= 2) {\n const localpart = value.slice(1, separator);\n return (\n !localpart.includes(\"\\0\") &&\n !hasLoneSurrogate(localpart) &&\n isMatrixServerName(value.slice(separator + 1))\n );\n }\n const opaqueId = value.slice(1);\n if (!/^[A-Za-z0-9_-]{43}$/u.test(opaqueId)) {\n return false;\n }\n const decoded = Buffer.from(opaqueId, \"base64url\");\n return decoded.length === 32 && decoded.toString(\"base64url\") === opaqueId;\n}\n\nfunction matrixRoomId(value: string): string {\n const trimmed = value.trim();\n if (!isMatrixRoomId(trimmed)) {\n throw new Error(\"Matrix targets must be native room IDs.\");\n }\n return trimmed;\n}\n\nfunction targetKey(roomId: string, threadId?: string): string {\n return threadId ? `${roomId}:thread:${threadId}` : roomId;\n}\n\nfunction matrixThreadId(value: string): string {\n const trimmed = value.trim();\n if (!isMatrixEventId(trimmed)) {\n throw new Error(\"Matrix thread IDs must be native event IDs.\");\n }\n return trimmed;\n}\n\nfunction eventThreadId(content: Record<string, unknown>): string | null | undefined {\n const relation = isRecord(content[\"m.relates_to\"]) ? content[\"m.relates_to\"] : undefined;\n if (relation?.rel_type !== \"m.thread\") {\n return undefined;\n }\n const eventId = readString(relation.event_id);\n return eventId && isMatrixEventId(eventId) ? eventId : null;\n}\n\nconst MAX_DELIVERED_MATRIX_TRANSACTIONS = 1_000;\n\nexport const MATRIX_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProviderBridge({\n provider: \"matrix\",\n createAdapter(matrix) {\n const deliveredTransactions = new Set<string>();\n return {\n async probe(signal) {\n const response = await fetch(`${matrix.endpoints.clientApiRoot}/account/whoami`, {\n headers: { authorization: `Bearer ${matrix.accessToken}` },\n ...(signal ? { signal } : {}),\n });\n if (!response.ok) {\n await throwProbeHttpError(\n response,\n `Crabline Matrix probe failed with HTTP ${response.status}.`,\n );\n }\n const payload: unknown = await response.json();\n if (!isRecord(payload) || readString(payload.user_id) !== matrix.botUserId) {\n throw new Error(\"Crabline Matrix whoami probe returned an unexpected user.\");\n }\n return payload;\n },\n createBinding() {\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n channel: \"matrix\",\n createProviderReadinessEnv: (env) => ({ ...env, ...matrix.env }),\n createGatewayConfig: (openclawConfig = {}) => {\n const channels = isRecord(openclawConfig.channels) ? openclawConfig.channels : {};\n const matrixConfig = isRecord(channels.matrix) ? channels.matrix : {};\n const dmConfig = isRecord(matrixConfig.dm) ? matrixConfig.dm : {};\n return {\n ...openclawConfig,\n channels: {\n ...channels,\n matrix: {\n ...matrixConfig,\n accessToken: matrix.accessToken,\n dm: {\n ...dmConfig,\n allowFrom: [\"*\"],\n policy: \"open\",\n },\n enabled: true,\n encryption: false,\n groupAllowFrom: [\"*\"],\n groupPolicy: \"open\",\n homeserver: matrix.baseUrl,\n network: { dangerouslyAllowPrivateNetwork: true },\n streaming: {\n mode: \"off\",\n block: { enabled: false },\n },\n userId: matrix.botUserId,\n },\n },\n };\n },\n requiredPluginIds: [\"matrix\"],\n };\n },\n createAgentDelivery(parsed) {\n if (parsed.threadId) {\n throw new Error(\"Matrix thread targets require OpenClaw QA thread forwarding.\");\n }\n const roomId = matrixRoomId(parsed.id);\n const to = `room:${roomId}`;\n return {\n channel: \"matrix\",\n providerTargetKey: roomId,\n replyChannel: \"matrix\",\n replyTo: to,\n to,\n };\n },\n createInbound(input) {\n const roomId = matrixRoomId(canonicalConversationIdForInbound(input));\n const rawThreadId = input.threadId?.trim();\n const threadId = rawThreadId ? matrixThreadId(rawThreadId) : undefined;\n const direct = input.conversation.kind === \"direct\";\n return {\n ...createAdminInboundRequest(matrix),\n providerBody: {\n roomId,\n direct,\n senderId: input.senderId,\n ...(input.senderName ? { senderName: input.senderName } : {}),\n text: input.text,\n ...(threadId ? { threadId } : {}),\n },\n providerTargetKey: targetKey(roomId, threadId),\n qaTarget: qaTargetForInbound(input),\n stateConversation: {\n id: roomId,\n kind: direct ? \"direct\" : \"group\",\n },\n ...(threadId ? { threadId } : {}),\n };\n },\n createOutboundObservation({ event }) {\n if (\n !isRecord(event) ||\n event.type !== \"api\" ||\n event.method !== \"PUT\" ||\n event.replayed === true ||\n !isRecord(event.body)\n ) {\n return null;\n }\n const match =\n /^\\/_matrix\\/client\\/(?:v3|r0)\\/rooms\\/([^/]+)\\/send\\/([^/]+)\\/([^/]+)$/u.exec(\n readString(event.path) ?? \"\",\n );\n if (!match) {\n return null;\n }\n let roomId: string;\n let eventType: string;\n let transactionId: string;\n try {\n roomId = decodeURIComponent(match[1]!);\n eventType = decodeURIComponent(match[2]!);\n transactionId = decodeURIComponent(match[3]!);\n } catch {\n return null;\n }\n if (eventType !== \"m.room.message\") {\n return null;\n }\n const text = readNonBlankString(event.body.body);\n if (!text) {\n return null;\n }\n const transactionKey = JSON.stringify([roomId, eventType, transactionId]);\n if (deliveredTransactions.has(transactionKey)) {\n return null;\n }\n const threadId = eventThreadId(event.body);\n if (threadId === null) {\n return null;\n }\n deliveredTransactions.add(transactionKey);\n if (deliveredTransactions.size > MAX_DELIVERED_MATRIX_TRANSACTIONS) {\n deliveredTransactions.delete(deliveredTransactions.values().next().value!);\n }\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n senderId: matrix.botUserId,\n senderName: \"OpenClaw QA\",\n text,\n providerTargetKeys: [targetKey(roomId, threadId)],\n fallbackTarget: targetKey(roomId, threadId),\n };\n },\n };\n },\n});\n"]}
@@ -1,25 +1,39 @@
1
- import { canonicalConversationIdForInbound, createAdminInboundRequest, createOpenClawCrablineProviderBridge, DEFAULT_ACCOUNT_ID, isRecord, qaTargetForInbound, readNonBlankString, readString, } from "../shared.js";
1
+ import { canonicalConversationIdForInbound, createAdminInboundRequest, createProviderIdRegistry, createOpenClawCrablineProviderBridge, DEFAULT_ACCOUNT_ID, isRecord, qaTargetForInbound, readNonBlankString, readString, } from "../shared.js";
2
2
  import { mattermostId } from "../../servers/mattermost.js";
3
3
  import { throwProbeHttpError } from "./probe-response.js";
4
+ const MATTERMOST_ID_PATTERN = /^[a-z0-9]{26}$/u;
4
5
  function nativeId(value, label = "Mattermost target") {
5
6
  const trimmed = value.trim();
6
- if (!/^[a-z0-9]{26}$/u.test(trimmed)) {
7
+ if (!MATTERMOST_ID_PATTERN.test(trimmed)) {
7
8
  throw new Error(`${label} must be exactly 26 lowercase alphanumeric characters.`);
8
9
  }
9
10
  return trimmed;
10
11
  }
11
- function directChannelId(botUserId, userId) {
12
- return mattermostId(`dm:${[botUserId, userId].sort().join(":")}`);
12
+ function providerId(value, label, registry) {
13
+ const trimmed = value.trim();
14
+ if (!trimmed) {
15
+ throw new Error(`${label} is required.`);
16
+ }
17
+ return MATTERMOST_ID_PATTERN.test(trimmed)
18
+ ? registry.reserveNative(trimmed)
19
+ : registry.resolveLogical(trimmed);
20
+ }
21
+ function directTargetKey(userId) {
22
+ return `user:${userId}`;
13
23
  }
14
24
  function targetKey(channelId, rootId) {
15
25
  return rootId ? `${channelId}:thread:${rootId}` : channelId;
16
26
  }
17
- function threadRootId(channelId, value) {
18
- return nativeId(value, `Mattermost root post for channel ${channelId}`);
19
- }
20
27
  export const MATTERMOST_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProviderBridge({
21
28
  provider: "mattermost",
22
29
  createAdapter(mattermost) {
30
+ const createRegistry = (label) => createProviderIdRegistry({
31
+ candidate: mattermostId,
32
+ conflictLabel: label,
33
+ });
34
+ const userIds = createRegistry("Mattermost user target");
35
+ const channelIds = createRegistry("Mattermost channel target");
36
+ const postIds = createRegistry("Mattermost post target");
23
37
  return {
24
38
  async probe(signal) {
25
39
  const response = await fetch(`${mattermost.endpoints.apiRoot}/users/me`, {
@@ -75,9 +89,19 @@ export const MATTERMOST_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrabli
75
89
  if (parsed.threadId) {
76
90
  throw new Error("Mattermost thread targets require OpenClaw QA thread forwarding.");
77
91
  }
78
- const id = nativeId(parsed.id);
92
+ const registry = parsed.kind === "direct" ? userIds : channelIds;
93
+ const targetId = parsed.id.trim();
94
+ const id = parsed.native || MATTERMOST_ID_PATTERN.test(targetId)
95
+ ? registry.reserveNative(nativeId(targetId))
96
+ : registry.resolveLogical(targetId);
79
97
  const to = parsed.kind === "direct" ? `user:${id}` : `channel:${id}`;
80
- return { channel: "mattermost", replyChannel: "mattermost", replyTo: to, to };
98
+ return {
99
+ channel: "mattermost",
100
+ providerTargetKey: parsed.kind === "direct" ? directTargetKey(id) : id,
101
+ replyChannel: "mattermost",
102
+ replyTo: to,
103
+ to,
104
+ };
81
105
  },
82
106
  createInbound(input) {
83
107
  const kind = input.conversation.kind === "direct" ? "direct" : "group";
@@ -85,33 +109,41 @@ export const MATTERMOST_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrabli
85
109
  if (!conversationId) {
86
110
  throw new Error("Mattermost conversation id is required.");
87
111
  }
88
- const senderId = nativeId(input.senderId);
89
- const recipientId = kind === "direct" ? nativeId(conversationId) : undefined;
112
+ const senderId = providerId(input.senderId, "Mattermost sender", userIds);
113
+ const recipientId = kind === "direct"
114
+ ? providerId(conversationId, "Mattermost conversation", userIds)
115
+ : undefined;
90
116
  if (recipientId !== undefined && recipientId !== senderId) {
91
117
  throw new Error("Mattermost direct conversation and sender must identify the same recipient.");
92
118
  }
93
- const channelId = kind === "direct"
94
- ? directChannelId(mattermost.botUserId, senderId)
95
- : nativeId(conversationId);
119
+ const channelId = kind === "group"
120
+ ? providerId(conversationId, "Mattermost conversation", channelIds)
121
+ : undefined;
96
122
  const threadId = input.threadId?.trim();
97
- const rootId = threadId ? threadRootId(channelId, threadId) : undefined;
123
+ const rootId = threadId
124
+ ? MATTERMOST_ID_PATTERN.test(threadId)
125
+ ? postIds.reserveNative(threadId)
126
+ : postIds.resolveLogical(`thread:${kind === "group" ? channelId : senderId}:${threadId}`)
127
+ : undefined;
98
128
  return {
99
129
  ...createAdminInboundRequest(mattermost),
100
130
  providerBody: {
101
- channelId,
131
+ ...(channelId ? { channelId } : {}),
102
132
  channelType: kind === "direct" ? "D" : "O",
103
133
  ...(rootId ? { rootId } : {}),
104
134
  senderId,
105
135
  ...(input.senderName ? { senderName: input.senderName } : {}),
106
136
  text: input.text,
107
137
  },
108
- providerTargetKey: targetKey(channelId, rootId),
138
+ providerTargetKey: kind === "direct"
139
+ ? targetKey(directTargetKey(senderId), rootId)
140
+ : targetKey(channelId, rootId),
109
141
  qaTarget: qaTargetForInbound(input),
110
142
  stateConversation: { id: conversationId, kind },
111
143
  ...(rootId ? { threadId: rootId } : {}),
112
144
  };
113
145
  },
114
- createOutboundFromRecorderEvent({ event, targetByProviderTarget }) {
146
+ createOutboundObservation({ event }) {
115
147
  if (!isRecord(event) ||
116
148
  event.type !== "api" ||
117
149
  event.method !== "POST" ||
@@ -125,18 +157,33 @@ export const MATTERMOST_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrabli
125
157
  if (!channelId || !text) {
126
158
  return null;
127
159
  }
128
- const target = targetByProviderTarget.get(targetKey(channelId, rootId));
129
- if (!target) {
130
- return null;
131
- }
160
+ const providerTargetKey = targetKey(channelId, rootId);
161
+ const channel = isRecord(event.channel) ? event.channel : undefined;
162
+ const directUserId = channel?.type === "D"
163
+ ? readString(channel.name)
164
+ ?.split("__")
165
+ .find((participant) => participant !== mattermost.botUserId)
166
+ : undefined;
132
167
  return {
133
168
  accountId: DEFAULT_ACCOUNT_ID,
134
169
  senderId: mattermost.botUserId,
135
170
  senderName: "OpenClaw QA",
136
171
  text,
137
- to: target,
172
+ providerTargetKeys: [
173
+ providerTargetKey,
174
+ ...(directUserId ? [targetKey(directTargetKey(directUserId), rootId)] : []),
175
+ ],
138
176
  };
139
177
  },
178
+ resolveInboundProviderTargetKey({ response }) {
179
+ const post = isRecord(response) && isRecord(response.post) ? response.post : undefined;
180
+ const channelId = post ? readString(post.channel_id) : undefined;
181
+ const rootId = post ? readString(post.root_id) : undefined;
182
+ if (!channelId) {
183
+ throw new Error("Crabline Mattermost inbound response did not identify its provider channel.");
184
+ }
185
+ return targetKey(channelId, rootId);
186
+ },
140
187
  };
141
188
  },
142
189
  });
@@ -1 +1 @@
1
- {"version":3,"file":"mattermost.js","sourceRoot":"","sources":["../../../../src/openclaw/bridges/mattermost.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n canonicalConversationIdForInbound,\n createAdminInboundRequest,\n createOpenClawCrablineProviderBridge,\n DEFAULT_ACCOUNT_ID,\n isRecord,\n qaTargetForInbound,\n readNonBlankString,\n readString,\n} from \"../shared.js\";\nimport { mattermostId } from \"../../servers/mattermost.js\";\nimport { throwProbeHttpError } from \"./probe-response.js\";\n\nfunction nativeId(value: string, label = \"Mattermost target\"): string {\n const trimmed = value.trim();\n if (!/^[a-z0-9]{26}$/u.test(trimmed)) {\n throw new Error(`${label} must be exactly 26 lowercase alphanumeric characters.`);\n }\n return trimmed;\n}\n\nfunction directChannelId(botUserId: string, userId: string): string {\n return mattermostId(`dm:${[botUserId, userId].sort().join(\":\")}`);\n}\n\nfunction targetKey(channelId: string, rootId?: string): string {\n return rootId ? `${channelId}:thread:${rootId}` : channelId;\n}\n\nfunction threadRootId(channelId: string, value: string): string {\n return nativeId(value, `Mattermost root post for channel ${channelId}`);\n}\n\nexport const MATTERMOST_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProviderBridge({\n provider: \"mattermost\",\n createAdapter(mattermost) {\n return {\n async probe(signal) {\n const response = await fetch(`${mattermost.endpoints.apiRoot}/users/me`, {\n headers: { authorization: `Bearer ${mattermost.botToken}` },\n ...(signal ? { signal } : {}),\n });\n if (!response.ok) {\n await throwProbeHttpError(\n response,\n `Crabline Mattermost probe failed with HTTP ${response.status}.`,\n );\n }\n const payload: unknown = await response.json();\n if (\n !isRecord(payload) ||\n readString(payload.id) !== mattermost.botUserId ||\n !readNonBlankString(payload.username) ||\n typeof payload.update_at !== \"number\" ||\n !Number.isSafeInteger(payload.update_at) ||\n payload.update_at < 0\n ) {\n throw new Error(\"Crabline Mattermost users/me probe returned an unexpected user.\");\n }\n return payload;\n },\n createBinding() {\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n channel: \"mattermost\",\n createProviderReadinessEnv: (env) => ({ ...env, ...mattermost.env }),\n createGatewayConfig: (openclawConfig = {}) => {\n const channels = isRecord(openclawConfig.channels) ? openclawConfig.channels : {};\n const mattermostConfig = isRecord(channels.mattermost) ? channels.mattermost : {};\n return {\n ...openclawConfig,\n channels: {\n ...channels,\n mattermost: {\n ...mattermostConfig,\n allowFrom: [\"*\"],\n baseUrl: mattermost.baseUrl,\n botToken: mattermost.botToken,\n chatmode: \"onmessage\",\n dmPolicy: \"open\",\n enabled: true,\n groupAllowFrom: [\"*\"],\n groupPolicy: \"open\",\n network: { dangerouslyAllowPrivateNetwork: true },\n streaming: { mode: \"off\" },\n },\n },\n };\n },\n requiredPluginIds: [\"mattermost\"],\n };\n },\n createAgentDelivery(parsed) {\n if (parsed.threadId) {\n throw new Error(\"Mattermost thread targets require OpenClaw QA thread forwarding.\");\n }\n const id = nativeId(parsed.id);\n const to = parsed.kind === \"direct\" ? `user:${id}` : `channel:${id}`;\n return { channel: \"mattermost\", replyChannel: \"mattermost\", replyTo: to, to };\n },\n createInbound(input) {\n const kind = input.conversation.kind === \"direct\" ? \"direct\" : \"group\";\n const conversationId = canonicalConversationIdForInbound(input);\n if (!conversationId) {\n throw new Error(\"Mattermost conversation id is required.\");\n }\n const senderId = nativeId(input.senderId);\n const recipientId = kind === \"direct\" ? nativeId(conversationId) : undefined;\n if (recipientId !== undefined && recipientId !== senderId) {\n throw new Error(\n \"Mattermost direct conversation and sender must identify the same recipient.\",\n );\n }\n const channelId =\n kind === \"direct\"\n ? directChannelId(mattermost.botUserId, senderId)\n : nativeId(conversationId);\n const threadId = input.threadId?.trim();\n const rootId = threadId ? threadRootId(channelId, threadId) : undefined;\n return {\n ...createAdminInboundRequest(mattermost),\n providerBody: {\n channelId,\n channelType: kind === \"direct\" ? \"D\" : \"O\",\n ...(rootId ? { rootId } : {}),\n senderId,\n ...(input.senderName ? { senderName: input.senderName } : {}),\n text: input.text,\n },\n providerTargetKey: targetKey(channelId, rootId),\n qaTarget: qaTargetForInbound(input),\n stateConversation: { id: conversationId, kind },\n ...(rootId ? { threadId: rootId } : {}),\n };\n },\n createOutboundFromRecorderEvent({ event, targetByProviderTarget }) {\n if (\n !isRecord(event) ||\n event.type !== \"api\" ||\n event.method !== \"POST\" ||\n event.path !== \"/api/v4/posts\" ||\n !isRecord(event.body)\n ) {\n return null;\n }\n const channelId = readString(event.body.channel_id);\n const rootId = readString(event.body.root_id);\n const text = readNonBlankString(event.body.message);\n if (!channelId || !text) {\n return null;\n }\n const target = targetByProviderTarget.get(targetKey(channelId, rootId));\n if (!target) {\n return null;\n }\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n senderId: mattermost.botUserId,\n senderName: \"OpenClaw QA\",\n text,\n to: target,\n };\n },\n };\n },\n});\n"]}
1
+ {"version":3,"file":"mattermost.js","sourceRoot":"","sources":["../../../../src/openclaw/bridges/mattermost.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n canonicalConversationIdForInbound,\n createAdminInboundRequest,\n createProviderIdRegistry,\n createOpenClawCrablineProviderBridge,\n DEFAULT_ACCOUNT_ID,\n isRecord,\n qaTargetForInbound,\n readNonBlankString,\n readString,\n} from \"../shared.js\";\nimport { mattermostId } from \"../../servers/mattermost.js\";\nimport { throwProbeHttpError } from \"./probe-response.js\";\n\nconst MATTERMOST_ID_PATTERN = /^[a-z0-9]{26}$/u;\n\nfunction nativeId(value: string, label = \"Mattermost target\"): string {\n const trimmed = value.trim();\n if (!MATTERMOST_ID_PATTERN.test(trimmed)) {\n throw new Error(`${label} must be exactly 26 lowercase alphanumeric characters.`);\n }\n return trimmed;\n}\n\nfunction providerId(\n value: string,\n label: string,\n registry: ReturnType<typeof createProviderIdRegistry>,\n): string {\n const trimmed = value.trim();\n if (!trimmed) {\n throw new Error(`${label} is required.`);\n }\n return MATTERMOST_ID_PATTERN.test(trimmed)\n ? registry.reserveNative(trimmed)\n : registry.resolveLogical(trimmed);\n}\n\nfunction directTargetKey(userId: string): string {\n return `user:${userId}`;\n}\n\nfunction targetKey(channelId: string, rootId?: string): string {\n return rootId ? `${channelId}:thread:${rootId}` : channelId;\n}\n\nexport const MATTERMOST_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablineProviderBridge({\n provider: \"mattermost\",\n createAdapter(mattermost) {\n const createRegistry = (label: string) =>\n createProviderIdRegistry({\n candidate: mattermostId,\n conflictLabel: label,\n });\n const userIds = createRegistry(\"Mattermost user target\");\n const channelIds = createRegistry(\"Mattermost channel target\");\n const postIds = createRegistry(\"Mattermost post target\");\n return {\n async probe(signal) {\n const response = await fetch(`${mattermost.endpoints.apiRoot}/users/me`, {\n headers: { authorization: `Bearer ${mattermost.botToken}` },\n ...(signal ? { signal } : {}),\n });\n if (!response.ok) {\n await throwProbeHttpError(\n response,\n `Crabline Mattermost probe failed with HTTP ${response.status}.`,\n );\n }\n const payload: unknown = await response.json();\n if (\n !isRecord(payload) ||\n readString(payload.id) !== mattermost.botUserId ||\n !readNonBlankString(payload.username) ||\n typeof payload.update_at !== \"number\" ||\n !Number.isSafeInteger(payload.update_at) ||\n payload.update_at < 0\n ) {\n throw new Error(\"Crabline Mattermost users/me probe returned an unexpected user.\");\n }\n return payload;\n },\n createBinding() {\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n channel: \"mattermost\",\n createProviderReadinessEnv: (env) => ({ ...env, ...mattermost.env }),\n createGatewayConfig: (openclawConfig = {}) => {\n const channels = isRecord(openclawConfig.channels) ? openclawConfig.channels : {};\n const mattermostConfig = isRecord(channels.mattermost) ? channels.mattermost : {};\n return {\n ...openclawConfig,\n channels: {\n ...channels,\n mattermost: {\n ...mattermostConfig,\n allowFrom: [\"*\"],\n baseUrl: mattermost.baseUrl,\n botToken: mattermost.botToken,\n chatmode: \"onmessage\",\n dmPolicy: \"open\",\n enabled: true,\n groupAllowFrom: [\"*\"],\n groupPolicy: \"open\",\n network: { dangerouslyAllowPrivateNetwork: true },\n streaming: { mode: \"off\" },\n },\n },\n };\n },\n requiredPluginIds: [\"mattermost\"],\n };\n },\n createAgentDelivery(parsed) {\n if (parsed.threadId) {\n throw new Error(\"Mattermost thread targets require OpenClaw QA thread forwarding.\");\n }\n const registry = parsed.kind === \"direct\" ? userIds : channelIds;\n const targetId = parsed.id.trim();\n const id =\n parsed.native || MATTERMOST_ID_PATTERN.test(targetId)\n ? registry.reserveNative(nativeId(targetId))\n : registry.resolveLogical(targetId);\n const to = parsed.kind === \"direct\" ? `user:${id}` : `channel:${id}`;\n return {\n channel: \"mattermost\",\n providerTargetKey: parsed.kind === \"direct\" ? directTargetKey(id) : id,\n replyChannel: \"mattermost\",\n replyTo: to,\n to,\n };\n },\n createInbound(input) {\n const kind = input.conversation.kind === \"direct\" ? \"direct\" : \"group\";\n const conversationId = canonicalConversationIdForInbound(input);\n if (!conversationId) {\n throw new Error(\"Mattermost conversation id is required.\");\n }\n const senderId = providerId(input.senderId, \"Mattermost sender\", userIds);\n const recipientId =\n kind === \"direct\"\n ? providerId(conversationId, \"Mattermost conversation\", userIds)\n : undefined;\n if (recipientId !== undefined && recipientId !== senderId) {\n throw new Error(\n \"Mattermost direct conversation and sender must identify the same recipient.\",\n );\n }\n const channelId =\n kind === \"group\"\n ? providerId(conversationId, \"Mattermost conversation\", channelIds)\n : undefined;\n const threadId = input.threadId?.trim();\n const rootId = threadId\n ? MATTERMOST_ID_PATTERN.test(threadId)\n ? postIds.reserveNative(threadId)\n : postIds.resolveLogical(\n `thread:${kind === \"group\" ? channelId : senderId}:${threadId}`,\n )\n : undefined;\n return {\n ...createAdminInboundRequest(mattermost),\n providerBody: {\n ...(channelId ? { channelId } : {}),\n channelType: kind === \"direct\" ? \"D\" : \"O\",\n ...(rootId ? { rootId } : {}),\n senderId,\n ...(input.senderName ? { senderName: input.senderName } : {}),\n text: input.text,\n },\n providerTargetKey:\n kind === \"direct\"\n ? targetKey(directTargetKey(senderId), rootId)\n : targetKey(channelId!, rootId),\n qaTarget: qaTargetForInbound(input),\n stateConversation: { id: conversationId, kind },\n ...(rootId ? { threadId: rootId } : {}),\n };\n },\n createOutboundObservation({ event }) {\n if (\n !isRecord(event) ||\n event.type !== \"api\" ||\n event.method !== \"POST\" ||\n event.path !== \"/api/v4/posts\" ||\n !isRecord(event.body)\n ) {\n return null;\n }\n const channelId = readString(event.body.channel_id);\n const rootId = readString(event.body.root_id);\n const text = readNonBlankString(event.body.message);\n if (!channelId || !text) {\n return null;\n }\n const providerTargetKey = targetKey(channelId, rootId);\n const channel = isRecord(event.channel) ? event.channel : undefined;\n const directUserId =\n channel?.type === \"D\"\n ? readString(channel.name)\n ?.split(\"__\")\n .find((participant) => participant !== mattermost.botUserId)\n : undefined;\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n senderId: mattermost.botUserId,\n senderName: \"OpenClaw QA\",\n text,\n providerTargetKeys: [\n providerTargetKey,\n ...(directUserId ? [targetKey(directTargetKey(directUserId), rootId)] : []),\n ],\n };\n },\n resolveInboundProviderTargetKey({ response }) {\n const post = isRecord(response) && isRecord(response.post) ? response.post : undefined;\n const channelId = post ? readString(post.channel_id) : undefined;\n const rootId = post ? readString(post.root_id) : undefined;\n if (!channelId) {\n throw new Error(\n \"Crabline Mattermost inbound response did not identify its provider channel.\",\n );\n }\n return targetKey(channelId, rootId);\n },\n };\n },\n});\n"]}
@@ -97,7 +97,13 @@ export const SIGNAL_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablinePr
97
97
  throw new Error("Signal does not support thread targets.");
98
98
  }
99
99
  const to = signalTarget(parsed.kind, parsed.id);
100
- return { channel: "signal", replyChannel: "signal", replyTo: to, to };
100
+ return {
101
+ channel: "signal",
102
+ providerTargetKey: to,
103
+ replyChannel: "signal",
104
+ replyTo: to,
105
+ to,
106
+ };
101
107
  },
102
108
  createInbound(input) {
103
109
  if (input.threadId !== undefined) {
@@ -129,7 +135,7 @@ export const SIGNAL_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablinePr
129
135
  stateConversation: { id: conversationId, kind },
130
136
  };
131
137
  },
132
- createOutboundFromRecorderEvent({ event, targetByProviderTarget }) {
138
+ createOutboundObservation({ event }) {
133
139
  if (!isRecord(event) ||
134
140
  event.type !== "api" ||
135
141
  event.path !== "/api/v1/rpc" ||
@@ -149,7 +155,8 @@ export const SIGNAL_OPENCLAW_CRABLINE_PROVIDER_BRIDGE = createOpenClawCrablinePr
149
155
  senderId: "openclaw",
150
156
  senderName: "OpenClaw QA",
151
157
  text,
152
- to: targetByProviderTarget.get(target) ?? target,
158
+ providerTargetKeys: [target],
159
+ fallbackTarget: target,
153
160
  };
154
161
  },
155
162
  };