@useorgx/openclaw-plugin 0.7.20 → 0.7.24
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/dashboard/dist/assets/B6VftyY6.js +1 -0
- package/dashboard/dist/assets/B6VftyY6.js.br +0 -0
- package/dashboard/dist/assets/B6VftyY6.js.gz +0 -0
- package/dashboard/dist/assets/{Dm0CfDGr.js → BANQdlC4.js} +1 -1
- package/dashboard/dist/assets/BANQdlC4.js.br +0 -0
- package/dashboard/dist/assets/BANQdlC4.js.gz +0 -0
- package/dashboard/dist/assets/{_zpQCpjm.js → BPL4CL3c.js} +1 -1
- package/dashboard/dist/assets/BPL4CL3c.js.br +0 -0
- package/dashboard/dist/assets/BPL4CL3c.js.gz +0 -0
- package/dashboard/dist/assets/{DXVs61e1.js → BZCkOZ20.js} +1 -1
- package/dashboard/dist/assets/BZCkOZ20.js.br +0 -0
- package/dashboard/dist/assets/BZCkOZ20.js.gz +0 -0
- package/dashboard/dist/assets/{BYb6DARX.js → B_LdOJUa.js} +1 -1
- package/dashboard/dist/assets/B_LdOJUa.js.br +0 -0
- package/dashboard/dist/assets/B_LdOJUa.js.gz +0 -0
- package/dashboard/dist/assets/Bfp-wdwb.css +1 -0
- package/dashboard/dist/assets/Bfp-wdwb.css.br +0 -0
- package/dashboard/dist/assets/Bfp-wdwb.css.gz +0 -0
- package/dashboard/dist/assets/{DibzNd0I.js → BvFcH_Iy.js} +1 -1
- package/dashboard/dist/assets/BvFcH_Iy.js.br +0 -0
- package/dashboard/dist/assets/BvFcH_Iy.js.gz +0 -0
- package/dashboard/dist/assets/By0MIBj_.js +1 -0
- package/dashboard/dist/assets/By0MIBj_.js.br +0 -0
- package/dashboard/dist/assets/By0MIBj_.js.gz +0 -0
- package/dashboard/dist/assets/C0i7ABUU.js +212 -0
- package/dashboard/dist/assets/C0i7ABUU.js.br +0 -0
- package/dashboard/dist/assets/C0i7ABUU.js.gz +0 -0
- package/dashboard/dist/assets/CFB0MM7j.js +1 -0
- package/dashboard/dist/assets/CFB0MM7j.js.br +0 -0
- package/dashboard/dist/assets/CFB0MM7j.js.gz +0 -0
- package/dashboard/dist/assets/CQSRb1yu.js +1 -0
- package/dashboard/dist/assets/CQSRb1yu.js.br +0 -0
- package/dashboard/dist/assets/CQSRb1yu.js.gz +0 -0
- package/dashboard/dist/assets/{wa4jJQK9.js → CUoQoSm-.js} +1 -1
- package/dashboard/dist/assets/CUoQoSm-.js.br +0 -0
- package/dashboard/dist/assets/CUoQoSm-.js.gz +0 -0
- package/dashboard/dist/assets/Ckd1R1iE.js +1 -0
- package/dashboard/dist/assets/Ckd1R1iE.js.br +0 -0
- package/dashboard/dist/assets/Ckd1R1iE.js.gz +0 -0
- package/dashboard/dist/assets/{BGY6oI8h.js → CqRNb2EL.js} +1 -1
- package/dashboard/dist/assets/CqRNb2EL.js.br +0 -0
- package/dashboard/dist/assets/CqRNb2EL.js.gz +0 -0
- package/dashboard/dist/assets/{DAr4MfFk.js → DClUc9rw.js} +1 -1
- package/dashboard/dist/assets/DClUc9rw.js.br +0 -0
- package/dashboard/dist/assets/DClUc9rw.js.gz +0 -0
- package/dashboard/dist/assets/DF2PMTwT.js +1 -0
- package/dashboard/dist/assets/DF2PMTwT.js.br +0 -0
- package/dashboard/dist/assets/DF2PMTwT.js.gz +0 -0
- package/dashboard/dist/assets/{B014hrCe.js → DJYl7gyA.js} +2 -2
- package/dashboard/dist/assets/DJYl7gyA.js.br +0 -0
- package/dashboard/dist/assets/DJYl7gyA.js.gz +0 -0
- package/dashboard/dist/assets/{BoDhb8_y.js → DZtNMX0t.js} +2 -2
- package/dashboard/dist/assets/DZtNMX0t.js.br +0 -0
- package/dashboard/dist/assets/DZtNMX0t.js.gz +0 -0
- package/dashboard/dist/assets/DlEa8PI0.js +1 -0
- package/dashboard/dist/assets/DlEa8PI0.js.br +0 -0
- package/dashboard/dist/assets/DlEa8PI0.js.gz +0 -0
- package/dashboard/dist/assets/M4QxcXjh.js +1 -0
- package/dashboard/dist/assets/M4QxcXjh.js.br +0 -0
- package/dashboard/dist/assets/M4QxcXjh.js.gz +0 -0
- package/dashboard/dist/assets/{CV0sWMbv.js → MrW1ixGx.js} +1 -1
- package/dashboard/dist/assets/MrW1ixGx.js.br +0 -0
- package/dashboard/dist/assets/MrW1ixGx.js.gz +0 -0
- package/dashboard/dist/index.html +2 -2
- package/dashboard/dist/index.html.br +0 -0
- package/dashboard/dist/index.html.gz +0 -0
- package/dist/activity-store.js +68 -8
- package/dist/agent-run-store.js +162 -24
- package/dist/cli/orgx.d.ts +3 -0
- package/dist/config/resolution.d.ts +7 -0
- package/dist/config/resolution.js +13 -5
- package/dist/contracts/onboarding-state.d.ts +2 -0
- package/dist/contracts/onboarding-state.js +23 -0
- package/dist/contracts/shared-types.d.ts +45 -0
- package/dist/http/helpers/auto-continue-engine.d.ts +23 -0
- package/dist/http/helpers/auto-continue-engine.js +468 -85
- package/dist/http/helpers/autopilot-runtime.js +5 -1
- package/dist/http/helpers/autopilot-slice-utils.js +25 -1
- package/dist/http/helpers/decision-mapper.d.ts +1 -0
- package/dist/http/helpers/decision-mapper.js +19 -2
- package/dist/http/helpers/dispatch-lifecycle.js +3 -0
- package/dist/http/helpers/mission-control.d.ts +1 -0
- package/dist/http/helpers/mission-control.js +5 -2
- package/dist/http/helpers/slice-run-projections.d.ts +27 -0
- package/dist/http/helpers/slice-run-projections.js +198 -10
- package/dist/http/helpers/triage-mapper.js +499 -6
- package/dist/http/helpers/value-utils.d.ts +1 -0
- package/dist/http/helpers/value-utils.js +17 -0
- package/dist/http/index.d.ts +1 -0
- package/dist/http/index.js +179 -46
- package/dist/http/router.js +64 -9
- package/dist/http/routes/live-legacy.d.ts +19 -2
- package/dist/http/routes/live-legacy.js +110 -27
- package/dist/http/routes/live-snapshot.d.ts +16 -2
- package/dist/http/routes/live-snapshot.js +169 -25
- package/dist/http/routes/live-triage.js +6 -1
- package/dist/http/routes/mission-control-actions.d.ts +9 -0
- package/dist/http/routes/mission-control-actions.js +185 -7
- package/dist/http/routes/mission-control-read.d.ts +13 -0
- package/dist/http/routes/mission-control-read.js +100 -219
- package/dist/http/routes/onboarding.d.ts +1 -0
- package/dist/http/routes/onboarding.js +17 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +199 -123
- package/dist/outbox.d.ts +0 -2
- package/dist/outbox.js +259 -148
- package/dist/reporting/rollups.js +18 -11
- package/dist/runtime-instance-store.js +212 -58
- package/dist/stores/materialized-snapshot-store.d.ts +18 -0
- package/dist/stores/materialized-snapshot-store.js +91 -0
- package/dist/stores/sqlite-state.d.ts +6 -0
- package/dist/stores/sqlite-state.js +330 -0
- package/package.json +5 -1
- package/dashboard/dist/assets/B014hrCe.js.br +0 -0
- package/dashboard/dist/assets/B014hrCe.js.gz +0 -0
- package/dashboard/dist/assets/BCudUvwg.js +0 -1
- package/dashboard/dist/assets/BCudUvwg.js.br +0 -0
- package/dashboard/dist/assets/BCudUvwg.js.gz +0 -0
- package/dashboard/dist/assets/BGY6oI8h.js.br +0 -0
- package/dashboard/dist/assets/BGY6oI8h.js.gz +0 -0
- package/dashboard/dist/assets/BJI1Iy5v.css +0 -1
- package/dashboard/dist/assets/BJI1Iy5v.css.br +0 -0
- package/dashboard/dist/assets/BJI1Iy5v.css.gz +0 -0
- package/dashboard/dist/assets/BUvcp_7V.js +0 -1
- package/dashboard/dist/assets/BUvcp_7V.js.br +0 -0
- package/dashboard/dist/assets/BUvcp_7V.js.gz +0 -0
- package/dashboard/dist/assets/BV2Tf8S2.js +0 -212
- package/dashboard/dist/assets/BV2Tf8S2.js.br +0 -0
- package/dashboard/dist/assets/BV2Tf8S2.js.gz +0 -0
- package/dashboard/dist/assets/BYb6DARX.js.br +0 -0
- package/dashboard/dist/assets/BYb6DARX.js.gz +0 -0
- package/dashboard/dist/assets/BoDhb8_y.js.br +0 -0
- package/dashboard/dist/assets/BoDhb8_y.js.gz +0 -0
- package/dashboard/dist/assets/Bqk_l0k6.js +0 -1
- package/dashboard/dist/assets/Bqk_l0k6.js.br +0 -0
- package/dashboard/dist/assets/Bqk_l0k6.js.gz +0 -0
- package/dashboard/dist/assets/C-MOJWHs.js +0 -1
- package/dashboard/dist/assets/C-MOJWHs.js.br +0 -0
- package/dashboard/dist/assets/C-MOJWHs.js.gz +0 -0
- package/dashboard/dist/assets/CV0sWMbv.js.br +0 -0
- package/dashboard/dist/assets/CV0sWMbv.js.gz +0 -0
- package/dashboard/dist/assets/CaAkScfa.js +0 -1
- package/dashboard/dist/assets/CaAkScfa.js.br +0 -0
- package/dashboard/dist/assets/CaAkScfa.js.gz +0 -0
- package/dashboard/dist/assets/Ck5KlsPN.js +0 -1
- package/dashboard/dist/assets/Ck5KlsPN.js.br +0 -0
- package/dashboard/dist/assets/Ck5KlsPN.js.gz +0 -0
- package/dashboard/dist/assets/D2G51wQm.js +0 -1
- package/dashboard/dist/assets/D2G51wQm.js.br +0 -0
- package/dashboard/dist/assets/D2G51wQm.js.gz +0 -0
- package/dashboard/dist/assets/DAr4MfFk.js.br +0 -0
- package/dashboard/dist/assets/DAr4MfFk.js.gz +0 -0
- package/dashboard/dist/assets/DXVs61e1.js.br +0 -0
- package/dashboard/dist/assets/DXVs61e1.js.gz +0 -0
- package/dashboard/dist/assets/DibzNd0I.js.br +0 -0
- package/dashboard/dist/assets/DibzNd0I.js.gz +0 -0
- package/dashboard/dist/assets/Dm0CfDGr.js.br +0 -0
- package/dashboard/dist/assets/Dm0CfDGr.js.gz +0 -0
- package/dashboard/dist/assets/_zpQCpjm.js.br +0 -0
- package/dashboard/dist/assets/_zpQCpjm.js.gz +0 -0
- package/dashboard/dist/assets/uNGpYMSH.js +0 -1
- package/dashboard/dist/assets/uNGpYMSH.js.br +0 -0
- package/dashboard/dist/assets/uNGpYMSH.js.gz +0 -0
- package/dashboard/dist/assets/wa4jJQK9.js.br +0 -0
- package/dashboard/dist/assets/wa4jJQK9.js.gz +0 -0
package/dist/http/index.js
CHANGED
|
@@ -41,6 +41,7 @@ import { listRuntimeInstances, resolveRuntimeHookToken, upsertRuntimeInstanceFro
|
|
|
41
41
|
import { parseJsonSafe } from "../json-utils.js";
|
|
42
42
|
import { readSkillPackState, refreshSkillPackState, rollbackSkillPackPolicy, updateSkillPackPolicy, } from "../skill-pack-state.js";
|
|
43
43
|
import { posthogCapture } from "../telemetry/posthog.js";
|
|
44
|
+
import { clearMaterializedSnapshotMemory, readMaterializedSnapshot, writeMaterializedSnapshot, } from "../stores/materialized-snapshot-store.js";
|
|
44
45
|
import { createRouter } from "./router.js";
|
|
45
46
|
import { summarizeActivityHeadline } from "./helpers/activity-headline.js";
|
|
46
47
|
import { createAutoContinueEngine, } from "./helpers/auto-continue-engine.js";
|
|
@@ -55,7 +56,7 @@ import { configureOpenClawProviderRouting, fetchBillingStatusSafe, isPidAlive, l
|
|
|
55
56
|
import { fetchKickoffContextSafe, renderKickoffMessage } from "./helpers/kickoff-context.js";
|
|
56
57
|
import { createDispatchLifecycle } from "./helpers/dispatch-lifecycle.js";
|
|
57
58
|
import { createRuntimeSseHub } from "./helpers/runtime-sse.js";
|
|
58
|
-
import { parseBooleanQuery, parsePositiveInt, pickHeaderString, pickNumber, pickString, } from "./helpers/value-utils.js";
|
|
59
|
+
import { parseBooleanQuery, pickBoolean, parsePositiveInt, pickHeaderString, pickNumber, pickString, } from "./helpers/value-utils.js";
|
|
59
60
|
import { registerAgentControlRoutes } from "./routes/agent-control.js";
|
|
60
61
|
import { registerAgentSuiteRoutes } from "./routes/agent-suite.js";
|
|
61
62
|
import { registerAgentsCatalogRoutes } from "./routes/agents-catalog.js";
|
|
@@ -271,7 +272,6 @@ async function mapWithConcurrency(items, concurrency, mapper) {
|
|
|
271
272
|
const ACTIVITY_WARM_THROTTLE_MS = 30_000;
|
|
272
273
|
const activityWarmByKey = new Map();
|
|
273
274
|
const SNAPSHOT_RESPONSE_CACHE_TTL_MS = 800;
|
|
274
|
-
const SNAPSHOT_RESPONSE_CACHE_MAX_ENTRIES = 16;
|
|
275
275
|
const SNAPSHOT_ACTIVITY_PERSIST_MIN_INTERVAL_MS = 15_000;
|
|
276
276
|
const SNAPSHOT_ACTIVITY_FINGERPRINT_DEPTH = 8;
|
|
277
277
|
const NEXT_UP_QUEUE_CACHE_TTL_MS = readPositiveIntEnv("ORGX_NEXT_UP_QUEUE_CACHE_TTL_MS", 30_000, { min: 250, max: 120_000 });
|
|
@@ -292,7 +292,6 @@ const LIVE_WORKSPACE_INITIATIVE_STATUSES = [
|
|
|
292
292
|
let lastSnapshotActivityPersistAt = 0;
|
|
293
293
|
let lastSnapshotActivityFingerprint = "";
|
|
294
294
|
let snapshotCacheGeneration = 0;
|
|
295
|
-
const snapshotResponseCache = new Map();
|
|
296
295
|
const ACTIVITY_DECISION_EVENT_HINTS = new Set([
|
|
297
296
|
"decision_buffered",
|
|
298
297
|
"auto_continue_spawn_guard_blocked",
|
|
@@ -435,39 +434,24 @@ function snapshotActivityFingerprint(items) {
|
|
|
435
434
|
.join(";");
|
|
436
435
|
return `${items.length}:${sample}`;
|
|
437
436
|
}
|
|
438
|
-
function
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
}
|
|
446
|
-
return entry.payload;
|
|
437
|
+
function getSnapshotCacheGeneration() {
|
|
438
|
+
return snapshotCacheGeneration;
|
|
439
|
+
}
|
|
440
|
+
function readSnapshotResponseCache(key, options) {
|
|
441
|
+
return readMaterializedSnapshot(key, {
|
|
442
|
+
allowStale: options?.allowStale,
|
|
443
|
+
generation: snapshotCacheGeneration,
|
|
444
|
+
});
|
|
447
445
|
}
|
|
448
446
|
function writeSnapshotResponseCache(key, payload) {
|
|
449
|
-
|
|
450
|
-
snapshotResponseCache.set(key, {
|
|
451
|
-
expiresAt: now + SNAPSHOT_RESPONSE_CACHE_TTL_MS,
|
|
447
|
+
writeMaterializedSnapshot(key, payload, {
|
|
452
448
|
generation: snapshotCacheGeneration,
|
|
453
|
-
|
|
449
|
+
ttlMs: SNAPSHOT_RESPONSE_CACHE_TTL_MS,
|
|
454
450
|
});
|
|
455
|
-
if (snapshotResponseCache.size <= SNAPSHOT_RESPONSE_CACHE_MAX_ENTRIES)
|
|
456
|
-
return;
|
|
457
|
-
for (const [cachedKey, entry] of snapshotResponseCache.entries()) {
|
|
458
|
-
if (entry.expiresAt <= now)
|
|
459
|
-
snapshotResponseCache.delete(cachedKey);
|
|
460
|
-
}
|
|
461
|
-
while (snapshotResponseCache.size > SNAPSHOT_RESPONSE_CACHE_MAX_ENTRIES) {
|
|
462
|
-
const oldestKey = snapshotResponseCache.keys().next().value;
|
|
463
|
-
if (!oldestKey)
|
|
464
|
-
break;
|
|
465
|
-
snapshotResponseCache.delete(oldestKey);
|
|
466
|
-
}
|
|
467
451
|
}
|
|
468
452
|
function clearSnapshotResponseCache() {
|
|
469
453
|
snapshotCacheGeneration += 1;
|
|
470
|
-
|
|
454
|
+
clearMaterializedSnapshotMemory();
|
|
471
455
|
}
|
|
472
456
|
function isUserScopedApiKey(apiKey) {
|
|
473
457
|
return apiKey.trim().toLowerCase().startsWith("oxk_");
|
|
@@ -1751,9 +1735,36 @@ async function parseJsonRequest(req) {
|
|
|
1751
1735
|
}
|
|
1752
1736
|
return parseJsonBody(streamed);
|
|
1753
1737
|
}
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1738
|
+
let activeHttpRuntimeLifecycle = null;
|
|
1739
|
+
function createHttpRuntimeLifecycle(input) {
|
|
1740
|
+
let nextUpPrewarmTimer = null;
|
|
1741
|
+
let autoContinueTimer = null;
|
|
1742
|
+
const stop = () => {
|
|
1743
|
+
if (nextUpPrewarmTimer) {
|
|
1744
|
+
clearTimeout(nextUpPrewarmTimer);
|
|
1745
|
+
nextUpPrewarmTimer = null;
|
|
1746
|
+
}
|
|
1747
|
+
if (autoContinueTimer) {
|
|
1748
|
+
clearInterval(autoContinueTimer);
|
|
1749
|
+
autoContinueTimer = null;
|
|
1750
|
+
}
|
|
1751
|
+
};
|
|
1752
|
+
return {
|
|
1753
|
+
start() {
|
|
1754
|
+
stop();
|
|
1755
|
+
nextUpPrewarmTimer = setTimeout(() => {
|
|
1756
|
+
nextUpPrewarmTimer = null;
|
|
1757
|
+
input.prewarmNextUpQueue();
|
|
1758
|
+
}, 75);
|
|
1759
|
+
nextUpPrewarmTimer.unref?.();
|
|
1760
|
+
autoContinueTimer = setInterval(() => {
|
|
1761
|
+
void input.tickAllAutoContinue();
|
|
1762
|
+
}, input.autoContinueTickMs);
|
|
1763
|
+
autoContinueTimer.unref?.();
|
|
1764
|
+
},
|
|
1765
|
+
stop,
|
|
1766
|
+
};
|
|
1767
|
+
}
|
|
1757
1768
|
export function createHttpHandler(config, client, getSnapshot, onboarding, diagnostics, adapters) {
|
|
1758
1769
|
const dashboardEnabled = config.dashboardEnabled ??
|
|
1759
1770
|
true;
|
|
@@ -2400,6 +2411,30 @@ export function createHttpHandler(config, client, getSnapshot, onboarding, diagn
|
|
|
2400
2411
|
? entry.blockers[0] ??
|
|
2401
2412
|
(statusValues.includes("failed") ? "Latest run failed" : "Workstream blocked")
|
|
2402
2413
|
: null,
|
|
2414
|
+
canStartNow: queueState === QueueState.QUEUED || queueState === QueueState.IDLE,
|
|
2415
|
+
startReasonCode: queueState === QueueState.RUNNING
|
|
2416
|
+
? "already_running"
|
|
2417
|
+
: hasBlocked
|
|
2418
|
+
? "blocked"
|
|
2419
|
+
: queueState === QueueState.QUEUED || queueState === QueueState.IDLE
|
|
2420
|
+
? "dispatchable"
|
|
2421
|
+
: "not_startable",
|
|
2422
|
+
startReasonLabel: hasBlocked
|
|
2423
|
+
? entry.blockers[0] ??
|
|
2424
|
+
(statusValues.includes("failed") ? "Latest run failed." : "Workstream blocked.")
|
|
2425
|
+
: queueState === QueueState.RUNNING
|
|
2426
|
+
? "Already running."
|
|
2427
|
+
: "Ready to start this workstream.",
|
|
2428
|
+
dispatchableTask: queueState === QueueState.QUEUED || queueState === QueueState.IDLE
|
|
2429
|
+
? {
|
|
2430
|
+
id: entry.latest.id ?? `${entry.initiativeId}:${entry.workstreamId}`,
|
|
2431
|
+
title: (entry.latest.lastEventSummary ?? "").trim() ||
|
|
2432
|
+
(entry.latest.title ?? "").trim() ||
|
|
2433
|
+
entry.workstreamTitle,
|
|
2434
|
+
scope: "workstream",
|
|
2435
|
+
milestoneId: null,
|
|
2436
|
+
}
|
|
2437
|
+
: null,
|
|
2403
2438
|
isPinned: pinnedRankByKey.has(pinKey),
|
|
2404
2439
|
pinnedRank: pinnedRankByKey.get(pinKey) ?? null,
|
|
2405
2440
|
autoContinue: null,
|
|
@@ -2492,6 +2527,14 @@ export function createHttpHandler(config, client, getSnapshot, onboarding, diagn
|
|
|
2492
2527
|
const nodeById = new Map(graph.nodes.map((node) => [node.id, node]));
|
|
2493
2528
|
const workstreamNodes = graph.nodes.filter((node) => node.type === "workstream");
|
|
2494
2529
|
const runningWorkstreams = new Set();
|
|
2530
|
+
const initiativeRun = autoContinueRuns.get(initiativeId) ?? null;
|
|
2531
|
+
const initiativeActiveRunIds = Array.isArray(initiativeRun?.activeSliceRunIds)
|
|
2532
|
+
? initiativeRun.activeSliceRunIds
|
|
2533
|
+
.filter((id) => typeof id === "string" && id.trim().length > 0)
|
|
2534
|
+
.map((id) => id.trim())
|
|
2535
|
+
: typeof initiativeRun?.activeRunId === "string" && initiativeRun.activeRunId.trim().length > 0
|
|
2536
|
+
? [initiativeRun.activeRunId.trim()]
|
|
2537
|
+
: [];
|
|
2495
2538
|
const taskIsReady = (task) => task.dependencyIds.every((depId) => {
|
|
2496
2539
|
const dependency = nodeById.get(depId);
|
|
2497
2540
|
return dependency ? isDoneStatus(dependency.status) : true;
|
|
@@ -2692,6 +2735,36 @@ export function createHttpHandler(config, client, getSnapshot, onboarding, diagn
|
|
|
2692
2735
|
if (isSuppressed(initiativeId, workstream.id) && queueState !== QueueState.RUNNING) {
|
|
2693
2736
|
continue;
|
|
2694
2737
|
}
|
|
2738
|
+
const dispatchableTask = preferredReadyTask ?? readyTask ?? null;
|
|
2739
|
+
const initiativeHasConcurrentRun = initiativeActiveRunIds.length > 0 &&
|
|
2740
|
+
laneState !== LaneState.RUNNING &&
|
|
2741
|
+
!(autoContinueRun && autoContinueRun.status === RunStatus.RUNNING);
|
|
2742
|
+
const canStartNow = Boolean(dispatchableTask) &&
|
|
2743
|
+
queueState !== QueueState.RUNNING &&
|
|
2744
|
+
queueState !== QueueState.BLOCKED &&
|
|
2745
|
+
!initiativeHasConcurrentRun;
|
|
2746
|
+
const startReasonCode = canStartNow
|
|
2747
|
+
? "dispatchable"
|
|
2748
|
+
: queueState === QueueState.RUNNING
|
|
2749
|
+
? "already_running"
|
|
2750
|
+
: initiativeHasConcurrentRun
|
|
2751
|
+
? "initiative_run_active"
|
|
2752
|
+
: queueState === QueueState.BLOCKED
|
|
2753
|
+
? "blocked"
|
|
2754
|
+
: !dispatchableTask
|
|
2755
|
+
? "no_dispatchable_task"
|
|
2756
|
+
: "not_startable";
|
|
2757
|
+
const startReasonLabel = canStartNow
|
|
2758
|
+
? `Ready to start ${dispatchableTask?.title ?? "this workstream"}.`
|
|
2759
|
+
: initiativeHasConcurrentRun
|
|
2760
|
+
? "Autopilot is already running for this initiative."
|
|
2761
|
+
: queueState === QueueState.RUNNING
|
|
2762
|
+
? "Already running."
|
|
2763
|
+
: blockReason
|
|
2764
|
+
? blockReason
|
|
2765
|
+
: dispatchableTask
|
|
2766
|
+
? "This workstream is not ready to start."
|
|
2767
|
+
: "No dispatchable task is available right now.";
|
|
2695
2768
|
runningWorkstreams.add(workstream.id);
|
|
2696
2769
|
const assignedRunnerAgents = [];
|
|
2697
2770
|
const assignedRunnerSeen = new Set();
|
|
@@ -2752,6 +2825,17 @@ export function createHttpHandler(config, client, getSnapshot, onboarding, diagn
|
|
|
2752
2825
|
runnerSource,
|
|
2753
2826
|
queueState,
|
|
2754
2827
|
blockReason,
|
|
2828
|
+
canStartNow,
|
|
2829
|
+
startReasonCode,
|
|
2830
|
+
startReasonLabel,
|
|
2831
|
+
dispatchableTask: dispatchableTask
|
|
2832
|
+
? {
|
|
2833
|
+
id: dispatchableTask.id,
|
|
2834
|
+
title: dispatchableTask.title,
|
|
2835
|
+
scope: defaultScope,
|
|
2836
|
+
milestoneId: dispatchableTask.milestoneId ?? null,
|
|
2837
|
+
}
|
|
2838
|
+
: null,
|
|
2755
2839
|
isPinned: Boolean(pin),
|
|
2756
2840
|
pinnedRank: pin ? (pinnedRankByKey.get(pinKey) ?? null) : null,
|
|
2757
2841
|
sliceScope: defaultScope,
|
|
@@ -2859,6 +2943,12 @@ export function createHttpHandler(config, client, getSnapshot, onboarding, diagn
|
|
|
2859
2943
|
blockReason: queueState === QueueState.BLOCKED
|
|
2860
2944
|
? lane?.blockedReason ?? "Blocked"
|
|
2861
2945
|
: null,
|
|
2946
|
+
canStartNow: false,
|
|
2947
|
+
startReasonCode: queueState === QueueState.RUNNING ? "already_running" : "initiative_run_active",
|
|
2948
|
+
startReasonLabel: queueState === QueueState.RUNNING
|
|
2949
|
+
? "Already running."
|
|
2950
|
+
: "Autopilot is already running for this initiative.",
|
|
2951
|
+
dispatchableTask: null,
|
|
2862
2952
|
isPinned: Boolean(pinnedByKey.get(`${initiativeId}:${workstream.id}`)),
|
|
2863
2953
|
pinnedRank: pinnedRankByKey.get(`${initiativeId}:${workstream.id}`) ?? null,
|
|
2864
2954
|
sliceScope,
|
|
@@ -2962,12 +3052,14 @@ export function createHttpHandler(config, client, getSnapshot, onboarding, diagn
|
|
|
2962
3052
|
// best effort prewarm only
|
|
2963
3053
|
});
|
|
2964
3054
|
};
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
3055
|
+
activeHttpRuntimeLifecycle?.stop();
|
|
3056
|
+
const runtimeLifecycle = createHttpRuntimeLifecycle({
|
|
3057
|
+
prewarmNextUpQueue,
|
|
3058
|
+
tickAllAutoContinue,
|
|
3059
|
+
autoContinueTickMs: AUTO_CONTINUE_TICK_MS,
|
|
3060
|
+
});
|
|
3061
|
+
runtimeLifecycle.start();
|
|
3062
|
+
activeHttpRuntimeLifecycle = runtimeLifecycle;
|
|
2971
3063
|
const apiRouter = createRouter();
|
|
2972
3064
|
registerOnboardingRoutes(apiRouter, {
|
|
2973
3065
|
onboarding,
|
|
@@ -3511,6 +3603,7 @@ export function createHttpHandler(config, client, getSnapshot, onboarding, diagn
|
|
|
3511
3603
|
outboxReadAllItems: () => outboxAdapter.readAllItems(),
|
|
3512
3604
|
toLocalLiveActivity,
|
|
3513
3605
|
loadLocalTurnDetail,
|
|
3606
|
+
summarizeActivityHeadline,
|
|
3514
3607
|
sendJson,
|
|
3515
3608
|
safeErrorMessage,
|
|
3516
3609
|
sendHtml,
|
|
@@ -3539,6 +3632,7 @@ export function createHttpHandler(config, client, getSnapshot, onboarding, diagn
|
|
|
3539
3632
|
parsePositiveInt,
|
|
3540
3633
|
readSnapshotResponseCache,
|
|
3541
3634
|
writeSnapshotResponseCache,
|
|
3635
|
+
getSnapshotCacheGeneration,
|
|
3542
3636
|
safeErrorMessage,
|
|
3543
3637
|
readAgentContexts,
|
|
3544
3638
|
getScopedAgentIds,
|
|
@@ -3596,6 +3690,8 @@ export function createHttpHandler(config, client, getSnapshot, onboarding, diagn
|
|
|
3596
3690
|
listChatThreads: ({ commandCenterId, initiativeId, limit, offset }) => listChatThreads({ commandCenterId, initiativeId, limit, offset }),
|
|
3597
3691
|
getCanonicalAutopilotState,
|
|
3598
3692
|
sendJson,
|
|
3693
|
+
securityHeaders: SECURITY_HEADERS,
|
|
3694
|
+
corsHeaders: CORS_HEADERS,
|
|
3599
3695
|
});
|
|
3600
3696
|
registerRuntimeHookRoutes(apiRouter, {
|
|
3601
3697
|
parseJsonRequest,
|
|
@@ -3679,12 +3775,18 @@ export function createHttpHandler(config, client, getSnapshot, onboarding, diagn
|
|
|
3679
3775
|
const keys = [...scopedKeys, ...fallbackKeys];
|
|
3680
3776
|
const seen = new Set();
|
|
3681
3777
|
const mapped = [];
|
|
3682
|
-
const deriveFailureType = (eventNameRaw, actionTypeRaw) => {
|
|
3778
|
+
const deriveFailureType = (eventNameRaw, actionTypeRaw, reasonRaw, blockingRaw) => {
|
|
3683
3779
|
const eventName = (eventNameRaw ?? "").trim().toLowerCase();
|
|
3684
3780
|
const actionType = (actionTypeRaw ?? "").trim().toLowerCase();
|
|
3685
|
-
const
|
|
3781
|
+
const reason = (reasonRaw ?? "").trim().toLowerCase();
|
|
3782
|
+
const signature = `${eventName} ${actionType} ${reason}`;
|
|
3686
3783
|
if (!signature.trim())
|
|
3687
3784
|
return null;
|
|
3785
|
+
if (signature.includes("question_asked") ||
|
|
3786
|
+
signature.includes("review_item_created") ||
|
|
3787
|
+
signature.includes("decision_requested")) {
|
|
3788
|
+
return blockingRaw === false ? "review_required" : "decision_required";
|
|
3789
|
+
}
|
|
3688
3790
|
if (signature.includes("status_updates_buffered"))
|
|
3689
3791
|
return "status_updates_buffered";
|
|
3690
3792
|
if (signature.includes("question_answer_failed"))
|
|
@@ -3707,6 +3809,18 @@ export function createHttpHandler(config, client, getSnapshot, onboarding, diagn
|
|
|
3707
3809
|
return "budget_exhausted";
|
|
3708
3810
|
if (signature.includes("stale_blocked_workstream"))
|
|
3709
3811
|
return "stale_blocked_workstream";
|
|
3812
|
+
if (signature.includes("credit") ||
|
|
3813
|
+
signature.includes("insufficient_quota") ||
|
|
3814
|
+
signature.includes("insufficient credit") ||
|
|
3815
|
+
signature.includes("payment required")) {
|
|
3816
|
+
return "budget_exhausted";
|
|
3817
|
+
}
|
|
3818
|
+
if (signature.includes("run_failed") ||
|
|
3819
|
+
signature.includes("autopilot_slice_result") ||
|
|
3820
|
+
signature.includes("autopilot_slice_finished") ||
|
|
3821
|
+
signature.includes("failed")) {
|
|
3822
|
+
return "worker_exit_no_output";
|
|
3823
|
+
}
|
|
3710
3824
|
return null;
|
|
3711
3825
|
};
|
|
3712
3826
|
try {
|
|
@@ -3724,7 +3838,22 @@ export function createHttpHandler(config, client, getSnapshot, onboarding, diagn
|
|
|
3724
3838
|
const metadataRecord = activityRecord.metadata && typeof activityRecord.metadata === "object"
|
|
3725
3839
|
? activityRecord.metadata
|
|
3726
3840
|
: {};
|
|
3727
|
-
const
|
|
3841
|
+
const resultRecord = metadataRecord.result && typeof metadataRecord.result === "object"
|
|
3842
|
+
? metadataRecord.result
|
|
3843
|
+
: null;
|
|
3844
|
+
const blockerRecord = metadataRecord.blocker && typeof metadataRecord.blocker === "object"
|
|
3845
|
+
? metadataRecord.blocker
|
|
3846
|
+
: resultRecord && resultRecord.blocker && typeof resultRecord.blocker === "object"
|
|
3847
|
+
? resultRecord.blocker
|
|
3848
|
+
: null;
|
|
3849
|
+
const reasonText = pickString(blockerRecord ?? {}, ["description", "summary"]) ??
|
|
3850
|
+
pickString(resultRecord ?? {}, ["error", "reason", "blocked_reason", "blockedReason", "summary"]) ??
|
|
3851
|
+
pickString(metadataRecord, ["error", "reason", "message", "blocked_reason", "blockedReason"]) ??
|
|
3852
|
+
pickString(activityRecord, ["description", "summary", "title"]);
|
|
3853
|
+
const blockingSignal = pickBoolean(metadataRecord, ["blocking"]) ??
|
|
3854
|
+
pickBoolean(resultRecord, ["blocking"]);
|
|
3855
|
+
const failureType = deriveFailureType(pickString(metadataRecord, ["event", "event_name"]), pickString(metadataRecord, ["action_type", "actionType"]) ??
|
|
3856
|
+
pickString(activityRecord, ["type"]), reasonText, blockingSignal);
|
|
3728
3857
|
if (!failureType)
|
|
3729
3858
|
continue;
|
|
3730
3859
|
const runId = pickString(metadataRecord, ["run_id", "source_run_id"]) ?? pickString(activityRecord, ["runId"]);
|
|
@@ -3743,9 +3872,9 @@ export function createHttpHandler(config, client, getSnapshot, onboarding, diagn
|
|
|
3743
3872
|
mapped.push({
|
|
3744
3873
|
id: dedupeId,
|
|
3745
3874
|
failureType,
|
|
3746
|
-
reason:
|
|
3747
|
-
|
|
3748
|
-
|
|
3875
|
+
reason: reasonText,
|
|
3876
|
+
provider: pickString(metadataRecord, ["provider"]) ??
|
|
3877
|
+
pickString(blockerRecord ?? {}, ["provider"]),
|
|
3749
3878
|
initiativeId,
|
|
3750
3879
|
initiativeTitle: pickString(metadataRecord, ["initiative_title"]) ??
|
|
3751
3880
|
pickString(activityRecord, ["initiativeTitle"]),
|
|
@@ -3759,8 +3888,12 @@ export function createHttpHandler(config, client, getSnapshot, onboarding, diagn
|
|
|
3759
3888
|
domain: pickString(metadataRecord, ["domain", "executor_domain"]),
|
|
3760
3889
|
sourceSystem: pickString(metadataRecord, ["source_system", "source"]) ?? "openclaw",
|
|
3761
3890
|
runId,
|
|
3762
|
-
logPath: pickString(metadataRecord, ["log_path"])
|
|
3763
|
-
|
|
3891
|
+
logPath: pickString(metadataRecord, ["log_path"]) ??
|
|
3892
|
+
pickString(resultRecord ?? {}, ["log_path"]) ??
|
|
3893
|
+
pickString(blockerRecord ?? {}, ["log_path"]),
|
|
3894
|
+
outputPath: pickString(metadataRecord, ["output_path"]) ??
|
|
3895
|
+
pickString(resultRecord ?? {}, ["output_path"]) ??
|
|
3896
|
+
pickString(blockerRecord ?? {}, ["output_path"]),
|
|
3764
3897
|
metadata: metadataRecord,
|
|
3765
3898
|
timestamp: timestamp ?? undefined,
|
|
3766
3899
|
});
|
package/dist/http/router.js
CHANGED
|
@@ -1,20 +1,75 @@
|
|
|
1
|
-
function
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
function normalizePrefixBase(pattern) {
|
|
2
|
+
return pattern.endsWith("/*") ? pattern.slice(0, -1) : null;
|
|
3
|
+
}
|
|
4
|
+
function getOrCreateBucket(map, key) {
|
|
5
|
+
const existing = map.get(key);
|
|
6
|
+
if (existing)
|
|
7
|
+
return existing;
|
|
8
|
+
const created = [];
|
|
9
|
+
map.set(key, created);
|
|
10
|
+
return created;
|
|
11
|
+
}
|
|
12
|
+
function getOrCreateMethodBuckets(map, method) {
|
|
13
|
+
const existing = map.get(method);
|
|
14
|
+
if (existing)
|
|
15
|
+
return existing;
|
|
16
|
+
const created = new Map();
|
|
17
|
+
map.set(method, created);
|
|
18
|
+
return created;
|
|
19
|
+
}
|
|
20
|
+
function collectPathPrefixBases(path) {
|
|
21
|
+
const bases = new Set();
|
|
22
|
+
let slashIndex = path.indexOf("/");
|
|
23
|
+
while (slashIndex !== -1) {
|
|
24
|
+
bases.add(path.slice(0, slashIndex + 1));
|
|
25
|
+
slashIndex = path.indexOf("/", slashIndex + 1);
|
|
4
26
|
}
|
|
5
|
-
|
|
27
|
+
bases.add(`${path}/`);
|
|
28
|
+
return Array.from(bases);
|
|
6
29
|
}
|
|
7
30
|
export function createRouter() {
|
|
8
31
|
const entries = [];
|
|
32
|
+
const exactRoutes = new Map();
|
|
33
|
+
const prefixRoutes = new Map();
|
|
9
34
|
function add(method, pattern, handler, description) {
|
|
10
|
-
|
|
35
|
+
const route = {
|
|
36
|
+
method,
|
|
37
|
+
pattern,
|
|
38
|
+
handler,
|
|
39
|
+
description,
|
|
40
|
+
order: entries.length,
|
|
41
|
+
prefixBase: normalizePrefixBase(pattern),
|
|
42
|
+
};
|
|
43
|
+
entries.push(route);
|
|
44
|
+
if (route.prefixBase) {
|
|
45
|
+
getOrCreateBucket(getOrCreateMethodBuckets(prefixRoutes, method), route.prefixBase).push(route);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
getOrCreateBucket(getOrCreateMethodBuckets(exactRoutes, method), pattern).push(route);
|
|
49
|
+
}
|
|
50
|
+
function pickEarlierRoute(current, candidate) {
|
|
51
|
+
if (!current)
|
|
52
|
+
return candidate;
|
|
53
|
+
return candidate.order < current.order ? candidate : current;
|
|
54
|
+
}
|
|
55
|
+
function matchFromBuckets(routeBuckets, method, key, current) {
|
|
56
|
+
const methodBuckets = routeBuckets.get(method);
|
|
57
|
+
const wildcardBuckets = routeBuckets.get("*");
|
|
58
|
+
for (const candidate of methodBuckets?.get(key) ?? []) {
|
|
59
|
+
current = pickEarlierRoute(current, candidate);
|
|
60
|
+
}
|
|
61
|
+
for (const candidate of wildcardBuckets?.get(key) ?? []) {
|
|
62
|
+
current = pickEarlierRoute(current, candidate);
|
|
63
|
+
}
|
|
64
|
+
return current;
|
|
11
65
|
}
|
|
12
66
|
function match(method, path) {
|
|
13
67
|
const normalizedMethod = method.toUpperCase();
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
68
|
+
let matched = matchFromBuckets(exactRoutes, normalizedMethod, path, undefined);
|
|
69
|
+
for (const base of collectPathPrefixBases(path)) {
|
|
70
|
+
matched = matchFromBuckets(prefixRoutes, normalizedMethod, base, matched);
|
|
71
|
+
}
|
|
72
|
+
return matched;
|
|
18
73
|
}
|
|
19
74
|
function routes() {
|
|
20
75
|
return entries;
|
|
@@ -13,6 +13,8 @@ type LocalLiveActivity = {
|
|
|
13
13
|
};
|
|
14
14
|
type LiveActivityPage = {
|
|
15
15
|
activities: LiveActivityItem[];
|
|
16
|
+
total?: number;
|
|
17
|
+
storeUpdatedAt?: string;
|
|
16
18
|
cursor?: string | null;
|
|
17
19
|
nextCursor?: string | null;
|
|
18
20
|
prevCursor?: string | null;
|
|
@@ -34,7 +36,7 @@ type RouteResLike = {
|
|
|
34
36
|
on?: (event: string, listener: () => void) => void;
|
|
35
37
|
once?: (event: string, listener: () => void) => void;
|
|
36
38
|
};
|
|
37
|
-
type RegisterLiveLegacyRoutesDeps<TRes extends RouteResLike> = {
|
|
39
|
+
type RegisterLiveLegacyRoutesDeps<TReq extends RouteReqLike, TRes extends RouteResLike> = {
|
|
38
40
|
getLiveSessions: (input: {
|
|
39
41
|
initiative: string | null;
|
|
40
42
|
projectId: string | null;
|
|
@@ -82,6 +84,15 @@ type RegisterLiveLegacyRoutesDeps<TRes extends RouteResLike> = {
|
|
|
82
84
|
sessionKey: string | null;
|
|
83
85
|
runId: string | null;
|
|
84
86
|
}) => Promise<Record<string, unknown> | null>;
|
|
87
|
+
summarizeActivityHeadline: (input: {
|
|
88
|
+
text: string;
|
|
89
|
+
title: string | null;
|
|
90
|
+
type: string | null;
|
|
91
|
+
}) => Promise<{
|
|
92
|
+
headline: string;
|
|
93
|
+
source: string;
|
|
94
|
+
model: string | null;
|
|
95
|
+
}>;
|
|
85
96
|
sendJson: (res: TRes, status: number, payload: unknown) => void;
|
|
86
97
|
safeErrorMessage: (err: unknown) => string;
|
|
87
98
|
sendHtml: (res: TRes, status: number, html: string) => void;
|
|
@@ -112,6 +123,12 @@ type RegisterLiveLegacyRoutesDeps<TRes extends RouteResLike> = {
|
|
|
112
123
|
};
|
|
113
124
|
isUserScopedApiKey: (apiKey: string) => boolean;
|
|
114
125
|
streamIdleTimeoutMs: number;
|
|
126
|
+
renderLiveStreamV2?: (input: {
|
|
127
|
+
path: string;
|
|
128
|
+
query: URLSearchParams;
|
|
129
|
+
req: TReq;
|
|
130
|
+
res: TRes;
|
|
131
|
+
}) => Promise<void>;
|
|
115
132
|
};
|
|
116
|
-
export declare function registerLiveLegacyRoutes<TReq extends RouteReqLike, TRes extends RouteResLike>(router: Router<Record<string, never>, TReq, TRes>, deps: RegisterLiveLegacyRoutesDeps<TRes>): void;
|
|
133
|
+
export declare function registerLiveLegacyRoutes<TReq extends RouteReqLike, TRes extends RouteResLike>(router: Router<Record<string, never>, TReq, TRes>, deps: RegisterLiveLegacyRoutesDeps<TReq, TRes>): void;
|
|
117
134
|
export {};
|