@useorgx/openclaw-plugin 0.4.9 → 0.7.0
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 +35 -0
- package/dashboard/dist/assets/BJgZIVUQ.js +53 -0
- package/dashboard/dist/assets/BJgZIVUQ.js.br +0 -0
- package/dashboard/dist/assets/BJgZIVUQ.js.gz +0 -0
- package/dashboard/dist/assets/BXWDRGm-.js +1 -0
- package/dashboard/dist/assets/BXWDRGm-.js.br +0 -0
- package/dashboard/dist/assets/BXWDRGm-.js.gz +0 -0
- package/dashboard/dist/assets/BgOYB78t.js +4 -0
- package/dashboard/dist/assets/BgOYB78t.js.br +0 -0
- package/dashboard/dist/assets/BgOYB78t.js.gz +0 -0
- package/dashboard/dist/assets/C-KIc3Wc.js.br +0 -0
- package/dashboard/dist/assets/C-KIc3Wc.js.gz +0 -0
- package/dashboard/dist/assets/CE38zU4U.js +1 -0
- package/dashboard/dist/assets/CE38zU4U.js.br +0 -0
- package/dashboard/dist/assets/CE38zU4U.js.gz +0 -0
- package/dashboard/dist/assets/CFGKRAzG.js +1 -0
- package/dashboard/dist/assets/CFGKRAzG.js.br +0 -0
- package/dashboard/dist/assets/CFGKRAzG.js.gz +0 -0
- package/dashboard/dist/assets/CGGR2GZh.js +1 -0
- package/dashboard/dist/assets/CGGR2GZh.js.br +0 -0
- package/dashboard/dist/assets/CGGR2GZh.js.gz +0 -0
- package/dashboard/dist/assets/CL_wXqR7.js +1 -0
- package/dashboard/dist/assets/CL_wXqR7.js.br +0 -0
- package/dashboard/dist/assets/CL_wXqR7.js.gz +0 -0
- package/dashboard/dist/assets/CPFiTmlw.js +8 -0
- package/dashboard/dist/assets/CPFiTmlw.js.br +0 -0
- package/dashboard/dist/assets/CPFiTmlw.js.gz +0 -0
- package/dashboard/dist/assets/CZZTvkQZ.js +1 -0
- package/dashboard/dist/assets/CZZTvkQZ.js.br +0 -0
- package/dashboard/dist/assets/CZZTvkQZ.js.gz +0 -0
- package/dashboard/dist/assets/{CpJsfbXo.js → CxQ08qFN.js} +2 -2
- package/dashboard/dist/assets/CxQ08qFN.js.br +0 -0
- package/dashboard/dist/assets/CxQ08qFN.js.gz +0 -0
- package/dashboard/dist/assets/D-bf6hEI.js +213 -0
- package/dashboard/dist/assets/D-bf6hEI.js.br +0 -0
- package/dashboard/dist/assets/D-bf6hEI.js.gz +0 -0
- package/dashboard/dist/assets/DG6y9wJI.js +2 -0
- package/dashboard/dist/assets/DG6y9wJI.js.br +0 -0
- package/dashboard/dist/assets/DG6y9wJI.js.gz +0 -0
- package/dashboard/dist/assets/DNxKz-GV.js +1 -0
- package/dashboard/dist/assets/DNxKz-GV.js.br +0 -0
- package/dashboard/dist/assets/DNxKz-GV.js.gz +0 -0
- package/dashboard/dist/assets/DW_rKUic.js +11 -0
- package/dashboard/dist/assets/DW_rKUic.js.br +0 -0
- package/dashboard/dist/assets/DW_rKUic.js.gz +0 -0
- package/dashboard/dist/assets/DbNoijHm.js +1 -0
- package/dashboard/dist/assets/DbNoijHm.js.br +0 -0
- package/dashboard/dist/assets/DbNoijHm.js.gz +0 -0
- package/dashboard/dist/assets/DjcdE6jC.js +2 -0
- package/dashboard/dist/assets/DjcdE6jC.js.br +0 -0
- package/dashboard/dist/assets/DjcdE6jC.js.gz +0 -0
- package/dashboard/dist/assets/FZYuCDnt.js +1 -0
- package/dashboard/dist/assets/FZYuCDnt.js.br +0 -0
- package/dashboard/dist/assets/FZYuCDnt.js.gz +0 -0
- package/dashboard/dist/assets/PAUiij_z.js +1 -0
- package/dashboard/dist/assets/PAUiij_z.js.br +0 -0
- package/dashboard/dist/assets/PAUiij_z.js.gz +0 -0
- package/dashboard/dist/assets/cNrhgGc1.js +8 -0
- package/dashboard/dist/assets/cNrhgGc1.js.br +0 -0
- package/dashboard/dist/assets/cNrhgGc1.js.gz +0 -0
- package/dashboard/dist/assets/h5biQs2I.css +1 -0
- package/dashboard/dist/assets/h5biQs2I.css.br +0 -0
- package/dashboard/dist/assets/h5biQs2I.css.gz +0 -0
- package/dashboard/dist/assets/ic2FaMnh.js +1 -0
- package/dashboard/dist/assets/ic2FaMnh.js.br +0 -0
- package/dashboard/dist/assets/ic2FaMnh.js.gz +0 -0
- package/dashboard/dist/assets/nByHNHoW.js +1 -0
- package/dashboard/dist/assets/nByHNHoW.js.br +0 -0
- package/dashboard/dist/assets/nByHNHoW.js.gz +0 -0
- package/dashboard/dist/assets/qm8xLgv-.css +1 -0
- package/dashboard/dist/assets/qm8xLgv-.css.br +0 -0
- package/dashboard/dist/assets/qm8xLgv-.css.gz +0 -0
- package/dashboard/dist/assets/tS9mbYZi.js +1 -0
- package/dashboard/dist/assets/tS9mbYZi.js.br +0 -0
- package/dashboard/dist/assets/tS9mbYZi.js.gz +0 -0
- package/dashboard/dist/brand/anthropic-mark.svg.br +0 -0
- package/dashboard/dist/brand/anthropic-mark.svg.gz +0 -0
- package/dashboard/dist/brand/openai-mark.svg.br +0 -0
- package/dashboard/dist/brand/openai-mark.svg.gz +0 -0
- package/dashboard/dist/brand/openclaw-mark.svg.br +0 -0
- package/dashboard/dist/brand/openclaw-mark.svg.gz +0 -0
- package/dashboard/dist/brand/xandy-orchestrator.png +0 -0
- package/dashboard/dist/index.html +7 -5
- package/dashboard/dist/index.html.br +0 -0
- package/dashboard/dist/index.html.gz +0 -0
- package/dist/activity-actor-fields.js +26 -4
- package/dist/activity-store.js +34 -8
- package/dist/agent-context-store.js +79 -17
- package/dist/agent-run-store.js +44 -3
- package/dist/agent-suite.d.ts +9 -0
- package/dist/agent-suite.js +149 -9
- package/dist/artifacts/artifact-domain-schemas.d.ts +66 -0
- package/dist/artifacts/artifact-domain-schemas.js +357 -0
- package/dist/artifacts/register-artifact.d.ts +4 -3
- package/dist/artifacts/register-artifact.js +170 -57
- package/dist/chat-store.d.ts +157 -0
- package/dist/chat-store.js +586 -0
- package/dist/cli/orgx.js +11 -0
- package/dist/contracts/client.d.ts +43 -3
- package/dist/contracts/client.js +159 -30
- package/dist/contracts/retro-schema.d.ts +81 -0
- package/dist/contracts/retro-schema.js +80 -0
- package/dist/contracts/shared-types.d.ts +159 -0
- package/dist/contracts/shared-types.js +177 -1
- package/dist/contracts/skill-pack-schema.d.ts +192 -0
- package/dist/contracts/skill-pack-schema.js +180 -0
- package/dist/contracts/types.d.ts +227 -2
- package/dist/entities/auto-assignment.js +43 -17
- package/dist/event-sanitization.d.ts +11 -0
- package/dist/event-sanitization.js +113 -0
- package/dist/fs-utils.js +13 -1
- package/dist/gateway-watchdog.d.ts +5 -0
- package/dist/gateway-watchdog.js +50 -0
- package/dist/hooks/post-reporting-event.mjs +1 -5
- package/dist/http/helpers/activity-headline.js +13 -132
- package/dist/http/helpers/auto-continue-engine.d.ts +198 -10
- package/dist/http/helpers/auto-continue-engine.js +2531 -186
- package/dist/http/helpers/autopilot-operations.d.ts +19 -0
- package/dist/http/helpers/autopilot-operations.js +182 -31
- package/dist/http/helpers/autopilot-runtime.d.ts +1 -0
- package/dist/http/helpers/autopilot-runtime.js +308 -20
- package/dist/http/helpers/autopilot-slice-utils.d.ts +18 -0
- package/dist/http/helpers/autopilot-slice-utils.js +516 -93
- package/dist/http/helpers/decision-mapper.d.ts +40 -0
- package/dist/http/helpers/decision-mapper.js +223 -7
- package/dist/http/helpers/dispatch-lifecycle.d.ts +19 -2
- package/dist/http/helpers/dispatch-lifecycle.js +242 -37
- package/dist/http/helpers/kickoff-context.js +74 -0
- package/dist/http/helpers/llm-client.d.ts +47 -0
- package/dist/http/helpers/llm-client.js +256 -0
- package/dist/http/helpers/mission-control.d.ts +102 -3
- package/dist/http/helpers/mission-control.js +498 -9
- package/dist/http/helpers/sentinel-catalog.d.ts +23 -0
- package/dist/http/helpers/sentinel-catalog.js +193 -0
- package/dist/http/helpers/session-classification.d.ts +9 -0
- package/dist/http/helpers/session-classification.js +564 -0
- package/dist/http/helpers/slice-experience-v2.d.ts +137 -0
- package/dist/http/helpers/slice-experience-v2.js +677 -0
- package/dist/http/helpers/slice-run-projections.d.ts +72 -0
- package/dist/http/helpers/slice-run-projections.js +860 -0
- package/dist/http/helpers/triage-mapper.d.ts +43 -0
- package/dist/http/helpers/triage-mapper.js +549 -0
- package/dist/http/helpers/value-utils.js +7 -2
- package/dist/http/helpers/workspace-scope.d.ts +15 -0
- package/dist/http/helpers/workspace-scope.js +170 -0
- package/dist/http/index.js +1354 -97
- package/dist/http/routes/agent-suite.d.ts +9 -0
- package/dist/http/routes/agent-suite.js +207 -8
- package/dist/http/routes/agents-catalog.js +64 -19
- package/dist/http/routes/chat.d.ts +19 -0
- package/dist/http/routes/chat.js +522 -0
- package/dist/http/routes/decision-actions.d.ts +8 -1
- package/dist/http/routes/decision-actions.js +42 -5
- package/dist/http/routes/dispatch-gateway-envelope.d.ts +25 -0
- package/dist/http/routes/dispatch-gateway-envelope.js +26 -0
- package/dist/http/routes/entities.d.ts +16 -0
- package/dist/http/routes/entities.js +294 -6
- package/dist/http/routes/live-legacy.d.ts +5 -0
- package/dist/http/routes/live-legacy.js +23 -509
- package/dist/http/routes/live-misc.d.ts +12 -0
- package/dist/http/routes/live-misc.js +251 -31
- package/dist/http/routes/live-snapshot.d.ts +48 -2
- package/dist/http/routes/live-snapshot.js +638 -19
- package/dist/http/routes/live-terminal.d.ts +11 -0
- package/dist/http/routes/live-terminal.js +261 -0
- package/dist/http/routes/live-triage.d.ts +61 -0
- package/dist/http/routes/live-triage.js +248 -0
- package/dist/http/routes/mission-control-actions.d.ts +49 -1
- package/dist/http/routes/mission-control-actions.js +1334 -84
- package/dist/http/routes/mission-control-read.d.ts +48 -3
- package/dist/http/routes/mission-control-read.js +1593 -20
- package/dist/http/routes/realtime-orchestrator.d.ts +10 -0
- package/dist/http/routes/realtime-orchestrator.js +74 -0
- package/dist/http/routes/run-control.d.ts +5 -2
- package/dist/http/routes/run-control.js +10 -0
- package/dist/http/routes/sentinels-catalog.d.ts +7 -0
- package/dist/http/routes/sentinels-catalog.js +24 -0
- package/dist/http/routes/summary.js +10 -3
- package/dist/http/routes/usage.d.ts +24 -0
- package/dist/http/routes/usage.js +362 -0
- package/dist/http/routes/work-artifacts.js +28 -9
- package/dist/index.js +165 -27
- package/dist/local-openclaw.js +29 -6
- package/dist/mcp-client-setup.js +3 -3
- package/dist/mcp-http-handler.js +33 -59
- package/dist/next-up-queue-store.d.ts +16 -1
- package/dist/next-up-queue-store.js +89 -7
- package/dist/outbox.d.ts +5 -0
- package/dist/outbox.js +113 -9
- package/dist/paths.js +24 -5
- package/dist/reporting/rollups.d.ts +53 -0
- package/dist/reporting/rollups.js +148 -0
- package/dist/retro/domain-templates.d.ts +45 -0
- package/dist/retro/domain-templates.js +297 -0
- package/dist/retro/quality-rubric.d.ts +33 -0
- package/dist/retro/quality-rubric.js +213 -0
- package/dist/runtime-cleanup.d.ts +18 -0
- package/dist/runtime-cleanup.js +87 -0
- package/dist/services/background.d.ts +11 -0
- package/dist/services/background.js +22 -0
- package/dist/services/experiment-randomization.d.ts +21 -0
- package/dist/services/experiment-randomization.js +63 -0
- package/dist/skill-pack-state.d.ts +36 -5
- package/dist/skill-pack-state.js +273 -29
- package/dist/sync/local-agent-telemetry.d.ts +13 -0
- package/dist/sync/local-agent-telemetry.js +128 -0
- package/dist/sync/outbox-replay.js +131 -24
- package/dist/team-context-store.d.ts +23 -0
- package/dist/team-context-store.js +116 -0
- package/dist/telemetry/posthog.js +4 -2
- package/dist/tools/core-tools.d.ts +10 -14
- package/dist/tools/core-tools.js +1289 -24
- package/dist/types.d.ts +2 -0
- package/dist/types.js +2 -0
- package/dist/worker-supervisor.js +23 -0
- package/package.json +14 -4
- package/dashboard/dist/assets/B3ziCA02.js +0 -8
- package/dashboard/dist/assets/B5NEElEI.css +0 -1
- package/dashboard/dist/assets/BhapSNAs.js +0 -215
- package/dashboard/dist/assets/iFdvE7lx.js +0 -1
- package/dashboard/dist/assets/jRJsmpYM.js +0 -1
- package/dashboard/dist/assets/sAhvFnpk.js +0 -4
|
@@ -1,4 +1,37 @@
|
|
|
1
|
+
import { resolveWorkspaceScope, workspaceScopeFromHeaders, } from "../helpers/workspace-scope.js";
|
|
2
|
+
function asRecord(input) {
|
|
3
|
+
if (!input || typeof input !== "object" || Array.isArray(input))
|
|
4
|
+
return null;
|
|
5
|
+
return input;
|
|
6
|
+
}
|
|
7
|
+
function pickStringFromRecord(input, keys) {
|
|
8
|
+
if (!input)
|
|
9
|
+
return null;
|
|
10
|
+
for (const key of keys) {
|
|
11
|
+
const value = input[key];
|
|
12
|
+
if (typeof value !== "string")
|
|
13
|
+
continue;
|
|
14
|
+
const normalized = value.trim();
|
|
15
|
+
if (normalized.length > 0)
|
|
16
|
+
return normalized;
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
function resolveInitiativeIdFromRecord(input) {
|
|
21
|
+
const direct = pickStringFromRecord(input, ["initiativeId", "initiative_id", "initiative"]);
|
|
22
|
+
if (direct)
|
|
23
|
+
return direct;
|
|
24
|
+
const metadata = asRecord(input.metadata);
|
|
25
|
+
return pickStringFromRecord(metadata, ["initiativeId", "initiative_id", "initiative"]);
|
|
26
|
+
}
|
|
1
27
|
export function registerLiveMiscRoutes(router, deps) {
|
|
28
|
+
async function resolveProjectInitiativeSet(projectIdRaw) {
|
|
29
|
+
const projectId = projectIdRaw?.trim() ?? "";
|
|
30
|
+
if (!projectId)
|
|
31
|
+
return null;
|
|
32
|
+
const ids = await deps.listInitiativeIdsForProject({ projectId });
|
|
33
|
+
return new Set(ids);
|
|
34
|
+
}
|
|
2
35
|
router.add("POST", "live/activity/headline", async ({ req, res }) => {
|
|
3
36
|
try {
|
|
4
37
|
const payload = await deps.parseJsonRequest(req);
|
|
@@ -29,20 +62,59 @@ export function registerLiveMiscRoutes(router, deps) {
|
|
|
29
62
|
router.add("*", "live/activity/headline", ({ res }) => {
|
|
30
63
|
deps.sendJson(res, 405, { error: "Use POST /orgx/api/live/activity/headline" });
|
|
31
64
|
}, "Reject unsupported methods for live/activity/headline");
|
|
32
|
-
async function renderLiveAgents(query, res) {
|
|
65
|
+
async function renderLiveAgents(query, res, headerScope) {
|
|
66
|
+
const scope = resolveWorkspaceScope(query, headerScope, {
|
|
67
|
+
allowProjectScope: false,
|
|
68
|
+
});
|
|
69
|
+
if (scope.error) {
|
|
70
|
+
deps.sendJson(res, 400, { error: scope.error });
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const workspaceId = scope.workspaceId;
|
|
33
74
|
try {
|
|
34
75
|
const initiative = query.get("initiative");
|
|
76
|
+
const projectInitiatives = await resolveProjectInitiativeSet(workspaceId);
|
|
35
77
|
const includeIdleRaw = query.get("include_idle");
|
|
36
78
|
const includeIdle = includeIdleRaw === null ? undefined : includeIdleRaw !== "false";
|
|
37
|
-
const data = await deps.getLiveAgents({
|
|
79
|
+
const data = (await deps.getLiveAgents({
|
|
38
80
|
initiative,
|
|
81
|
+
projectId: workspaceId,
|
|
39
82
|
includeIdle,
|
|
83
|
+
}));
|
|
84
|
+
const agents = Array.isArray(data.agents) ? data.agents : [];
|
|
85
|
+
const scopedAgents = agents.filter((entry) => {
|
|
86
|
+
const row = asRecord(entry);
|
|
87
|
+
if (!row)
|
|
88
|
+
return false;
|
|
89
|
+
const initiativeId = resolveInitiativeIdFromRecord(row);
|
|
90
|
+
if (initiative && initiative.trim().length > 0 && initiativeId !== initiative)
|
|
91
|
+
return false;
|
|
92
|
+
if (projectInitiatives && (!initiativeId || !projectInitiatives.has(initiativeId))) {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
if (includeIdle === false) {
|
|
96
|
+
const status = pickStringFromRecord(row, ["status"]);
|
|
97
|
+
if (status === "idle")
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
return true;
|
|
101
|
+
});
|
|
102
|
+
const summary = scopedAgents.reduce((acc, entry) => {
|
|
103
|
+
const row = asRecord(entry);
|
|
104
|
+
const status = pickStringFromRecord(row, ["status"]) ?? "unknown";
|
|
105
|
+
acc[status] = (acc[status] ?? 0) + 1;
|
|
106
|
+
return acc;
|
|
107
|
+
}, {});
|
|
108
|
+
deps.sendJson(res, 200, {
|
|
109
|
+
...data,
|
|
110
|
+
agents: scopedAgents,
|
|
111
|
+
summary,
|
|
40
112
|
});
|
|
41
|
-
deps.sendJson(res, 200, data);
|
|
42
113
|
}
|
|
43
114
|
catch (err) {
|
|
44
115
|
try {
|
|
45
116
|
const initiative = query.get("initiative");
|
|
117
|
+
const projectInitiatives = await resolveProjectInitiativeSet(workspaceId);
|
|
46
118
|
const includeIdleRaw = query.get("include_idle");
|
|
47
119
|
const includeIdle = includeIdleRaw === null ? undefined : includeIdleRaw !== "false";
|
|
48
120
|
const localSnapshot = await deps.loadLocalOpenClawSnapshot(240);
|
|
@@ -51,6 +123,12 @@ export function registerLiveMiscRoutes(router, deps) {
|
|
|
51
123
|
if (initiative && initiative.trim().length > 0) {
|
|
52
124
|
agents = agents.filter((agent) => agent.initiativeId === initiative);
|
|
53
125
|
}
|
|
126
|
+
if (projectInitiatives) {
|
|
127
|
+
agents = agents.filter((agent) => {
|
|
128
|
+
const initiativeId = typeof agent.initiativeId === "string" ? agent.initiativeId : "";
|
|
129
|
+
return initiativeId.length > 0 && projectInitiatives.has(initiativeId);
|
|
130
|
+
});
|
|
131
|
+
}
|
|
54
132
|
if (includeIdle === false) {
|
|
55
133
|
agents = agents.filter((agent) => agent.status !== "idle");
|
|
56
134
|
}
|
|
@@ -68,50 +146,161 @@ export function registerLiveMiscRoutes(router, deps) {
|
|
|
68
146
|
}
|
|
69
147
|
}
|
|
70
148
|
}
|
|
71
|
-
router.add("GET", "live/agents", async ({ query, res }) => renderLiveAgents(query, res), "Get live agents");
|
|
72
|
-
router.add("HEAD", "live/agents", async ({ query, res }) => renderLiveAgents(query, res), "Get live agents (HEAD)");
|
|
73
|
-
async function renderLiveInitiatives(query, res) {
|
|
149
|
+
router.add("GET", "live/agents", async ({ query, res, req }) => renderLiveAgents(query, res, workspaceScopeFromHeaders(req?.headers)), "Get live agents");
|
|
150
|
+
router.add("HEAD", "live/agents", async ({ query, res, req }) => renderLiveAgents(query, res, workspaceScopeFromHeaders(req?.headers)), "Get live agents (HEAD)");
|
|
151
|
+
async function renderLiveInitiatives(query, res, headerScope) {
|
|
152
|
+
const scope = resolveWorkspaceScope(query, headerScope, {
|
|
153
|
+
allowProjectScope: false,
|
|
154
|
+
});
|
|
155
|
+
if (scope.error) {
|
|
156
|
+
deps.sendJson(res, 400, { error: scope.error });
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const workspaceId = scope.workspaceId;
|
|
74
160
|
try {
|
|
75
161
|
const id = query.get("id");
|
|
76
|
-
const
|
|
162
|
+
const projectInitiatives = await resolveProjectInitiativeSet(workspaceId);
|
|
163
|
+
const limitRaw = query.get("limit") ? Number(query.get("limit")) : undefined;
|
|
164
|
+
const offsetRaw = query.get("offset") ? Number(query.get("offset")) : undefined;
|
|
165
|
+
const requestedLimit = Number.isFinite(limitRaw)
|
|
166
|
+
? Math.max(1, Math.floor(Number(limitRaw)))
|
|
167
|
+
: null;
|
|
168
|
+
const requestedOffset = Number.isFinite(offsetRaw)
|
|
169
|
+
? Math.max(0, Math.floor(Number(offsetRaw)))
|
|
170
|
+
: 0;
|
|
77
171
|
const data = await deps.getLiveInitiatives({
|
|
78
172
|
id,
|
|
79
|
-
|
|
173
|
+
projectId: workspaceId,
|
|
174
|
+
limit: requestedLimit ?? undefined,
|
|
175
|
+
offset: requestedOffset,
|
|
80
176
|
});
|
|
81
177
|
const payload = data;
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
178
|
+
const rawInitiatives = Array.isArray(payload.initiatives) ? payload.initiatives : [];
|
|
179
|
+
const applyLocalOverrides = (rows) => rows.map((entry) => {
|
|
180
|
+
if (!entry || typeof entry !== "object")
|
|
181
|
+
return entry;
|
|
182
|
+
const row = entry;
|
|
183
|
+
const initiativeId = deps.pickString(row, ["id"]);
|
|
184
|
+
if (!initiativeId)
|
|
185
|
+
return entry;
|
|
186
|
+
const override = deps.localInitiativeStatusOverrides.get(initiativeId) ?? null;
|
|
187
|
+
if (!override)
|
|
188
|
+
return entry;
|
|
189
|
+
return {
|
|
190
|
+
...row,
|
|
191
|
+
status: override.status,
|
|
192
|
+
updatedAt: deps.pickString(row, ["updatedAt", "updated_at"]) ?? override.updatedAt,
|
|
193
|
+
};
|
|
194
|
+
});
|
|
195
|
+
let initiatives = Array.isArray(payload.initiatives)
|
|
196
|
+
? payload.initiatives
|
|
197
|
+
.filter((entry) => {
|
|
198
|
+
const row = asRecord(entry);
|
|
199
|
+
if (!row)
|
|
200
|
+
return false;
|
|
87
201
|
const initiativeId = deps.pickString(row, ["id"]);
|
|
88
202
|
if (!initiativeId)
|
|
89
|
-
return
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
status: override.status,
|
|
96
|
-
updatedAt: deps.pickString(row, ["updatedAt", "updated_at"]) ?? override.updatedAt,
|
|
97
|
-
};
|
|
203
|
+
return false;
|
|
204
|
+
if (id && id.trim().length > 0 && initiativeId !== id)
|
|
205
|
+
return false;
|
|
206
|
+
if (projectInitiatives && !projectInitiatives.has(initiativeId))
|
|
207
|
+
return false;
|
|
208
|
+
return true;
|
|
98
209
|
})
|
|
210
|
+
.map((entry) => entry)
|
|
99
211
|
: payload.initiatives;
|
|
212
|
+
initiatives = Array.isArray(initiatives) ? applyLocalOverrides(initiatives) : initiatives;
|
|
213
|
+
let fallbackHydratedFromScope = false;
|
|
214
|
+
if (Array.isArray(initiatives) &&
|
|
215
|
+
initiatives.length === 0 &&
|
|
216
|
+
!id &&
|
|
217
|
+
projectInitiatives &&
|
|
218
|
+
projectInitiatives.size > 0) {
|
|
219
|
+
const scopedIds = Array.from(projectInitiatives.values()).slice(requestedOffset, requestedOffset + (requestedLimit ?? 50));
|
|
220
|
+
const hydrated = [];
|
|
221
|
+
for (const initiativeId of scopedIds) {
|
|
222
|
+
try {
|
|
223
|
+
const single = await deps.getLiveInitiatives({
|
|
224
|
+
id: initiativeId,
|
|
225
|
+
projectId: null,
|
|
226
|
+
limit: 1,
|
|
227
|
+
offset: 0,
|
|
228
|
+
});
|
|
229
|
+
const singleRows = Array.isArray(single?.initiatives)
|
|
230
|
+
? single.initiatives
|
|
231
|
+
: [];
|
|
232
|
+
const match = singleRows.find((entry) => {
|
|
233
|
+
const row = asRecord(entry);
|
|
234
|
+
const rowId = deps.pickString(row ?? {}, ["id"]);
|
|
235
|
+
return rowId === initiativeId;
|
|
236
|
+
});
|
|
237
|
+
if (match)
|
|
238
|
+
hydrated.push(match);
|
|
239
|
+
}
|
|
240
|
+
catch {
|
|
241
|
+
// Ignore per-initiative hydration failures and continue with remaining IDs.
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (hydrated.length > 0) {
|
|
245
|
+
initiatives = applyLocalOverrides(hydrated);
|
|
246
|
+
fallbackHydratedFromScope = true;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
const remotePagination = asRecord(payload.pagination);
|
|
250
|
+
const remoteHasMoreComputed = typeof remotePagination?.has_more === "boolean"
|
|
251
|
+
? remotePagination.has_more
|
|
252
|
+
: typeof payload.total === "number"
|
|
253
|
+
? requestedOffset + rawInitiatives.length < payload.total
|
|
254
|
+
: requestedLimit !== null
|
|
255
|
+
? rawInitiatives.length >= requestedLimit
|
|
256
|
+
: false;
|
|
257
|
+
const scopedTotal = fallbackHydratedFromScope && projectInitiatives
|
|
258
|
+
? projectInitiatives.size
|
|
259
|
+
: Array.isArray(initiatives)
|
|
260
|
+
? initiatives.length
|
|
261
|
+
: 0;
|
|
262
|
+
const scopedHasMore = fallbackHydratedFromScope && projectInitiatives
|
|
263
|
+
? requestedOffset + (Array.isArray(initiatives) ? initiatives.length : 0) <
|
|
264
|
+
projectInitiatives.size
|
|
265
|
+
: remoteHasMoreComputed;
|
|
100
266
|
deps.sendJson(res, 200, {
|
|
101
267
|
...payload,
|
|
102
268
|
initiatives,
|
|
269
|
+
total: scopedTotal,
|
|
270
|
+
pagination: {
|
|
271
|
+
...(remotePagination ?? {}),
|
|
272
|
+
limit: typeof remotePagination?.limit === "number"
|
|
273
|
+
? remotePagination.limit
|
|
274
|
+
: (requestedLimit ?? rawInitiatives.length),
|
|
275
|
+
offset: typeof remotePagination?.offset === "number"
|
|
276
|
+
? remotePagination.offset
|
|
277
|
+
: requestedOffset,
|
|
278
|
+
has_more: scopedHasMore,
|
|
279
|
+
},
|
|
280
|
+
...(fallbackHydratedFromScope
|
|
281
|
+
? {
|
|
282
|
+
scopedFallback: true,
|
|
283
|
+
scopedFallbackReason: "upstream live initiatives page did not contain requested workspace rows",
|
|
284
|
+
}
|
|
285
|
+
: {}),
|
|
103
286
|
});
|
|
104
287
|
}
|
|
105
288
|
catch (err) {
|
|
106
289
|
try {
|
|
107
290
|
const id = query.get("id");
|
|
291
|
+
const projectInitiatives = await resolveProjectInitiativeSet(workspaceId);
|
|
108
292
|
const limitRaw = query.get("limit") ? Number(query.get("limit")) : undefined;
|
|
293
|
+
const offsetRaw = query.get("offset") ? Number(query.get("offset")) : undefined;
|
|
109
294
|
const limit = Number.isFinite(limitRaw) ? Math.max(1, Number(limitRaw)) : 100;
|
|
295
|
+
const offset = Number.isFinite(offsetRaw) ? Math.max(0, Number(offsetRaw)) : 0;
|
|
110
296
|
const local = deps.toLocalLiveInitiatives(await deps.loadLocalOpenClawSnapshot(240));
|
|
111
297
|
let initiatives = local.initiatives;
|
|
112
298
|
if (id && id.trim().length > 0) {
|
|
113
299
|
initiatives = initiatives.filter((item) => item.id === id);
|
|
114
300
|
}
|
|
301
|
+
if (projectInitiatives) {
|
|
302
|
+
initiatives = initiatives.filter((item) => projectInitiatives.has(item.id));
|
|
303
|
+
}
|
|
115
304
|
initiatives = initiatives.map((item) => {
|
|
116
305
|
const override = deps.localInitiativeStatusOverrides.get(item.id) ?? null;
|
|
117
306
|
if (!override)
|
|
@@ -125,7 +314,10 @@ export function registerLiveMiscRoutes(router, deps) {
|
|
|
125
314
|
const requestedId = id?.trim() ?? "";
|
|
126
315
|
if (requestedId.length > 0) {
|
|
127
316
|
const override = deps.localInitiativeStatusOverrides.get(requestedId) ?? null;
|
|
128
|
-
|
|
317
|
+
const allowedByProject = !projectInitiatives || projectInitiatives.has(requestedId);
|
|
318
|
+
if (override &&
|
|
319
|
+
allowedByProject &&
|
|
320
|
+
!initiatives.some((item) => item.id === requestedId)) {
|
|
129
321
|
initiatives.push({
|
|
130
322
|
id: requestedId,
|
|
131
323
|
title: `Initiative ${requestedId.slice(0, 8)}`,
|
|
@@ -138,6 +330,8 @@ export function registerLiveMiscRoutes(router, deps) {
|
|
|
138
330
|
}
|
|
139
331
|
else {
|
|
140
332
|
for (const [initiativeId, override] of deps.localInitiativeStatusOverrides.entries()) {
|
|
333
|
+
if (projectInitiatives && !projectInitiatives.has(initiativeId))
|
|
334
|
+
continue;
|
|
141
335
|
if (initiatives.some((item) => item.id === initiativeId))
|
|
142
336
|
continue;
|
|
143
337
|
initiatives.push({
|
|
@@ -150,9 +344,16 @@ export function registerLiveMiscRoutes(router, deps) {
|
|
|
150
344
|
});
|
|
151
345
|
}
|
|
152
346
|
}
|
|
347
|
+
const total = initiatives.length;
|
|
348
|
+
const page = initiatives.slice(offset, offset + limit);
|
|
153
349
|
deps.sendJson(res, 200, {
|
|
154
|
-
initiatives:
|
|
155
|
-
total
|
|
350
|
+
initiatives: page,
|
|
351
|
+
total,
|
|
352
|
+
pagination: {
|
|
353
|
+
limit,
|
|
354
|
+
offset,
|
|
355
|
+
has_more: offset + page.length < total,
|
|
356
|
+
},
|
|
156
357
|
localFallback: true,
|
|
157
358
|
warning: deps.safeErrorMessage(err),
|
|
158
359
|
});
|
|
@@ -165,22 +366,41 @@ export function registerLiveMiscRoutes(router, deps) {
|
|
|
165
366
|
}
|
|
166
367
|
}
|
|
167
368
|
}
|
|
168
|
-
router.add("GET", "live/initiatives", async ({ query, res }) => renderLiveInitiatives(query, res), "Get live initiatives");
|
|
169
|
-
router.add("HEAD", "live/initiatives", async ({ query, res }) => renderLiveInitiatives(query, res), "Get live initiatives (HEAD)");
|
|
170
|
-
async function renderLiveDecisions(query, res) {
|
|
369
|
+
router.add("GET", "live/initiatives", async ({ query, res, req }) => renderLiveInitiatives(query, res, workspaceScopeFromHeaders(req?.headers)), "Get live initiatives");
|
|
370
|
+
router.add("HEAD", "live/initiatives", async ({ query, res, req }) => renderLiveInitiatives(query, res, workspaceScopeFromHeaders(req?.headers)), "Get live initiatives (HEAD)");
|
|
371
|
+
async function renderLiveDecisions(query, res, headerScope) {
|
|
372
|
+
const scope = resolveWorkspaceScope(query, headerScope, {
|
|
373
|
+
allowProjectScope: false,
|
|
374
|
+
});
|
|
375
|
+
if (scope.error) {
|
|
376
|
+
deps.sendJson(res, 400, { error: scope.error });
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
const workspaceId = scope.workspaceId;
|
|
171
380
|
try {
|
|
172
381
|
const status = query.get("status") ?? "pending";
|
|
382
|
+
const projectInitiatives = await resolveProjectInitiativeSet(workspaceId);
|
|
173
383
|
const limit = query.get("limit") ? Number(query.get("limit")) : 100;
|
|
174
384
|
const data = await deps.getLiveDecisions({
|
|
175
385
|
status,
|
|
386
|
+
projectId: workspaceId,
|
|
176
387
|
limit: Number.isFinite(limit) ? limit : 100,
|
|
177
388
|
});
|
|
178
389
|
const decisions = data.decisions
|
|
179
390
|
.map(deps.mapDecisionEntity)
|
|
391
|
+
.filter((entry) => {
|
|
392
|
+
if (!projectInitiatives)
|
|
393
|
+
return true;
|
|
394
|
+
const row = asRecord(entry);
|
|
395
|
+
if (!row)
|
|
396
|
+
return false;
|
|
397
|
+
const initiativeId = resolveInitiativeIdFromRecord(row);
|
|
398
|
+
return Boolean(initiativeId && projectInitiatives.has(initiativeId));
|
|
399
|
+
})
|
|
180
400
|
.sort((a, b) => b.waitingMinutes - a.waitingMinutes);
|
|
181
401
|
deps.sendJson(res, 200, {
|
|
182
402
|
decisions,
|
|
183
|
-
total:
|
|
403
|
+
total: decisions.length,
|
|
184
404
|
});
|
|
185
405
|
}
|
|
186
406
|
catch {
|
|
@@ -190,8 +410,8 @@ export function registerLiveMiscRoutes(router, deps) {
|
|
|
190
410
|
});
|
|
191
411
|
}
|
|
192
412
|
}
|
|
193
|
-
router.add("GET", "live/decisions", async ({ query, res }) => renderLiveDecisions(query, res), "Get live decisions");
|
|
194
|
-
router.add("HEAD", "live/decisions", async ({ query, res }) => renderLiveDecisions(query, res), "Get live decisions (HEAD)");
|
|
413
|
+
router.add("GET", "live/decisions", async ({ query, res, req }) => renderLiveDecisions(query, res, workspaceScopeFromHeaders(req?.headers)), "Get live decisions");
|
|
414
|
+
router.add("HEAD", "live/decisions", async ({ query, res, req }) => renderLiveDecisions(query, res, workspaceScopeFromHeaders(req?.headers)), "Get live decisions (HEAD)");
|
|
195
415
|
async function renderHandoffs(res) {
|
|
196
416
|
try {
|
|
197
417
|
const data = await deps.getHandoffs();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { HandoffSummary, LiveActivityItem, SessionTreeResponse } from "../../types.js";
|
|
2
2
|
import type { RuntimeInstanceRecord } from "../../runtime-instance-store.js";
|
|
3
3
|
import type { OutboxSummary } from "../../outbox.js";
|
|
4
|
+
import type { ChatThreadSummary } from "../../chat-store.js";
|
|
4
5
|
import type { AgentLaunchContext, RunLaunchContext } from "../../agent-context-store.js";
|
|
5
6
|
import type { Router } from "../router.js";
|
|
6
7
|
type LocalSnapshot = Awaited<ReturnType<typeof import("../../local-openclaw.js").loadLocalOpenClawSnapshot>>;
|
|
@@ -12,7 +13,7 @@ type SnapshotPersistState = {
|
|
|
12
13
|
lastFingerprint: string;
|
|
13
14
|
lastPersistAt: number;
|
|
14
15
|
};
|
|
15
|
-
type LiveSnapshotRoutesDeps<TRes> = {
|
|
16
|
+
type LiveSnapshotRoutesDeps<TReq, TRes> = {
|
|
16
17
|
parsePositiveInt: (raw: string | null, fallback: number) => number;
|
|
17
18
|
readSnapshotResponseCache: (key: string) => Record<string, unknown> | null;
|
|
18
19
|
writeSnapshotResponseCache: (key: string, payload: Record<string, unknown>) => void;
|
|
@@ -36,11 +37,13 @@ type LiveSnapshotRoutesDeps<TRes> = {
|
|
|
36
37
|
};
|
|
37
38
|
getLiveSessions: (input: {
|
|
38
39
|
initiative: string | null;
|
|
40
|
+
projectId: string | null;
|
|
39
41
|
limit: number;
|
|
40
42
|
}) => Promise<SessionTreeResponse>;
|
|
41
43
|
getLiveActivity: (input: {
|
|
42
44
|
run: string | null;
|
|
43
45
|
since: string | null;
|
|
46
|
+
projectId: string | null;
|
|
44
47
|
limit: number;
|
|
45
48
|
}) => Promise<{
|
|
46
49
|
activities: LiveActivityItem[];
|
|
@@ -50,16 +53,21 @@ type LiveSnapshotRoutesDeps<TRes> = {
|
|
|
50
53
|
}>;
|
|
51
54
|
getLiveDecisions: (input: {
|
|
52
55
|
status: string;
|
|
56
|
+
projectId: string | null;
|
|
53
57
|
limit: number;
|
|
54
58
|
}) => Promise<{
|
|
55
59
|
decisions: unknown[];
|
|
56
60
|
}>;
|
|
57
61
|
getLiveAgents: (input: {
|
|
58
62
|
initiative: string | null;
|
|
63
|
+
projectId: string | null;
|
|
59
64
|
includeIdle: boolean | undefined;
|
|
60
65
|
}) => Promise<{
|
|
61
66
|
agents?: unknown[];
|
|
62
67
|
}>;
|
|
68
|
+
listInitiativeIdsForProject: (input: {
|
|
69
|
+
projectId: string;
|
|
70
|
+
}) => Promise<string[]>;
|
|
63
71
|
mapDecisionEntity: (entry: unknown) => Record<string, unknown> & {
|
|
64
72
|
waitingMinutes: number;
|
|
65
73
|
};
|
|
@@ -84,7 +92,45 @@ type LiveSnapshotRoutesDeps<TRes> = {
|
|
|
84
92
|
snapshotActivityPersistMinIntervalMs: number;
|
|
85
93
|
readSnapshotPersistState: () => SnapshotPersistState;
|
|
86
94
|
writeSnapshotPersistState: (state: SnapshotPersistState) => void;
|
|
95
|
+
parseJsonRequest?: (req: TReq) => Promise<Record<string, unknown>>;
|
|
96
|
+
buildNextUpQueue?: (input: {
|
|
97
|
+
initiativeId?: string | null;
|
|
98
|
+
projectId?: string | null;
|
|
99
|
+
}) => Promise<{
|
|
100
|
+
items: Array<Record<string, unknown>>;
|
|
101
|
+
degraded: string[];
|
|
102
|
+
}>;
|
|
103
|
+
bulkDecideDecisions?: (ids: string[], action: "approve" | "reject", input?: {
|
|
104
|
+
note?: string;
|
|
105
|
+
optionId?: string;
|
|
106
|
+
}) => Promise<Array<{
|
|
107
|
+
id?: string;
|
|
108
|
+
ok?: boolean;
|
|
109
|
+
error?: string;
|
|
110
|
+
}>>;
|
|
111
|
+
emitDecisionResolvedActivity?: (input: {
|
|
112
|
+
ids: string[];
|
|
113
|
+
action: "approve" | "reject";
|
|
114
|
+
note?: string | null;
|
|
115
|
+
optionId?: string | null;
|
|
116
|
+
sliceRunId?: string | null;
|
|
117
|
+
initiativeId?: string | null;
|
|
118
|
+
}) => Promise<void>;
|
|
119
|
+
runAction?: (runId: string, action: "pause" | "resume" | "cancel" | "rollback", input?: {
|
|
120
|
+
checkpointId?: string;
|
|
121
|
+
reason?: string;
|
|
122
|
+
}) => Promise<unknown>;
|
|
123
|
+
listChatThreads?: (input: {
|
|
124
|
+
commandCenterId?: string | null;
|
|
125
|
+
initiativeId?: string | null;
|
|
126
|
+
limit?: number;
|
|
127
|
+
offset?: number;
|
|
128
|
+
}) => {
|
|
129
|
+
threads: ChatThreadSummary[];
|
|
130
|
+
total: number;
|
|
131
|
+
updatedAt: string;
|
|
132
|
+
};
|
|
87
133
|
sendJson: (res: TRes, status: number, payload: unknown) => void;
|
|
88
134
|
};
|
|
89
|
-
export declare function registerLiveSnapshotRoutes<TReq, TRes>(router: Router<Record<string, never>, TReq, TRes>, deps: LiveSnapshotRoutesDeps<TRes>): void;
|
|
135
|
+
export declare function registerLiveSnapshotRoutes<TReq, TRes>(router: Router<Record<string, never>, TReq, TRes>, deps: LiveSnapshotRoutesDeps<TReq, TRes>): void;
|
|
90
136
|
export {};
|