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
|
@@ -35,6 +35,7 @@ var import_AgentPlanValidator = require("./AgentPlanValidator");
|
|
|
35
35
|
var import_AgentLoopRepository = require("./AgentLoopRepository");
|
|
36
36
|
var import_AgentHarness = require("./AgentHarness");
|
|
37
37
|
var import_AgentLoopController = require("./AgentLoopController");
|
|
38
|
+
var import_TokenTracker = require("./TokenTracker");
|
|
38
39
|
class AgentLoopService {
|
|
39
40
|
constructor(plugin) {
|
|
40
41
|
this.plugin = plugin;
|
|
@@ -43,12 +44,14 @@ class AgentLoopService {
|
|
|
43
44
|
this.validator = new import_AgentPlanValidator.AgentPlanValidator();
|
|
44
45
|
this.repository = new import_AgentLoopRepository.AgentLoopRepository(plugin);
|
|
45
46
|
this.harness = new import_AgentHarness.AgentHarness(plugin, this.registryService);
|
|
47
|
+
const tokenTracker = new import_TokenTracker.TokenTracker(plugin);
|
|
46
48
|
this.controller = new import_AgentLoopController.AgentLoopController(
|
|
47
49
|
this.registryService,
|
|
48
50
|
this.plannerService,
|
|
49
51
|
this.validator,
|
|
50
52
|
this.repository,
|
|
51
|
-
this.harness
|
|
53
|
+
this.harness,
|
|
54
|
+
tokenTracker
|
|
52
55
|
);
|
|
53
56
|
}
|
|
54
57
|
registryService;
|
|
@@ -108,6 +111,9 @@ class AgentLoopService {
|
|
|
108
111
|
async retryStep(stepId, options = {}) {
|
|
109
112
|
return this.controller.retryStep(stepId, options);
|
|
110
113
|
}
|
|
114
|
+
async stepFeedback(stepId, feedback, options = {}) {
|
|
115
|
+
return this.controller.stepFeedback(stepId, feedback, options);
|
|
116
|
+
}
|
|
111
117
|
async finishRun(runId, finalAnswer, options = {}) {
|
|
112
118
|
return this.controller.finishRun(runId, finalAnswer, options);
|
|
113
119
|
}
|
|
@@ -29,27 +29,7 @@ __export(AgentPlannerService_exports, {
|
|
|
29
29
|
AgentPlannerService: () => AgentPlannerService
|
|
30
30
|
});
|
|
31
31
|
module.exports = __toCommonJS(AgentPlannerService_exports);
|
|
32
|
-
|
|
33
|
-
return ["reasoning", "skill", "tool", "sub_agent", "verification"].includes(value) ? value : "tool";
|
|
34
|
-
}
|
|
35
|
-
function normalizePlanKey(step, index) {
|
|
36
|
-
return String(step.planKey || step.key || step.id || `step_${index + 1}`);
|
|
37
|
-
}
|
|
38
|
-
function asArray(value) {
|
|
39
|
-
return Array.isArray(value) ? value : [];
|
|
40
|
-
}
|
|
41
|
-
function asObject(value) {
|
|
42
|
-
if (value && typeof value === "object" && !Array.isArray(value)) return value;
|
|
43
|
-
if (typeof value === "string" && value.trim()) {
|
|
44
|
-
try {
|
|
45
|
-
const parsed = JSON.parse(value);
|
|
46
|
-
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
47
|
-
} catch {
|
|
48
|
-
return {};
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
return {};
|
|
52
|
-
}
|
|
32
|
+
var import_ctx_utils = require("../utils/ctx-utils");
|
|
53
33
|
class AgentPlannerService {
|
|
54
34
|
buildPlan(goal, plan, options) {
|
|
55
35
|
var _a;
|
|
@@ -58,11 +38,11 @@ class AgentPlannerService {
|
|
|
58
38
|
var _a2;
|
|
59
39
|
return {
|
|
60
40
|
...step,
|
|
61
|
-
planKey: normalizePlanKey(step, index),
|
|
62
|
-
type: normalizeStepType(step.type),
|
|
63
|
-
dependsOn: asArray(step.dependsOn).map(String),
|
|
41
|
+
planKey: (0, import_ctx_utils.normalizePlanKey)(step, index),
|
|
42
|
+
type: (0, import_ctx_utils.normalizeStepType)(step.type),
|
|
43
|
+
dependsOn: (0, import_ctx_utils.asArray)(step.dependsOn).map(String),
|
|
64
44
|
metadata: {
|
|
65
|
-
...asObject(step.metadata),
|
|
45
|
+
...(0, import_ctx_utils.asObject)(step.metadata),
|
|
66
46
|
harnessTag: options.harnessTag || ((_a2 = options.metadata) == null ? void 0 : _a2.harnessTag) || "default"
|
|
67
47
|
}
|
|
68
48
|
};
|
|
@@ -29,27 +29,7 @@ __export(AgentRegistryService_exports, {
|
|
|
29
29
|
AgentRegistryService: () => AgentRegistryService
|
|
30
30
|
});
|
|
31
31
|
module.exports = __toCommonJS(AgentRegistryService_exports);
|
|
32
|
-
|
|
33
|
-
var _a;
|
|
34
|
-
return ((_a = record == null ? void 0 : record.toJSON) == null ? void 0 : _a.call(record)) || record;
|
|
35
|
-
}
|
|
36
|
-
function asObject(value) {
|
|
37
|
-
if (value && typeof value === "object" && !Array.isArray(value)) return value;
|
|
38
|
-
if (typeof value === "string" && value.trim()) {
|
|
39
|
-
try {
|
|
40
|
-
const parsed = JSON.parse(value);
|
|
41
|
-
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
42
|
-
} catch {
|
|
43
|
-
return {};
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return {};
|
|
47
|
-
}
|
|
48
|
-
function normalizeEmployeeUsername(raw) {
|
|
49
|
-
if (!raw) return null;
|
|
50
|
-
if (typeof raw === "string") return raw;
|
|
51
|
-
return raw.username || raw.aiEmployeeUsername || raw.name || null;
|
|
52
|
-
}
|
|
32
|
+
var import_ctx_utils = require("../utils/ctx-utils");
|
|
53
33
|
class AgentRegistryService {
|
|
54
34
|
constructor(plugin) {
|
|
55
35
|
this.plugin = plugin;
|
|
@@ -67,7 +47,7 @@ class AgentRegistryService {
|
|
|
67
47
|
enabled: true
|
|
68
48
|
}
|
|
69
49
|
});
|
|
70
|
-
return profile ? toPlain(profile) : null;
|
|
50
|
+
return profile ? (0, import_ctx_utils.toPlain)(profile) : null;
|
|
71
51
|
} catch {
|
|
72
52
|
return null;
|
|
73
53
|
}
|
|
@@ -83,7 +63,7 @@ class AgentRegistryService {
|
|
|
83
63
|
enabled: true
|
|
84
64
|
}
|
|
85
65
|
});
|
|
86
|
-
return config ? toPlain(config) : null;
|
|
66
|
+
return config ? (0, import_ctx_utils.toPlain)(config) : null;
|
|
87
67
|
} catch {
|
|
88
68
|
return null;
|
|
89
69
|
}
|
|
@@ -95,7 +75,7 @@ class AgentRegistryService {
|
|
|
95
75
|
const employee = await repo.findOne({
|
|
96
76
|
filter: { username }
|
|
97
77
|
});
|
|
98
|
-
return employee ? toPlain(employee) : null;
|
|
78
|
+
return employee ? (0, import_ctx_utils.toPlain)(employee) : null;
|
|
99
79
|
} catch {
|
|
100
80
|
return null;
|
|
101
81
|
}
|
|
@@ -122,6 +102,36 @@ class AgentRegistryService {
|
|
|
122
102
|
}
|
|
123
103
|
return modelSettings;
|
|
124
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Find alternative sub-agents for the same leader, excluding a specific one.
|
|
107
|
+
* Used by the smart retry feature to route around a failing sub-agent.
|
|
108
|
+
*/
|
|
109
|
+
async findAlternativeSubAgents(leaderUsername, excludeSubAgentUsername) {
|
|
110
|
+
try {
|
|
111
|
+
const repo = this.db.getRepository("orchestratorConfig");
|
|
112
|
+
if (!repo) return [];
|
|
113
|
+
const configs = await repo.find({
|
|
114
|
+
filter: {
|
|
115
|
+
leaderUsername,
|
|
116
|
+
enabled: true,
|
|
117
|
+
subAgentUsername: { $ne: excludeSubAgentUsername }
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
if (!configs || configs.length === 0) return [];
|
|
121
|
+
const result = [];
|
|
122
|
+
for (const config of configs) {
|
|
123
|
+
const plain = (0, import_ctx_utils.toPlain)(config);
|
|
124
|
+
const employee = await this.getAIEmployee(plain.subAgentUsername);
|
|
125
|
+
result.push({
|
|
126
|
+
username: plain.subAgentUsername,
|
|
127
|
+
label: (employee == null ? void 0 : employee.nickname) || (employee == null ? void 0 : employee.username) || plain.subAgentUsername
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
return result;
|
|
131
|
+
} catch {
|
|
132
|
+
return [];
|
|
133
|
+
}
|
|
134
|
+
}
|
|
125
135
|
async isRegisteredDelegationTool(toolName) {
|
|
126
136
|
if (!toolName || typeof toolName !== "string") return false;
|
|
127
137
|
if (!toolName.startsWith("delegate_") && !toolName.startsWith("dispatch_subagents_")) {
|
|
@@ -0,0 +1,120 @@
|
|
|
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 CircuitBreaker_exports = {};
|
|
28
|
+
__export(CircuitBreaker_exports, {
|
|
29
|
+
CircuitBreakerRegistry: () => CircuitBreakerRegistry,
|
|
30
|
+
getCircuitBreaker: () => getCircuitBreaker
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(CircuitBreaker_exports);
|
|
33
|
+
class CircuitBreakerRegistry {
|
|
34
|
+
circuits = /* @__PURE__ */ new Map();
|
|
35
|
+
threshold;
|
|
36
|
+
recoveryTimeout;
|
|
37
|
+
halfOpenMaxRequests;
|
|
38
|
+
appLog;
|
|
39
|
+
constructor(options) {
|
|
40
|
+
this.threshold = (options == null ? void 0 : options.threshold) ?? 3;
|
|
41
|
+
this.recoveryTimeout = (options == null ? void 0 : options.recoveryTimeout) ?? 3e4;
|
|
42
|
+
this.halfOpenMaxRequests = (options == null ? void 0 : options.halfOpenMaxRequests) ?? 1;
|
|
43
|
+
this.appLog = options == null ? void 0 : options.appLog;
|
|
44
|
+
}
|
|
45
|
+
getOrCreate(key) {
|
|
46
|
+
let state = this.circuits.get(key);
|
|
47
|
+
if (!state) {
|
|
48
|
+
state = { failures: 0, lastFailureTime: 0, state: "closed" };
|
|
49
|
+
this.circuits.set(key, state);
|
|
50
|
+
}
|
|
51
|
+
return state;
|
|
52
|
+
}
|
|
53
|
+
recordSuccess(key) {
|
|
54
|
+
var _a, _b;
|
|
55
|
+
const state = this.getOrCreate(key);
|
|
56
|
+
if (state.state === "half-open") {
|
|
57
|
+
state.state = "closed";
|
|
58
|
+
state.failures = 0;
|
|
59
|
+
(_b = (_a = this.appLog) == null ? void 0 : _a.debug) == null ? void 0 : _b.call(_a, `[CircuitBreaker] "${key}" recovered \u2192 closed`);
|
|
60
|
+
} else if (state.state === "closed" && state.failures > 0) {
|
|
61
|
+
state.failures = Math.max(0, state.failures - 1);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
recordFailure(key) {
|
|
65
|
+
var _a, _b, _c, _d;
|
|
66
|
+
const state = this.getOrCreate(key);
|
|
67
|
+
state.failures += 1;
|
|
68
|
+
state.lastFailureTime = Date.now();
|
|
69
|
+
if (state.state === "half-open") {
|
|
70
|
+
state.state = "open";
|
|
71
|
+
(_b = (_a = this.appLog) == null ? void 0 : _a.warn) == null ? void 0 : _b.call(_a, `[CircuitBreaker] "${key}" half-open probe failed \u2192 open`);
|
|
72
|
+
} else if (state.state === "closed" && state.failures >= this.threshold) {
|
|
73
|
+
state.state = "open";
|
|
74
|
+
(_d = (_c = this.appLog) == null ? void 0 : _c.warn) == null ? void 0 : _d.call(_c, `[CircuitBreaker] "${key}" opened after ${state.failures} failures`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
isAllowed(key) {
|
|
78
|
+
var _a, _b;
|
|
79
|
+
const state = this.getOrCreate(key);
|
|
80
|
+
if (state.state === "closed") return true;
|
|
81
|
+
if (state.state === "open") {
|
|
82
|
+
const elapsed = Date.now() - state.lastFailureTime;
|
|
83
|
+
if (elapsed >= this.recoveryTimeout) {
|
|
84
|
+
state.state = "half-open";
|
|
85
|
+
(_b = (_a = this.appLog) == null ? void 0 : _a.debug) == null ? void 0 : _b.call(_a, `[CircuitBreaker] "${key}" open timeout elapsed \u2192 half-open`);
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
return this.halfOpenMaxRequests > 0;
|
|
91
|
+
}
|
|
92
|
+
getState(key) {
|
|
93
|
+
return this.circuits.get(key) ?? null;
|
|
94
|
+
}
|
|
95
|
+
/** Reset a circuit back to closed state. */
|
|
96
|
+
reset(key) {
|
|
97
|
+
const state = this.circuits.get(key);
|
|
98
|
+
if (state) {
|
|
99
|
+
state.state = "closed";
|
|
100
|
+
state.failures = 0;
|
|
101
|
+
state.lastFailureTime = 0;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/** Get all circuit state keys (for monitoring/diagnostics). */
|
|
105
|
+
getKeys() {
|
|
106
|
+
return Array.from(this.circuits.keys());
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
let globalInstance = null;
|
|
110
|
+
function getCircuitBreaker(options) {
|
|
111
|
+
if (!globalInstance) {
|
|
112
|
+
globalInstance = new CircuitBreakerRegistry(options);
|
|
113
|
+
}
|
|
114
|
+
return globalInstance;
|
|
115
|
+
}
|
|
116
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
117
|
+
0 && (module.exports = {
|
|
118
|
+
CircuitBreakerRegistry,
|
|
119
|
+
getCircuitBreaker
|
|
120
|
+
});
|
|
@@ -0,0 +1,201 @@
|
|
|
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 ContextAggregator_exports = {};
|
|
28
|
+
__export(ContextAggregator_exports, {
|
|
29
|
+
ContextAggregator: () => ContextAggregator
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(ContextAggregator_exports);
|
|
32
|
+
function trimText(text, maxLen) {
|
|
33
|
+
if (text.length <= maxLen) return text;
|
|
34
|
+
return text.slice(0, maxLen) + "\n...[truncated]";
|
|
35
|
+
}
|
|
36
|
+
function estimateTokens(text) {
|
|
37
|
+
return Math.ceil(text.length / 4);
|
|
38
|
+
}
|
|
39
|
+
class ContextAggregator {
|
|
40
|
+
constructor(plugin) {
|
|
41
|
+
this.plugin = plugin;
|
|
42
|
+
}
|
|
43
|
+
get db() {
|
|
44
|
+
return this.plugin.db;
|
|
45
|
+
}
|
|
46
|
+
get app() {
|
|
47
|
+
return this.plugin.app;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Build a structured context string from completed steps of a run.
|
|
51
|
+
*
|
|
52
|
+
* @param runId - agentLoopRuns.id
|
|
53
|
+
* @param maxTokens - Maximum tokens for the context output (default 4000)
|
|
54
|
+
* @param options - Strategy options
|
|
55
|
+
*/
|
|
56
|
+
async buildStepContext(runId, maxTokens, options) {
|
|
57
|
+
var _a;
|
|
58
|
+
const effectiveMaxTokens = maxTokens || 4e3;
|
|
59
|
+
let steps;
|
|
60
|
+
try {
|
|
61
|
+
const repo = this.db.getRepository("agentLoopSteps");
|
|
62
|
+
if (!repo) return "";
|
|
63
|
+
steps = await repo.find({
|
|
64
|
+
filter: { runId },
|
|
65
|
+
sort: ["index", "createdAt"],
|
|
66
|
+
pageSize: 500
|
|
67
|
+
});
|
|
68
|
+
} catch {
|
|
69
|
+
return "";
|
|
70
|
+
}
|
|
71
|
+
if (!steps || steps.length === 0) return "";
|
|
72
|
+
const completedSteps = steps.filter((s) => s.status === "succeeded" || s.status === "failed");
|
|
73
|
+
if (completedSteps.length === 0) return "";
|
|
74
|
+
const config = {
|
|
75
|
+
strategy: (options == null ? void 0 : options.strategy) || "all",
|
|
76
|
+
includeToolResults: (options == null ? void 0 : options.includeToolResults) ?? false,
|
|
77
|
+
includeStepOutputs: (options == null ? void 0 : options.includeStepOutputs) ?? true
|
|
78
|
+
};
|
|
79
|
+
let candidates = completedSteps;
|
|
80
|
+
if (config.strategy === "last_n") {
|
|
81
|
+
const n = Math.min(10, completedSteps.length);
|
|
82
|
+
candidates = completedSteps.slice(-n);
|
|
83
|
+
}
|
|
84
|
+
const parts = [];
|
|
85
|
+
for (const step of candidates) {
|
|
86
|
+
const key = step.planKey || `step_${step.index || 0}`;
|
|
87
|
+
const type = step.type || "unknown";
|
|
88
|
+
const target = step.target || "";
|
|
89
|
+
const title = step.title || key;
|
|
90
|
+
const status = step.status || "unknown";
|
|
91
|
+
const lines = [];
|
|
92
|
+
lines.push(`<step key="${key}" type="${type}" target="${target}" status="${status}">`);
|
|
93
|
+
lines.push(` <title>${this.escapeXml(title)}</title>`);
|
|
94
|
+
if (step.description) {
|
|
95
|
+
lines.push(` <description>${this.escapeXml(trimText(step.description, 500))}</description>`);
|
|
96
|
+
}
|
|
97
|
+
if (config.includeStepOutputs && step.output) {
|
|
98
|
+
const outputStr = typeof step.output === "string" ? step.output : this.safeStringify(step.output);
|
|
99
|
+
lines.push(` <output>${this.escapeXml(trimText(outputStr, 2e3))}</output>`);
|
|
100
|
+
}
|
|
101
|
+
if (config.includeToolResults && ((_a = step.metadata) == null ? void 0 : _a.toolResults)) {
|
|
102
|
+
const toolStr = this.safeStringify(step.metadata.toolResults);
|
|
103
|
+
lines.push(` <tool_results>${this.escapeXml(trimText(toolStr, 1500))}</tool_results>`);
|
|
104
|
+
}
|
|
105
|
+
if (step.error) {
|
|
106
|
+
lines.push(` <error>${this.escapeXml(trimText(step.error, 1e3))}</error>`);
|
|
107
|
+
}
|
|
108
|
+
lines.push("</step>");
|
|
109
|
+
parts.push(lines.join("\n"));
|
|
110
|
+
}
|
|
111
|
+
let context = `<previous_steps>
|
|
112
|
+
${parts.join("\n\n")}
|
|
113
|
+
</previous_steps>`;
|
|
114
|
+
if (estimateTokens(context) > effectiveMaxTokens) {
|
|
115
|
+
context = this.truncateToTokenLimit(context, effectiveMaxTokens);
|
|
116
|
+
}
|
|
117
|
+
return context;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Enrich a base system prompt with step context from the run.
|
|
121
|
+
* Fetches the run from DB to access policy settings (maxContextTokens, etc.).
|
|
122
|
+
*
|
|
123
|
+
* @param basePrompt - The original system prompt to enrich
|
|
124
|
+
* @param runId - agentLoopRuns.id
|
|
125
|
+
* @param _stepId - agentLoopSteps.id (reserved for future per-step context)
|
|
126
|
+
*/
|
|
127
|
+
async enrichSystemPrompt(basePrompt, runId, _stepId, options) {
|
|
128
|
+
let run;
|
|
129
|
+
try {
|
|
130
|
+
const repo = this.db.getRepository("agentLoopRuns");
|
|
131
|
+
if (!repo) return basePrompt;
|
|
132
|
+
run = await repo.findOne({ filter: { id: runId } });
|
|
133
|
+
if (!run) return basePrompt;
|
|
134
|
+
} catch {
|
|
135
|
+
return basePrompt;
|
|
136
|
+
}
|
|
137
|
+
const policy = run.policy || {};
|
|
138
|
+
const maxCtxTokens = (options == null ? void 0 : options.maxContextTokens) ?? policy.maxContextTokens ?? 4e3;
|
|
139
|
+
const strategy = (options == null ? void 0 : options.contextSummaryStrategy) ?? policy.contextSummaryStrategy ?? "all";
|
|
140
|
+
const includeToolResults = (options == null ? void 0 : options.includeToolResults) ?? policy.includeToolResults ?? false;
|
|
141
|
+
const includeStepOutputs = (options == null ? void 0 : options.includeStepOutputs) ?? policy.includeStepOutputs ?? true;
|
|
142
|
+
const stepContext = await this.buildStepContext(runId, maxCtxTokens, {
|
|
143
|
+
strategy,
|
|
144
|
+
includeToolResults,
|
|
145
|
+
includeStepOutputs
|
|
146
|
+
});
|
|
147
|
+
if (!stepContext) return basePrompt;
|
|
148
|
+
return `${basePrompt}
|
|
149
|
+
|
|
150
|
+
<previous_steps_context>
|
|
151
|
+
${stepContext}
|
|
152
|
+
</previous_steps_context>`;
|
|
153
|
+
}
|
|
154
|
+
truncateToTokenLimit(text, maxTokens) {
|
|
155
|
+
const outerMatch = text.match(/<previous_steps>\n([\s\S]*)\n<\/previous_steps>/);
|
|
156
|
+
if (!outerMatch) return text;
|
|
157
|
+
const inner = outerMatch[1];
|
|
158
|
+
const stepBlocks = this.splitStepBlocks(inner);
|
|
159
|
+
if (stepBlocks.length <= 2) {
|
|
160
|
+
const maxChars2 = maxTokens * 4;
|
|
161
|
+
if (text.length <= maxChars2) return text;
|
|
162
|
+
return text.slice(0, maxChars2) + "\n...[truncated]\n</previous_steps>";
|
|
163
|
+
}
|
|
164
|
+
const keepFirst = stepBlocks.slice(0, 2);
|
|
165
|
+
const keepLast = stepBlocks.slice(-2);
|
|
166
|
+
const removed = stepBlocks.length - keepFirst.length - keepLast.length;
|
|
167
|
+
const rebuilt = [
|
|
168
|
+
"<previous_steps>",
|
|
169
|
+
...keepFirst,
|
|
170
|
+
` <!-- ... ${removed} intermediate step(s) omitted due to context limit ... -->`,
|
|
171
|
+
...keepLast,
|
|
172
|
+
"</previous_steps>"
|
|
173
|
+
].join("\n");
|
|
174
|
+
const maxChars = maxTokens * 4;
|
|
175
|
+
if (rebuilt.length <= maxChars) return rebuilt;
|
|
176
|
+
return rebuilt.slice(0, maxChars) + "\n...[truncated]\n</previous_steps>";
|
|
177
|
+
}
|
|
178
|
+
splitStepBlocks(text) {
|
|
179
|
+
const blocks = [];
|
|
180
|
+
const regex = /<step[\s\S]*?<\/step>/g;
|
|
181
|
+
let match;
|
|
182
|
+
while ((match = regex.exec(text)) !== null) {
|
|
183
|
+
blocks.push(match[0]);
|
|
184
|
+
}
|
|
185
|
+
return blocks;
|
|
186
|
+
}
|
|
187
|
+
escapeXml(value) {
|
|
188
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
189
|
+
}
|
|
190
|
+
safeStringify(value) {
|
|
191
|
+
try {
|
|
192
|
+
return JSON.stringify(value, null, 2);
|
|
193
|
+
} catch {
|
|
194
|
+
return String(value);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
199
|
+
0 && (module.exports = {
|
|
200
|
+
ContextAggregator
|
|
201
|
+
});
|
|
@@ -32,11 +32,8 @@ __export(ExecutionSpanService_exports, {
|
|
|
32
32
|
setOrchestratorTraceContext: () => setOrchestratorTraceContext
|
|
33
33
|
});
|
|
34
34
|
module.exports = __toCommonJS(ExecutionSpanService_exports);
|
|
35
|
+
var import_ctx_utils = require("../utils/ctx-utils");
|
|
35
36
|
const ORCHESTRATOR_TRACE_CONTEXT_KEY = "__orchestratorTraceContext";
|
|
36
|
-
function toPlain(record) {
|
|
37
|
-
var _a;
|
|
38
|
-
return ((_a = record == null ? void 0 : record.toJSON) == null ? void 0 : _a.call(record)) || record;
|
|
39
|
-
}
|
|
40
37
|
class ExecutionSpanService {
|
|
41
38
|
constructor(plugin) {
|
|
42
39
|
this.plugin = plugin;
|
|
@@ -53,7 +50,7 @@ class ExecutionSpanService {
|
|
|
53
50
|
createdAt: /* @__PURE__ */ new Date()
|
|
54
51
|
}
|
|
55
52
|
});
|
|
56
|
-
return toPlain(record);
|
|
53
|
+
return (0, import_ctx_utils.toPlain)(record);
|
|
57
54
|
} catch (error) {
|
|
58
55
|
(_b = (_a = this.plugin.app.log) == null ? void 0 : _a.warn) == null ? void 0 : _b.call(_a, "[AgentOrchestrator] Failed to create execution span", error);
|
|
59
56
|
return null;
|
|
@@ -0,0 +1,73 @@
|
|
|
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 RunEventBus_exports = {};
|
|
28
|
+
__export(RunEventBus_exports, {
|
|
29
|
+
getRunEventBus: () => getRunEventBus
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(RunEventBus_exports);
|
|
32
|
+
class RunEventBusImpl {
|
|
33
|
+
listeners = /* @__PURE__ */ new Map();
|
|
34
|
+
subscribe(runId, callback) {
|
|
35
|
+
let set = this.listeners.get(runId);
|
|
36
|
+
if (!set) {
|
|
37
|
+
set = /* @__PURE__ */ new Set();
|
|
38
|
+
this.listeners.set(runId, set);
|
|
39
|
+
}
|
|
40
|
+
set.add(callback);
|
|
41
|
+
return () => {
|
|
42
|
+
set == null ? void 0 : set.delete(callback);
|
|
43
|
+
if ((set == null ? void 0 : set.size) === 0) {
|
|
44
|
+
this.listeners.delete(runId);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
emit(runId, event) {
|
|
49
|
+
const set = this.listeners.get(runId);
|
|
50
|
+
if (!set) return;
|
|
51
|
+
for (const callback of set) {
|
|
52
|
+
try {
|
|
53
|
+
callback(event);
|
|
54
|
+
} catch {
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
listenerCount(runId) {
|
|
59
|
+
var _a;
|
|
60
|
+
return ((_a = this.listeners.get(runId)) == null ? void 0 : _a.size) || 0;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
let instance = null;
|
|
64
|
+
function getRunEventBus() {
|
|
65
|
+
if (!instance) {
|
|
66
|
+
instance = new RunEventBusImpl();
|
|
67
|
+
}
|
|
68
|
+
return instance;
|
|
69
|
+
}
|
|
70
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
71
|
+
0 && (module.exports = {
|
|
72
|
+
getRunEventBus
|
|
73
|
+
});
|