@chbo297/infoflow 2026.3.18 → 2026.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -528
- package/dist/index.js +21 -0
- package/dist/src/accounts.js +110 -0
- package/dist/src/actions.js +386 -0
- package/dist/src/bot.js +1010 -0
- package/dist/src/channel.js +385 -0
- package/dist/src/infoflow-req-parse.js +394 -0
- package/dist/src/logging.js +102 -0
- package/dist/src/markdown-local-images.js +65 -0
- package/dist/src/media.js +318 -0
- package/dist/src/monitor.js +145 -0
- package/dist/src/reply-dispatcher.js +301 -0
- package/dist/src/runtime.js +10 -0
- package/dist/src/send.js +820 -0
- package/dist/src/sent-message-store.js +190 -0
- package/dist/src/targets.js +90 -0
- package/dist/src/types.js +4 -0
- package/dist/src/ws-receiver.js +378 -0
- package/openclaw.plugin.json +194 -0
- package/package.json +18 -3
- package/scripts/deploy.sh +215 -0
- package/src/accounts.ts +25 -3
- package/src/actions.ts +9 -3
- package/src/bot.ts +63 -20
- package/src/channel.ts +64 -45
- package/src/infoflow-req-parse.ts +2 -2
- package/src/infoflow-sdk.d.ts +12 -0
- package/src/monitor.ts +21 -2
- package/src/reply-dispatcher.ts +2 -5
- package/src/types.ts +11 -0
- package/src/ws-receiver.ts +482 -0
- package/tsconfig.build.json +6 -0
package/src/bot.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildAgentMediaPayload,
|
|
3
|
+
getAgentScopedMediaLocalRoots,
|
|
4
|
+
} from "openclaw/plugin-sdk/agent-media-payload";
|
|
1
5
|
import {
|
|
2
6
|
buildPendingHistoryContextFromMap,
|
|
3
7
|
clearHistoryEntriesIfEnabled,
|
|
4
8
|
DEFAULT_GROUP_HISTORY_LIMIT,
|
|
5
9
|
type HistoryEntry,
|
|
6
10
|
recordPendingHistoryEntryIfEnabled,
|
|
7
|
-
|
|
8
|
-
} from "openclaw/plugin-sdk";
|
|
9
|
-
import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/mattermost";
|
|
11
|
+
} from "openclaw/plugin-sdk/reply-history";
|
|
10
12
|
import { resolveInfoflowAccount } from "./accounts.js";
|
|
11
13
|
import { getInfoflowBotLog, formatInfoflowError, logVerbose } from "./logging.js";
|
|
12
14
|
import { createInfoflowReplyDispatcher } from "./reply-dispatcher.js";
|
|
@@ -52,34 +54,62 @@ type InfoflowBodyItem = {
|
|
|
52
54
|
messageid?: string | number;
|
|
53
55
|
};
|
|
54
56
|
|
|
57
|
+
/** Identity used to detect @bot in group body (name, app agent id, or persisted robot id). */
|
|
58
|
+
export type InfoflowBotMentionIdentity = {
|
|
59
|
+
robotName?: string;
|
|
60
|
+
appAgentId?: number;
|
|
61
|
+
robotId?: string;
|
|
62
|
+
};
|
|
63
|
+
|
|
55
64
|
/**
|
|
56
65
|
* Check if the bot was @mentioned in the message body.
|
|
57
|
-
* Matches
|
|
66
|
+
* Matches appAgentId, robotName, or robotId against AT items (same order as Baidu reference plugin).
|
|
58
67
|
*/
|
|
59
|
-
function checkBotMentioned(
|
|
60
|
-
|
|
61
|
-
|
|
68
|
+
export function checkBotMentioned(
|
|
69
|
+
bodyItems: InfoflowBodyItem[],
|
|
70
|
+
identityOrName?: string | InfoflowBotMentionIdentity,
|
|
71
|
+
): boolean {
|
|
72
|
+
const identity: InfoflowBotMentionIdentity =
|
|
73
|
+
typeof identityOrName === "string" || identityOrName === undefined
|
|
74
|
+
? { robotName: identityOrName }
|
|
75
|
+
: identityOrName;
|
|
76
|
+
const { robotName, appAgentId, robotId } = identity;
|
|
77
|
+
const appAgentIdStr = appAgentId != null ? String(appAgentId) : undefined;
|
|
78
|
+
const normalizedRobotName = robotName?.toLowerCase();
|
|
79
|
+
const normalizedRobotId = robotId?.trim();
|
|
62
80
|
for (const item of bodyItems) {
|
|
63
81
|
if (item.type !== "AT") continue;
|
|
64
|
-
if (item.
|
|
82
|
+
if (appAgentIdStr && item.robotid != null && String(item.robotid) === appAgentIdStr)
|
|
83
|
+
return true;
|
|
84
|
+
if (normalizedRobotName && item.name?.toLowerCase() === normalizedRobotName) return true;
|
|
85
|
+
if (normalizedRobotId && item.robotid != null && String(item.robotid) === normalizedRobotId)
|
|
86
|
+
return true;
|
|
65
87
|
}
|
|
66
88
|
return false;
|
|
67
89
|
}
|
|
68
90
|
|
|
69
91
|
/**
|
|
70
|
-
* When the bot is @mentioned
|
|
71
|
-
* Used to discover and persist the account's robotId from incoming group messages.
|
|
92
|
+
* When the bot is @mentioned, return that AT item's robotid string for persistence.
|
|
72
93
|
*/
|
|
73
94
|
function getBotRobotidFromBody(
|
|
74
95
|
bodyItems: InfoflowBodyItem[],
|
|
75
96
|
robotName?: string,
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const normalizedRobotName = robotName
|
|
97
|
+
robotId?: string,
|
|
98
|
+
): string | undefined {
|
|
99
|
+
const normalizedRobotName = robotName?.toLowerCase();
|
|
100
|
+
const normalizedRobotId = robotId?.trim();
|
|
79
101
|
for (const item of bodyItems) {
|
|
80
102
|
if (item.type !== "AT") continue;
|
|
81
|
-
if (item.
|
|
82
|
-
return
|
|
103
|
+
if (normalizedRobotId && item.robotid != null && String(item.robotid) === normalizedRobotId) {
|
|
104
|
+
return normalizedRobotId;
|
|
105
|
+
}
|
|
106
|
+
if (
|
|
107
|
+
normalizedRobotName &&
|
|
108
|
+
item.name?.toLowerCase() === normalizedRobotName &&
|
|
109
|
+
item.robotid != null
|
|
110
|
+
) {
|
|
111
|
+
return String(item.robotid);
|
|
112
|
+
}
|
|
83
113
|
}
|
|
84
114
|
return undefined;
|
|
85
115
|
}
|
|
@@ -557,14 +587,27 @@ export async function handleGroupChatMessage(params: HandleGroupChatParams): Pro
|
|
|
557
587
|
const account = resolveInfoflowAccount({ cfg, accountId });
|
|
558
588
|
const robotName = account.config.robotName;
|
|
559
589
|
|
|
560
|
-
|
|
561
|
-
|
|
590
|
+
const mentionIdentity: InfoflowBotMentionIdentity = {
|
|
591
|
+
robotName,
|
|
592
|
+
appAgentId: account.config.appAgentId,
|
|
593
|
+
robotId: account.config.robotId?.trim() || undefined,
|
|
594
|
+
};
|
|
595
|
+
|
|
596
|
+
const rawEventType = String(msgData.eventtype ?? "");
|
|
597
|
+
const wasMentioned =
|
|
598
|
+
msgData.wasMentioned === true
|
|
599
|
+
? true
|
|
600
|
+
: rawEventType === "ALL_MESSAGE_FORWARD"
|
|
601
|
+
? checkBotMentioned(bodyItems, mentionIdentity)
|
|
602
|
+
: rawEventType === "MESSAGE_RECEIVE"
|
|
603
|
+
? true
|
|
604
|
+
: checkBotMentioned(bodyItems, mentionIdentity);
|
|
562
605
|
|
|
563
606
|
// When bot is @mentioned, discover and persist robotId from the AT item so we can ignore our own messages later.
|
|
564
607
|
let effectiveRobotId = account.config.robotId?.trim() || undefined;
|
|
565
|
-
const
|
|
566
|
-
if (wasMentioned &&
|
|
567
|
-
const newRobotId =
|
|
608
|
+
const discoveredRobotId = getBotRobotidFromBody(bodyItems, robotName, effectiveRobotId);
|
|
609
|
+
if (wasMentioned && discoveredRobotId != null) {
|
|
610
|
+
const newRobotId = discoveredRobotId;
|
|
568
611
|
if (newRobotId !== effectiveRobotId) {
|
|
569
612
|
try {
|
|
570
613
|
const runtime = getInfoflowRuntime();
|
package/src/channel.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ChannelPlugin, OpenClawConfig } from "openclaw/plugin-sdk";
|
|
1
2
|
import {
|
|
2
3
|
applyAccountNameToChannelSection,
|
|
3
4
|
DEFAULT_ACCOUNT_ID,
|
|
@@ -6,9 +7,7 @@ import {
|
|
|
6
7
|
migrateBaseNameToDefaultAccount,
|
|
7
8
|
normalizeAccountId,
|
|
8
9
|
setAccountEnabledInConfigSection,
|
|
9
|
-
|
|
10
|
-
type OpenClawConfig,
|
|
11
|
-
} from "openclaw/plugin-sdk";
|
|
10
|
+
} from "openclaw/plugin-sdk/core";
|
|
12
11
|
import {
|
|
13
12
|
getChannelSection,
|
|
14
13
|
listInfoflowAccountIds,
|
|
@@ -19,20 +18,68 @@ import { infoflowMessageActions } from "./actions.js";
|
|
|
19
18
|
import { logVerbose } from "./logging.js";
|
|
20
19
|
import { parseMarkdownForLocalImages } from "./markdown-local-images.js";
|
|
21
20
|
import { prepareInfoflowImageBase64, sendInfoflowImageMessage } from "./media.js";
|
|
22
|
-
import { startInfoflowMonitor } from "./monitor.js";
|
|
21
|
+
import { startInfoflowMonitor, startInfoflowWSMonitor } from "./monitor.js";
|
|
23
22
|
import { getInfoflowRuntime } from "./runtime.js";
|
|
24
23
|
import { sendInfoflowMessage } from "./send.js";
|
|
25
24
|
import { normalizeInfoflowTarget, looksLikeInfoflowId } from "./targets.js";
|
|
26
25
|
import type { InfoflowOutboundReply, ResolvedInfoflowAccount } from "./types.js";
|
|
27
26
|
|
|
28
27
|
// Re-export types and account functions for external consumers
|
|
29
|
-
export type {
|
|
28
|
+
export type {
|
|
29
|
+
InfoflowAccountConfig,
|
|
30
|
+
InfoflowConnectionMode,
|
|
31
|
+
ResolvedInfoflowAccount,
|
|
32
|
+
} from "./types.js";
|
|
30
33
|
export { resolveInfoflowAccount } from "./accounts.js";
|
|
31
34
|
|
|
32
35
|
// ---------------------------------------------------------------------------
|
|
33
36
|
// Channel plugin
|
|
34
37
|
// ---------------------------------------------------------------------------
|
|
35
38
|
|
|
39
|
+
function applyInfoflowSetupPatch(params: {
|
|
40
|
+
cfg: OpenClawConfig;
|
|
41
|
+
accountId: string;
|
|
42
|
+
patch: Record<string, unknown>;
|
|
43
|
+
}): OpenClawConfig {
|
|
44
|
+
const { cfg, accountId, patch } = params;
|
|
45
|
+
const channels = (cfg.channels ?? {}) as Record<string, unknown>;
|
|
46
|
+
const existingInfoflow = (channels["infoflow"] ?? {}) as Record<string, unknown>;
|
|
47
|
+
|
|
48
|
+
if (accountId === DEFAULT_ACCOUNT_ID) {
|
|
49
|
+
return {
|
|
50
|
+
...cfg,
|
|
51
|
+
channels: {
|
|
52
|
+
...channels,
|
|
53
|
+
infoflow: {
|
|
54
|
+
...existingInfoflow,
|
|
55
|
+
enabled: true,
|
|
56
|
+
...patch,
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const existingAccounts = (existingInfoflow.accounts ?? {}) as Record<string, Record<string, unknown>>;
|
|
63
|
+
return {
|
|
64
|
+
...cfg,
|
|
65
|
+
channels: {
|
|
66
|
+
...channels,
|
|
67
|
+
infoflow: {
|
|
68
|
+
...existingInfoflow,
|
|
69
|
+
enabled: true,
|
|
70
|
+
accounts: {
|
|
71
|
+
...existingAccounts,
|
|
72
|
+
[accountId]: {
|
|
73
|
+
...existingAccounts[accountId],
|
|
74
|
+
enabled: true,
|
|
75
|
+
...patch,
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
36
83
|
export const infoflowPlugin: ChannelPlugin<ResolvedInfoflowAccount> = {
|
|
37
84
|
id: "infoflow",
|
|
38
85
|
meta: {
|
|
@@ -96,7 +143,7 @@ export const infoflowPlugin: ChannelPlugin<ResolvedInfoflowAccount> = {
|
|
|
96
143
|
policy: ((account.config as Record<string, unknown>).dmPolicy as string) ?? "open",
|
|
97
144
|
allowFrom: ((account.config as Record<string, unknown>).allowFrom as string[]) ?? [],
|
|
98
145
|
policyPath: `${basePath}dmPolicy`,
|
|
99
|
-
allowFromPath: basePath
|
|
146
|
+
allowFromPath: `${basePath}allowFrom`,
|
|
100
147
|
approveHint: formatPairingApproveHint("infoflow"),
|
|
101
148
|
normalizeEntry: (raw: string) => raw.replace(/^infoflow:/i, ""),
|
|
102
149
|
};
|
|
@@ -169,40 +216,7 @@ export const infoflowPlugin: ChannelPlugin<ResolvedInfoflowAccount> = {
|
|
|
169
216
|
if (input.token) {
|
|
170
217
|
patch.checkToken = input.token;
|
|
171
218
|
}
|
|
172
|
-
|
|
173
|
-
const existing = (next.channels?.["infoflow"] ?? {}) as Record<string, unknown>;
|
|
174
|
-
if (accountId === DEFAULT_ACCOUNT_ID) {
|
|
175
|
-
return {
|
|
176
|
-
...next,
|
|
177
|
-
channels: {
|
|
178
|
-
...next.channels,
|
|
179
|
-
infoflow: {
|
|
180
|
-
...existing,
|
|
181
|
-
enabled: true,
|
|
182
|
-
...patch,
|
|
183
|
-
},
|
|
184
|
-
},
|
|
185
|
-
} as OpenClawConfig;
|
|
186
|
-
}
|
|
187
|
-
const existingAccounts = (existing.accounts ?? {}) as Record<string, Record<string, unknown>>;
|
|
188
|
-
return {
|
|
189
|
-
...next,
|
|
190
|
-
channels: {
|
|
191
|
-
...next.channels,
|
|
192
|
-
infoflow: {
|
|
193
|
-
...existing,
|
|
194
|
-
enabled: true,
|
|
195
|
-
accounts: {
|
|
196
|
-
...existingAccounts,
|
|
197
|
-
[accountId]: {
|
|
198
|
-
...existingAccounts[accountId],
|
|
199
|
-
enabled: true,
|
|
200
|
-
...patch,
|
|
201
|
-
},
|
|
202
|
-
},
|
|
203
|
-
},
|
|
204
|
-
},
|
|
205
|
-
} as OpenClawConfig;
|
|
219
|
+
return applyInfoflowSetupPatch({ cfg: next, accountId, patch });
|
|
206
220
|
},
|
|
207
221
|
},
|
|
208
222
|
outbound: {
|
|
@@ -390,19 +404,24 @@ export const infoflowPlugin: ChannelPlugin<ResolvedInfoflowAccount> = {
|
|
|
390
404
|
gateway: {
|
|
391
405
|
startAccount: async (ctx) => {
|
|
392
406
|
const account = ctx.account;
|
|
393
|
-
|
|
407
|
+
const connectionMode = account.config.connectionMode ?? "webhook";
|
|
408
|
+
ctx.log?.info(`[${account.accountId}] starting Infoflow (${connectionMode})`);
|
|
394
409
|
ctx.setStatus({
|
|
395
410
|
accountId: account.accountId,
|
|
396
411
|
running: true,
|
|
397
412
|
lastStartAt: Date.now(),
|
|
398
413
|
});
|
|
399
|
-
const
|
|
414
|
+
const monitorOptions = {
|
|
400
415
|
account,
|
|
401
416
|
config: ctx.cfg,
|
|
402
|
-
runtime: ctx.runtime,
|
|
403
417
|
abortSignal: ctx.abortSignal,
|
|
404
|
-
statusSink: (patch
|
|
405
|
-
|
|
418
|
+
statusSink: (patch: { lastInboundAt?: number; lastOutboundAt?: number }) =>
|
|
419
|
+
ctx.setStatus({ accountId: account.accountId, ...patch }),
|
|
420
|
+
};
|
|
421
|
+
const unregister =
|
|
422
|
+
connectionMode === "websocket"
|
|
423
|
+
? await startInfoflowWSMonitor(monitorOptions)
|
|
424
|
+
: await startInfoflowMonitor(monitorOptions);
|
|
406
425
|
|
|
407
426
|
// Keep the channel alive until explicitly stopped.
|
|
408
427
|
// Without this, the promise resolves immediately and the gateway
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createHash, createDecipheriv, timingSafeEqual } from "node:crypto";
|
|
2
2
|
import type { IncomingMessage } from "node:http";
|
|
3
3
|
import type { OpenClawConfig } from "openclaw/plugin-sdk";
|
|
4
|
-
import { createDedupeCache } from "openclaw/plugin-sdk";
|
|
4
|
+
import { createDedupeCache } from "openclaw/plugin-sdk/core";
|
|
5
5
|
// ---------------------------------------------------------------------------
|
|
6
6
|
// Message deduplication
|
|
7
7
|
// ---------------------------------------------------------------------------
|
|
@@ -98,7 +98,7 @@ function extractDedupeKey(msgData: Record<string, unknown>): string | null {
|
|
|
98
98
|
* Returns true if the message is a duplicate (already seen within TTL).
|
|
99
99
|
* Uses shared dedupe cache implementation.
|
|
100
100
|
*/
|
|
101
|
-
function isDuplicateMessage(msgData: Record<string, unknown>): boolean {
|
|
101
|
+
export function isDuplicateMessage(msgData: Record<string, unknown>): boolean {
|
|
102
102
|
const key = extractDedupeKey(msgData);
|
|
103
103
|
if (!key) return false; // Cannot extract key, allow through
|
|
104
104
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ambient types when `@baidu/infoflow-sdk-nodejs` is not installed (e.g. public npm).
|
|
3
|
+
* Install the SDK from Baidu's registry to use `connectionMode: "websocket"`.
|
|
4
|
+
*/
|
|
5
|
+
declare module "@baidu/infoflow-sdk-nodejs" {
|
|
6
|
+
export class WSClient {
|
|
7
|
+
constructor(options: Record<string, unknown>);
|
|
8
|
+
on(event: string, handler: (...args: unknown[]) => void): void;
|
|
9
|
+
connect(): Promise<void>;
|
|
10
|
+
disconnect(): void;
|
|
11
|
+
}
|
|
12
|
+
}
|
package/src/monitor.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
} from "./infoflow-req-parse.js";
|
|
9
9
|
import { getInfoflowWebhookLog, formatInfoflowError, logVerbose } from "./logging.js";
|
|
10
10
|
import { getInfoflowRuntime } from "./runtime.js";
|
|
11
|
+
import { InfoflowWSReceiver } from "./ws-receiver.js";
|
|
11
12
|
|
|
12
13
|
// ---------------------------------------------------------------------------
|
|
13
14
|
// Types
|
|
@@ -16,7 +17,6 @@ import { getInfoflowRuntime } from "./runtime.js";
|
|
|
16
17
|
export type InfoflowMonitorOptions = {
|
|
17
18
|
account: ResolvedInfoflowAccount;
|
|
18
19
|
config: OpenClawConfig;
|
|
19
|
-
runtime: unknown;
|
|
20
20
|
abortSignal: AbortSignal;
|
|
21
21
|
statusSink?: (patch: { lastInboundAt?: number; lastOutboundAt?: number }) => void;
|
|
22
22
|
};
|
|
@@ -79,7 +79,7 @@ function isInfoflowPath(requestPath: string): boolean {
|
|
|
79
79
|
/**
|
|
80
80
|
* Handles incoming Infoflow webhook HTTP requests.
|
|
81
81
|
*
|
|
82
|
-
* - Routes by path to registered targets (
|
|
82
|
+
* - Routes by path to registered targets (exact match).
|
|
83
83
|
* - Only allows POST.
|
|
84
84
|
* - Delegates body reading, echostr verification, authentication,
|
|
85
85
|
* and message dispatch to infoflow_req_parse.
|
|
@@ -167,3 +167,22 @@ export async function startInfoflowMonitor(options: InfoflowMonitorOptions): Pro
|
|
|
167
167
|
|
|
168
168
|
return unregister;
|
|
169
169
|
}
|
|
170
|
+
|
|
171
|
+
/** Starts a WebSocket message receiver and returns a stop function. */
|
|
172
|
+
export async function startInfoflowWSMonitor(options: InfoflowMonitorOptions): Promise<() => void> {
|
|
173
|
+
const receiver = new InfoflowWSReceiver({
|
|
174
|
+
account: options.account,
|
|
175
|
+
config: options.config,
|
|
176
|
+
abortSignal: options.abortSignal,
|
|
177
|
+
statusSink: options.statusSink,
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
try {
|
|
181
|
+
await receiver.start();
|
|
182
|
+
} catch (err) {
|
|
183
|
+
receiver.stop();
|
|
184
|
+
throw err;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return () => receiver.stop();
|
|
188
|
+
}
|
package/src/reply-dispatcher.ts
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
type OpenClawConfig,
|
|
4
|
-
type ReplyPayload,
|
|
5
|
-
} from "openclaw/plugin-sdk";
|
|
1
|
+
import type { OpenClawConfig, ReplyPayload } from "openclaw/plugin-sdk";
|
|
2
|
+
import { createReplyPrefixOptions } from "openclaw/plugin-sdk/channel-reply-pipeline";
|
|
6
3
|
import { getInfoflowSendLog, formatInfoflowError, logVerbose } from "./logging.js";
|
|
7
4
|
import { parseMarkdownForLocalImages } from "./markdown-local-images.js";
|
|
8
5
|
import { prepareInfoflowImageBase64, sendInfoflowImageMessage } from "./media.js";
|
package/src/types.ts
CHANGED
|
@@ -10,6 +10,9 @@ export type InfoflowDmPolicy = "open" | "pairing" | "allowlist";
|
|
|
10
10
|
export type InfoflowGroupPolicy = "open" | "allowlist" | "disabled";
|
|
11
11
|
export type InfoflowChatType = "direct" | "group";
|
|
12
12
|
|
|
13
|
+
/** Inbound message transport: webhook (Infoflow POSTs to your server) or websocket (plugin connects to gateway). */
|
|
14
|
+
export type InfoflowConnectionMode = "webhook" | "websocket";
|
|
15
|
+
|
|
13
16
|
/** Reply mode controlling bot behavior per group */
|
|
14
17
|
export type InfoflowReplyMode =
|
|
15
18
|
| "ignore"
|
|
@@ -101,6 +104,11 @@ export type InfoflowAccountConfig = {
|
|
|
101
104
|
enabled?: boolean;
|
|
102
105
|
name?: string;
|
|
103
106
|
apiHost?: string;
|
|
107
|
+
connectionMode?: InfoflowConnectionMode;
|
|
108
|
+
/** WebSocket gateway host (websocket mode). */
|
|
109
|
+
wsGateway?: string;
|
|
110
|
+
/** Override WebSocket handshake host (optional, intranet). */
|
|
111
|
+
wsConnectDomain?: string;
|
|
104
112
|
checkToken?: string;
|
|
105
113
|
encodingAESKey?: string;
|
|
106
114
|
appKey?: string;
|
|
@@ -142,6 +150,9 @@ export type ResolvedInfoflowAccount = {
|
|
|
142
150
|
enabled?: boolean;
|
|
143
151
|
name?: string;
|
|
144
152
|
apiHost: string;
|
|
153
|
+
connectionMode: InfoflowConnectionMode;
|
|
154
|
+
wsGateway: string;
|
|
155
|
+
wsConnectDomain?: string;
|
|
145
156
|
checkToken: string;
|
|
146
157
|
encodingAESKey: string;
|
|
147
158
|
appKey: string;
|