aamp-openclaw-plugin 0.1.30 → 0.1.31
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/dist/index.js +124 -11
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1833,6 +1833,7 @@ var AampClient = class _AampClient extends TinyEmitter {
|
|
|
1833
1833
|
jmapClient;
|
|
1834
1834
|
smtpSender;
|
|
1835
1835
|
config;
|
|
1836
|
+
streamAppendQueues = /* @__PURE__ */ new Map();
|
|
1836
1837
|
constructor(config) {
|
|
1837
1838
|
super();
|
|
1838
1839
|
this.config = config;
|
|
@@ -2162,7 +2163,15 @@ var AampClient = class _AampClient extends TinyEmitter {
|
|
|
2162
2163
|
}
|
|
2163
2164
|
return res.json();
|
|
2164
2165
|
}
|
|
2165
|
-
|
|
2166
|
+
getStreamAppendQueue(streamId) {
|
|
2167
|
+
let queue = this.streamAppendQueues.get(streamId);
|
|
2168
|
+
if (!queue) {
|
|
2169
|
+
queue = { running: false, operations: [] };
|
|
2170
|
+
this.streamAppendQueues.set(streamId, queue);
|
|
2171
|
+
}
|
|
2172
|
+
return queue;
|
|
2173
|
+
}
|
|
2174
|
+
async dispatchStreamAppend(opts) {
|
|
2166
2175
|
const stream = await this.resolveStreamCapability();
|
|
2167
2176
|
const res = await _AampClient.callDiscoveredApi(this.config.baseUrl, {
|
|
2168
2177
|
action: stream.appendAction ?? "aamp.stream.append",
|
|
@@ -2176,7 +2185,98 @@ var AampClient = class _AampClient extends TinyEmitter {
|
|
|
2176
2185
|
}
|
|
2177
2186
|
return res.json();
|
|
2178
2187
|
}
|
|
2188
|
+
enqueueStreamAppend(streamId, operation) {
|
|
2189
|
+
const queue = this.getStreamAppendQueue(streamId);
|
|
2190
|
+
queue.operations.push(operation);
|
|
2191
|
+
void this.drainStreamAppendQueue(streamId);
|
|
2192
|
+
}
|
|
2193
|
+
async drainStreamAppendQueue(streamId) {
|
|
2194
|
+
const queue = this.streamAppendQueues.get(streamId);
|
|
2195
|
+
if (!queue || queue.running)
|
|
2196
|
+
return;
|
|
2197
|
+
queue.running = true;
|
|
2198
|
+
try {
|
|
2199
|
+
while (queue.operations.length) {
|
|
2200
|
+
const operation = queue.operations.shift();
|
|
2201
|
+
if (!operation)
|
|
2202
|
+
continue;
|
|
2203
|
+
if (operation.kind === "text-delta-batch") {
|
|
2204
|
+
try {
|
|
2205
|
+
const event = await this.dispatchStreamAppend({
|
|
2206
|
+
streamId,
|
|
2207
|
+
type: "text.delta",
|
|
2208
|
+
payload: {
|
|
2209
|
+
...operation.payload,
|
|
2210
|
+
text: operation.text
|
|
2211
|
+
}
|
|
2212
|
+
});
|
|
2213
|
+
for (const resolve of operation.resolvers)
|
|
2214
|
+
resolve(event);
|
|
2215
|
+
} catch (error) {
|
|
2216
|
+
for (const reject of operation.rejecters)
|
|
2217
|
+
reject(error);
|
|
2218
|
+
}
|
|
2219
|
+
continue;
|
|
2220
|
+
}
|
|
2221
|
+
try {
|
|
2222
|
+
const event = await this.dispatchStreamAppend(operation.opts);
|
|
2223
|
+
operation.resolve(event);
|
|
2224
|
+
} catch (error) {
|
|
2225
|
+
operation.reject(error);
|
|
2226
|
+
}
|
|
2227
|
+
}
|
|
2228
|
+
} finally {
|
|
2229
|
+
queue.running = false;
|
|
2230
|
+
if (queue.operations.length === 0) {
|
|
2231
|
+
this.streamAppendQueues.delete(streamId);
|
|
2232
|
+
}
|
|
2233
|
+
}
|
|
2234
|
+
}
|
|
2235
|
+
async flushStreamAppendQueue(streamId) {
|
|
2236
|
+
while (true) {
|
|
2237
|
+
const queue = this.streamAppendQueues.get(streamId);
|
|
2238
|
+
if (!queue)
|
|
2239
|
+
return;
|
|
2240
|
+
if (!queue.running && queue.operations.length === 0) {
|
|
2241
|
+
this.streamAppendQueues.delete(streamId);
|
|
2242
|
+
return;
|
|
2243
|
+
}
|
|
2244
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
2245
|
+
}
|
|
2246
|
+
}
|
|
2247
|
+
async appendStreamEvent(opts) {
|
|
2248
|
+
if (opts.type === "text.delta" && typeof opts.payload.text === "string") {
|
|
2249
|
+
return await new Promise((resolve, reject) => {
|
|
2250
|
+
const queue = this.getStreamAppendQueue(opts.streamId);
|
|
2251
|
+
const lastOperation = queue.operations.at(-1);
|
|
2252
|
+
if (lastOperation?.kind === "text-delta-batch") {
|
|
2253
|
+
lastOperation.text += String(opts.payload.text ?? "");
|
|
2254
|
+
lastOperation.resolvers.push(resolve);
|
|
2255
|
+
lastOperation.rejecters.push(reject);
|
|
2256
|
+
return;
|
|
2257
|
+
}
|
|
2258
|
+
this.enqueueStreamAppend(opts.streamId, {
|
|
2259
|
+
kind: "text-delta-batch",
|
|
2260
|
+
text: String(opts.payload.text ?? ""),
|
|
2261
|
+
payload: {
|
|
2262
|
+
...opts.payload
|
|
2263
|
+
},
|
|
2264
|
+
resolvers: [resolve],
|
|
2265
|
+
rejecters: [reject]
|
|
2266
|
+
});
|
|
2267
|
+
});
|
|
2268
|
+
}
|
|
2269
|
+
return await new Promise((resolve, reject) => {
|
|
2270
|
+
this.enqueueStreamAppend(opts.streamId, {
|
|
2271
|
+
kind: "single-event",
|
|
2272
|
+
opts,
|
|
2273
|
+
resolve,
|
|
2274
|
+
reject
|
|
2275
|
+
});
|
|
2276
|
+
});
|
|
2277
|
+
}
|
|
2179
2278
|
async closeStream(opts) {
|
|
2279
|
+
await this.flushStreamAppendQueue(opts.streamId);
|
|
2180
2280
|
const stream = await this.resolveStreamCapability();
|
|
2181
2281
|
const res = await _AampClient.callDiscoveredApi(this.config.baseUrl, {
|
|
2182
2282
|
action: stream.closeAction ?? "aamp.stream.close",
|
|
@@ -2436,6 +2536,7 @@ function baseUrl(aampHost) {
|
|
|
2436
2536
|
var pendingTasks = /* @__PURE__ */ new Map();
|
|
2437
2537
|
var activeTaskStreams = /* @__PURE__ */ new Map();
|
|
2438
2538
|
var terminalTaskIds = new Set(loadTaskState(defaultTaskStatePath()).terminalTaskIds ?? []);
|
|
2539
|
+
var AAMP_SESSION_PREFIX = "aamp:";
|
|
2439
2540
|
var dispatchedSubtasks = /* @__PURE__ */ new Map();
|
|
2440
2541
|
var waitingDispatches = /* @__PURE__ */ new Map();
|
|
2441
2542
|
var aampClient = null;
|
|
@@ -2447,7 +2548,6 @@ var lastLoggedTransportMode = "disconnected";
|
|
|
2447
2548
|
var reconcileTimer = null;
|
|
2448
2549
|
var transportMonitorTimer = null;
|
|
2449
2550
|
var historicalReconcileCompleted = false;
|
|
2450
|
-
var currentSessionKey = "agent:main:main";
|
|
2451
2551
|
var channelRuntime = null;
|
|
2452
2552
|
var channelCfg = null;
|
|
2453
2553
|
async function ensureTaskStream(task) {
|
|
@@ -2514,6 +2614,12 @@ function logTransportState(api, mode, email, previousMode) {
|
|
|
2514
2614
|
function isSyntheticPendingKey(taskKey) {
|
|
2515
2615
|
return taskKey.startsWith("result:") || taskKey.startsWith("help:");
|
|
2516
2616
|
}
|
|
2617
|
+
function isAampSessionKey(sessionKey) {
|
|
2618
|
+
return typeof sessionKey === "string" && sessionKey.startsWith(AAMP_SESSION_PREFIX);
|
|
2619
|
+
}
|
|
2620
|
+
function buildAampWakeSessionKey(kind, id) {
|
|
2621
|
+
return `${AAMP_SESSION_PREFIX}wake:${kind}:${id}`;
|
|
2622
|
+
}
|
|
2517
2623
|
function saveTerminalTaskIds() {
|
|
2518
2624
|
saveTaskState({ terminalTaskIds: [...terminalTaskIds] }, defaultTaskStatePath());
|
|
2519
2625
|
}
|
|
@@ -2749,10 +2855,11 @@ var src_default = {
|
|
|
2749
2855
|
api.logger.info(`[AAMP] Directory profile synced${cardText ? " (card text registered)" : ""}`);
|
|
2750
2856
|
}
|
|
2751
2857
|
function wakeAgentForPendingTask(task) {
|
|
2752
|
-
const
|
|
2858
|
+
const fallbackSessionKey = buildAampWakeSessionKey("task", task.taskId);
|
|
2859
|
+
const fallback = () => triggerHeartbeatWake(fallbackSessionKey, `task ${task.taskId}`);
|
|
2753
2860
|
const dispatcher = channelRuntime?.reply?.dispatchReplyWithBufferedBlockDispatcher;
|
|
2754
2861
|
api.logger.info(
|
|
2755
|
-
`[AAMP] Wake requested for task ${task.taskId} \u2014 channelRuntime=${channelRuntime ? "yes" : "no"} channelCfg=${channelCfg ? "yes" : "no"} dispatcher=${typeof dispatcher === "function" ? "yes" : "no"}
|
|
2862
|
+
`[AAMP] Wake requested for task ${task.taskId} \u2014 channelRuntime=${channelRuntime ? "yes" : "no"} channelCfg=${channelCfg ? "yes" : "no"} dispatcher=${typeof dispatcher === "function" ? "yes" : "no"} fallbackSession=${fallbackSessionKey}`
|
|
2756
2863
|
);
|
|
2757
2864
|
if (!channelRuntime || !channelCfg || typeof dispatcher !== "function") {
|
|
2758
2865
|
fallback();
|
|
@@ -2879,7 +2986,7 @@ var src_default = {
|
|
|
2879
2986
|
} catch (err) {
|
|
2880
2987
|
api.logger.error(`[AAMP] task.dispatch handler failed for ${task.taskId}: ${err.message}`);
|
|
2881
2988
|
if (pendingTasks.has(task.taskId)) {
|
|
2882
|
-
triggerHeartbeatWake(
|
|
2989
|
+
triggerHeartbeatWake(buildAampWakeSessionKey("task", task.taskId), `task ${task.taskId}`);
|
|
2883
2990
|
}
|
|
2884
2991
|
}
|
|
2885
2992
|
})();
|
|
@@ -3014,7 +3121,7 @@ ${notifyBody?.bodyText ?? "Sub-task completed."}${actionSection}`;
|
|
|
3014
3121
|
api.logger.error(`[AAMP] Channel dispatch failed: ${err.message}`);
|
|
3015
3122
|
});
|
|
3016
3123
|
} else {
|
|
3017
|
-
const notifySessionKey =
|
|
3124
|
+
const notifySessionKey = buildAampWakeSessionKey("result", result.taskId);
|
|
3018
3125
|
try {
|
|
3019
3126
|
api.runtime.system.requestHeartbeatNow({ reason: "wake", sessionKey: notifySessionKey });
|
|
3020
3127
|
api.logger.info(`[AAMP] Heartbeat for sub-task result ${result.taskId}`);
|
|
@@ -3090,7 +3197,7 @@ ${notifyBody?.bodyText ?? help.question}`;
|
|
|
3090
3197
|
api.logger.error(`[AAMP] Channel dispatch failed for help: ${err.message}`);
|
|
3091
3198
|
});
|
|
3092
3199
|
} else {
|
|
3093
|
-
const helpSessionKey =
|
|
3200
|
+
const helpSessionKey = buildAampWakeSessionKey("help", help.taskId);
|
|
3094
3201
|
try {
|
|
3095
3202
|
api.runtime.system.requestHeartbeatNow({ reason: "wake", sessionKey: helpSessionKey });
|
|
3096
3203
|
api.logger.info(`[AAMP] Heartbeat fallback for sub-task help ${help.taskId}`);
|
|
@@ -3230,7 +3337,10 @@ ${notifyBody?.bodyText ?? help.question}`;
|
|
|
3230
3337
|
return;
|
|
3231
3338
|
api.logger.info(`[AAMP] gateway_start: re-triggering heartbeat for ${pendingTasks.size} pending task(s)`);
|
|
3232
3339
|
try {
|
|
3233
|
-
api.runtime.system.requestHeartbeatNow({
|
|
3340
|
+
api.runtime.system.requestHeartbeatNow({
|
|
3341
|
+
reason: "wake",
|
|
3342
|
+
sessionKey: buildAampWakeSessionKey("queue", "gateway-start")
|
|
3343
|
+
});
|
|
3234
3344
|
} catch (err) {
|
|
3235
3345
|
api.logger.warn(`[AAMP] gateway_start heartbeat failed: ${err.message}`);
|
|
3236
3346
|
}
|
|
@@ -3238,8 +3348,8 @@ ${notifyBody?.bodyText ?? help.question}`;
|
|
|
3238
3348
|
api.on(
|
|
3239
3349
|
"before_prompt_build",
|
|
3240
3350
|
(_event, ctx) => {
|
|
3241
|
-
if (
|
|
3242
|
-
|
|
3351
|
+
if (!isAampSessionKey(ctx?.sessionKey)) {
|
|
3352
|
+
return {};
|
|
3243
3353
|
}
|
|
3244
3354
|
for (const [id, t] of pendingTasks) {
|
|
3245
3355
|
if (hasExpired(t)) {
|
|
@@ -3525,7 +3635,10 @@ ${task.contextLinks.map((l) => ` - ${l}`).join("\n")}` : "",
|
|
|
3525
3635
|
api.logger.info(`[AAMP] \u2192 task.result ${task.taskId} ${p.status}`);
|
|
3526
3636
|
if (pendingTasks.size > 0) {
|
|
3527
3637
|
try {
|
|
3528
|
-
api.runtime.system.requestHeartbeatNow({
|
|
3638
|
+
api.runtime.system.requestHeartbeatNow({
|
|
3639
|
+
reason: "wake",
|
|
3640
|
+
sessionKey: buildAampWakeSessionKey("queue", "follow-up")
|
|
3641
|
+
});
|
|
3529
3642
|
} catch {
|
|
3530
3643
|
}
|
|
3531
3644
|
}
|