adp-openclaw 0.0.55 → 0.0.56
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/monitor.ts +59 -1
package/package.json
CHANGED
package/src/monitor.ts
CHANGED
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
formatUploadResultAsMarkdown,
|
|
24
24
|
} from "./tool-result-message-blocks.js";
|
|
25
25
|
import crypto from "crypto";
|
|
26
|
+
import fs from "fs";
|
|
26
27
|
// @ts-ignore - import JSON file
|
|
27
28
|
import packageJson from "../package.json" with { type: "json" };
|
|
28
29
|
|
|
@@ -116,6 +117,53 @@ function generateRequestId(): string {
|
|
|
116
117
|
return `req-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
117
118
|
}
|
|
118
119
|
|
|
120
|
+
/**
|
|
121
|
+
* Mark a session's abortedLastRun flag in the sessions store.
|
|
122
|
+
* This tells the SDK to inject an "abort hint" on the next message,
|
|
123
|
+
* preventing the AI from resuming the cancelled task.
|
|
124
|
+
*/
|
|
125
|
+
async function markSessionAborted(params: {
|
|
126
|
+
sessionKey: string;
|
|
127
|
+
runtime: ReturnType<typeof getAdpOpenclawRuntime>;
|
|
128
|
+
cfg?: ClawdbotConfig;
|
|
129
|
+
log?: PluginLogger;
|
|
130
|
+
}): Promise<void> {
|
|
131
|
+
const { sessionKey, runtime, cfg, log } = params;
|
|
132
|
+
try {
|
|
133
|
+
// Use SDK's resolveStorePath to find the sessions.json location
|
|
134
|
+
const storePath = runtime.channel.session.resolveStorePath(cfg?.session?.store);
|
|
135
|
+
if (!storePath || !fs.existsSync(storePath)) {
|
|
136
|
+
log?.warn?.(`[adp-openclaw] Cannot mark session aborted: store not found at ${storePath}`);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const raw = fs.readFileSync(storePath, "utf-8");
|
|
141
|
+
const store = JSON.parse(raw) as Record<string, { abortedLastRun?: boolean; updatedAt?: number; [key: string]: unknown }>;
|
|
142
|
+
|
|
143
|
+
// Try both the raw sessionKey and the "agent:main:{sessionKey}" variant
|
|
144
|
+
const candidates = [sessionKey, `agent:main:${sessionKey}`];
|
|
145
|
+
let matchedKey: string | undefined;
|
|
146
|
+
for (const key of candidates) {
|
|
147
|
+
if (store[key]) {
|
|
148
|
+
matchedKey = key;
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (!matchedKey) {
|
|
154
|
+
log?.info?.(`[adp-openclaw] Session key not found in store for abort marking: ${sessionKey}`);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
store[matchedKey].abortedLastRun = true;
|
|
159
|
+
store[matchedKey].updatedAt = Date.now();
|
|
160
|
+
fs.writeFileSync(storePath, JSON.stringify(store, null, 2), "utf-8");
|
|
161
|
+
log?.info?.(`[adp-openclaw] Marked session ${matchedKey} as abortedLastRun=true`);
|
|
162
|
+
} catch (err) {
|
|
163
|
+
log?.error?.(`[adp-openclaw] Failed to mark session aborted: ${err}`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
119
167
|
export async function monitorAdpOpenclaw(params: MonitorParams): Promise<void> {
|
|
120
168
|
const { wsUrl, clientToken, signKey, abortSignal, log, cfg } = params;
|
|
121
169
|
const runtime = getAdpOpenclawRuntime();
|
|
@@ -255,6 +303,7 @@ async function connectAndHandle(params: ConnectParams): Promise<void> {
|
|
|
255
303
|
log?.info(`[adp-openclaw] Received: ${inMsg.from}: ${inMsg.text} (conv=${inMsg.conversationId}, rec=${inMsg.recordId || 'none'}, user=${JSON.stringify(inMsg.user || {})})`);
|
|
256
304
|
|
|
257
305
|
// Process the message with full user identity
|
|
306
|
+
const convIdForCleanup = inMsg.conversationId || `fallback-${Date.now()}`;
|
|
258
307
|
try {
|
|
259
308
|
// Build user identity string for From field (like Feishu: "feishu:user_id")
|
|
260
309
|
const userIdentifier = inMsg.user?.userId || inMsg.from;
|
|
@@ -582,6 +631,15 @@ async function connectAndHandle(params: ConnectParams): Promise<void> {
|
|
|
582
631
|
const cancelText = lastPartialText ? `${lastPartialText}\n\n[已停止生成]` : "[已停止生成]";
|
|
583
632
|
log?.info(`[adp-openclaw] Generation cancelled, sending outbound_end with partial text`);
|
|
584
633
|
sendOutboundEnd(cancelText);
|
|
634
|
+
|
|
635
|
+
// Mark the session as aborted so the SDK injects an "abort hint"
|
|
636
|
+
// on the next message, preventing the AI from resuming the cancelled task
|
|
637
|
+
await markSessionAborted({
|
|
638
|
+
sessionKey: route.sessionKey,
|
|
639
|
+
runtime,
|
|
640
|
+
cfg,
|
|
641
|
+
log,
|
|
642
|
+
});
|
|
585
643
|
}
|
|
586
644
|
|
|
587
645
|
// IMPORTANT: After dispatchReplyWithBufferedBlockDispatcher completes,
|
|
@@ -595,7 +653,7 @@ async function connectAndHandle(params: ConnectParams): Promise<void> {
|
|
|
595
653
|
}
|
|
596
654
|
} catch (err) {
|
|
597
655
|
// Clean up on error
|
|
598
|
-
activeGenerations.delete(
|
|
656
|
+
activeGenerations.delete(convIdForCleanup);
|
|
599
657
|
log?.error(`[adp-openclaw] Failed to process message: ${err}`);
|
|
600
658
|
}
|
|
601
659
|
break;
|