plugin-agent-orchestrator 1.0.20 → 1.0.21
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/hooks/useRunEventStream.d.ts +22 -0
- package/dist/client/index.d.ts +1 -0
- 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.d.ts +7 -0
- package/dist/server/migrations/20260601000000-add-token-fields.js +101 -0
- package/dist/server/plugin.js +47 -0
- package/dist/server/resources/agent-loop.js +33 -25
- package/dist/server/resources/tracing.js +5 -8
- package/dist/server/services/AgentHarness.d.ts +2 -0
- package/dist/server/services/AgentHarness.js +56 -90
- package/dist/server/services/AgentLoopController.d.ts +33 -20
- package/dist/server/services/AgentLoopController.js +164 -125
- package/dist/server/services/AgentLoopRepository.js +16 -34
- package/dist/server/services/AgentLoopService.d.ts +28 -18
- package/dist/server/services/AgentLoopService.js +7 -1
- package/dist/server/services/AgentPlannerService.js +5 -25
- package/dist/server/services/AgentRegistryService.d.ts +8 -0
- package/dist/server/services/AgentRegistryService.js +34 -24
- package/dist/server/services/CircuitBreaker.d.ts +40 -0
- package/dist/server/services/CircuitBreaker.js +120 -0
- package/dist/server/services/ContextAggregator.d.ts +45 -0
- package/dist/server/services/ContextAggregator.js +201 -0
- package/dist/server/services/ExecutionSpanService.js +2 -5
- package/dist/server/services/RunEventBus.d.ts +9 -0
- package/dist/server/services/RunEventBus.js +73 -0
- package/dist/server/services/TokenTracker.d.ts +62 -0
- package/dist/server/services/TokenTracker.js +173 -0
- package/dist/server/tools/agent-loop.d.ts +8 -8
- package/dist/server/tools/agent-loop.js +30 -63
- package/dist/server/tools/delegate-task.js +14 -72
- package/dist/server/tools/orchestrator-plan.d.ts +6 -6
- package/dist/server/tools/orchestrator-plan.js +10 -47
- package/dist/server/types.d.ts +47 -0
- package/dist/server/types.js +24 -0
- package/dist/server/utils/ctx-utils.d.ts +30 -0
- package/dist/server/utils/ctx-utils.js +152 -0
- package/dist/server/utils/logging.d.ts +6 -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 +53 -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
|
@@ -14,6 +14,11 @@ export type AgentLoopPolicy = {
|
|
|
14
14
|
allowReplan: boolean;
|
|
15
15
|
requireVerification: boolean;
|
|
16
16
|
stopOnApprovalRequired: boolean;
|
|
17
|
+
maxContextTokens?: number;
|
|
18
|
+
contextSummaryStrategy?: 'last_n' | 'all';
|
|
19
|
+
includeToolResults?: boolean;
|
|
20
|
+
includeStepOutputs?: boolean;
|
|
21
|
+
maxConcurrency?: number;
|
|
17
22
|
};
|
|
18
23
|
export type AgentLoopPlanStepInput = {
|
|
19
24
|
id?: string;
|
|
@@ -44,7 +49,7 @@ export declare class AgentLoopService {
|
|
|
44
49
|
createRun(options: any): Promise<{
|
|
45
50
|
run: any;
|
|
46
51
|
steps: any;
|
|
47
|
-
|
|
52
|
+
nextSteps: any[];
|
|
48
53
|
}>;
|
|
49
54
|
planGoal(options: any): Promise<{
|
|
50
55
|
events: any;
|
|
@@ -52,7 +57,7 @@ export declare class AgentLoopService {
|
|
|
52
57
|
skillExecutions: any;
|
|
53
58
|
run: any;
|
|
54
59
|
steps: any;
|
|
55
|
-
|
|
60
|
+
nextSteps: any[];
|
|
56
61
|
}>;
|
|
57
62
|
revisePlanGoal(runId: any, plan: any, options?: any): Promise<{
|
|
58
63
|
events: any;
|
|
@@ -60,17 +65,17 @@ export declare class AgentLoopService {
|
|
|
60
65
|
skillExecutions: any;
|
|
61
66
|
run: any;
|
|
62
67
|
steps: any;
|
|
63
|
-
|
|
68
|
+
nextSteps: any[];
|
|
64
69
|
}>;
|
|
65
70
|
approvePlanAndExecute(runId: any, options?: any): Promise<{
|
|
66
71
|
run: any;
|
|
67
72
|
steps: any;
|
|
68
|
-
|
|
73
|
+
nextSteps: any[];
|
|
69
74
|
}>;
|
|
70
75
|
rejectPlan(runId: any, options?: any): Promise<{
|
|
71
76
|
run: any;
|
|
72
77
|
steps: any;
|
|
73
|
-
|
|
78
|
+
nextSteps: any[];
|
|
74
79
|
}>;
|
|
75
80
|
requestPlanChanges(runId: any, options?: any): Promise<{
|
|
76
81
|
events: any;
|
|
@@ -78,64 +83,69 @@ export declare class AgentLoopService {
|
|
|
78
83
|
skillExecutions: any;
|
|
79
84
|
run: any;
|
|
80
85
|
steps: any;
|
|
81
|
-
|
|
86
|
+
nextSteps: any[];
|
|
82
87
|
}>;
|
|
83
88
|
replacePlan(runId: any, plan: any, options?: any): Promise<any[]>;
|
|
84
89
|
replan(runId: any, plan: any, options?: any): Promise<any[]>;
|
|
85
90
|
startStep(stepId: any, options?: any): Promise<{
|
|
86
91
|
run: any;
|
|
87
92
|
steps: any;
|
|
88
|
-
|
|
93
|
+
nextSteps: any[];
|
|
89
94
|
}>;
|
|
90
95
|
completeStep(stepId: any, output: any, options?: any): Promise<{
|
|
91
96
|
run: any;
|
|
92
97
|
steps: any;
|
|
93
|
-
|
|
98
|
+
nextSteps: any[];
|
|
94
99
|
}>;
|
|
95
100
|
failStep(stepId: any, error: any, options?: any): Promise<{
|
|
96
101
|
run: any;
|
|
97
102
|
steps: any;
|
|
98
|
-
|
|
103
|
+
nextSteps: any[];
|
|
99
104
|
}>;
|
|
100
105
|
skipStep(stepId: any, reason?: any, options?: any): Promise<{
|
|
101
106
|
run: any;
|
|
102
107
|
steps: any;
|
|
103
|
-
|
|
108
|
+
nextSteps: any[];
|
|
104
109
|
}>;
|
|
105
110
|
requestApproval(stepId: any, approval: any, options?: any): Promise<{
|
|
106
111
|
run: any;
|
|
107
112
|
steps: any;
|
|
108
|
-
|
|
113
|
+
nextSteps: any[];
|
|
109
114
|
}>;
|
|
110
115
|
resumeRun(runId: any, options: any): Promise<{
|
|
111
116
|
run: any;
|
|
112
117
|
steps: any;
|
|
113
|
-
|
|
118
|
+
nextSteps: any[];
|
|
114
119
|
}>;
|
|
115
120
|
retryStep(stepId: any, options?: any): Promise<{
|
|
116
121
|
run: any;
|
|
117
122
|
steps: any;
|
|
118
|
-
|
|
123
|
+
nextSteps: any[];
|
|
124
|
+
}>;
|
|
125
|
+
stepFeedback(stepId: any, feedback: any, options?: any): Promise<{
|
|
126
|
+
run: any;
|
|
127
|
+
steps: any;
|
|
128
|
+
nextSteps: any[];
|
|
119
129
|
}>;
|
|
120
130
|
finishRun(runId: any, finalAnswer: any, options?: any): Promise<{
|
|
121
131
|
run: any;
|
|
122
132
|
steps: any;
|
|
123
|
-
|
|
133
|
+
nextSteps: any[];
|
|
124
134
|
}>;
|
|
125
135
|
cancelRun(runId: any, options?: any): Promise<{
|
|
126
136
|
run: any;
|
|
127
137
|
steps: any;
|
|
128
|
-
|
|
138
|
+
nextSteps: any[];
|
|
129
139
|
}>;
|
|
130
140
|
executeApprovedPlan(runId: any, options?: any): Promise<{
|
|
131
141
|
run: any;
|
|
132
142
|
steps: any;
|
|
133
|
-
|
|
143
|
+
nextSteps: any[];
|
|
134
144
|
}>;
|
|
135
145
|
getRunSnapshot(runId: any): Promise<{
|
|
136
146
|
run: any;
|
|
137
147
|
steps: any;
|
|
138
|
-
|
|
148
|
+
nextSteps: any[];
|
|
139
149
|
}>;
|
|
140
150
|
getRunDetail(runId: any): Promise<{
|
|
141
151
|
events: any;
|
|
@@ -143,7 +153,7 @@ export declare class AgentLoopService {
|
|
|
143
153
|
skillExecutions: any;
|
|
144
154
|
run: any;
|
|
145
155
|
steps: any;
|
|
146
|
-
|
|
156
|
+
nextSteps: any[];
|
|
147
157
|
}>;
|
|
148
158
|
createEvent(values: any): Promise<any>;
|
|
149
159
|
}
|
|
@@ -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
|
};
|
|
@@ -9,5 +9,13 @@ export declare class AgentRegistryService {
|
|
|
9
9
|
llmService: string;
|
|
10
10
|
model: string;
|
|
11
11
|
}>;
|
|
12
|
+
/**
|
|
13
|
+
* Find alternative sub-agents for the same leader, excluding a specific one.
|
|
14
|
+
* Used by the smart retry feature to route around a failing sub-agent.
|
|
15
|
+
*/
|
|
16
|
+
findAlternativeSubAgents(leaderUsername: string, excludeSubAgentUsername: string): Promise<{
|
|
17
|
+
username: string;
|
|
18
|
+
label: string;
|
|
19
|
+
}[]>;
|
|
12
20
|
isRegisteredDelegationTool(toolName: string): Promise<boolean>;
|
|
13
21
|
}
|
|
@@ -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,40 @@
|
|
|
1
|
+
export interface CircuitState {
|
|
2
|
+
failures: number;
|
|
3
|
+
lastFailureTime: number;
|
|
4
|
+
state: 'closed' | 'open' | 'half-open';
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* CircuitBreakerRegistry — prevents cascading failures by tracking per-key
|
|
8
|
+
* failure rates and temporarily stopping calls when thresholds are exceeded.
|
|
9
|
+
*
|
|
10
|
+
* State machine: closed → open (after threshold failures) → half-open (after recoveryTimeout)
|
|
11
|
+
* half-open: allows 1 probe request; success → closed, failure → open.
|
|
12
|
+
*/
|
|
13
|
+
export declare class CircuitBreakerRegistry {
|
|
14
|
+
private readonly circuits;
|
|
15
|
+
readonly threshold: number;
|
|
16
|
+
readonly recoveryTimeout: number;
|
|
17
|
+
readonly halfOpenMaxRequests: number;
|
|
18
|
+
private readonly appLog;
|
|
19
|
+
constructor(options?: {
|
|
20
|
+
threshold?: number;
|
|
21
|
+
recoveryTimeout?: number;
|
|
22
|
+
halfOpenMaxRequests?: number;
|
|
23
|
+
appLog?: any;
|
|
24
|
+
});
|
|
25
|
+
private getOrCreate;
|
|
26
|
+
recordSuccess(key: string): void;
|
|
27
|
+
recordFailure(key: string): void;
|
|
28
|
+
isAllowed(key: string): boolean;
|
|
29
|
+
getState(key: string): CircuitState | null;
|
|
30
|
+
/** Reset a circuit back to closed state. */
|
|
31
|
+
reset(key: string): void;
|
|
32
|
+
/** Get all circuit state keys (for monitoring/diagnostics). */
|
|
33
|
+
getKeys(): string[];
|
|
34
|
+
}
|
|
35
|
+
export declare function getCircuitBreaker(options?: {
|
|
36
|
+
threshold?: number;
|
|
37
|
+
recoveryTimeout?: number;
|
|
38
|
+
halfOpenMaxRequests?: number;
|
|
39
|
+
appLog?: any;
|
|
40
|
+
}): CircuitBreakerRegistry;
|
|
@@ -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,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ContextAggregator — builds structured step context for sub-agent system prompts.
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities:
|
|
5
|
+
* 1. Query completed steps of a run
|
|
6
|
+
* 2. Format them as structured XML context
|
|
7
|
+
* 3. Apply truncation/summarization based on policy
|
|
8
|
+
* 4. Inject into sub-agent system prompt
|
|
9
|
+
*/
|
|
10
|
+
export declare class ContextAggregator {
|
|
11
|
+
private readonly plugin;
|
|
12
|
+
constructor(plugin: any);
|
|
13
|
+
get db(): any;
|
|
14
|
+
get app(): any;
|
|
15
|
+
/**
|
|
16
|
+
* Build a structured context string from completed steps of a run.
|
|
17
|
+
*
|
|
18
|
+
* @param runId - agentLoopRuns.id
|
|
19
|
+
* @param maxTokens - Maximum tokens for the context output (default 4000)
|
|
20
|
+
* @param options - Strategy options
|
|
21
|
+
*/
|
|
22
|
+
buildStepContext(runId: string | number, maxTokens?: number, options?: {
|
|
23
|
+
strategy?: 'last_n' | 'all';
|
|
24
|
+
includeToolResults?: boolean;
|
|
25
|
+
includeStepOutputs?: boolean;
|
|
26
|
+
}): Promise<string>;
|
|
27
|
+
/**
|
|
28
|
+
* Enrich a base system prompt with step context from the run.
|
|
29
|
+
* Fetches the run from DB to access policy settings (maxContextTokens, etc.).
|
|
30
|
+
*
|
|
31
|
+
* @param basePrompt - The original system prompt to enrich
|
|
32
|
+
* @param runId - agentLoopRuns.id
|
|
33
|
+
* @param _stepId - agentLoopSteps.id (reserved for future per-step context)
|
|
34
|
+
*/
|
|
35
|
+
enrichSystemPrompt(basePrompt: string, runId: string | number, _stepId?: string | number, options?: {
|
|
36
|
+
maxContextTokens?: number;
|
|
37
|
+
contextSummaryStrategy?: 'last_n' | 'all';
|
|
38
|
+
includeToolResults?: boolean;
|
|
39
|
+
includeStepOutputs?: boolean;
|
|
40
|
+
}): Promise<string>;
|
|
41
|
+
private truncateToTokenLimit;
|
|
42
|
+
private splitStepBlocks;
|
|
43
|
+
private escapeXml;
|
|
44
|
+
private safeStringify;
|
|
45
|
+
}
|