adp-openclaw 0.0.68 → 0.0.70
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/package.json +1 -1
- package/src/channel.ts +6 -6
- package/src/monitor.ts +4 -4
- package/src/onboarding.ts +76 -69
- package/src/session-history.ts +11 -2
package/package.json
CHANGED
package/src/channel.ts
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
type ChannelPlugin,
|
|
6
|
-
type
|
|
7
|
-
DEFAULT_ACCOUNT_ID,
|
|
6
|
+
type OpenClawConfig,
|
|
8
7
|
} from "openclaw/plugin-sdk";
|
|
9
|
-
import {
|
|
8
|
+
import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/core";
|
|
9
|
+
import { adpOpenclawSetupWizard } from "./onboarding.js";
|
|
10
10
|
import { getActiveWebSocket } from "./runtime.js";
|
|
11
11
|
|
|
12
12
|
// Default WebSocket URL for ADP OpenClaw
|
|
@@ -61,7 +61,7 @@ function resolveAdpOpenclawCredentials(channelCfg?: AdpOpenclawChannelConfig): {
|
|
|
61
61
|
return { wsUrl, clientToken, signKey };
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
function resolveAccount(cfg:
|
|
64
|
+
function resolveAccount(cfg: OpenClawConfig, accountId?: string): ResolvedAdpOpenclawAccount {
|
|
65
65
|
const channelCfg = cfg.channels?.["adp-openclaw"] as AdpOpenclawChannelConfig | undefined;
|
|
66
66
|
const enabled = channelCfg?.enabled !== false;
|
|
67
67
|
const creds = resolveAdpOpenclawCredentials(channelCfg);
|
|
@@ -87,7 +87,7 @@ export const adpOpenclawPlugin: ChannelPlugin<ResolvedAdpOpenclawAccount> = {
|
|
|
87
87
|
blurb: "ADP channel backed by a Go WebSocket server.",
|
|
88
88
|
order: 999,
|
|
89
89
|
},
|
|
90
|
-
|
|
90
|
+
setupWizard: adpOpenclawSetupWizard,
|
|
91
91
|
capabilities: {
|
|
92
92
|
chatTypes: ["direct"],
|
|
93
93
|
polls: false,
|
|
@@ -128,7 +128,7 @@ export const adpOpenclawPlugin: ChannelPlugin<ResolvedAdpOpenclawAccount> = {
|
|
|
128
128
|
},
|
|
129
129
|
}),
|
|
130
130
|
deleteAccount: ({ cfg }) => {
|
|
131
|
-
const next = { ...cfg } as
|
|
131
|
+
const next = { ...cfg } as OpenClawConfig;
|
|
132
132
|
const nextChannels = { ...cfg.channels };
|
|
133
133
|
delete (nextChannels as Record<string, unknown>)["adp-openclaw"];
|
|
134
134
|
if (Object.keys(nextChannels).length > 0) {
|
package/src/monitor.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Monitor: WebSocket connection to Go server for real-time message handling
|
|
2
2
|
// Supports: API Token auth, conversation tracking for multi-turn dialogues
|
|
3
3
|
|
|
4
|
-
import type { PluginLogger,
|
|
4
|
+
import type { PluginLogger, OpenClawConfig } from "openclaw/plugin-sdk";
|
|
5
5
|
import { getAdpOpenclawRuntime, setActiveWebSocket } from "./runtime.js";
|
|
6
6
|
import {
|
|
7
7
|
getChatHistory,
|
|
@@ -40,7 +40,7 @@ export type MonitorParams = {
|
|
|
40
40
|
signKey?: string; // HMAC key for signature generation
|
|
41
41
|
abortSignal?: AbortSignal;
|
|
42
42
|
log?: PluginLogger;
|
|
43
|
-
cfg?:
|
|
43
|
+
cfg?: OpenClawConfig; // OpenClaw config for model settings
|
|
44
44
|
setStatus?: (next: Record<string, unknown>) => void; // SDK health-monitor status reporter
|
|
45
45
|
};
|
|
46
46
|
|
|
@@ -127,7 +127,7 @@ function generateRequestId(): string {
|
|
|
127
127
|
async function markSessionAborted(params: {
|
|
128
128
|
sessionKey: string;
|
|
129
129
|
runtime: ReturnType<typeof getAdpOpenclawRuntime>;
|
|
130
|
-
cfg?:
|
|
130
|
+
cfg?: OpenClawConfig;
|
|
131
131
|
log?: PluginLogger;
|
|
132
132
|
}): Promise<void> {
|
|
133
133
|
const { sessionKey, runtime, cfg, log } = params;
|
|
@@ -206,7 +206,7 @@ type ConnectParams = {
|
|
|
206
206
|
abortSignal?: AbortSignal;
|
|
207
207
|
log?: PluginLogger;
|
|
208
208
|
runtime: ReturnType<typeof getAdpOpenclawRuntime>;
|
|
209
|
-
cfg?:
|
|
209
|
+
cfg?: OpenClawConfig;
|
|
210
210
|
setStatus?: (next: Record<string, unknown>) => void;
|
|
211
211
|
};
|
|
212
212
|
|
package/src/onboarding.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Setup wizard adapter for ADP OpenClaw channel plugin
|
|
2
|
+
// Migrated from ChannelOnboardingAdapter to ChannelSetupWizard for openclaw >= 2026.3.22
|
|
2
3
|
import type {
|
|
3
|
-
|
|
4
|
+
ChannelSetupWizard,
|
|
4
5
|
OpenClawConfig,
|
|
5
|
-
WizardPrompter,
|
|
6
6
|
} from "openclaw/plugin-sdk";
|
|
7
|
-
import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk";
|
|
8
7
|
|
|
9
8
|
const channel = "adp-openclaw" as const;
|
|
10
9
|
|
|
@@ -42,81 +41,89 @@ function updateAdpOpenclawConfig(
|
|
|
42
41
|
};
|
|
43
42
|
}
|
|
44
43
|
|
|
45
|
-
|
|
46
|
-
await prompter.note(
|
|
47
|
-
[
|
|
48
|
-
"ADP OpenClaw connects to a WebSocket server for real-time messaging.",
|
|
49
|
-
"You need a clientToken to authenticate with the server.",
|
|
50
|
-
"The signKey is used for HMAC signature generation (default: ADPOpenClaw).",
|
|
51
|
-
].join("\n"),
|
|
52
|
-
"ADP OpenClaw setup",
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export const adpOpenclawOnboardingAdapter: ChannelOnboardingAdapter = {
|
|
44
|
+
export const adpOpenclawSetupWizard: ChannelSetupWizard = {
|
|
57
45
|
channel,
|
|
58
|
-
getStatus: async ({ cfg }) => {
|
|
59
|
-
const channelCfg = getChannelConfig(cfg);
|
|
60
|
-
const configured = isConfigured(channelCfg);
|
|
61
46
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
47
|
+
status: {
|
|
48
|
+
configuredLabel: "configured",
|
|
49
|
+
unconfiguredLabel: "needs clientToken",
|
|
50
|
+
configuredHint: "configured",
|
|
51
|
+
unconfiguredHint: "requires clientToken",
|
|
52
|
+
configuredScore: 1,
|
|
53
|
+
unconfiguredScore: 10,
|
|
54
|
+
resolveConfigured: ({ cfg }) => {
|
|
55
|
+
const channelCfg = getChannelConfig(cfg);
|
|
56
|
+
return isConfigured(channelCfg);
|
|
57
|
+
},
|
|
58
|
+
resolveStatusLines: ({ cfg, configured }) => {
|
|
59
|
+
return [`ADP OpenClaw: ${configured ? "configured" : "needs clientToken"}`];
|
|
60
|
+
},
|
|
69
61
|
},
|
|
70
|
-
configure: async ({ cfg, prompter }) => {
|
|
71
|
-
let next = cfg;
|
|
72
|
-
const accountId = DEFAULT_ACCOUNT_ID;
|
|
73
|
-
|
|
74
|
-
await noteAdpOpenclawSetup(prompter);
|
|
75
62
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
63
|
+
introNote: {
|
|
64
|
+
title: "ADP OpenClaw setup",
|
|
65
|
+
lines: [
|
|
66
|
+
"ADP OpenClaw connects to a WebSocket server for real-time messaging.",
|
|
67
|
+
"You need a clientToken to authenticate with the server.",
|
|
68
|
+
"The signKey is used for HMAC signature generation (default: ADPOpenClaw).",
|
|
69
|
+
],
|
|
70
|
+
},
|
|
83
71
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
next = updateAdpOpenclawConfig(next, { enabled: true });
|
|
91
|
-
return { cfg: next, accountId };
|
|
92
|
-
}
|
|
93
|
-
}
|
|
72
|
+
envShortcut: {
|
|
73
|
+
prompt: "ADP_OPENCLAW_CLIENT_TOKEN detected in env. Use environment variables?",
|
|
74
|
+
preferredEnvVar: "ADP_OPENCLAW_CLIENT_TOKEN",
|
|
75
|
+
isAvailable: () => Boolean(process.env.ADP_OPENCLAW_CLIENT_TOKEN?.trim()),
|
|
76
|
+
apply: ({ cfg }) => updateAdpOpenclawConfig(cfg, { enabled: true }),
|
|
77
|
+
},
|
|
94
78
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
79
|
+
credentials: [
|
|
80
|
+
{
|
|
81
|
+
inputKey: "token",
|
|
82
|
+
providerHint: "ADP OpenClaw",
|
|
83
|
+
credentialLabel: "Client Token",
|
|
84
|
+
preferredEnvVar: "ADP_OPENCLAW_CLIENT_TOKEN",
|
|
85
|
+
envPrompt: "ADP_OPENCLAW_CLIENT_TOKEN detected. Use it?",
|
|
86
|
+
keepPrompt: "Client Token already set. Keep it?",
|
|
87
|
+
inputPrompt: "Client Token",
|
|
88
|
+
inspect: ({ cfg }) => {
|
|
89
|
+
const channelCfg = getChannelConfig(cfg);
|
|
90
|
+
const configuredValue = channelCfg?.clientToken?.trim();
|
|
91
|
+
const envValue = process.env.ADP_OPENCLAW_CLIENT_TOKEN?.trim();
|
|
92
|
+
return {
|
|
93
|
+
accountConfigured: Boolean(configuredValue || envValue),
|
|
94
|
+
hasConfiguredValue: Boolean(configuredValue),
|
|
95
|
+
resolvedValue: configuredValue || envValue,
|
|
96
|
+
envValue,
|
|
97
|
+
};
|
|
98
|
+
},
|
|
99
|
+
applySet: ({ cfg, resolvedValue }) => {
|
|
100
|
+
return updateAdpOpenclawConfig(cfg, { clientToken: resolvedValue, enabled: true });
|
|
101
|
+
},
|
|
102
|
+
applyUseEnv: ({ cfg }) => {
|
|
103
|
+
return updateAdpOpenclawConfig(cfg, { enabled: true });
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
],
|
|
103
107
|
|
|
104
|
-
|
|
105
|
-
|
|
108
|
+
textInputs: [
|
|
109
|
+
{
|
|
110
|
+
inputKey: "name",
|
|
106
111
|
message: "Sign Key (press Enter for default: ADPOpenClaw)",
|
|
107
112
|
placeholder: "ADPOpenClaw",
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
113
|
+
required: false,
|
|
114
|
+
currentValue: ({ cfg }) => {
|
|
115
|
+
const channelCfg = getChannelConfig(cfg);
|
|
116
|
+
return channelCfg?.signKey?.trim() || process.env.ADP_OPENCLAW_SIGN_KEY?.trim();
|
|
117
|
+
},
|
|
118
|
+
applySet: ({ cfg, value }) => {
|
|
119
|
+
return updateAdpOpenclawConfig(cfg, {
|
|
120
|
+
...(value ? { signKey: value } : {}),
|
|
121
|
+
enabled: true,
|
|
122
|
+
});
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
],
|
|
117
126
|
|
|
118
|
-
return { cfg: next, accountId };
|
|
119
|
-
},
|
|
120
127
|
disable: (cfg) => {
|
|
121
128
|
return {
|
|
122
129
|
...cfg,
|
package/src/session-history.ts
CHANGED
|
@@ -498,9 +498,10 @@ export async function getMergedChatHistory(
|
|
|
498
498
|
options?: {
|
|
499
499
|
limit?: number;
|
|
500
500
|
log?: PluginLogger;
|
|
501
|
+
filterAfterNewSession?: boolean; // Default true: filter out messages before last /new
|
|
501
502
|
},
|
|
502
503
|
): Promise<ChatHistoryResponse> {
|
|
503
|
-
const { limit = 200, log } = options ?? {};
|
|
504
|
+
const { limit = 200, log, filterAfterNewSession = true } = options ?? {};
|
|
504
505
|
|
|
505
506
|
// Build both old and new session key formats
|
|
506
507
|
const oldSessionKey = `agent:main:direct:${conversationId}`;
|
|
@@ -511,6 +512,7 @@ export async function getMergedChatHistory(
|
|
|
511
512
|
log?.info?.(`[session-history] New sessionKey: ${newSessionKey}`);
|
|
512
513
|
|
|
513
514
|
// Fetch history from both session keys in parallel
|
|
515
|
+
// Note: getChatHistory already applies filterAfterNewSession for each session individually
|
|
514
516
|
const [oldResult, newResult] = await Promise.all([
|
|
515
517
|
getChatHistory(oldSessionKey, { limit, log }).catch((err) => {
|
|
516
518
|
log?.debug?.(`[session-history] Failed to fetch old session history: ${err}`);
|
|
@@ -537,7 +539,7 @@ export async function getMergedChatHistory(
|
|
|
537
539
|
|
|
538
540
|
// Deduplicate by message id (if available) or content+timestamp
|
|
539
541
|
const seen = new Set<string>();
|
|
540
|
-
|
|
542
|
+
let dedupedMessages = allMessages.filter((msg) => {
|
|
541
543
|
// Create a unique key for deduplication
|
|
542
544
|
const key = msg.id || `${msg.role}:${msg.timestamp}:${msg.content.slice(0, 100)}`;
|
|
543
545
|
if (seen.has(key)) {
|
|
@@ -547,6 +549,13 @@ export async function getMergedChatHistory(
|
|
|
547
549
|
return true;
|
|
548
550
|
});
|
|
549
551
|
|
|
552
|
+
// Filter out messages before the last /new session on the MERGED result
|
|
553
|
+
// This is important because the /new might be in the old sessionKey but we still
|
|
554
|
+
// want to filter the combined history based on the latest /new across both sessions
|
|
555
|
+
if (filterAfterNewSession) {
|
|
556
|
+
dedupedMessages = filterMessagesAfterLastNewSession(dedupedMessages, log);
|
|
557
|
+
}
|
|
558
|
+
|
|
550
559
|
// Apply limit (return last N messages if exceeds limit)
|
|
551
560
|
const limitedMessages = dedupedMessages.length > limit
|
|
552
561
|
? dedupedMessages.slice(-limit)
|