plugin-agent-orchestrator 1.0.20 → 1.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/index.js +1 -1
- package/dist/externalVersion.js +6 -6
- package/dist/server/collections/agent-execution-spans.js +24 -0
- package/dist/server/collections/agent-loop-runs.js +36 -0
- package/dist/server/collections/orchestrator-config.js +14 -0
- package/dist/server/migrations/20260601000000-add-token-fields.js +101 -0
- package/dist/server/plugin.js +56 -0
- package/dist/server/resources/agent-loop.js +33 -25
- package/dist/server/resources/tracing.js +5 -8
- package/dist/server/services/AgentHarness.js +56 -90
- package/dist/server/services/AgentLoopController.js +164 -125
- package/dist/server/services/AgentLoopRepository.js +16 -34
- package/dist/server/services/AgentLoopService.js +7 -1
- package/dist/server/services/AgentPlannerService.js +5 -25
- package/dist/server/services/AgentRegistryService.js +34 -24
- package/dist/server/services/CircuitBreaker.js +120 -0
- package/dist/server/services/ContextAggregator.js +201 -0
- package/dist/server/services/ExecutionSpanService.js +2 -5
- package/dist/server/services/RunEventBus.js +73 -0
- package/dist/server/services/TokenTracker.js +173 -0
- package/dist/server/tools/agent-loop.js +30 -63
- package/dist/server/tools/delegate-task.js +14 -72
- package/dist/server/tools/orchestrator-plan.js +10 -47
- package/dist/server/types.js +24 -0
- package/dist/server/utils/ctx-utils.js +152 -0
- package/dist/server/utils/logging.js +86 -0
- package/package.json +44 -44
- package/src/client/AgentRunsTab.tsx +764 -764
- package/src/client/HarnessProfilesTab.tsx +247 -247
- package/src/client/OrchestratorSettings.tsx +106 -106
- package/src/client/RulesTab.tsx +716 -716
- package/src/client/hooks/useRunEventStream.ts +76 -0
- package/src/client/index.tsx +2 -1
- package/src/client/plugin.tsx +27 -27
- package/src/client/skill-hub/components/LoopSettings.tsx +331 -331
- package/src/client/skill-hub/index.tsx +51 -51
- package/src/client/skill-hub/tools/InteractionSchemasProvider.tsx +99 -99
- package/src/client/skill-hub/tools/SkillHubCard.tsx +109 -109
- package/src/client/skill-hub/tools/loopTemplates.ts +52 -52
- package/src/client/skill-hub/tools/registerSkillLoopCards.ts +58 -58
- package/src/client/tools/PlanApprovalCard.tsx +175 -175
- package/src/client/tools/registerOrchestratorCards.ts +7 -7
- package/src/server/__tests__/agent-loop-controller.test.ts +375 -0
- package/src/server/__tests__/circuit-breaker.test.ts +169 -0
- package/src/server/__tests__/context-aggregator.test.ts +222 -0
- package/src/server/__tests__/parallel-execution.test.ts +318 -0
- package/src/server/__tests__/smoke.test.ts +120 -0
- package/src/server/collections/agent-execution-spans.ts +24 -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-runs.ts +38 -1
- package/src/server/collections/agent-loop-steps.ts +144 -144
- package/src/server/collections/orchestrator-config.ts +14 -0
- package/src/server/collections/skill-executions.ts +106 -106
- package/src/server/collections/skill-loop-configs.ts +65 -65
- 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 +142 -142
- package/src/server/migrations/20260601000000-add-token-fields.ts +89 -0
- package/src/server/plugin.ts +68 -0
- package/src/server/resources/agent-loop.ts +21 -12
- package/src/server/resources/tracing.ts +3 -7
- package/src/server/services/AgentHarness.ts +78 -116
- package/src/server/services/AgentLoopController.ts +197 -122
- package/src/server/services/AgentLoopRepository.ts +9 -25
- package/src/server/services/AgentLoopService.ts +13 -1
- package/src/server/services/AgentPlanValidator.ts +73 -73
- package/src/server/services/AgentPlannerService.ts +2 -25
- package/src/server/services/AgentRegistryService.ts +40 -31
- package/src/server/services/CircuitBreaker.ts +116 -0
- package/src/server/services/ContextAggregator.ts +239 -0
- package/src/server/services/ExecutionSpanService.ts +2 -4
- package/src/server/services/RunEventBus.ts +45 -0
- package/src/server/services/TokenTracker.ts +209 -0
- package/src/server/skill-hub/plugin.ts +898 -898
- package/src/server/skill-hub/tasks/SkillExecutionTask.ts +460 -460
- package/src/server/tools/agent-loop.ts +18 -57
- package/src/server/tools/delegate-task.ts +11 -93
- package/src/server/tools/orchestrator-plan.ts +26 -50
- package/src/server/tools/skill-execute.ts +160 -160
- package/src/server/types.ts +55 -0
- package/src/server/utils/ctx-utils.ts +118 -0
- package/src/server/utils/logging.ts +63 -0
- package/dist/client/AIEmployeeSelect.d.ts +0 -11
- package/dist/client/AIEmployeesContext.d.ts +0 -30
- package/dist/client/AgentRunsTab.d.ts +0 -2
- package/dist/client/HarnessProfilesTab.d.ts +0 -2
- package/dist/client/OrchestratorSettings.d.ts +0 -3
- package/dist/client/RulesTab.d.ts +0 -2
- package/dist/client/TracingTab.d.ts +0 -2
- package/dist/client/index.d.ts +0 -1
- package/dist/client/plugin.d.ts +0 -6
- package/dist/client/skill-hub/components/ExecutionHistory.d.ts +0 -2
- package/dist/client/skill-hub/components/ExecutionProgress.d.ts +0 -20
- package/dist/client/skill-hub/components/GitSkillImport.d.ts +0 -7
- package/dist/client/skill-hub/components/LoopSettings.d.ts +0 -2
- package/dist/client/skill-hub/components/SkillEditor.d.ts +0 -7
- package/dist/client/skill-hub/components/SkillManager.d.ts +0 -2
- package/dist/client/skill-hub/components/SkillMetrics.d.ts +0 -2
- package/dist/client/skill-hub/components/SkillTestPanel.d.ts +0 -7
- package/dist/client/skill-hub/index.d.ts +0 -11
- package/dist/client/skill-hub/locale.d.ts +0 -3
- package/dist/client/skill-hub/tools/InteractionSchemasProvider.d.ts +0 -6
- package/dist/client/skill-hub/tools/SkillHubCard.d.ts +0 -3
- package/dist/client/skill-hub/tools/loopTemplates.d.ts +0 -22
- package/dist/client/skill-hub/tools/registerSkillLoopCards.d.ts +0 -1
- package/dist/client/skill-hub/utils/jsonFields.d.ts +0 -3
- package/dist/client/tools/PlanApprovalCard.d.ts +0 -3
- package/dist/client/tools/registerOrchestratorCards.d.ts +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/server/collections/agent-execution-spans.d.ts +0 -9
- package/dist/server/collections/agent-harness-profiles.d.ts +0 -2
- package/dist/server/collections/agent-loop-events.d.ts +0 -2
- package/dist/server/collections/agent-loop-runs.d.ts +0 -2
- package/dist/server/collections/agent-loop-steps.d.ts +0 -2
- package/dist/server/collections/orchestrator-config.d.ts +0 -2
- package/dist/server/collections/orchestrator-logs.d.ts +0 -8
- package/dist/server/collections/skill-definitions.d.ts +0 -3
- package/dist/server/collections/skill-executions.d.ts +0 -3
- package/dist/server/collections/skill-loop-configs.d.ts +0 -3
- package/dist/server/collections/skill-worker-configs.d.ts +0 -3
- package/dist/server/index.d.ts +0 -1
- package/dist/server/migrations/20260423000000-add-progress-fields.d.ts +0 -4
- package/dist/server/migrations/20260425000000-add-interaction-schema.d.ts +0 -4
- package/dist/server/migrations/20260427000000-add-tracing-detail-fields.d.ts +0 -7
- package/dist/server/migrations/20260427000000-change-packages-to-text.d.ts +0 -4
- package/dist/server/migrations/20260427000001-change-other-json-to-text.d.ts +0 -4
- package/dist/server/migrations/20260429000000-add-llm-fields.d.ts +0 -7
- package/dist/server/migrations/20260429000000-fix-inputargs-json-to-text.d.ts +0 -16
- package/dist/server/migrations/20260503000000-add-orchestrator-trace-fields.d.ts +0 -7
- package/dist/server/migrations/20260524000000-add-agent-loop-fields-to-skill-executions.d.ts +0 -7
- package/dist/server/migrations/20260524001000-add-plan-approval-and-harness-profiles.d.ts +0 -12
- package/dist/server/plugin.d.ts +0 -16
- package/dist/server/resources/agent-loop.d.ts +0 -3
- package/dist/server/resources/tracing.d.ts +0 -7
- package/dist/server/services/AgentHarness.d.ts +0 -42
- package/dist/server/services/AgentLoopController.d.ts +0 -205
- package/dist/server/services/AgentLoopRepository.d.ts +0 -20
- package/dist/server/services/AgentLoopService.d.ts +0 -149
- package/dist/server/services/AgentPlanValidator.d.ts +0 -4
- package/dist/server/services/AgentPlannerService.d.ts +0 -8
- package/dist/server/services/AgentRegistryService.d.ts +0 -13
- package/dist/server/services/CodeValidator.d.ts +0 -32
- package/dist/server/services/ExecutionSpanService.d.ts +0 -46
- package/dist/server/services/FileManager.d.ts +0 -28
- package/dist/server/services/SandboxRunner.d.ts +0 -41
- package/dist/server/services/SkillManager.d.ts +0 -6
- package/dist/server/services/SkillRepositoryService.d.ts +0 -22
- package/dist/server/services/WorkerEnvManager.d.ts +0 -26
- package/dist/server/skill-hub/actions/git-import.d.ts +0 -21
- package/dist/server/skill-hub/mcp/McpController.d.ts +0 -15
- package/dist/server/skill-hub/plugin.d.ts +0 -61
- package/dist/server/skill-hub/tasks/SkillExecutionTask.d.ts +0 -16
- package/dist/server/skill-hub/utils/json-fields.d.ts +0 -7
- package/dist/server/tools/agent-loop.d.ts +0 -235
- package/dist/server/tools/delegate-task.d.ts +0 -19
- package/dist/server/tools/external-rag-search.d.ts +0 -42
- package/dist/server/tools/orchestrator-plan.d.ts +0 -205
- package/dist/server/tools/skill-execute.d.ts +0 -36
|
@@ -5,41 +5,16 @@ import { DynamicStructuredTool } from '@langchain/core/tools';
|
|
|
5
5
|
import { HumanMessage, SystemMessage } from '@langchain/core/messages';
|
|
6
6
|
import { ExecutionSpanService, setOrchestratorTraceContext } from './ExecutionSpanService';
|
|
7
7
|
import { AgentRegistryService } from './AgentRegistryService';
|
|
8
|
+
import { TokenTracker, extractTokenUsage } from './TokenTracker';
|
|
9
|
+
import { ContextAggregator } from './ContextAggregator';
|
|
10
|
+
import { getCircuitBreaker } from './CircuitBreaker';
|
|
11
|
+
import { toPlain, asObject, trimText, nowIso } from '../utils/ctx-utils';
|
|
12
|
+
import { logDelegation as sharedLogDelegation } from '../utils/logging';
|
|
13
|
+
import { TraceEvent } from '../types';
|
|
8
14
|
|
|
9
15
|
const ORCHESTRATOR_DEPTH_KEY = '__orchestratorDepth';
|
|
10
16
|
const ORCHESTRATOR_PATH_KEY = '__orchestratorPath';
|
|
11
17
|
|
|
12
|
-
function toPlain(record: any) {
|
|
13
|
-
return record?.toJSON?.() || record;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function asObject(value: any) {
|
|
17
|
-
if (value && typeof value === 'object' && !Array.isArray(value)) return value;
|
|
18
|
-
if (typeof value === 'string' && value.trim()) {
|
|
19
|
-
try {
|
|
20
|
-
const parsed = JSON.parse(value);
|
|
21
|
-
return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : {};
|
|
22
|
-
} catch {
|
|
23
|
-
return {};
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
return {};
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function trimText(value: any, max = 50000) {
|
|
30
|
-
let text = '';
|
|
31
|
-
if (typeof value === 'string') {
|
|
32
|
-
text = value;
|
|
33
|
-
} else if (value != null) {
|
|
34
|
-
try {
|
|
35
|
-
text = JSON.stringify(value);
|
|
36
|
-
} catch {
|
|
37
|
-
text = String(value);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
return text.length > max ? `${text.slice(0, max)}\n...[truncated]` : text;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
18
|
function sanitizeToolPart(value: string) {
|
|
44
19
|
return (value || '').replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
45
20
|
}
|
|
@@ -48,28 +23,18 @@ function buildDelegateToolName(leaderUsername: string, subAgentUsername: string)
|
|
|
48
23
|
return `delegate_${sanitizeToolPart(leaderUsername)}_to_${sanitizeToolPart(subAgentUsername)}`;
|
|
49
24
|
}
|
|
50
25
|
|
|
51
|
-
function nowIso() {
|
|
52
|
-
return new Date().toISOString();
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
type TraceEvent = {
|
|
56
|
-
type: string;
|
|
57
|
-
at: string;
|
|
58
|
-
title: string;
|
|
59
|
-
content?: string;
|
|
60
|
-
toolName?: string;
|
|
61
|
-
args?: any;
|
|
62
|
-
status?: string;
|
|
63
|
-
};
|
|
64
|
-
|
|
65
26
|
export class AgentHarness {
|
|
66
27
|
private readonly spanService: ExecutionSpanService;
|
|
28
|
+
private readonly tokenTracker: TokenTracker;
|
|
29
|
+
private readonly contextAggregator: ContextAggregator;
|
|
67
30
|
|
|
68
31
|
constructor(
|
|
69
32
|
private readonly plugin: any,
|
|
70
|
-
private readonly registryService: AgentRegistryService
|
|
33
|
+
private readonly registryService: AgentRegistryService,
|
|
71
34
|
) {
|
|
72
35
|
this.spanService = new ExecutionSpanService(plugin);
|
|
36
|
+
this.tokenTracker = new TokenTracker(plugin);
|
|
37
|
+
this.contextAggregator = new ContextAggregator(plugin);
|
|
73
38
|
}
|
|
74
39
|
|
|
75
40
|
get db() {
|
|
@@ -80,11 +45,7 @@ export class AgentHarness {
|
|
|
80
45
|
return this.plugin.app;
|
|
81
46
|
}
|
|
82
47
|
|
|
83
|
-
async executeStep(
|
|
84
|
-
run: any,
|
|
85
|
-
step: any,
|
|
86
|
-
options: { userId?: string | number; ctx?: any } = {}
|
|
87
|
-
): Promise<any> {
|
|
48
|
+
async executeStep(run: any, step: any, options: { userId?: string | number; ctx?: any } = {}): Promise<any> {
|
|
88
49
|
const harnessTag = asObject(run.metadata).harnessTag || asObject(step.metadata).harnessTag || 'default';
|
|
89
50
|
const profile = await this.registryService.getHarnessProfile(harnessTag);
|
|
90
51
|
const settings = asObject(profile?.settings);
|
|
@@ -124,7 +85,7 @@ export class AgentHarness {
|
|
|
124
85
|
run: any,
|
|
125
86
|
step: any,
|
|
126
87
|
settings: any,
|
|
127
|
-
options: { userId?: string | number; ctx?: any }
|
|
88
|
+
options: { userId?: string | number; ctx?: any },
|
|
128
89
|
) {
|
|
129
90
|
const target = step.target || asObject(step.metadata).subAgentUsername || step.input?.subAgentUsername;
|
|
130
91
|
if (!target) {
|
|
@@ -147,10 +108,30 @@ export class AgentHarness {
|
|
|
147
108
|
agentLoopRunId: String(run.id),
|
|
148
109
|
agentLoopStepId: String(step.id),
|
|
149
110
|
},
|
|
150
|
-
20000
|
|
111
|
+
20000,
|
|
151
112
|
);
|
|
152
113
|
|
|
153
|
-
|
|
114
|
+
const circuitBreaker = getCircuitBreaker({ appLog: this.app });
|
|
115
|
+
|
|
116
|
+
// ── Circuit breaker check before invoking sub-agent ──────────────
|
|
117
|
+
if (!circuitBreaker.isAllowed(target)) {
|
|
118
|
+
const state = circuitBreaker.getState(target);
|
|
119
|
+
throw new Error(
|
|
120
|
+
`Sub-agent "${target}" circuit is open (${state?.failures || 0} failures). Retry after the recovery timeout.`,
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
const result = await this.invokeNamedTool(run, step, toolName, { task, context }, settings, options);
|
|
126
|
+
circuitBreaker.recordSuccess(target);
|
|
127
|
+
return result;
|
|
128
|
+
} catch (e: any) {
|
|
129
|
+
// Don't count approval pauses as circuit failures
|
|
130
|
+
if (e?.message !== 'requires_approval') {
|
|
131
|
+
circuitBreaker.recordFailure(target);
|
|
132
|
+
}
|
|
133
|
+
throw e;
|
|
134
|
+
}
|
|
154
135
|
}
|
|
155
136
|
|
|
156
137
|
private async invokeNamedTool(
|
|
@@ -159,7 +140,7 @@ export class AgentHarness {
|
|
|
159
140
|
toolName: string,
|
|
160
141
|
args: any,
|
|
161
142
|
settings: any,
|
|
162
|
-
options: { userId?: string | number; ctx?: any }
|
|
143
|
+
options: { userId?: string | number; ctx?: any },
|
|
163
144
|
) {
|
|
164
145
|
if (String(toolName).startsWith('orchestrator_')) {
|
|
165
146
|
throw new Error(`Tool step "${step.planKey}" cannot call internal orchestrator control tool "${toolName}".`);
|
|
@@ -185,7 +166,12 @@ export class AgentHarness {
|
|
|
185
166
|
const isDelegationTool = await this.registryService.isRegisteredDelegationTool(toolName);
|
|
186
167
|
const isStepAlreadyApproved = step?.approval?.approved === true;
|
|
187
168
|
|
|
188
|
-
if (
|
|
169
|
+
if (
|
|
170
|
+
!isDelegationTool &&
|
|
171
|
+
!isStepAlreadyApproved &&
|
|
172
|
+
(tool.defaultPermission === 'ASK' ||
|
|
173
|
+
(settings.requireApprovalRiskLevel && tool.riskLevel && tool.riskLevel >= settings.requireApprovalRiskLevel))
|
|
174
|
+
) {
|
|
189
175
|
throw new Error('requires_approval');
|
|
190
176
|
}
|
|
191
177
|
|
|
@@ -245,7 +231,7 @@ export class AgentHarness {
|
|
|
245
231
|
parentSpanId?: string;
|
|
246
232
|
agentLoopRunId?: string;
|
|
247
233
|
agentLoopStepId?: string;
|
|
248
|
-
}
|
|
234
|
+
},
|
|
249
235
|
) {
|
|
250
236
|
const {
|
|
251
237
|
leaderUsername,
|
|
@@ -324,7 +310,7 @@ export class AgentHarness {
|
|
|
324
310
|
const modelSettings = await this.registryService.resolveModelSettings(
|
|
325
311
|
subAgentUsername,
|
|
326
312
|
leaderUsername,
|
|
327
|
-
llmService && model ? { llmService, model } : undefined
|
|
313
|
+
llmService && model ? { llmService, model } : undefined,
|
|
328
314
|
);
|
|
329
315
|
|
|
330
316
|
if (!modelSettings) {
|
|
@@ -342,7 +328,7 @@ export class AgentHarness {
|
|
|
342
328
|
|
|
343
329
|
const employeeSkills = (subAgentEmployee.skillSettings?.skills ?? [])
|
|
344
330
|
.map((s: any) =>
|
|
345
|
-
typeof s === 'string' ? { name: s, autoCall: false } : { name: s?.name, autoCall: s?.autoCall === true }
|
|
331
|
+
typeof s === 'string' ? { name: s, autoCall: false } : { name: s?.name, autoCall: s?.autoCall === true },
|
|
346
332
|
)
|
|
347
333
|
.filter((s: any) => Boolean(s.name));
|
|
348
334
|
const employeeSkillMap = new Map<string, any>(employeeSkills.map((s: any) => [s.name, s]));
|
|
@@ -354,11 +340,7 @@ export class AgentHarness {
|
|
|
354
340
|
if (!entryName) continue;
|
|
355
341
|
const employeeSkill = employeeSkillMap.get(entryName);
|
|
356
342
|
|
|
357
|
-
if (
|
|
358
|
-
!employeeSkill ||
|
|
359
|
-
employeeSkill.autoCall !== true ||
|
|
360
|
-
toolEntry.defaultPermission !== 'ALLOW'
|
|
361
|
-
) {
|
|
343
|
+
if (!employeeSkill || employeeSkill.autoCall !== true || toolEntry.defaultPermission !== 'ALLOW') {
|
|
362
344
|
continue;
|
|
363
345
|
}
|
|
364
346
|
|
|
@@ -456,14 +438,14 @@ export class AgentHarness {
|
|
|
456
438
|
throw e;
|
|
457
439
|
}
|
|
458
440
|
},
|
|
459
|
-
})
|
|
441
|
+
}),
|
|
460
442
|
);
|
|
461
443
|
}
|
|
462
444
|
|
|
463
445
|
const abortController = new AbortController();
|
|
464
446
|
const executor = createReactAgent({
|
|
465
447
|
llm: chatModel,
|
|
466
|
-
tools: langchainTools,
|
|
448
|
+
tools: langchainTools as any,
|
|
467
449
|
});
|
|
468
450
|
|
|
469
451
|
let systemPrompt =
|
|
@@ -480,20 +462,31 @@ export class AgentHarness {
|
|
|
480
462
|
ctx.action?.params?.values?.sessionId || ctx.action?.params?.sessionId || ctx.state?.sessionId;
|
|
481
463
|
const contextSummary = await kbPlugin.sessionContext.buildSummary(
|
|
482
464
|
{ rootRunId, ...(sessionId ? { sessionId } : {}) },
|
|
483
|
-
6000
|
|
465
|
+
6000,
|
|
484
466
|
);
|
|
485
467
|
if (contextSummary) {
|
|
486
468
|
systemPrompt += `\n\n<shared_context>\nThe following context was shared by other agents in this workflow:\n${contextSummary}\n</shared_context>`;
|
|
487
469
|
}
|
|
488
470
|
}
|
|
489
|
-
} catch {
|
|
471
|
+
} catch (e) {
|
|
472
|
+
// ignore — kb integration is best-effort
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// ── Step context enrichment ────────────────────────────────────
|
|
476
|
+
if (agentLoopRunId) {
|
|
477
|
+
try {
|
|
478
|
+
systemPrompt = await this.contextAggregator.enrichSystemPrompt(systemPrompt, agentLoopRunId, agentLoopStepId);
|
|
479
|
+
} catch {
|
|
480
|
+
// Best-effort: context enrichment failure should not break execution
|
|
481
|
+
}
|
|
482
|
+
}
|
|
490
483
|
|
|
491
484
|
const combinedTask = context ? `Task: ${task}\n\nContext:\n${context}` : `Task: ${task}`;
|
|
492
485
|
const effectiveLimit = recursionLimit && recursionLimit > 0 ? recursionLimit : 50;
|
|
493
486
|
|
|
494
487
|
let timeoutId: any;
|
|
495
488
|
const timeoutMs = Number(timeout) > 0 ? Number(timeout) : 120000;
|
|
496
|
-
const timeoutPromise = new Promise<never>((
|
|
489
|
+
const timeoutPromise = new Promise<never>((_resolve, reject) => {
|
|
497
490
|
timeoutId = setTimeout(() => {
|
|
498
491
|
abortController.abort();
|
|
499
492
|
reject(new Error(`Sub-agent execution timed out after ${timeoutMs}ms.`));
|
|
@@ -502,9 +495,9 @@ export class AgentHarness {
|
|
|
502
495
|
|
|
503
496
|
const invokePromise = executor.invoke(
|
|
504
497
|
{
|
|
505
|
-
messages: [new SystemMessage(systemPrompt), new HumanMessage(combinedTask)],
|
|
498
|
+
messages: [new SystemMessage(systemPrompt), new HumanMessage(combinedTask)] as any,
|
|
506
499
|
},
|
|
507
|
-
{ recursionLimit: effectiveLimit, signal: abortController.signal }
|
|
500
|
+
{ recursionLimit: effectiveLimit, signal: abortController.signal },
|
|
508
501
|
);
|
|
509
502
|
|
|
510
503
|
let finalState: any;
|
|
@@ -514,15 +507,22 @@ export class AgentHarness {
|
|
|
514
507
|
if (timeoutId) clearTimeout(timeoutId);
|
|
515
508
|
}
|
|
516
509
|
|
|
510
|
+
// ── Token tracking ────────────────────────────────────────────────
|
|
511
|
+
const tokenUsage = extractTokenUsage(finalState);
|
|
512
|
+
if (tokenUsage) {
|
|
513
|
+
await this.tokenTracker.trackSpan(executionSpanId, tokenUsage, agentLoopRunId);
|
|
514
|
+
}
|
|
515
|
+
|
|
517
516
|
const messages = finalState?.messages || [];
|
|
518
517
|
const lastAIMessage = [...messages].reverse().find((m) => m.getType() === 'ai');
|
|
519
518
|
let content = '';
|
|
520
519
|
if (lastAIMessage) {
|
|
521
|
-
content =
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
520
|
+
content =
|
|
521
|
+
typeof lastAIMessage.content === 'string'
|
|
522
|
+
? lastAIMessage.content
|
|
523
|
+
: Array.isArray(lastAIMessage.content)
|
|
524
|
+
? lastAIMessage.content.map((c: any) => c.text || JSON.stringify(c)).join('\n')
|
|
525
|
+
: String(lastAIMessage.content);
|
|
526
526
|
}
|
|
527
527
|
|
|
528
528
|
trace.push({
|
|
@@ -618,46 +618,8 @@ export class AgentHarness {
|
|
|
618
618
|
durationMs: number;
|
|
619
619
|
error?: string;
|
|
620
620
|
trace?: TraceEvent[];
|
|
621
|
-
}
|
|
621
|
+
},
|
|
622
622
|
) {
|
|
623
|
-
|
|
624
|
-
const logsRepo = this.db.getRepository('orchestratorLogs');
|
|
625
|
-
if (!logsRepo) return null;
|
|
626
|
-
|
|
627
|
-
const userId = ctx?.auth?.user?.id || ctx?.state?.currentUser?.id;
|
|
628
|
-
const values = {
|
|
629
|
-
leaderUsername: data.leaderUsername,
|
|
630
|
-
subAgentUsername: data.subAgentUsername,
|
|
631
|
-
toolName: data.toolName,
|
|
632
|
-
task: trimText(data.task, 10000),
|
|
633
|
-
context: trimText(data.context || '', 10000),
|
|
634
|
-
result: trimText(data.result || '', 50000),
|
|
635
|
-
status: data.status,
|
|
636
|
-
depth: data.depth,
|
|
637
|
-
durationMs: data.durationMs,
|
|
638
|
-
error: trimText(data.error || '', 10000),
|
|
639
|
-
trace: data.trace || [],
|
|
640
|
-
userId,
|
|
641
|
-
updatedAt: new Date(),
|
|
642
|
-
};
|
|
643
|
-
|
|
644
|
-
if (data.id) {
|
|
645
|
-
await logsRepo.update({
|
|
646
|
-
filterByTk: data.id,
|
|
647
|
-
values,
|
|
648
|
-
});
|
|
649
|
-
return { id: data.id };
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
const record = await logsRepo.create({
|
|
653
|
-
values: {
|
|
654
|
-
...values,
|
|
655
|
-
createdAt: new Date(),
|
|
656
|
-
},
|
|
657
|
-
});
|
|
658
|
-
return toPlain(record);
|
|
659
|
-
} catch {
|
|
660
|
-
return null;
|
|
661
|
-
}
|
|
623
|
+
return sharedLogDelegation(ctx, this.plugin, data);
|
|
662
624
|
}
|
|
663
625
|
}
|