plugin-agent-orchestrator 1.0.27 → 1.0.32
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 +9 -7
- package/dist/client/index.js +1 -1
- package/dist/client-v2/{214.723affb37c13bf7a.js → 214.79650a549273f163.js} +1 -1
- package/dist/client-v2/264.718a107e43fc163c.js +10 -0
- package/dist/client-v2/373.f5d5292e53c4e832.js +10 -0
- package/dist/client-v2/{41.1805b2edfaa4afe2.js → 41.ba6e080cc0488143.js} +1 -1
- package/dist/client-v2/418.29e713f79131eece.js +10 -0
- package/dist/client-v2/619.bd3c5698b40705c3.js +10 -0
- package/dist/client-v2/677.a991ce0250ff5c77.js +10 -0
- package/dist/client-v2/{70.a15d7fcec7c41768.js → 70.bda9518881c05360.js} +1 -1
- package/dist/client-v2/925.f5370de8f6632d65.js +10 -0
- package/dist/client-v2/index.js +1 -1
- package/dist/externalVersion.js +7 -10
- package/dist/locale/en-US.json +94 -25
- package/dist/locale/vi-VN.json +94 -25
- package/dist/locale/zh-CN.json +94 -25
- package/dist/server/collections/agent-execution-spans.js +37 -0
- package/dist/server/collections/agent-harness-profiles.js +2 -2
- package/dist/server/collections/agent-memory-contexts.js +125 -0
- package/dist/server/collections/orchestrator-logs.js +2 -2
- package/dist/server/migrations/20260425000000-add-interaction-schema.js +3 -1
- package/dist/server/migrations/20260427000000-change-packages-to-text.js +3 -1
- package/dist/server/migrations/20260427000001-change-other-json-to-text.js +6 -2
- package/dist/server/migrations/20260524001000-add-plan-approval-and-harness-profiles.js +21 -19
- package/dist/server/migrations/20260621000000-native-policy-profile-defaults.js +193 -0
- package/dist/server/plugin.js +128 -74
- package/dist/server/resources/agent-monitor.js +454 -0
- package/dist/server/services/AgentHarness.js +24 -499
- package/dist/server/services/AgentMemoryContextService.js +216 -0
- package/dist/server/services/ExecutionSpanService.js +2 -2
- package/dist/server/services/NativeSubAgentObserver.js +413 -0
- package/dist/server/skill-hub/mcp/McpController.js +16 -5
- package/dist/server/skill-hub/plugin.js +81 -5
- package/dist/server/skill-hub/tasks/SkillExecutionTask.js +9 -3
- package/dist/server/tools/delegate-task.js +11 -589
- package/dist/server/utils/skill-settings.js +18 -1
- package/package.json +47 -49
- package/src/client/AIEmployeesContext.tsx +5 -18
- package/src/client/AgentRunsTab.tsx +2 -771
- package/src/client/HarnessProfilesTab.tsx +2 -257
- package/src/client/OrchestratorSettings.tsx +97 -106
- package/src/client/RulesTab.tsx +2 -788
- package/src/client/plugin.tsx +0 -2
- package/src/client/skill-hub/components/ExecutionHistory.tsx +200 -202
- package/src/client/skill-hub/components/ExecutionProgress.tsx +51 -55
- package/src/client/skill-hub/components/LoopSettings.tsx +331 -331
- package/src/client/skill-hub/components/SkillEditor.tsx +43 -39
- package/src/client/skill-hub/components/SkillManager.tsx +194 -181
- package/src/client/skill-hub/components/SkillTestPanel.tsx +141 -145
- package/src/client/skill-hub/locale.ts +16 -16
- package/src/client/skill-hub/tools/SkillHubCard.tsx +104 -109
- package/src/client/skill-hub/tools/loopTemplates.ts +52 -52
- package/src/client/skill-hub/utils/jsonFields.ts +7 -3
- package/src/client-v2/components/AIEmployeesContext.tsx +3 -16
- package/src/client-v2/components/AgentRunsTab.tsx +182 -455
- package/src/client-v2/components/HarnessProfilesTab.tsx +34 -31
- package/src/client-v2/components/RulesTab.tsx +2 -782
- package/src/client-v2/components/TracingTab.tsx +1 -1
- package/src/client-v2/hooks/useApiRequest.ts +8 -1
- package/src/client-v2/pages/RulesPage.tsx +2 -2
- package/src/client-v2/plugin.tsx +3 -3
- package/src/locale/en-US.json +94 -25
- package/src/locale/vi-VN.json +94 -25
- package/src/locale/zh-CN.json +94 -25
- package/src/server/__tests__/native-sub-agent-observer.test.ts +246 -0
- package/src/server/__tests__/skill-settings.test.ts +6 -6
- package/src/server/__tests__/smoke.test.ts +1 -0
- package/src/server/collections/agent-execution-spans.ts +37 -0
- package/src/server/collections/agent-harness-profiles.ts +59 -59
- package/src/server/collections/agent-loop-events.ts +71 -71
- package/src/server/collections/agent-loop-steps.ts +144 -144
- package/src/server/collections/agent-memory-contexts.ts +95 -0
- package/src/server/collections/orchestrator-logs.ts +4 -4
- package/src/server/collections/skill-definitions.ts +111 -111
- package/src/server/collections/skill-executions.ts +106 -106
- package/src/server/collections/skill-loop-configs.ts +65 -65
- package/src/server/migrations/20260423000000-add-progress-fields.ts +14 -14
- package/src/server/migrations/20260425000000-add-interaction-schema.ts +3 -1
- package/src/server/migrations/20260427000000-change-packages-to-text.ts +4 -2
- package/src/server/migrations/20260427000001-change-other-json-to-text.ts +9 -5
- package/src/server/migrations/20260524000000-add-agent-loop-fields-to-skill-executions.ts +30 -30
- package/src/server/migrations/20260524001000-add-plan-approval-and-harness-profiles.ts +145 -142
- package/src/server/migrations/20260615000000-normalize-ai-employee-tool-bindings.ts +2 -2
- package/src/server/migrations/20260621000000-native-policy-profile-defaults.ts +193 -0
- package/src/server/plugin.ts +151 -94
- package/src/server/resources/agent-monitor.ts +482 -0
- package/src/server/services/AgentHarness.ts +38 -623
- package/src/server/services/AgentMemoryContextService.ts +256 -0
- package/src/server/services/AgentPlanValidator.ts +73 -73
- package/src/server/services/ExecutionSpanService.ts +6 -2
- package/src/server/services/FileManager.ts +144 -144
- package/src/server/services/NativeSubAgentObserver.ts +507 -0
- package/src/server/services/SkillManager.ts +583 -583
- package/src/server/services/SkillRepositoryService.ts +5 -7
- package/src/server/services/TokenTracker.ts +3 -3
- package/src/server/services/WorkerEnvManager.ts +1 -2
- package/src/server/skill-hub/actions/git-import.ts +5 -7
- package/src/server/skill-hub/mcp/McpController.ts +41 -14
- package/src/server/skill-hub/plugin.ts +89 -6
- package/src/server/skill-hub/tasks/SkillExecutionTask.ts +470 -460
- package/src/server/skill-hub/utils/json-fields.ts +1 -1
- package/src/server/tools/delegate-task.ts +13 -847
- package/src/server/utils/skill-settings.ts +24 -6
- package/dist/client-v2/264.0533912e6c5ea2d7.js +0 -10
- package/dist/client-v2/418.5ae055abf141820e.js +0 -10
- package/dist/client-v2/619.d99d3c9e61c99064.js +0 -10
- package/dist/client-v2/892.72db4161511c8a16.js +0 -10
- package/dist/client-v2/926.87f660b670d85bcc.js +0 -10
- package/src/client/tools/PlanApprovalCard.tsx +0 -176
- package/src/client/tools/registerOrchestratorCards.ts +0 -17
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __export = (target, all) => {
|
|
15
|
+
for (var name in all)
|
|
16
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
17
|
+
};
|
|
18
|
+
var __copyProps = (to, from, except, desc) => {
|
|
19
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
20
|
+
for (let key of __getOwnPropNames(from))
|
|
21
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
22
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
23
|
+
}
|
|
24
|
+
return to;
|
|
25
|
+
};
|
|
26
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
|
+
var agent_monitor_exports = {};
|
|
28
|
+
__export(agent_monitor_exports, {
|
|
29
|
+
registerAgentMonitorResource: () => registerAgentMonitorResource
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(agent_monitor_exports);
|
|
32
|
+
var import_ctx_utils = require("../utils/ctx-utils");
|
|
33
|
+
var import_NativeSubAgentObserver = require("../services/NativeSubAgentObserver");
|
|
34
|
+
function normalizeString(value) {
|
|
35
|
+
return typeof value === "string" ? value.trim() : "";
|
|
36
|
+
}
|
|
37
|
+
function readValue(record, key) {
|
|
38
|
+
const model = record;
|
|
39
|
+
return typeof (model == null ? void 0 : model.get) === "function" ? model.get(key) : model == null ? void 0 : model[key];
|
|
40
|
+
}
|
|
41
|
+
function isAdmin(ctx) {
|
|
42
|
+
var _a;
|
|
43
|
+
const context = ctx;
|
|
44
|
+
if ((0, import_ctx_utils.isAdminUser)(ctx)) return true;
|
|
45
|
+
const roles = (_a = context == null ? void 0 : context.state) == null ? void 0 : _a.currentRoles;
|
|
46
|
+
return Array.isArray(roles) && roles.some((role) => role === "root" || role === "admin");
|
|
47
|
+
}
|
|
48
|
+
function statusFromNative(status) {
|
|
49
|
+
if (status === "completed" || status === "done" || status === "success") return "success";
|
|
50
|
+
if (status === "error" || status === "failed") return "error";
|
|
51
|
+
return "running";
|
|
52
|
+
}
|
|
53
|
+
function formatDuration(ms) {
|
|
54
|
+
const value = Number(ms);
|
|
55
|
+
if (!Number.isFinite(value) || value <= 0) return null;
|
|
56
|
+
return value;
|
|
57
|
+
}
|
|
58
|
+
function formatSpanListRow(raw) {
|
|
59
|
+
const row = (0, import_ctx_utils.toPlain)(raw);
|
|
60
|
+
const input = (0, import_ctx_utils.asObject)(row == null ? void 0 : row.input);
|
|
61
|
+
const metadata = (0, import_ctx_utils.asObject)(row == null ? void 0 : row.metadata);
|
|
62
|
+
return {
|
|
63
|
+
id: row == null ? void 0 : row.id,
|
|
64
|
+
rootRunId: row == null ? void 0 : row.rootRunId,
|
|
65
|
+
source: (row == null ? void 0 : row.source) || metadata.source,
|
|
66
|
+
parentSessionId: (row == null ? void 0 : row.parentSessionId) || metadata.parentSessionId,
|
|
67
|
+
subSessionId: (row == null ? void 0 : row.subSessionId) || metadata.subSessionId,
|
|
68
|
+
toolCallId: (row == null ? void 0 : row.toolCallId) || metadata.toolCallId,
|
|
69
|
+
leaderUsername: row == null ? void 0 : row.leaderUsername,
|
|
70
|
+
employeeUsername: row == null ? void 0 : row.employeeUsername,
|
|
71
|
+
subAgentUsername: row == null ? void 0 : row.employeeUsername,
|
|
72
|
+
toolName: (row == null ? void 0 : row.toolName) || "dispatch-sub-agent-task",
|
|
73
|
+
task: input.question || input.task || (row == null ? void 0 : row.title) || "",
|
|
74
|
+
status: row == null ? void 0 : row.status,
|
|
75
|
+
durationMs: row == null ? void 0 : row.durationMs,
|
|
76
|
+
error: row == null ? void 0 : row.error,
|
|
77
|
+
userId: row == null ? void 0 : row.userId,
|
|
78
|
+
memoryContextApplied: Boolean(metadata.memoryContextApplied),
|
|
79
|
+
memoryScopes: metadata.memoryScopes || [],
|
|
80
|
+
harnessTag: metadata.harnessTag || "default",
|
|
81
|
+
createdAt: (row == null ? void 0 : row.createdAt) || (row == null ? void 0 : row.startedAt),
|
|
82
|
+
startedAt: row == null ? void 0 : row.startedAt,
|
|
83
|
+
endedAt: row == null ? void 0 : row.endedAt
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function buildSpanTree(rows) {
|
|
87
|
+
var _a;
|
|
88
|
+
const byId = /* @__PURE__ */ new Map();
|
|
89
|
+
const roots = [];
|
|
90
|
+
for (const raw of rows) {
|
|
91
|
+
const row = (0, import_ctx_utils.toPlain)(raw);
|
|
92
|
+
byId.set(String(row.id), { ...row, children: [] });
|
|
93
|
+
}
|
|
94
|
+
for (const row of byId.values()) {
|
|
95
|
+
const parentSpanId = normalizeString(row.parentSpanId);
|
|
96
|
+
if (parentSpanId && byId.has(parentSpanId)) {
|
|
97
|
+
(_a = byId.get(parentSpanId)) == null ? void 0 : _a.children.push(row);
|
|
98
|
+
} else {
|
|
99
|
+
roots.push(row);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
const sort = (items) => {
|
|
103
|
+
items.sort(
|
|
104
|
+
(a, b) => new Date(String(a.startedAt || a.createdAt || 0)).getTime() - new Date(String(b.startedAt || b.createdAt || 0)).getTime()
|
|
105
|
+
);
|
|
106
|
+
for (const item of items) sort(item.children);
|
|
107
|
+
};
|
|
108
|
+
sort(roots);
|
|
109
|
+
return roots;
|
|
110
|
+
}
|
|
111
|
+
function flattenTimeline(rows) {
|
|
112
|
+
return rows.map(import_ctx_utils.toPlain).sort(
|
|
113
|
+
(a, b) => new Date(String(a.startedAt || a.createdAt || 0)).getTime() - new Date(String(b.startedAt || b.createdAt || 0)).getTime()
|
|
114
|
+
).map((row) => ({
|
|
115
|
+
id: row.id,
|
|
116
|
+
type: row.type,
|
|
117
|
+
at: row.startedAt || row.createdAt,
|
|
118
|
+
title: row.title || row.toolName || row.type,
|
|
119
|
+
toolName: row.toolName,
|
|
120
|
+
status: row.status,
|
|
121
|
+
durationMs: row.durationMs,
|
|
122
|
+
content: row.output || row.error || (0, import_ctx_utils.asObject)(row.input).question || "",
|
|
123
|
+
parentSpanId: row.parentSpanId,
|
|
124
|
+
input: row.input,
|
|
125
|
+
output: row.output,
|
|
126
|
+
error: row.error
|
|
127
|
+
}));
|
|
128
|
+
}
|
|
129
|
+
async function findConversation(ctx, sessionId) {
|
|
130
|
+
if (!sessionId) return null;
|
|
131
|
+
try {
|
|
132
|
+
return (0, import_ctx_utils.toPlain)(
|
|
133
|
+
await ctx.db.getRepository("aiConversations").findOne({
|
|
134
|
+
filter: { sessionId }
|
|
135
|
+
})
|
|
136
|
+
);
|
|
137
|
+
} catch {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
async function findToolMessages(ctx, sessionIds) {
|
|
142
|
+
const repo = ctx.db.getRepository("aiToolMessages");
|
|
143
|
+
const rows = [];
|
|
144
|
+
for (const sessionId of Array.from(new Set(sessionIds.filter(Boolean)))) {
|
|
145
|
+
try {
|
|
146
|
+
const list = await repo.find({
|
|
147
|
+
filter: { sessionId },
|
|
148
|
+
sort: ["messageId", "id"]
|
|
149
|
+
});
|
|
150
|
+
rows.push(...list);
|
|
151
|
+
} catch {
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return rows.map(import_ctx_utils.toPlain);
|
|
155
|
+
}
|
|
156
|
+
async function findNativeMessages(ctx, parentSessionId, subSessionId) {
|
|
157
|
+
const repo = ctx.db.getRepository("aiMessages");
|
|
158
|
+
const rows = [];
|
|
159
|
+
for (const sessionId of [parentSessionId, subSessionId].filter(Boolean)) {
|
|
160
|
+
try {
|
|
161
|
+
const list = await repo.find({
|
|
162
|
+
filter: { sessionId },
|
|
163
|
+
sort: ["messageId"],
|
|
164
|
+
limit: 200
|
|
165
|
+
});
|
|
166
|
+
rows.push(...list);
|
|
167
|
+
} catch {
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return rows.map(import_ctx_utils.toPlain);
|
|
171
|
+
}
|
|
172
|
+
async function backfillFromMetadata(ctx, spanRepo, limit) {
|
|
173
|
+
const messageRepo = ctx.db.getRepository("aiMessages");
|
|
174
|
+
const toolRepo = ctx.db.getRepository("aiToolMessages");
|
|
175
|
+
const conversationRepo = ctx.db.getRepository("aiConversations");
|
|
176
|
+
const messages = await messageRepo.find({
|
|
177
|
+
sort: ["-messageId"],
|
|
178
|
+
limit
|
|
179
|
+
});
|
|
180
|
+
let created = 0;
|
|
181
|
+
let skipped = 0;
|
|
182
|
+
for (const rawMessage of messages) {
|
|
183
|
+
const message = (0, import_ctx_utils.toPlain)(rawMessage);
|
|
184
|
+
const conversations = (0, import_ctx_utils.asObject)(message.metadata).subAgentConversations;
|
|
185
|
+
if (!Array.isArray(conversations)) continue;
|
|
186
|
+
for (const item of conversations) {
|
|
187
|
+
const subSessionId = normalizeString(item == null ? void 0 : item.sessionId);
|
|
188
|
+
const toolCallId = normalizeString(item == null ? void 0 : item.toolCallId);
|
|
189
|
+
if (!subSessionId || !toolCallId) {
|
|
190
|
+
skipped += 1;
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
const existing = await spanRepo.findOne({
|
|
194
|
+
filter: {
|
|
195
|
+
source: import_NativeSubAgentObserver.NATIVE_SOURCE,
|
|
196
|
+
subSessionId,
|
|
197
|
+
toolCallId,
|
|
198
|
+
type: "sub_agent"
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
if (existing) {
|
|
202
|
+
skipped += 1;
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
const toolMessage = (0, import_ctx_utils.toPlain)(
|
|
206
|
+
await toolRepo.findOne({
|
|
207
|
+
filter: { toolCallId }
|
|
208
|
+
})
|
|
209
|
+
);
|
|
210
|
+
const parentSessionId = normalizeString(toolMessage == null ? void 0 : toolMessage.sessionId) || normalizeString(message.sessionId);
|
|
211
|
+
const parentConversation = parentSessionId ? (0, import_ctx_utils.toPlain)(await conversationRepo.findOne({ filter: { sessionId: parentSessionId } })) : null;
|
|
212
|
+
const subConversation = (0, import_ctx_utils.toPlain)(await conversationRepo.findOne({ filter: { sessionId: subSessionId } }));
|
|
213
|
+
const invokeStart = Number(toolMessage == null ? void 0 : toolMessage.invokeStartTime);
|
|
214
|
+
const invokeEnd = Number(toolMessage == null ? void 0 : toolMessage.invokeEndTime);
|
|
215
|
+
const durationMs = Number.isFinite(invokeStart) && Number.isFinite(invokeEnd) && invokeEnd >= invokeStart ? invokeEnd - invokeStart : void 0;
|
|
216
|
+
const rootRunId = (0, import_NativeSubAgentObserver.makeNativeRunId)([
|
|
217
|
+
parentSessionId,
|
|
218
|
+
subSessionId,
|
|
219
|
+
toolCallId,
|
|
220
|
+
subConversation == null ? void 0 : subConversation.aiEmployeeUsername
|
|
221
|
+
]);
|
|
222
|
+
const content = (0, import_ctx_utils.asObject)(toolMessage == null ? void 0 : toolMessage.content);
|
|
223
|
+
await spanRepo.create({
|
|
224
|
+
values: {
|
|
225
|
+
rootRunId,
|
|
226
|
+
parentSpanId: null,
|
|
227
|
+
source: import_NativeSubAgentObserver.NATIVE_SOURCE,
|
|
228
|
+
parentSessionId: parentSessionId || void 0,
|
|
229
|
+
subSessionId: subSessionId || void 0,
|
|
230
|
+
toolCallId,
|
|
231
|
+
type: "sub_agent",
|
|
232
|
+
status: statusFromNative((item == null ? void 0 : item.status) || (toolMessage == null ? void 0 : toolMessage.status)),
|
|
233
|
+
leaderUsername: parentConversation == null ? void 0 : parentConversation.aiEmployeeUsername,
|
|
234
|
+
employeeUsername: subConversation == null ? void 0 : subConversation.aiEmployeeUsername,
|
|
235
|
+
toolName: "dispatch-sub-agent-task",
|
|
236
|
+
title: (subConversation == null ? void 0 : subConversation.title) || `${(parentConversation == null ? void 0 : parentConversation.aiEmployeeUsername) || "main"} -> ${(subConversation == null ? void 0 : subConversation.aiEmployeeUsername) || "sub-agent"}`,
|
|
237
|
+
input: {
|
|
238
|
+
question: subConversation == null ? void 0 : subConversation.title,
|
|
239
|
+
parentSessionId: parentSessionId || void 0,
|
|
240
|
+
subSessionId: subSessionId || void 0
|
|
241
|
+
},
|
|
242
|
+
output: (0, import_ctx_utils.trimText)(content.answer || (toolMessage == null ? void 0 : toolMessage.content), 2e4),
|
|
243
|
+
durationMs: formatDuration(durationMs),
|
|
244
|
+
startedAt: invokeStart ? new Date(invokeStart) : /* @__PURE__ */ new Date(),
|
|
245
|
+
endedAt: invokeEnd ? new Date(invokeEnd) : void 0,
|
|
246
|
+
metadata: {
|
|
247
|
+
source: import_NativeSubAgentObserver.NATIVE_SOURCE,
|
|
248
|
+
backfilled: true,
|
|
249
|
+
messageId: message.messageId,
|
|
250
|
+
toolMessageId: toolMessage == null ? void 0 : toolMessage.id,
|
|
251
|
+
nativeStatus: item == null ? void 0 : item.status
|
|
252
|
+
},
|
|
253
|
+
userId: (parentConversation == null ? void 0 : parentConversation.userId) || (subConversation == null ? void 0 : subConversation.userId),
|
|
254
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
created += 1;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return { created, skipped };
|
|
261
|
+
}
|
|
262
|
+
async function backfillFromToolMessages(ctx, spanRepo, limit) {
|
|
263
|
+
const toolRepo = ctx.db.getRepository("aiToolMessages");
|
|
264
|
+
const toolMessages = await toolRepo.find({
|
|
265
|
+
filter: { toolName: "dispatch-sub-agent-task" },
|
|
266
|
+
sort: ["-id"],
|
|
267
|
+
limit
|
|
268
|
+
});
|
|
269
|
+
let created = 0;
|
|
270
|
+
let skipped = 0;
|
|
271
|
+
for (const rawToolMessage of toolMessages) {
|
|
272
|
+
const toolMessage = (0, import_ctx_utils.toPlain)(rawToolMessage);
|
|
273
|
+
const content = (0, import_ctx_utils.asObject)(toolMessage.content);
|
|
274
|
+
const subSessionId = normalizeString(content.sessionId);
|
|
275
|
+
const toolCallId = normalizeString(toolMessage.toolCallId);
|
|
276
|
+
if (!subSessionId || !toolCallId) {
|
|
277
|
+
skipped += 1;
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
const existing = await spanRepo.findOne({
|
|
281
|
+
filter: {
|
|
282
|
+
source: import_NativeSubAgentObserver.NATIVE_SOURCE,
|
|
283
|
+
subSessionId,
|
|
284
|
+
toolCallId,
|
|
285
|
+
type: "sub_agent"
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
if (existing) {
|
|
289
|
+
skipped += 1;
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
const parentSessionId = normalizeString(toolMessage.sessionId);
|
|
293
|
+
const parentConversation = await findConversation(ctx, parentSessionId);
|
|
294
|
+
const subConversation = await findConversation(ctx, subSessionId);
|
|
295
|
+
const invokeStart = Number(toolMessage.invokeStartTime);
|
|
296
|
+
const invokeEnd = Number(toolMessage.invokeEndTime);
|
|
297
|
+
const rootRunId = (0, import_NativeSubAgentObserver.makeNativeRunId)([parentSessionId, subSessionId, toolCallId, subConversation == null ? void 0 : subConversation.aiEmployeeUsername]);
|
|
298
|
+
await spanRepo.create({
|
|
299
|
+
values: {
|
|
300
|
+
rootRunId,
|
|
301
|
+
parentSpanId: null,
|
|
302
|
+
source: import_NativeSubAgentObserver.NATIVE_SOURCE,
|
|
303
|
+
parentSessionId: parentSessionId || void 0,
|
|
304
|
+
subSessionId: subSessionId || void 0,
|
|
305
|
+
toolCallId,
|
|
306
|
+
type: "sub_agent",
|
|
307
|
+
status: statusFromNative(toolMessage.status),
|
|
308
|
+
leaderUsername: parentConversation == null ? void 0 : parentConversation.aiEmployeeUsername,
|
|
309
|
+
employeeUsername: subConversation == null ? void 0 : subConversation.aiEmployeeUsername,
|
|
310
|
+
toolName: "dispatch-sub-agent-task",
|
|
311
|
+
title: (subConversation == null ? void 0 : subConversation.title) || `${(parentConversation == null ? void 0 : parentConversation.aiEmployeeUsername) || "main"} -> ${(subConversation == null ? void 0 : subConversation.aiEmployeeUsername) || "sub-agent"}`,
|
|
312
|
+
input: {
|
|
313
|
+
question: subConversation == null ? void 0 : subConversation.title,
|
|
314
|
+
parentSessionId: parentSessionId || void 0,
|
|
315
|
+
subSessionId: subSessionId || void 0
|
|
316
|
+
},
|
|
317
|
+
output: (0, import_ctx_utils.trimText)(content.answer || toolMessage.content, 2e4),
|
|
318
|
+
durationMs: Number.isFinite(invokeStart) && Number.isFinite(invokeEnd) && invokeEnd >= invokeStart ? invokeEnd - invokeStart : void 0,
|
|
319
|
+
startedAt: invokeStart ? new Date(invokeStart) : /* @__PURE__ */ new Date(),
|
|
320
|
+
endedAt: invokeEnd ? new Date(invokeEnd) : void 0,
|
|
321
|
+
metadata: {
|
|
322
|
+
source: import_NativeSubAgentObserver.NATIVE_SOURCE,
|
|
323
|
+
backfilled: true,
|
|
324
|
+
toolMessageId: toolMessage.id
|
|
325
|
+
},
|
|
326
|
+
userId: (parentConversation == null ? void 0 : parentConversation.userId) || (subConversation == null ? void 0 : subConversation.userId),
|
|
327
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
created += 1;
|
|
331
|
+
}
|
|
332
|
+
return { created, skipped };
|
|
333
|
+
}
|
|
334
|
+
function registerAgentMonitorResource(plugin) {
|
|
335
|
+
plugin.app.resource({
|
|
336
|
+
name: "agentMonitor",
|
|
337
|
+
actions: {
|
|
338
|
+
async list(ctx, next) {
|
|
339
|
+
const { page = 1, pageSize = 20, sort = ["-createdAt"], filter = {} } = ctx.action.params;
|
|
340
|
+
const requestedFilter = (0, import_ctx_utils.asObject)(filter);
|
|
341
|
+
const spanFilter = {
|
|
342
|
+
source: import_NativeSubAgentObserver.NATIVE_SOURCE,
|
|
343
|
+
type: "sub_agent",
|
|
344
|
+
parentSpanId: null
|
|
345
|
+
};
|
|
346
|
+
for (const key of [
|
|
347
|
+
"leaderUsername",
|
|
348
|
+
"employeeUsername",
|
|
349
|
+
"status",
|
|
350
|
+
"parentSessionId",
|
|
351
|
+
"subSessionId",
|
|
352
|
+
"toolCallId"
|
|
353
|
+
]) {
|
|
354
|
+
if (requestedFilter[key]) spanFilter[key] = requestedFilter[key];
|
|
355
|
+
}
|
|
356
|
+
if (requestedFilter.subAgentUsername) spanFilter.employeeUsername = requestedFilter.subAgentUsername;
|
|
357
|
+
if (requestedFilter.sessionId) spanFilter.parentSessionId = requestedFilter.sessionId;
|
|
358
|
+
if (!isAdmin(ctx)) {
|
|
359
|
+
const userId = (0, import_ctx_utils.currentUserId)(ctx);
|
|
360
|
+
if (!userId) ctx.throw(401, "Not authenticated");
|
|
361
|
+
spanFilter.userId = userId;
|
|
362
|
+
} else if (requestedFilter.userId) {
|
|
363
|
+
spanFilter.userId = requestedFilter.userId;
|
|
364
|
+
}
|
|
365
|
+
const repo = ctx.db.getRepository("agentExecutionSpans");
|
|
366
|
+
const [rows, count] = await repo.findAndCount({
|
|
367
|
+
filter: spanFilter,
|
|
368
|
+
sort,
|
|
369
|
+
offset: (Number(page) - 1) * Number(pageSize),
|
|
370
|
+
limit: Number(pageSize)
|
|
371
|
+
});
|
|
372
|
+
ctx.body = {
|
|
373
|
+
data: rows.map(formatSpanListRow),
|
|
374
|
+
meta: {
|
|
375
|
+
count,
|
|
376
|
+
page: Number(page),
|
|
377
|
+
pageSize: Number(pageSize),
|
|
378
|
+
totalPage: Math.ceil(count / Number(pageSize))
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
await next();
|
|
382
|
+
},
|
|
383
|
+
async get(ctx, next) {
|
|
384
|
+
const { filterByTk } = ctx.action.params;
|
|
385
|
+
if (!filterByTk) {
|
|
386
|
+
ctx.throw(400, "span id is required");
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
const repo = ctx.db.getRepository("agentExecutionSpans");
|
|
390
|
+
const span = (0, import_ctx_utils.toPlain)(
|
|
391
|
+
await repo.findOne({
|
|
392
|
+
filter: { id: filterByTk }
|
|
393
|
+
})
|
|
394
|
+
);
|
|
395
|
+
if (!span) {
|
|
396
|
+
ctx.throw(404, "span not found");
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
if (!isAdmin(ctx) && String(span.userId || "") !== String((0, import_ctx_utils.currentUserId)(ctx) || "")) {
|
|
400
|
+
ctx.throw(403, "You cannot view this agent run.");
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
const rows = await repo.find({
|
|
404
|
+
filter: { rootRunId: span.rootRunId },
|
|
405
|
+
sort: ["createdAt"]
|
|
406
|
+
});
|
|
407
|
+
const parentSessionId = normalizeString(span.parentSessionId || (0, import_ctx_utils.asObject)(span.metadata).parentSessionId);
|
|
408
|
+
const subSessionId = normalizeString(span.subSessionId || (0, import_ctx_utils.asObject)(span.metadata).subSessionId);
|
|
409
|
+
ctx.body = {
|
|
410
|
+
data: {
|
|
411
|
+
...formatSpanListRow(span),
|
|
412
|
+
input: span.input,
|
|
413
|
+
output: span.output,
|
|
414
|
+
metadata: span.metadata || {},
|
|
415
|
+
children: buildSpanTree(rows),
|
|
416
|
+
trace: flattenTimeline(rows),
|
|
417
|
+
nativeConversations: {
|
|
418
|
+
parent: await findConversation(ctx, parentSessionId),
|
|
419
|
+
subAgent: await findConversation(ctx, subSessionId)
|
|
420
|
+
},
|
|
421
|
+
nativeMessages: await findNativeMessages(ctx, parentSessionId, subSessionId),
|
|
422
|
+
toolMessages: await findToolMessages(ctx, [parentSessionId, subSessionId])
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
await next();
|
|
426
|
+
},
|
|
427
|
+
async sync(ctx, next) {
|
|
428
|
+
var _a, _b;
|
|
429
|
+
if (!isAdmin(ctx)) {
|
|
430
|
+
ctx.throw(403, "Admin role is required to sync native agent monitor spans.");
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
const values = (0, import_ctx_utils.asObject)((_a = ctx.action.params) == null ? void 0 : _a.values);
|
|
434
|
+
const limit = Math.min(Math.max(Number(values.limit || ((_b = ctx.action.params) == null ? void 0 : _b.limit) || 200), 1), 1e3);
|
|
435
|
+
const spanRepo = ctx.db.getRepository("agentExecutionSpans");
|
|
436
|
+
const metadataResult = await backfillFromMetadata(ctx, spanRepo, limit);
|
|
437
|
+
const toolResult = await backfillFromToolMessages(ctx, spanRepo, limit);
|
|
438
|
+
ctx.body = {
|
|
439
|
+
data: {
|
|
440
|
+
created: metadataResult.created + toolResult.created,
|
|
441
|
+
skipped: metadataResult.skipped + toolResult.skipped,
|
|
442
|
+
metadata: metadataResult,
|
|
443
|
+
toolMessages: toolResult
|
|
444
|
+
}
|
|
445
|
+
};
|
|
446
|
+
await next();
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
452
|
+
0 && (module.exports = {
|
|
453
|
+
registerAgentMonitorResource
|
|
454
|
+
});
|