@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
@@ -40,6 +40,10 @@ export type OpenClawCrablineAgentDelivery = {
40
40
  replyTo: string;
41
41
  to: string;
42
42
  };
43
+ export type OpenClawCrablineCorrelatedAgentDelivery = OpenClawCrablineAgentDelivery & {
44
+ /** Adapter correlation key used to associate later provider recorder events with this target. */
45
+ providerTargetKey: string;
46
+ };
43
47
  export type OpenClawCrablineInboundInput = {
44
48
  conversation: {
45
49
  id: string;
@@ -69,6 +73,12 @@ export type OpenClawCrablineOutboundMessage = {
69
73
  text: string;
70
74
  to: string;
71
75
  };
76
+ export type OpenClawCrablineOutboundObservation = Omit<OpenClawCrablineOutboundMessage, "to"> & {
77
+ /** Provider-authoritative keys, in lookup priority order, for consumer correlation. */
78
+ providerTargetKeys: readonly [string, ...string[]];
79
+ /** Provider-native target used only when no consumer correlation exists. */
80
+ fallbackTarget?: string | undefined;
81
+ };
72
82
  export type StartOpenClawCrablineAdapterParams = {
73
83
  channel: CrablineServerChannel;
74
84
  onEvent?: ServerEventObserver | undefined;
@@ -79,10 +89,15 @@ export type StartedOpenClawCrablineAdapter = OpenClawCrablineGatewayBinding & {
79
89
  close(): Promise<void>;
80
90
  createAgentDelivery(params: {
81
91
  target: string;
92
+ threadId?: string | undefined;
82
93
  }): OpenClawCrablineAgentDelivery;
83
94
  createInbound(params: {
84
95
  input: OpenClawCrablineInboundInput;
85
96
  }): OpenClawCrablineInbound;
97
+ createOutboundObservation(params: {
98
+ event: unknown;
99
+ }): OpenClawCrablineOutboundObservation | null;
100
+ /** @deprecated Use createOutboundObservation and correlate providerTargetKeys in the consumer. */
86
101
  createOutboundFromRecorderEvent(params: {
87
102
  event: unknown;
88
103
  targetByProviderTarget: ReadonlyMap<string, string>;
@@ -90,21 +105,46 @@ export type StartedOpenClawCrablineAdapter = OpenClawCrablineGatewayBinding & {
90
105
  manifest: CrablineServerManifest;
91
106
  probe(): Promise<unknown>;
92
107
  };
108
+ export type StartedOpenClawCrablineCorrelatedAdapter = Omit<StartedOpenClawCrablineAdapter, "createAgentDelivery"> & {
109
+ createAgentDelivery(params: {
110
+ target: string;
111
+ threadId?: string | undefined;
112
+ }): OpenClawCrablineCorrelatedAgentDelivery;
113
+ /** Resolves the provider-authoritative key from a successful inbound response. */
114
+ resolveInboundProviderTargetKey(params: {
115
+ inbound: OpenClawCrablineInbound;
116
+ response: unknown;
117
+ }): string;
118
+ };
93
119
  export type ParsedQaTarget = {
94
120
  kind: "direct" | "group";
95
121
  id: string;
96
122
  native: boolean;
97
123
  threadId?: string;
98
124
  };
125
+ export declare function parseQaDeliveryTarget(params: {
126
+ target: string;
127
+ threadId?: string | undefined;
128
+ }): ParsedQaTarget;
129
+ export declare function createProviderIdRegistry(params: {
130
+ candidate(logicalKey: string): string;
131
+ conflictLabel: string;
132
+ }): {
133
+ resolveLogical(logicalKey: string): string;
134
+ reserveNative(nativeId: string): string;
135
+ };
99
136
  export type OpenClawCrablineProviderAdapter = {
100
- createAgentDelivery(parsed: ParsedQaTarget): OpenClawCrablineAgentDelivery;
137
+ createAgentDelivery(parsed: ParsedQaTarget): OpenClawCrablineCorrelatedAgentDelivery;
101
138
  createBinding(): OpenClawCrablineGatewayBinding;
102
139
  createInbound(input: OpenClawCrablineInboundInput): OpenClawCrablineInbound;
103
- createOutboundFromRecorderEvent(params: {
140
+ createOutboundObservation(params: {
104
141
  event: unknown;
105
- targetByProviderTarget: ReadonlyMap<string, string>;
106
- }): OpenClawCrablineOutboundMessage | null;
142
+ }): OpenClawCrablineOutboundObservation | null;
107
143
  probe(signal?: AbortSignal): Promise<unknown>;
144
+ resolveInboundProviderTargetKey?(params: {
145
+ inbound: OpenClawCrablineInbound;
146
+ response: unknown;
147
+ }): string;
108
148
  };
109
149
  export type OpenClawCrablineProviderBridge<TManifest extends CrablineServerManifest = CrablineServerManifest> = {
110
150
  createAdapter(manifest: TManifest): OpenClawCrablineProviderAdapter;
@@ -124,6 +164,10 @@ export declare function createOpenClawCrablineProviderBridge<TProvider extends C
124
164
  }): OpenClawCrablineProviderBridge<Extract<CrablineServerManifest, {
125
165
  provider: TProvider;
126
166
  }>>;
167
+ export declare function correlateOpenClawCrablineOutboundObservation(params: {
168
+ observation: OpenClawCrablineOutboundObservation;
169
+ targetByProviderTarget: ReadonlyMap<string, string>;
170
+ }): OpenClawCrablineOutboundMessage | null;
127
171
  export declare function runOpenClawCrablineProviderProbe<T>(provider: CrablineServerManifest["provider"], probe: (signal: AbortSignal) => Promise<T>): Promise<T>;
128
172
  export declare function getUnsettledOpenClawCrablineProviderProbe(error: unknown): Promise<void> | undefined;
129
173
  export declare function readString(value: unknown): string | undefined;
@@ -19,6 +19,42 @@ const OPENCLAW_CRABLINE_PROVIDER_PROBE_LABELS = {
19
19
  zalo: "Zalo getMe",
20
20
  };
21
21
  const unsettledProviderProbeSettlements = new WeakMap();
22
+ export function parseQaDeliveryTarget(params) {
23
+ const parsed = parseQaTarget(params.target);
24
+ const threadId = params.threadId?.trim();
25
+ if (parsed.threadId && threadId && parsed.threadId !== threadId) {
26
+ throw new Error("OpenClaw Crabline delivery received conflicting thread targets.");
27
+ }
28
+ return threadId ? { ...parsed, threadId } : parsed;
29
+ }
30
+ export function createProviderIdRegistry(params) {
31
+ const idByLogicalKey = new Map();
32
+ const ownerById = new Map();
33
+ return {
34
+ resolveLogical(logicalKey) {
35
+ const existingId = idByLogicalKey.get(logicalKey);
36
+ if (existingId) {
37
+ return existingId;
38
+ }
39
+ const candidate = params.candidate(logicalKey);
40
+ const owner = ownerById.get(candidate);
41
+ if (owner && owner !== `logical:${logicalKey}`) {
42
+ throw new Error(`${params.conflictLabel} conflicts with another provider identity.`);
43
+ }
44
+ idByLogicalKey.set(logicalKey, candidate);
45
+ ownerById.set(candidate, `logical:${logicalKey}`);
46
+ return candidate;
47
+ },
48
+ reserveNative(nativeId) {
49
+ const owner = ownerById.get(nativeId);
50
+ if (owner?.startsWith("logical:")) {
51
+ throw new Error(`${params.conflictLabel} native id conflicts with a logical identity.`);
52
+ }
53
+ ownerById.set(nativeId, `native:${nativeId}`);
54
+ return nativeId;
55
+ },
56
+ };
57
+ }
22
58
  export function createOpenClawCrablineProviderBridge(params) {
23
59
  const createAdapter = (manifest) => {
24
60
  const adapter = params.createAdapter(manifest);
@@ -38,12 +74,17 @@ export function createOpenClawCrablineProviderBridge(params) {
38
74
  }
39
75
  return adapter.createInbound(input);
40
76
  },
41
- createOutboundFromRecorderEvent(outboundParams) {
42
- return adapter.createOutboundFromRecorderEvent(outboundParams);
77
+ createOutboundObservation(outboundParams) {
78
+ return adapter.createOutboundObservation(outboundParams);
43
79
  },
44
80
  probe(signal) {
45
81
  return adapter.probe(signal);
46
82
  },
83
+ ...(adapter.resolveInboundProviderTargetKey
84
+ ? {
85
+ resolveInboundProviderTargetKey: adapter.resolveInboundProviderTargetKey.bind(adapter),
86
+ }
87
+ : {}),
47
88
  };
48
89
  };
49
90
  const bridge = {
@@ -58,6 +99,16 @@ export function createOpenClawCrablineProviderBridge(params) {
58
99
  };
59
100
  return bridge;
60
101
  }
102
+ export function correlateOpenClawCrablineOutboundObservation(params) {
103
+ const to = params.observation.providerTargetKeys
104
+ .map((key) => params.targetByProviderTarget.get(key))
105
+ .find((target) => target !== undefined) ?? params.observation.fallbackTarget;
106
+ if (!to) {
107
+ return null;
108
+ }
109
+ const { fallbackTarget: _fallbackTarget, providerTargetKeys: _providerTargetKeys, ...message } = params.observation;
110
+ return { ...message, to };
111
+ }
61
112
  export async function runOpenClawCrablineProviderProbe(provider, probe) {
62
113
  const signal = AbortSignal.timeout(OPENCLAW_CRABLINE_PROVIDER_PROBE_TIMEOUT_MS);
63
114
  const timeoutError = (cause) => new Error(`Crabline ${OPENCLAW_CRABLINE_PROVIDER_PROBE_LABELS[provider]} probe timed out after ${OPENCLAW_CRABLINE_PROVIDER_PROBE_TIMEOUT_MS} ms.`, { cause });
@@ -142,12 +193,15 @@ export function parseQaTarget(target) {
142
193
  if (trimmed.startsWith("thread:")) {
143
194
  const encoded = trimmed.startsWith("thread:/v1/");
144
195
  const rest = trimmed.slice(encoded ? "thread:/v1/".length : "thread:".length);
145
- const slash = rest.indexOf("/");
146
- if (slash <= 0 || slash !== rest.lastIndexOf("/")) {
196
+ const components = rest.split("/");
197
+ const explicitKind = encoded && components.length === 3 && (components[0] === "dm" || components[0] === "group")
198
+ ? components.shift()
199
+ : undefined;
200
+ if (components.length !== 2) {
147
201
  return invalidTarget();
148
202
  }
149
- let id = rest.slice(0, slash).trim();
150
- let threadId = rest.slice(slash + 1).trim();
203
+ let id = components[0].trim();
204
+ let threadId = components[1].trim();
151
205
  if (encoded) {
152
206
  try {
153
207
  id = decodeURIComponent(id).trim();
@@ -160,11 +214,16 @@ export function parseQaTarget(target) {
160
214
  if (!id || !threadId) {
161
215
  return invalidTarget();
162
216
  }
163
- return { kind: "group", id, native: false, threadId };
217
+ return {
218
+ kind: explicitKind === "dm" ? "direct" : "group",
219
+ id,
220
+ native: false,
221
+ threadId,
222
+ };
164
223
  }
165
224
  if (trimmed.startsWith("channel:")) {
166
225
  const id = trimmed.slice("channel:".length).trim();
167
- return id ? { kind: "group", id, native: false } : invalidTarget();
226
+ return id ? { kind: "group", id, native: true } : invalidTarget();
168
227
  }
169
228
  if (trimmed.startsWith("group:")) {
170
229
  const id = trimmed.slice("group:".length).trim();
@@ -194,7 +253,7 @@ export function qaTargetForInbound(input) {
194
253
  const threadId = input.threadId?.trim();
195
254
  const prefix = input.conversation.kind === "direct" ? "dm" : "group";
196
255
  return threadId
197
- ? `thread:/v1/${encodeQaThreadComponent(conversationId)}/${encodeQaThreadComponent(threadId)}`
256
+ ? `thread:/v1/${input.conversation.kind === "direct" ? "dm/" : ""}${encodeQaThreadComponent(conversationId)}/${encodeQaThreadComponent(threadId)}`
198
257
  : `${prefix}:${conversationId}`;
199
258
  }
200
259
  export function createAdminInboundRequest(manifest) {
@@ -1 +1 @@
1
- {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/openclaw/shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAIxD,MAAM,CAAC,MAAM,kBAAkB,GAAG,SAAS,CAAC;AAC5C,MAAM,CAAC,MAAM,gDAAgD,GAC3D,2CAA2C,CAAC;AAC9C,MAAM,CAAC,MAAM,yCAAyC,GAAG,kCAAkC,CAAC;AAC5F,MAAM,CAAC,MAAM,+BAA+B,GAAG,+BAA+B,CAAC;AAC/E,MAAM,CAAC,MAAM,0CAA0C,GAAG,oCAAoC,CAAC;AAC/F,MAAM,CAAC,MAAM,uCAAuC,GAAG,GAAG,0CAA0C,eAAe,CAAC;AACpH,MAAM,CAAC,MAAM,iCAAiC,GAAG,UAAU,CAAC;AAE5D,MAAM,2CAA2C,GAAG,KAAK,CAAC;AAC1D,MAAM,+CAA+C,GAAG,GAAG,CAAC;AAC5D,MAAM,uCAAuC,GAAG;IAC9C,OAAO,EAAE,mBAAmB;IAC5B,UAAU,EAAE,qBAAqB;IACjC,MAAM,EAAE,eAAe;IACvB,MAAM,EAAE,cAAc;IACtB,KAAK,EAAE,iBAAiB;IACxB,QAAQ,EAAE,gBAAgB;IAC1B,QAAQ,EAAE,uBAAuB;IACjC,IAAI,EAAE,YAAY;CAC0C,CAAC;AAC/D,MAAM,iCAAiC,GAAG,IAAI,OAAO,EAAwB,CAAC;AAwH9E,MAAM,UAAU,oCAAoC,CAElD,MAKD;IAEC,MAAM,aAAa,GAAG,CAAC,QAA0B,EAAmC,EAAE;QACpF,MAAM,OAAO,GAAG,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC/C,OAAO;YACL,mBAAmB,CAAC,MAAM;gBACxB,OAAO,OAAO,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;YAC7C,CAAC;YACD,aAAa;gBACX,OAAO,OAAO,CAAC,aAAa,EAAE,CAAC;YACjC,CAAC;YACD,aAAa,CAAC,KAAK;gBACjB,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;oBACpC,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;gBACzE,CAAC;gBACD,IAAI,KAAK,CAAC,YAAY,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,YAAY,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBAChF,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;gBAC1F,CAAC;gBACD,OAAO,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YACtC,CAAC;YACD,+BAA+B,CAAC,cAAc;gBAC5C,OAAO,OAAO,CAAC,+BAA+B,CAAC,cAAc,CAAC,CAAC;YACjE,CAAC;YACD,KAAK,CAAC,MAAM;gBACV,OAAO,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC/B,CAAC;SACF,CAAC;IACJ,CAAC,CAAC;IACF,MAAM,MAAM,GAAqD;QAC/D,aAAa;QACb,yBAAyB,CAAC,QAAQ;YAChC,IAAI,QAAQ,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,EAAE,CAAC;gBAC1C,MAAM,IAAI,KAAK,CACb,mDAAmD,MAAM,CAAC,QAAQ,SAAS,QAAQ,CAAC,QAAQ,GAAG,CAChG,CAAC;YACJ,CAAC;YACD,OAAO,aAAa,CAAC,QAA4B,CAAC,CAAC;QACrD,CAAC;QACD,QAAQ,EAAE,MAAM,CAAC,QAAwC;KAC1D,CAAC;IACF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gCAAgC,CACpD,QAA4C,EAC5C,KAA0C;IAE1C,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,2CAA2C,CAAC,CAAC;IAChF,MAAM,YAAY,GAAG,CAAC,KAAc,EAAE,EAAE,CACtC,IAAI,KAAK,CACP,YAAY,uCAAuC,CAAC,QAAQ,CAAC,0BAA0B,2CAA2C,MAAM,EACxI,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAC5B,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CAChB,CAAC;IACF,IAAI,OAAiC,CAAC;IACtC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAsB,CAAC,OAAO,EAAE,EAAE;QAC3D,OAAO,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;QAC7C,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO,EAAE,CAAC;YACV,OAAO;QACT,CAAC;QACD,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IACH,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;YACjC,SAAS,CAAC,IAAI,CACZ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAiB,EAAE,KAAK,EAAE,CAAC,EAC/C,CAAC,KAAc,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,OAAgB,EAAE,CAAC,CACxD;YACD,OAAO;SACR,CAAC,CAAC;QACH,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,OAAO,CAAC,KAAK,CAAC;QACvB,CAAC;QACD,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAChD,MAAM,OAAO,CAAC,KAAK,CAAC;QACtB,CAAC;QAED,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACvF,IAAI,UAAqD,CAAC;QAC1D,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;YACjC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAa,CAAC;YACjC,IAAI,OAAO,CAAQ,CAAC,OAAO,EAAE,EAAE;gBAC7B,UAAU,GAAG,UAAU,CACrB,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EACpB,+CAA+C,CAChD,CAAC;YACJ,CAAC,CAAC;SACH,CAAC,CAAC;QACH,IAAI,UAAU,EAAE,CAAC;YACf,YAAY,CAAC,UAAU,CAAC,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,iCAAiC,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC1D,CAAC;QACD,MAAM,OAAO,CAAC;IAChB,CAAC;YAAS,CAAC;QACT,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,yCAAyC,CACvD,KAAc;IAEd,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,iCAAiC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3F,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QAC9C,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;IACtB,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC3D,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAc;IAC/C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IACtC,IAAI,CAAC,WAAW,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QAClD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;IACnC,OAAO,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAC9B,MAAM,aAAa,GAAG,GAAG,EAAE;QACzB,MAAM,IAAI,KAAK,CACb,yIAAyI,CAC1I,CAAC;IACJ,CAAC,CAAC;IACF,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,aAAa,EAAE,CAAC;IACzB,CAAC;IACD,IAAI,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;QAClD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC9E,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;YAClD,OAAO,aAAa,EAAE,CAAC;QACzB,CAAC;QACD,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;QACrC,IAAI,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5C,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC;gBACH,EAAE,GAAG,kBAAkB,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;gBACnC,QAAQ,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;YACjD,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,aAAa,EAAE,CAAC;YACzB,CAAC;QACH,CAAC;QACD,IAAI,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACrB,OAAO,aAAa,EAAE,CAAC;QACzB,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IACxD,CAAC;IACD,IAAI,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QACnC,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QACnD,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACrE,CAAC;IACD,IAAI,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjC,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QACjD,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACrE,CAAC;IACD,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9C,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACtE,CAAC;IACD,IAAI,0CAA0C,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7D,OAAO,aAAa,EAAE,CAAC;IACzB,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,iCAAiC,CAAC,KAAmC;IACnF,MAAM,cAAc,GAAG,kBAAkB,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IACjE,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,cAAc,CAAC,IAAI,EAAE,CAAC;AAC/B,CAAC;AAED,SAAS,uBAAuB,CAAC,KAAa;IAC5C,OAAO,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAmC;IACpE,MAAM,cAAc,GAAG,iCAAiC,CAAC,KAAK,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;IACxC,MAAM,MAAM,GAAG,KAAK,CAAC,YAAY,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;IACrE,OAAO,QAAQ;QACb,CAAC,CAAC,cAAc,uBAAuB,CAAC,cAAc,CAAC,IAAI,uBAAuB,CAAC,QAAQ,CAAC,EAAE;QAC9F,CAAC,CAAC,GAAG,MAAM,IAAI,cAAc,EAAE,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,QAAgC;IACxE,OAAO;QACL,eAAe,EAAE;YACf,cAAc,EAAE,kBAAkB;YAClC,CAAC,kBAAkB,CAAC,EAAE,QAAQ,CAAC,UAAU;SAC1C;QACD,WAAW,EAAE,QAAQ,CAAC,SAAS,CAAC,eAAe;KAChD,CAAC;AACJ,CAAC","sourcesContent":["import { ADMIN_TOKEN_HEADER } from \"../servers/http.js\";\nimport type { CrablineServerChannel, CrablineServerManifest } from \"../servers/index.js\";\nimport type { ServerEventObserver } from \"../servers/recorder.js\";\n\nexport const DEFAULT_ACCOUNT_ID = \"default\";\nexport const OPENCLAW_CRABLINE_CHANNEL_CAPABILITY_MATRIX_PATH =\n \"crabline-channel-driver-capabilities.json\";\nexport const OPENCLAW_CRABLINE_PROVIDER_READINESS_PATH = \"crabline-provider-readiness.json\";\nexport const OPENCLAW_CRABLINE_MANIFEST_PATH = \"crabline-provider-server.json\";\nexport const OPENCLAW_CRABLINE_ARTIFACT_STORE_DIRECTORY = \".crabline-channel-driver-artifacts\";\nexport const OPENCLAW_CRABLINE_ARTIFACT_POINTER_PATH = `${OPENCLAW_CRABLINE_ARTIFACT_STORE_DIRECTORY}/current.json`;\nexport const OPENCLAW_CRABLINE_DEFAULT_CHANNEL = \"telegram\";\n\nconst OPENCLAW_CRABLINE_PROVIDER_PROBE_TIMEOUT_MS = 5_000;\nconst OPENCLAW_CRABLINE_PROVIDER_PROBE_ABORT_GRACE_MS = 250;\nconst OPENCLAW_CRABLINE_PROVIDER_PROBE_LABELS = {\n discord: \"Discord users/@me\",\n mattermost: \"Mattermost users.me\",\n matrix: \"Matrix whoami\",\n signal: \"Signal check\",\n slack: \"Slack auth.test\",\n telegram: \"Telegram getMe\",\n whatsapp: \"WhatsApp phone number\",\n zalo: \"Zalo getMe\",\n} satisfies Record<CrablineServerManifest[\"provider\"], string>;\nconst unsettledProviderProbeSettlements = new WeakMap<Error, Promise<void>>();\n\nexport type OpenClawCrablineChannelDriverSelection = {\n channel: CrablineServerChannel;\n channelDriver: \"crabline\";\n capabilityMatrixPath: typeof OPENCLAW_CRABLINE_CHANNEL_CAPABILITY_MATRIX_PATH;\n providerReadinessArtifactPath: typeof OPENCLAW_CRABLINE_PROVIDER_READINESS_PATH;\n};\n\nexport type OpenClawCrablineProviderReadinessResult = {\n artifactPointerPath: string;\n capabilityReport: unknown;\n capabilityMatrixPath: string;\n generation: string;\n manifestPath: string;\n providerReadiness: unknown;\n providerReadinessArtifactPath: string;\n warnings?: string[];\n};\nexport type OpenClawCrablineConversation = {\n id: string;\n kind: \"direct\" | \"group\";\n};\n\nexport type OpenClawCrablineGatewayBinding = {\n accountId: string;\n channel: string;\n createProviderReadinessEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv;\n createGatewayConfig(openclawConfig?: Record<string, unknown>): Record<string, unknown>;\n requiredPluginIds: string[];\n};\n\nexport type OpenClawCrablineAgentDelivery = {\n channel: string;\n replyChannel: string;\n replyTo: string;\n to: string;\n};\n\nexport type OpenClawCrablineInboundInput = {\n conversation: {\n id: string;\n kind: \"direct\" | \"group\";\n };\n senderId: string;\n senderName?: string | undefined;\n text: string;\n threadId?: string | undefined;\n nativeCommand?: { name: string } | undefined;\n};\n\nexport type OpenClawCrablineInbound = {\n providerBody: Record<string, unknown>;\n providerHeaders: Record<string, string>;\n providerTargetKey: string;\n providerUrl: string;\n qaTarget: string;\n stateConversation: OpenClawCrablineConversation;\n threadId?: string | undefined;\n};\n\nexport type OpenClawCrablineOutboundMessage = {\n accountId: string;\n senderId: string;\n senderName: string;\n text: string;\n to: string;\n};\n\nexport type StartOpenClawCrablineAdapterParams = {\n channel: CrablineServerChannel;\n onEvent?: ServerEventObserver | undefined;\n openclawConfig?: Record<string, unknown> | undefined;\n recorderPath?: string | undefined;\n};\n\nexport type StartedOpenClawCrablineAdapter = OpenClawCrablineGatewayBinding & {\n close(): Promise<void>;\n createAgentDelivery(params: { target: string }): OpenClawCrablineAgentDelivery;\n createInbound(params: { input: OpenClawCrablineInboundInput }): OpenClawCrablineInbound;\n createOutboundFromRecorderEvent(params: {\n event: unknown;\n targetByProviderTarget: ReadonlyMap<string, string>;\n }): OpenClawCrablineOutboundMessage | null;\n manifest: CrablineServerManifest;\n probe(): Promise<unknown>;\n};\n\nexport type ParsedQaTarget = {\n kind: \"direct\" | \"group\";\n id: string;\n native: boolean;\n threadId?: string;\n};\n\nexport type OpenClawCrablineProviderAdapter = {\n createAgentDelivery(parsed: ParsedQaTarget): OpenClawCrablineAgentDelivery;\n createBinding(): OpenClawCrablineGatewayBinding;\n createInbound(input: OpenClawCrablineInboundInput): OpenClawCrablineInbound;\n createOutboundFromRecorderEvent(params: {\n event: unknown;\n targetByProviderTarget: ReadonlyMap<string, string>;\n }): OpenClawCrablineOutboundMessage | null;\n probe(signal?: AbortSignal): Promise<unknown>;\n};\n\nexport type OpenClawCrablineProviderBridge<\n TManifest extends CrablineServerManifest = CrablineServerManifest,\n> = {\n createAdapter(manifest: TManifest): OpenClawCrablineProviderAdapter;\n createAdapterFromManifest(manifest: CrablineServerManifest): OpenClawCrablineProviderAdapter;\n provider: TManifest[\"provider\"];\n};\n\nexport type OpenClawCrablineProviderBridgeRegistry = {\n [Provider in CrablineServerManifest[\"provider\"]]: OpenClawCrablineProviderBridge<\n Extract<CrablineServerManifest, { provider: Provider }>\n >;\n};\n\nexport function createOpenClawCrablineProviderBridge<\n TProvider extends CrablineServerManifest[\"provider\"],\n>(params: {\n createAdapter(\n manifest: Extract<CrablineServerManifest, { provider: TProvider }>,\n ): OpenClawCrablineProviderAdapter;\n provider: TProvider;\n}): OpenClawCrablineProviderBridge<Extract<CrablineServerManifest, { provider: TProvider }>> {\n type ProviderManifest = Extract<CrablineServerManifest, { provider: TProvider }>;\n const createAdapter = (manifest: ProviderManifest): OpenClawCrablineProviderAdapter => {\n const adapter = params.createAdapter(manifest);\n return {\n createAgentDelivery(parsed) {\n return adapter.createAgentDelivery(parsed);\n },\n createBinding() {\n return adapter.createBinding();\n },\n createInbound(input) {\n if (!readNonBlankString(input.text)) {\n throw new Error(\"OpenClaw Crabline inbound message text is required.\");\n }\n if (input.conversation.kind !== \"direct\" && input.conversation.kind !== \"group\") {\n throw new Error(\"OpenClaw Crabline inbound conversation kind must be direct or group.\");\n }\n return adapter.createInbound(input);\n },\n createOutboundFromRecorderEvent(outboundParams) {\n return adapter.createOutboundFromRecorderEvent(outboundParams);\n },\n probe(signal) {\n return adapter.probe(signal);\n },\n };\n };\n const bridge: OpenClawCrablineProviderBridge<ProviderManifest> = {\n createAdapter,\n createAdapterFromManifest(manifest) {\n if (manifest.provider !== params.provider) {\n throw new Error(\n `Unsupported OpenClaw provider binding: expected ${params.provider}, got ${manifest.provider}.`,\n );\n }\n return createAdapter(manifest as ProviderManifest);\n },\n provider: params.provider as ProviderManifest[\"provider\"],\n };\n return bridge;\n}\n\nexport async function runOpenClawCrablineProviderProbe<T>(\n provider: CrablineServerManifest[\"provider\"],\n probe: (signal: AbortSignal) => Promise<T>,\n): Promise<T> {\n const signal = AbortSignal.timeout(OPENCLAW_CRABLINE_PROVIDER_PROBE_TIMEOUT_MS);\n const timeoutError = (cause: unknown) =>\n new Error(\n `Crabline ${OPENCLAW_CRABLINE_PROVIDER_PROBE_LABELS[provider]} probe timed out after ${OPENCLAW_CRABLINE_PROVIDER_PROBE_TIMEOUT_MS} ms.`,\n { cause },\n );\n const operation = Promise.resolve().then(() => probe(signal));\n const settled = operation.then(\n () => undefined,\n () => undefined,\n );\n let onAbort: (() => void) | undefined;\n const timeout = new Promise<{ kind: \"timeout\" }>((resolve) => {\n onAbort = () => resolve({ kind: \"timeout\" });\n if (signal.aborted) {\n onAbort();\n return;\n }\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n try {\n const outcome = await Promise.race([\n operation.then(\n (value) => ({ kind: \"result\" as const, value }),\n (error: unknown) => ({ error, kind: \"error\" as const }),\n ),\n timeout,\n ]);\n if (outcome.kind === \"result\") {\n return outcome.value;\n }\n if (outcome.kind === \"error\" && !signal.aborted) {\n throw outcome.error;\n }\n\n const failure = timeoutError(outcome.kind === \"error\" ? outcome.error : signal.reason);\n let abortGrace: ReturnType<typeof setTimeout> | undefined;\n const drained = await Promise.race([\n settled.then(() => true as const),\n new Promise<false>((resolve) => {\n abortGrace = setTimeout(\n () => resolve(false),\n OPENCLAW_CRABLINE_PROVIDER_PROBE_ABORT_GRACE_MS,\n );\n }),\n ]);\n if (abortGrace) {\n clearTimeout(abortGrace);\n }\n if (!drained) {\n unsettledProviderProbeSettlements.set(failure, settled);\n }\n throw failure;\n } finally {\n if (onAbort) {\n signal.removeEventListener(\"abort\", onAbort);\n }\n }\n}\n\nexport function getUnsettledOpenClawCrablineProviderProbe(\n error: unknown,\n): Promise<void> | undefined {\n return error instanceof Error ? unsettledProviderProbeSettlements.get(error) : undefined;\n}\n\nexport function readString(value: unknown): string | undefined {\n if (typeof value === \"string\" && value.trim()) {\n return value.trim();\n }\n if (typeof value === \"number\" || typeof value === \"bigint\") {\n return String(value);\n }\n return undefined;\n}\n\nexport function readNonBlankString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value : undefined;\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport function readInteger(value: unknown): number | undefined {\n const stringValue = readString(value);\n if (!stringValue || !/^-?\\d+$/u.test(stringValue)) {\n return undefined;\n }\n const parsed = Number(stringValue);\n return Number.isSafeInteger(parsed) ? parsed : undefined;\n}\n\nexport function parseQaTarget(target: string): ParsedQaTarget {\n const trimmed = target.trim();\n const invalidTarget = () => {\n throw new Error(\n \"OpenClaw Crabline target must be a non-blank native id or a valid dm:<id>, group:<id>, channel:<id>, or thread:<id>/<thread-id> target.\",\n );\n };\n if (!trimmed) {\n return invalidTarget();\n }\n if (trimmed.startsWith(\"thread:\")) {\n const encoded = trimmed.startsWith(\"thread:/v1/\");\n const rest = trimmed.slice(encoded ? \"thread:/v1/\".length : \"thread:\".length);\n const slash = rest.indexOf(\"/\");\n if (slash <= 0 || slash !== rest.lastIndexOf(\"/\")) {\n return invalidTarget();\n }\n let id = rest.slice(0, slash).trim();\n let threadId = rest.slice(slash + 1).trim();\n if (encoded) {\n try {\n id = decodeURIComponent(id).trim();\n threadId = decodeURIComponent(threadId).trim();\n } catch {\n return invalidTarget();\n }\n }\n if (!id || !threadId) {\n return invalidTarget();\n }\n return { kind: \"group\", id, native: false, threadId };\n }\n if (trimmed.startsWith(\"channel:\")) {\n const id = trimmed.slice(\"channel:\".length).trim();\n return id ? { kind: \"group\", id, native: false } : invalidTarget();\n }\n if (trimmed.startsWith(\"group:\")) {\n const id = trimmed.slice(\"group:\".length).trim();\n return id ? { kind: \"group\", id, native: false } : invalidTarget();\n }\n if (trimmed.startsWith(\"dm:\")) {\n const id = trimmed.slice(\"dm:\".length).trim();\n return id ? { kind: \"direct\", id, native: false } : invalidTarget();\n }\n if (/^(?:dm|group|channel|thread)(?=\\s*:|$)/iu.test(trimmed)) {\n return invalidTarget();\n }\n return { kind: \"direct\", id: trimmed, native: true };\n}\n\nexport function canonicalConversationIdForInbound(input: OpenClawCrablineInboundInput) {\n const conversationId = readNonBlankString(input.conversation.id);\n if (!conversationId) {\n throw new Error(\"OpenClaw Crabline inbound conversation id is required.\");\n }\n return conversationId.trim();\n}\n\nfunction encodeQaThreadComponent(value: string): string {\n return value.replaceAll(\"%\", \"%25\").replaceAll(\"/\", \"%2F\");\n}\n\nexport function qaTargetForInbound(input: OpenClawCrablineInboundInput) {\n const conversationId = canonicalConversationIdForInbound(input);\n const threadId = input.threadId?.trim();\n const prefix = input.conversation.kind === \"direct\" ? \"dm\" : \"group\";\n return threadId\n ? `thread:/v1/${encodeQaThreadComponent(conversationId)}/${encodeQaThreadComponent(threadId)}`\n : `${prefix}:${conversationId}`;\n}\n\nexport function createAdminInboundRequest(manifest: CrablineServerManifest) {\n return {\n providerHeaders: {\n \"content-type\": \"application/json\",\n [ADMIN_TOKEN_HEADER]: manifest.adminToken,\n },\n providerUrl: manifest.endpoints.adminInboundUrl,\n };\n}\n"]}
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/openclaw/shared.ts"],"names":[],"mappings":"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","sourcesContent":["import { ADMIN_TOKEN_HEADER } from \"../servers/http.js\";\nimport type { CrablineServerChannel, CrablineServerManifest } from \"../servers/index.js\";\nimport type { ServerEventObserver } from \"../servers/recorder.js\";\n\nexport const DEFAULT_ACCOUNT_ID = \"default\";\nexport const OPENCLAW_CRABLINE_CHANNEL_CAPABILITY_MATRIX_PATH =\n \"crabline-channel-driver-capabilities.json\";\nexport const OPENCLAW_CRABLINE_PROVIDER_READINESS_PATH = \"crabline-provider-readiness.json\";\nexport const OPENCLAW_CRABLINE_MANIFEST_PATH = \"crabline-provider-server.json\";\nexport const OPENCLAW_CRABLINE_ARTIFACT_STORE_DIRECTORY = \".crabline-channel-driver-artifacts\";\nexport const OPENCLAW_CRABLINE_ARTIFACT_POINTER_PATH = `${OPENCLAW_CRABLINE_ARTIFACT_STORE_DIRECTORY}/current.json`;\nexport const OPENCLAW_CRABLINE_DEFAULT_CHANNEL = \"telegram\";\n\nconst OPENCLAW_CRABLINE_PROVIDER_PROBE_TIMEOUT_MS = 5_000;\nconst OPENCLAW_CRABLINE_PROVIDER_PROBE_ABORT_GRACE_MS = 250;\nconst OPENCLAW_CRABLINE_PROVIDER_PROBE_LABELS = {\n discord: \"Discord users/@me\",\n mattermost: \"Mattermost users.me\",\n matrix: \"Matrix whoami\",\n signal: \"Signal check\",\n slack: \"Slack auth.test\",\n telegram: \"Telegram getMe\",\n whatsapp: \"WhatsApp phone number\",\n zalo: \"Zalo getMe\",\n} satisfies Record<CrablineServerManifest[\"provider\"], string>;\nconst unsettledProviderProbeSettlements = new WeakMap<Error, Promise<void>>();\n\nexport type OpenClawCrablineChannelDriverSelection = {\n channel: CrablineServerChannel;\n channelDriver: \"crabline\";\n capabilityMatrixPath: typeof OPENCLAW_CRABLINE_CHANNEL_CAPABILITY_MATRIX_PATH;\n providerReadinessArtifactPath: typeof OPENCLAW_CRABLINE_PROVIDER_READINESS_PATH;\n};\n\nexport type OpenClawCrablineProviderReadinessResult = {\n artifactPointerPath: string;\n capabilityReport: unknown;\n capabilityMatrixPath: string;\n generation: string;\n manifestPath: string;\n providerReadiness: unknown;\n providerReadinessArtifactPath: string;\n warnings?: string[];\n};\nexport type OpenClawCrablineConversation = {\n id: string;\n kind: \"direct\" | \"group\";\n};\n\nexport type OpenClawCrablineGatewayBinding = {\n accountId: string;\n channel: string;\n createProviderReadinessEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv;\n createGatewayConfig(openclawConfig?: Record<string, unknown>): Record<string, unknown>;\n requiredPluginIds: string[];\n};\n\nexport type OpenClawCrablineAgentDelivery = {\n channel: string;\n replyChannel: string;\n replyTo: string;\n to: string;\n};\n\nexport type OpenClawCrablineCorrelatedAgentDelivery = OpenClawCrablineAgentDelivery & {\n /** Adapter correlation key used to associate later provider recorder events with this target. */\n providerTargetKey: string;\n};\n\nexport type OpenClawCrablineInboundInput = {\n conversation: {\n id: string;\n kind: \"direct\" | \"group\";\n };\n senderId: string;\n senderName?: string | undefined;\n text: string;\n threadId?: string | undefined;\n nativeCommand?: { name: string } | undefined;\n};\n\nexport type OpenClawCrablineInbound = {\n providerBody: Record<string, unknown>;\n providerHeaders: Record<string, string>;\n providerTargetKey: string;\n providerUrl: string;\n qaTarget: string;\n stateConversation: OpenClawCrablineConversation;\n threadId?: string | undefined;\n};\n\nexport type OpenClawCrablineOutboundMessage = {\n accountId: string;\n senderId: string;\n senderName: string;\n text: string;\n to: string;\n};\n\nexport type OpenClawCrablineOutboundObservation = Omit<OpenClawCrablineOutboundMessage, \"to\"> & {\n /** Provider-authoritative keys, in lookup priority order, for consumer correlation. */\n providerTargetKeys: readonly [string, ...string[]];\n /** Provider-native target used only when no consumer correlation exists. */\n fallbackTarget?: string | undefined;\n};\n\nexport type StartOpenClawCrablineAdapterParams = {\n channel: CrablineServerChannel;\n onEvent?: ServerEventObserver | undefined;\n openclawConfig?: Record<string, unknown> | undefined;\n recorderPath?: string | undefined;\n};\n\nexport type StartedOpenClawCrablineAdapter = OpenClawCrablineGatewayBinding & {\n close(): Promise<void>;\n createAgentDelivery(params: {\n target: string;\n threadId?: string | undefined;\n }): OpenClawCrablineAgentDelivery;\n createInbound(params: { input: OpenClawCrablineInboundInput }): OpenClawCrablineInbound;\n createOutboundObservation(params: { event: unknown }): OpenClawCrablineOutboundObservation | null;\n /** @deprecated Use createOutboundObservation and correlate providerTargetKeys in the consumer. */\n createOutboundFromRecorderEvent(params: {\n event: unknown;\n targetByProviderTarget: ReadonlyMap<string, string>;\n }): OpenClawCrablineOutboundMessage | null;\n manifest: CrablineServerManifest;\n probe(): Promise<unknown>;\n};\n\nexport type StartedOpenClawCrablineCorrelatedAdapter = Omit<\n StartedOpenClawCrablineAdapter,\n \"createAgentDelivery\"\n> & {\n createAgentDelivery(params: {\n target: string;\n threadId?: string | undefined;\n }): OpenClawCrablineCorrelatedAgentDelivery;\n /** Resolves the provider-authoritative key from a successful inbound response. */\n resolveInboundProviderTargetKey(params: {\n inbound: OpenClawCrablineInbound;\n response: unknown;\n }): string;\n};\n\nexport type ParsedQaTarget = {\n kind: \"direct\" | \"group\";\n id: string;\n native: boolean;\n threadId?: string;\n};\n\nexport function parseQaDeliveryTarget(params: {\n target: string;\n threadId?: string | undefined;\n}): ParsedQaTarget {\n const parsed = parseQaTarget(params.target);\n const threadId = params.threadId?.trim();\n if (parsed.threadId && threadId && parsed.threadId !== threadId) {\n throw new Error(\"OpenClaw Crabline delivery received conflicting thread targets.\");\n }\n return threadId ? { ...parsed, threadId } : parsed;\n}\n\nexport function createProviderIdRegistry(params: {\n candidate(logicalKey: string): string;\n conflictLabel: string;\n}) {\n const idByLogicalKey = new Map<string, string>();\n const ownerById = new Map<string, string>();\n return {\n resolveLogical(logicalKey: string) {\n const existingId = idByLogicalKey.get(logicalKey);\n if (existingId) {\n return existingId;\n }\n const candidate = params.candidate(logicalKey);\n const owner = ownerById.get(candidate);\n if (owner && owner !== `logical:${logicalKey}`) {\n throw new Error(`${params.conflictLabel} conflicts with another provider identity.`);\n }\n idByLogicalKey.set(logicalKey, candidate);\n ownerById.set(candidate, `logical:${logicalKey}`);\n return candidate;\n },\n reserveNative(nativeId: string) {\n const owner = ownerById.get(nativeId);\n if (owner?.startsWith(\"logical:\")) {\n throw new Error(`${params.conflictLabel} native id conflicts with a logical identity.`);\n }\n ownerById.set(nativeId, `native:${nativeId}`);\n return nativeId;\n },\n };\n}\n\nexport type OpenClawCrablineProviderAdapter = {\n createAgentDelivery(parsed: ParsedQaTarget): OpenClawCrablineCorrelatedAgentDelivery;\n createBinding(): OpenClawCrablineGatewayBinding;\n createInbound(input: OpenClawCrablineInboundInput): OpenClawCrablineInbound;\n createOutboundObservation(params: { event: unknown }): OpenClawCrablineOutboundObservation | null;\n probe(signal?: AbortSignal): Promise<unknown>;\n resolveInboundProviderTargetKey?(params: {\n inbound: OpenClawCrablineInbound;\n response: unknown;\n }): string;\n};\n\nexport type OpenClawCrablineProviderBridge<\n TManifest extends CrablineServerManifest = CrablineServerManifest,\n> = {\n createAdapter(manifest: TManifest): OpenClawCrablineProviderAdapter;\n createAdapterFromManifest(manifest: CrablineServerManifest): OpenClawCrablineProviderAdapter;\n provider: TManifest[\"provider\"];\n};\n\nexport type OpenClawCrablineProviderBridgeRegistry = {\n [Provider in CrablineServerManifest[\"provider\"]]: OpenClawCrablineProviderBridge<\n Extract<CrablineServerManifest, { provider: Provider }>\n >;\n};\n\nexport function createOpenClawCrablineProviderBridge<\n TProvider extends CrablineServerManifest[\"provider\"],\n>(params: {\n createAdapter(\n manifest: Extract<CrablineServerManifest, { provider: TProvider }>,\n ): OpenClawCrablineProviderAdapter;\n provider: TProvider;\n}): OpenClawCrablineProviderBridge<Extract<CrablineServerManifest, { provider: TProvider }>> {\n type ProviderManifest = Extract<CrablineServerManifest, { provider: TProvider }>;\n const createAdapter = (manifest: ProviderManifest): OpenClawCrablineProviderAdapter => {\n const adapter = params.createAdapter(manifest);\n return {\n createAgentDelivery(parsed) {\n return adapter.createAgentDelivery(parsed);\n },\n createBinding() {\n return adapter.createBinding();\n },\n createInbound(input) {\n if (!readNonBlankString(input.text)) {\n throw new Error(\"OpenClaw Crabline inbound message text is required.\");\n }\n if (input.conversation.kind !== \"direct\" && input.conversation.kind !== \"group\") {\n throw new Error(\"OpenClaw Crabline inbound conversation kind must be direct or group.\");\n }\n return adapter.createInbound(input);\n },\n createOutboundObservation(outboundParams) {\n return adapter.createOutboundObservation(outboundParams);\n },\n probe(signal) {\n return adapter.probe(signal);\n },\n ...(adapter.resolveInboundProviderTargetKey\n ? {\n resolveInboundProviderTargetKey: adapter.resolveInboundProviderTargetKey.bind(adapter),\n }\n : {}),\n };\n };\n const bridge: OpenClawCrablineProviderBridge<ProviderManifest> = {\n createAdapter,\n createAdapterFromManifest(manifest) {\n if (manifest.provider !== params.provider) {\n throw new Error(\n `Unsupported OpenClaw provider binding: expected ${params.provider}, got ${manifest.provider}.`,\n );\n }\n return createAdapter(manifest as ProviderManifest);\n },\n provider: params.provider as ProviderManifest[\"provider\"],\n };\n return bridge;\n}\n\nexport function correlateOpenClawCrablineOutboundObservation(params: {\n observation: OpenClawCrablineOutboundObservation;\n targetByProviderTarget: ReadonlyMap<string, string>;\n}): OpenClawCrablineOutboundMessage | null {\n const to =\n params.observation.providerTargetKeys\n .map((key) => params.targetByProviderTarget.get(key))\n .find((target) => target !== undefined) ?? params.observation.fallbackTarget;\n if (!to) {\n return null;\n }\n const {\n fallbackTarget: _fallbackTarget,\n providerTargetKeys: _providerTargetKeys,\n ...message\n } = params.observation;\n return { ...message, to };\n}\n\nexport async function runOpenClawCrablineProviderProbe<T>(\n provider: CrablineServerManifest[\"provider\"],\n probe: (signal: AbortSignal) => Promise<T>,\n): Promise<T> {\n const signal = AbortSignal.timeout(OPENCLAW_CRABLINE_PROVIDER_PROBE_TIMEOUT_MS);\n const timeoutError = (cause: unknown) =>\n new Error(\n `Crabline ${OPENCLAW_CRABLINE_PROVIDER_PROBE_LABELS[provider]} probe timed out after ${OPENCLAW_CRABLINE_PROVIDER_PROBE_TIMEOUT_MS} ms.`,\n { cause },\n );\n const operation = Promise.resolve().then(() => probe(signal));\n const settled = operation.then(\n () => undefined,\n () => undefined,\n );\n let onAbort: (() => void) | undefined;\n const timeout = new Promise<{ kind: \"timeout\" }>((resolve) => {\n onAbort = () => resolve({ kind: \"timeout\" });\n if (signal.aborted) {\n onAbort();\n return;\n }\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n try {\n const outcome = await Promise.race([\n operation.then(\n (value) => ({ kind: \"result\" as const, value }),\n (error: unknown) => ({ error, kind: \"error\" as const }),\n ),\n timeout,\n ]);\n if (outcome.kind === \"result\") {\n return outcome.value;\n }\n if (outcome.kind === \"error\" && !signal.aborted) {\n throw outcome.error;\n }\n\n const failure = timeoutError(outcome.kind === \"error\" ? outcome.error : signal.reason);\n let abortGrace: ReturnType<typeof setTimeout> | undefined;\n const drained = await Promise.race([\n settled.then(() => true as const),\n new Promise<false>((resolve) => {\n abortGrace = setTimeout(\n () => resolve(false),\n OPENCLAW_CRABLINE_PROVIDER_PROBE_ABORT_GRACE_MS,\n );\n }),\n ]);\n if (abortGrace) {\n clearTimeout(abortGrace);\n }\n if (!drained) {\n unsettledProviderProbeSettlements.set(failure, settled);\n }\n throw failure;\n } finally {\n if (onAbort) {\n signal.removeEventListener(\"abort\", onAbort);\n }\n }\n}\n\nexport function getUnsettledOpenClawCrablineProviderProbe(\n error: unknown,\n): Promise<void> | undefined {\n return error instanceof Error ? unsettledProviderProbeSettlements.get(error) : undefined;\n}\n\nexport function readString(value: unknown): string | undefined {\n if (typeof value === \"string\" && value.trim()) {\n return value.trim();\n }\n if (typeof value === \"number\" || typeof value === \"bigint\") {\n return String(value);\n }\n return undefined;\n}\n\nexport function readNonBlankString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value : undefined;\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport function readInteger(value: unknown): number | undefined {\n const stringValue = readString(value);\n if (!stringValue || !/^-?\\d+$/u.test(stringValue)) {\n return undefined;\n }\n const parsed = Number(stringValue);\n return Number.isSafeInteger(parsed) ? parsed : undefined;\n}\n\nexport function parseQaTarget(target: string): ParsedQaTarget {\n const trimmed = target.trim();\n const invalidTarget = () => {\n throw new Error(\n \"OpenClaw Crabline target must be a non-blank native id or a valid dm:<id>, group:<id>, channel:<id>, or thread:<id>/<thread-id> target.\",\n );\n };\n if (!trimmed) {\n return invalidTarget();\n }\n if (trimmed.startsWith(\"thread:\")) {\n const encoded = trimmed.startsWith(\"thread:/v1/\");\n const rest = trimmed.slice(encoded ? \"thread:/v1/\".length : \"thread:\".length);\n const components = rest.split(\"/\");\n const explicitKind =\n encoded && components.length === 3 && (components[0] === \"dm\" || components[0] === \"group\")\n ? components.shift()\n : undefined;\n if (components.length !== 2) {\n return invalidTarget();\n }\n let id = components[0]!.trim();\n let threadId = components[1]!.trim();\n if (encoded) {\n try {\n id = decodeURIComponent(id).trim();\n threadId = decodeURIComponent(threadId).trim();\n } catch {\n return invalidTarget();\n }\n }\n if (!id || !threadId) {\n return invalidTarget();\n }\n return {\n kind: explicitKind === \"dm\" ? \"direct\" : \"group\",\n id,\n native: false,\n threadId,\n };\n }\n if (trimmed.startsWith(\"channel:\")) {\n const id = trimmed.slice(\"channel:\".length).trim();\n return id ? { kind: \"group\", id, native: true } : invalidTarget();\n }\n if (trimmed.startsWith(\"group:\")) {\n const id = trimmed.slice(\"group:\".length).trim();\n return id ? { kind: \"group\", id, native: false } : invalidTarget();\n }\n if (trimmed.startsWith(\"dm:\")) {\n const id = trimmed.slice(\"dm:\".length).trim();\n return id ? { kind: \"direct\", id, native: false } : invalidTarget();\n }\n if (/^(?:dm|group|channel|thread)(?=\\s*:|$)/iu.test(trimmed)) {\n return invalidTarget();\n }\n return { kind: \"direct\", id: trimmed, native: true };\n}\n\nexport function canonicalConversationIdForInbound(input: OpenClawCrablineInboundInput) {\n const conversationId = readNonBlankString(input.conversation.id);\n if (!conversationId) {\n throw new Error(\"OpenClaw Crabline inbound conversation id is required.\");\n }\n return conversationId.trim();\n}\n\nfunction encodeQaThreadComponent(value: string): string {\n return value.replaceAll(\"%\", \"%25\").replaceAll(\"/\", \"%2F\");\n}\n\nexport function qaTargetForInbound(input: OpenClawCrablineInboundInput) {\n const conversationId = canonicalConversationIdForInbound(input);\n const threadId = input.threadId?.trim();\n const prefix = input.conversation.kind === \"direct\" ? \"dm\" : \"group\";\n return threadId\n ? `thread:/v1/${input.conversation.kind === \"direct\" ? \"dm/\" : \"\"}${encodeQaThreadComponent(conversationId)}/${encodeQaThreadComponent(threadId)}`\n : `${prefix}:${conversationId}`;\n}\n\nexport function createAdminInboundRequest(manifest: CrablineServerManifest) {\n return {\n providerHeaders: {\n \"content-type\": \"application/json\",\n [ADMIN_TOKEN_HEADER]: manifest.adminToken,\n },\n providerUrl: manifest.endpoints.adminInboundUrl,\n };\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import { type CrablineServerChannel, type CrablineServerManifest, type StartCrablineServerParams, type StartedCrablineServer } from "./servers/index.js";
2
- import { OPENCLAW_CRABLINE_CHANNEL_CAPABILITY_MATRIX_PATH, OPENCLAW_CRABLINE_PROVIDER_READINESS_PATH, OPENCLAW_CRABLINE_DEFAULT_CHANNEL, OPENCLAW_CRABLINE_ARTIFACT_POINTER_PATH, OPENCLAW_CRABLINE_ARTIFACT_STORE_DIRECTORY, OPENCLAW_CRABLINE_MANIFEST_PATH, type OpenClawCrablineAgentDelivery, type OpenClawCrablineChannelDriverSelection, type OpenClawCrablineProviderReadinessResult, type OpenClawCrablineGatewayBinding, type OpenClawCrablineInbound, type OpenClawCrablineInboundInput, type OpenClawCrablineOutboundMessage, type OpenClawCrablineProviderAdapter, type StartedOpenClawCrablineAdapter, type StartOpenClawCrablineAdapterParams } from "./openclaw/shared.js";
2
+ import { OPENCLAW_CRABLINE_CHANNEL_CAPABILITY_MATRIX_PATH, OPENCLAW_CRABLINE_PROVIDER_READINESS_PATH, OPENCLAW_CRABLINE_DEFAULT_CHANNEL, OPENCLAW_CRABLINE_ARTIFACT_POINTER_PATH, OPENCLAW_CRABLINE_ARTIFACT_STORE_DIRECTORY, OPENCLAW_CRABLINE_MANIFEST_PATH, type OpenClawCrablineChannelDriverSelection, type OpenClawCrablineCorrelatedAgentDelivery, type OpenClawCrablineProviderReadinessResult, type OpenClawCrablineGatewayBinding, type OpenClawCrablineInbound, type OpenClawCrablineInboundInput, type OpenClawCrablineOutboundMessage, type OpenClawCrablineOutboundObservation, type OpenClawCrablineProviderAdapter, type StartedOpenClawCrablineCorrelatedAdapter, type StartOpenClawCrablineAdapterParams } from "./openclaw/shared.js";
3
3
  export { 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, };
4
- export type { OpenClawCrablineAgentDelivery, OpenClawCrablineChannelDriverSelection, OpenClawCrablineProviderReadinessResult, OpenClawCrablineConversation, OpenClawCrablineGatewayBinding, OpenClawCrablineInbound, OpenClawCrablineInboundInput, OpenClawCrablineOutboundMessage, StartedOpenClawCrablineAdapter, StartOpenClawCrablineAdapterParams, } from "./openclaw/shared.js";
4
+ export type { OpenClawCrablineAgentDelivery, OpenClawCrablineChannelDriverSelection, OpenClawCrablineCorrelatedAgentDelivery, OpenClawCrablineProviderReadinessResult, OpenClawCrablineConversation, OpenClawCrablineGatewayBinding, OpenClawCrablineInbound, OpenClawCrablineInboundInput, OpenClawCrablineOutboundMessage, OpenClawCrablineOutboundObservation, StartedOpenClawCrablineAdapter, StartedOpenClawCrablineCorrelatedAdapter, StartOpenClawCrablineAdapterParams, } from "./openclaw/shared.js";
5
5
  declare function createOpenClawCrablineProviderAdapter(manifest: CrablineServerManifest): OpenClawCrablineProviderAdapter;
6
6
  export declare function resolveOpenClawCrablineChannel(input?: string | null): CrablineServerChannel;
7
7
  export declare function resolveOpenClawCrablineChannelDriverSelection(params: {
@@ -14,20 +14,26 @@ export declare function createOpenClawCrablineProviderBinding(manifest: Crabline
14
14
  export declare function createOpenClawCrablineAgentDelivery(params: {
15
15
  manifest: CrablineServerManifest;
16
16
  target: string;
17
- }): OpenClawCrablineAgentDelivery;
17
+ threadId?: string | undefined;
18
+ }): OpenClawCrablineCorrelatedAgentDelivery;
18
19
  export declare function createOpenClawCrablineInbound(params: {
19
20
  input: OpenClawCrablineInboundInput;
20
21
  manifest: CrablineServerManifest;
21
22
  }): OpenClawCrablineInbound;
23
+ /** @deprecated Use createOpenClawCrablineOutboundObservation and correlate in the consumer. */
22
24
  export declare function createOpenClawCrablineOutboundFromRecorderEvent(params: {
23
25
  event: unknown;
24
26
  manifest: CrablineServerManifest;
25
27
  targetByProviderTarget: ReadonlyMap<string, string>;
26
28
  }): OpenClawCrablineOutboundMessage | null;
29
+ export declare function createOpenClawCrablineOutboundObservation(params: {
30
+ event: unknown;
31
+ manifest: CrablineServerManifest;
32
+ }): OpenClawCrablineOutboundObservation | null;
27
33
  export declare function startOpenClawCrablineAdapter(params: StartOpenClawCrablineAdapterParams, dependencies?: {
28
34
  createProviderAdapter?: typeof createOpenClawCrablineProviderAdapter;
29
35
  startServer?: (params: StartCrablineServerParams) => Promise<StartedCrablineServer>;
30
- }): Promise<StartedOpenClawCrablineAdapter>;
36
+ }): Promise<StartedOpenClawCrablineCorrelatedAdapter>;
31
37
  export declare function runOpenClawCrablineProviderReadiness(params: {
32
38
  outputDir: string;
33
39
  selection: OpenClawCrablineChannelDriverSelection;
@@ -8,7 +8,7 @@ import { SIGNAL_OPENCLAW_CRABLINE_PROVIDER_BRIDGE } from "./openclaw/bridges/sig
8
8
  import { TELEGRAM_OPENCLAW_CRABLINE_PROVIDER_BRIDGE } from "./openclaw/bridges/telegram.js";
9
9
  import { WHATSAPP_OPENCLAW_CRABLINE_PROVIDER_BRIDGE } from "./openclaw/bridges/whatsapp.js";
10
10
  import { ZALO_OPENCLAW_CRABLINE_PROVIDER_BRIDGE } from "./openclaw/bridges/zalo.js";
11
- import { OPENCLAW_CRABLINE_CHANNEL_CAPABILITY_MATRIX_PATH, OPENCLAW_CRABLINE_PROVIDER_READINESS_PATH, OPENCLAW_CRABLINE_DEFAULT_CHANNEL, OPENCLAW_CRABLINE_ARTIFACT_POINTER_PATH, OPENCLAW_CRABLINE_ARTIFACT_STORE_DIRECTORY, OPENCLAW_CRABLINE_MANIFEST_PATH, getUnsettledOpenClawCrablineProviderProbe, isRecord, parseQaTarget, runOpenClawCrablineProviderProbe, } from "./openclaw/shared.js";
11
+ import { OPENCLAW_CRABLINE_CHANNEL_CAPABILITY_MATRIX_PATH, OPENCLAW_CRABLINE_PROVIDER_READINESS_PATH, OPENCLAW_CRABLINE_DEFAULT_CHANNEL, OPENCLAW_CRABLINE_ARTIFACT_POINTER_PATH, OPENCLAW_CRABLINE_ARTIFACT_STORE_DIRECTORY, OPENCLAW_CRABLINE_MANIFEST_PATH, getUnsettledOpenClawCrablineProviderProbe, isRecord, parseQaDeliveryTarget, runOpenClawCrablineProviderProbe, correlateOpenClawCrablineOutboundObservation, } from "./openclaw/shared.js";
12
12
  import { publishOpenClawCrablineArtifactGeneration } from "./openclaw/artifact-generation.js";
13
13
  import { isAcceptedOpenClawCrablineOutbound } from "./openclaw/outbound-contract.js";
14
14
  import { securePrivateDirectory, syncParentDirectory, } from "./openclaw/private-file.js";
@@ -246,11 +246,11 @@ function createOpenClawCrablineProviderAdapter(manifest) {
246
246
  const adapter = bridge.createAdapterFromManifest(manifest);
247
247
  return {
248
248
  ...adapter,
249
- createOutboundFromRecorderEvent: (params) => isAcceptedOpenClawCrablineOutbound({
249
+ createOutboundObservation: (params) => isAcceptedOpenClawCrablineOutbound({
250
250
  event: params.event,
251
251
  manifest,
252
252
  })
253
- ? adapter.createOutboundFromRecorderEvent(params)
253
+ ? adapter.createOutboundObservation(params)
254
254
  : null,
255
255
  probe: () => runOpenClawCrablineProviderProbe(manifest.provider, (signal) => adapter.probe(signal)),
256
256
  };
@@ -281,15 +281,27 @@ export function createOpenClawCrablineProviderBinding(manifest) {
281
281
  return createOpenClawCrablineProviderAdapter(manifest).createBinding();
282
282
  }
283
283
  export function createOpenClawCrablineAgentDelivery(params) {
284
- return createOpenClawCrablineProviderAdapter(params.manifest).createAgentDelivery(parseQaTarget(params.target));
284
+ return createOpenClawCrablineProviderAdapter(params.manifest).createAgentDelivery(parseQaDeliveryTarget(params));
285
285
  }
286
286
  export function createOpenClawCrablineInbound(params) {
287
287
  return createOpenClawCrablineProviderAdapter(params.manifest).createInbound(params.input);
288
288
  }
289
+ /** @deprecated Use createOpenClawCrablineOutboundObservation and correlate in the consumer. */
289
290
  export function createOpenClawCrablineOutboundFromRecorderEvent(params) {
290
- return createOpenClawCrablineProviderAdapter(params.manifest).createOutboundFromRecorderEvent({
291
+ const observation = createOpenClawCrablineOutboundObservation({
292
+ event: params.event,
293
+ manifest: params.manifest,
294
+ });
295
+ return observation
296
+ ? correlateOpenClawCrablineOutboundObservation({
297
+ observation,
298
+ targetByProviderTarget: params.targetByProviderTarget,
299
+ })
300
+ : null;
301
+ }
302
+ export function createOpenClawCrablineOutboundObservation(params) {
303
+ return createOpenClawCrablineProviderAdapter(params.manifest).createOutboundObservation({
291
304
  event: params.event,
292
- targetByProviderTarget: params.targetByProviderTarget,
293
305
  });
294
306
  }
295
307
  export async function startOpenClawCrablineAdapter(params, dependencies = {}) {
@@ -305,14 +317,22 @@ export async function startOpenClawCrablineAdapter(params, dependencies = {}) {
305
317
  ...binding,
306
318
  close: server.close,
307
319
  createGatewayConfig: (openclawConfig = params.openclawConfig ?? {}) => binding.createGatewayConfig(openclawConfig),
308
- createAgentDelivery: ({ target }) => providerAdapter.createAgentDelivery(parseQaTarget(target)),
320
+ createAgentDelivery: ({ target, threadId }) => providerAdapter.createAgentDelivery(parseQaDeliveryTarget({ target, threadId })),
309
321
  createInbound: ({ input }) => providerAdapter.createInbound(input),
310
- createOutboundFromRecorderEvent: ({ event, targetByProviderTarget }) => providerAdapter.createOutboundFromRecorderEvent({
311
- event,
312
- targetByProviderTarget,
313
- }),
322
+ createOutboundObservation: ({ event }) => providerAdapter.createOutboundObservation({ event }),
323
+ createOutboundFromRecorderEvent: ({ event, targetByProviderTarget }) => {
324
+ const observation = providerAdapter.createOutboundObservation({ event });
325
+ return observation
326
+ ? correlateOpenClawCrablineOutboundObservation({
327
+ observation,
328
+ targetByProviderTarget,
329
+ })
330
+ : null;
331
+ },
314
332
  manifest: server.manifest,
315
333
  probe: () => providerAdapter.probe(),
334
+ resolveInboundProviderTargetKey: ({ inbound, response }) => providerAdapter.resolveInboundProviderTargetKey?.({ inbound, response }) ??
335
+ inbound.providerTargetKey,
316
336
  };
317
337
  }
318
338
  catch (error) {