@nebulaos/core 0.1.1
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 +206 -0
- package/dist/__tests__/mocks/mock-provider.d.ts +15 -0
- package/dist/__tests__/mocks/mock-provider.js +44 -0
- package/dist/agent/Agent.d.ts +96 -0
- package/dist/agent/Agent.js +861 -0
- package/dist/agent/BaseAgent.d.ts +53 -0
- package/dist/agent/BaseAgent.js +126 -0
- package/dist/agent/events/events.d.ts +14 -0
- package/dist/agent/events/events.js +2 -0
- package/dist/agent/events/events.spec.d.ts +1 -0
- package/dist/agent/events/events.spec.js +75 -0
- package/dist/agent/instruction/index.d.ts +23 -0
- package/dist/agent/instruction/index.js +76 -0
- package/dist/agent/memory/in-memory.d.ts +24 -0
- package/dist/agent/memory/in-memory.js +78 -0
- package/dist/agent/memory/index.d.ts +2 -0
- package/dist/agent/memory/index.js +18 -0
- package/dist/agent/memory/memory.d.ts +43 -0
- package/dist/agent/memory/memory.js +7 -0
- package/dist/agent/provider/file-parts.spec.d.ts +1 -0
- package/dist/agent/provider/file-parts.spec.js +83 -0
- package/dist/agent/provider/index.d.ts +130 -0
- package/dist/agent/provider/index.js +8 -0
- package/dist/agent/skills/index.d.ts +61 -0
- package/dist/agent/skills/index.js +9 -0
- package/dist/agent/tools/index.d.ts +35 -0
- package/dist/agent/tools/index.js +87 -0
- package/dist/cost/add-cost.d.ts +10 -0
- package/dist/cost/add-cost.js +80 -0
- package/dist/cost/add-cost.spec.d.ts +1 -0
- package/dist/cost/add-cost.spec.js +36 -0
- package/dist/cost/index.d.ts +1 -0
- package/dist/cost/index.js +17 -0
- package/dist/domain-events/index.d.ts +16 -0
- package/dist/domain-events/index.js +38 -0
- package/dist/eval/index.d.ts +19 -0
- package/dist/eval/index.js +24 -0
- package/dist/events/base.d.ts +5 -0
- package/dist/events/base.js +2 -0
- package/dist/events/schemas.d.ts +3463 -0
- package/dist/events/schemas.js +244 -0
- package/dist/execution-context/index.d.ts +21 -0
- package/dist/execution-context/index.js +17 -0
- package/dist/index.cjs +2958 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +3425 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/dist/lgpd/index.d.ts +7 -0
- package/dist/lgpd/index.js +21 -0
- package/dist/logger/agent-logger.d.ts +16 -0
- package/dist/logger/agent-logger.js +110 -0
- package/dist/logger/formatters.d.ts +32 -0
- package/dist/logger/formatters.js +146 -0
- package/dist/logger/index.d.ts +30 -0
- package/dist/logger/index.js +88 -0
- package/dist/logger/styles.d.ts +46 -0
- package/dist/logger/styles.js +53 -0
- package/dist/logger/workflow-logger.d.ts +16 -0
- package/dist/logger/workflow-logger.js +79 -0
- package/dist/multi-agent/agent-as-tool/AgentAsTool.d.ts +16 -0
- package/dist/multi-agent/agent-as-tool/AgentAsTool.js +54 -0
- package/dist/multi-agent/agent-as-tool/AgentAsTool.spec.d.ts +1 -0
- package/dist/multi-agent/agent-as-tool/AgentAsTool.spec.js +76 -0
- package/dist/multi-agent/committee-team/CommitteeTeam.d.ts +16 -0
- package/dist/multi-agent/committee-team/CommitteeTeam.js +150 -0
- package/dist/multi-agent/committee-team/CommitteeTeam.spec.d.ts +1 -0
- package/dist/multi-agent/committee-team/CommitteeTeam.spec.js +43 -0
- package/dist/multi-agent/handoff-team/HandoffTeam.d.ts +16 -0
- package/dist/multi-agent/handoff-team/HandoffTeam.js +185 -0
- package/dist/multi-agent/handoff-team/HandoffTeam.spec.d.ts +1 -0
- package/dist/multi-agent/handoff-team/HandoffTeam.spec.js +105 -0
- package/dist/multi-agent/hierarchical-team/HierarchicalTeam.d.ts +18 -0
- package/dist/multi-agent/hierarchical-team/HierarchicalTeam.js +164 -0
- package/dist/multi-agent/hierarchical-team/HierarchicalTeam.spec.d.ts +1 -0
- package/dist/multi-agent/hierarchical-team/HierarchicalTeam.spec.js +53 -0
- package/dist/multi-agent/index.d.ts +10 -0
- package/dist/multi-agent/index.js +26 -0
- package/dist/multi-agent/pipeline-team/PipelineTeam.d.ts +13 -0
- package/dist/multi-agent/pipeline-team/PipelineTeam.js +104 -0
- package/dist/multi-agent/pipeline-team/PipelineTeam.spec.d.ts +1 -0
- package/dist/multi-agent/pipeline-team/PipelineTeam.spec.js +54 -0
- package/dist/multi-agent/router-team/RouterTeam.d.ts +15 -0
- package/dist/multi-agent/router-team/RouterTeam.js +153 -0
- package/dist/multi-agent/router-team/RouterTeam.spec.d.ts +1 -0
- package/dist/multi-agent/router-team/RouterTeam.spec.js +69 -0
- package/dist/multi-agent/types/index.d.ts +349 -0
- package/dist/multi-agent/types/index.js +79 -0
- package/dist/multi-agent/utils/guardrails.d.ts +6 -0
- package/dist/multi-agent/utils/guardrails.js +34 -0
- package/dist/multi-agent/utils/memory.d.ts +8 -0
- package/dist/multi-agent/utils/memory.js +40 -0
- package/dist/multi-agent/utils/prompts.d.ts +4 -0
- package/dist/multi-agent/utils/prompts.js +25 -0
- package/dist/tracing/index.d.ts +89 -0
- package/dist/tracing/index.js +188 -0
- package/dist/tsup.config.d.ts +2 -0
- package/dist/tsup.config.js +11 -0
- package/dist/utils/schema-to-zod.d.ts +7 -0
- package/dist/utils/schema-to-zod.js +36 -0
- package/dist/workflow/Workflow.d.ts +106 -0
- package/dist/workflow/Workflow.js +204 -0
- package/dist/workflow/adapters.d.ts +61 -0
- package/dist/workflow/adapters.js +29 -0
- package/dist/workflow/definition/DefinitionBuilder.d.ts +9 -0
- package/dist/workflow/definition/DefinitionBuilder.js +91 -0
- package/dist/workflow/definition/DefinitionBuilder.spec.d.ts +1 -0
- package/dist/workflow/definition/DefinitionBuilder.spec.js +66 -0
- package/dist/workflow/definition/DefinitionHasher.d.ts +8 -0
- package/dist/workflow/definition/DefinitionHasher.js +11 -0
- package/dist/workflow/definition/DefinitionHasher.spec.d.ts +1 -0
- package/dist/workflow/definition/DefinitionHasher.spec.js +28 -0
- package/dist/workflow/definition/types.d.ts +27 -0
- package/dist/workflow/definition/types.js +2 -0
- package/dist/workflow/events.d.ts +9 -0
- package/dist/workflow/events.js +2 -0
- package/dist/workflow/execution/AgentNodeIntegration.spec.d.ts +1 -0
- package/dist/workflow/execution/AgentNodeIntegration.spec.js +50 -0
- package/dist/workflow/execution/NodeExecutor.d.ts +9 -0
- package/dist/workflow/execution/NodeExecutor.js +43 -0
- package/dist/workflow/execution/NodeExecutor.spec.d.ts +1 -0
- package/dist/workflow/execution/NodeExecutor.spec.js +45 -0
- package/dist/workflow/execution/WorkflowEventBus.d.ts +14 -0
- package/dist/workflow/execution/WorkflowEventBus.js +42 -0
- package/dist/workflow/execution/WorkflowEventBus.spec.d.ts +1 -0
- package/dist/workflow/execution/WorkflowEventBus.spec.js +78 -0
- package/dist/workflow/execution/WorkflowRunner.d.ts +26 -0
- package/dist/workflow/execution/WorkflowRunner.js +212 -0
- package/dist/workflow/execution/WorkflowRunner.spec.d.ts +1 -0
- package/dist/workflow/execution/WorkflowRunner.spec.js +92 -0
- package/dist/workflow/execution/WorkflowTelemetry.d.ts +13 -0
- package/dist/workflow/execution/WorkflowTelemetry.js +43 -0
- package/dist/workflow/execution/WorkflowTelemetry.spec.d.ts +1 -0
- package/dist/workflow/execution/WorkflowTelemetry.spec.js +31 -0
- package/dist/workflow/graph/NodeNameRegistry.d.ts +20 -0
- package/dist/workflow/graph/NodeNameRegistry.js +21 -0
- package/dist/workflow/graph/NodeNameRegistry.spec.d.ts +1 -0
- package/dist/workflow/graph/NodeNameRegistry.spec.js +18 -0
- package/dist/workflow/graph/WorkflowGraph.d.ts +14 -0
- package/dist/workflow/graph/WorkflowGraph.js +23 -0
- package/dist/workflow/graph/nodes.d.ts +26 -0
- package/dist/workflow/graph/nodes.js +2 -0
- package/dist/workflow/queue/WorkflowQueueService.d.ts +22 -0
- package/dist/workflow/queue/WorkflowQueueService.js +47 -0
- package/dist/workflow/state/WorkflowStateService.d.ts +7 -0
- package/dist/workflow/state/WorkflowStateService.js +20 -0
- package/dist/workflow/types.d.ts +16 -0
- package/dist/workflow/types.js +2 -0
- package/package.json +56 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HierarchicalTeam = void 0;
|
|
4
|
+
const BaseAgent_js_1 = require("../../agent/BaseAgent.js");
|
|
5
|
+
const AgentAsTool_js_1 = require("../agent-as-tool/AgentAsTool.js");
|
|
6
|
+
const HandoffTeam_js_1 = require("../handoff-team/HandoffTeam.js");
|
|
7
|
+
const memory_js_1 = require("../utils/memory.js");
|
|
8
|
+
const index_js_1 = require("../../tracing/index.js");
|
|
9
|
+
class HierarchicalTeam extends BaseAgent_js_1.BaseAgent {
|
|
10
|
+
config;
|
|
11
|
+
kind = 'team:hierarchical';
|
|
12
|
+
manager;
|
|
13
|
+
workers;
|
|
14
|
+
teamMemory;
|
|
15
|
+
allowHandoff;
|
|
16
|
+
workerCollaboration;
|
|
17
|
+
constructor(config) {
|
|
18
|
+
super(config.id, config.name, undefined, config.memory ?? config.manager.config.memory);
|
|
19
|
+
this.config = config;
|
|
20
|
+
this.manager = config.manager;
|
|
21
|
+
this.workers = config.workers;
|
|
22
|
+
this.teamMemory = config.memory;
|
|
23
|
+
this.allowHandoff = config.allowHandoff ?? false;
|
|
24
|
+
this.workerCollaboration = config.workerCollaboration ?? false;
|
|
25
|
+
}
|
|
26
|
+
async execute(input, options) {
|
|
27
|
+
const correlationId = `hierarchical_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
28
|
+
const startTime = Date.now();
|
|
29
|
+
return index_js_1.Tracing.withSpan({
|
|
30
|
+
kind: "agent",
|
|
31
|
+
name: `team:hierarchical:${this.name}`,
|
|
32
|
+
correlationId,
|
|
33
|
+
executionId: options?.executionId,
|
|
34
|
+
data: { agentName: this.name, input },
|
|
35
|
+
}, async (teamSpan) => {
|
|
36
|
+
this.emit("agent:execution:start", {
|
|
37
|
+
correlationId,
|
|
38
|
+
executionId: options?.executionId,
|
|
39
|
+
data: {
|
|
40
|
+
agentId: this.id,
|
|
41
|
+
agentName: this.name,
|
|
42
|
+
input: input,
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
try {
|
|
46
|
+
const result = this.allowHandoff
|
|
47
|
+
? await this.executeWithHandoff(input, options)
|
|
48
|
+
: await this.executeDelegationOnly(input, options);
|
|
49
|
+
this.emit("agent:execution:end", {
|
|
50
|
+
correlationId,
|
|
51
|
+
executionId: options?.executionId,
|
|
52
|
+
data: {
|
|
53
|
+
agentId: this.id,
|
|
54
|
+
agentName: this.name,
|
|
55
|
+
status: result.truncated ? "truncated" : "success",
|
|
56
|
+
output: result.content,
|
|
57
|
+
durationMs: Date.now() - startTime,
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
await teamSpan.end({
|
|
61
|
+
status: result.truncated ? "cancelled" : "success",
|
|
62
|
+
data: { output: result.content },
|
|
63
|
+
});
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
68
|
+
this.emit("agent:execution:error", {
|
|
69
|
+
correlationId,
|
|
70
|
+
executionId: options?.executionId,
|
|
71
|
+
data: {
|
|
72
|
+
agentId: this.id,
|
|
73
|
+
agentName: this.name,
|
|
74
|
+
error: {
|
|
75
|
+
message: err.message,
|
|
76
|
+
stack: err.stack,
|
|
77
|
+
name: err.name,
|
|
78
|
+
},
|
|
79
|
+
durationMs: Date.now() - startTime,
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
await teamSpan.end({ status: "error" });
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
async executeDelegationOnly(input, options) {
|
|
88
|
+
const teamMemory = this.teamMemory ?? this.manager.config.memory;
|
|
89
|
+
const tools = this.buildWorkerTools(teamMemory);
|
|
90
|
+
const originalTools = this.manager.config.tools ?? [];
|
|
91
|
+
this.manager.config.tools = [...originalTools, ...tools];
|
|
92
|
+
const restoreMemory = (0, memory_js_1.overrideAgentMemory)(this.manager, teamMemory);
|
|
93
|
+
try {
|
|
94
|
+
if (input) {
|
|
95
|
+
await this.addMessage({ role: "user", content: input });
|
|
96
|
+
}
|
|
97
|
+
return await this.manager.execute(undefined, {
|
|
98
|
+
...(options ?? {}),
|
|
99
|
+
executionId: options?.executionId,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
finally {
|
|
103
|
+
this.manager.config.tools = originalTools;
|
|
104
|
+
restoreMemory();
|
|
105
|
+
tools.forEach((t) => t.setCallingMemory(undefined));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
async executeWithHandoff(input, options) {
|
|
109
|
+
const teamMemory = this.teamMemory ?? this.manager.config.memory;
|
|
110
|
+
if (this.workerCollaboration) {
|
|
111
|
+
this.workers.forEach((worker) => {
|
|
112
|
+
const originalTools = worker.config.tools ?? [];
|
|
113
|
+
const peerTools = this.workers
|
|
114
|
+
.filter((w) => w !== worker)
|
|
115
|
+
.map((w) => new AgentAsTool_js_1.AgentAsTool({
|
|
116
|
+
agent: w,
|
|
117
|
+
memory: { type: "shared" },
|
|
118
|
+
additionalPrompt: "Use this to consult another specialist.",
|
|
119
|
+
}));
|
|
120
|
+
worker.config.tools = [...originalTools, ...peerTools];
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
const team = new HandoffTeam_js_1.HandoffTeam({
|
|
124
|
+
id: `${this.config.id}-internal-handoff`,
|
|
125
|
+
name: `${this.config.name}-internal-handoff`,
|
|
126
|
+
agents: [this.manager, ...this.workers],
|
|
127
|
+
edges: [
|
|
128
|
+
...this.workers.map((w) => ({
|
|
129
|
+
from: this.manager,
|
|
130
|
+
to: w,
|
|
131
|
+
toolId: `handoff_to_${w.name.toLowerCase()}`,
|
|
132
|
+
description: `Pass control to worker ${w.name}`,
|
|
133
|
+
})),
|
|
134
|
+
...this.workers.map((w) => ({
|
|
135
|
+
from: w,
|
|
136
|
+
to: this.manager,
|
|
137
|
+
toolId: `back_to_manager`,
|
|
138
|
+
description: `Return control to manager`,
|
|
139
|
+
})),
|
|
140
|
+
],
|
|
141
|
+
initialAgent: this.manager,
|
|
142
|
+
memory: teamMemory,
|
|
143
|
+
additionalPrompt: this.config.additionalPrompt,
|
|
144
|
+
maxTransfers: 10,
|
|
145
|
+
});
|
|
146
|
+
return team.execute(input, {
|
|
147
|
+
...(options ?? {}),
|
|
148
|
+
executionId: options?.executionId,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
buildWorkerTools(teamMemory) {
|
|
152
|
+
return this.workers.map((worker) => {
|
|
153
|
+
const tool = new AgentAsTool_js_1.AgentAsTool({
|
|
154
|
+
agent: worker,
|
|
155
|
+
id: `delegate_${worker.name.toLowerCase()}`,
|
|
156
|
+
memory: { type: "shared" },
|
|
157
|
+
additionalPrompt: "Delegate a subtask to this specialist.",
|
|
158
|
+
});
|
|
159
|
+
tool.setCallingMemory(teamMemory);
|
|
160
|
+
return tool;
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
exports.HierarchicalTeam = HierarchicalTeam;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const Agent_js_1 = require("../../agent/Agent.js");
|
|
4
|
+
const in_memory_js_1 = require("../../agent/memory/in-memory.js");
|
|
5
|
+
const mock_provider_js_1 = require("../../__tests__/mocks/mock-provider.js");
|
|
6
|
+
const HierarchicalTeam_js_1 = require("./HierarchicalTeam.js");
|
|
7
|
+
function agentWithToolCall(name, toolName) {
|
|
8
|
+
const provider = new mock_provider_js_1.MockProvider();
|
|
9
|
+
provider.enqueueResponse({
|
|
10
|
+
content: "",
|
|
11
|
+
toolCalls: [
|
|
12
|
+
{
|
|
13
|
+
id: "call-1",
|
|
14
|
+
type: "function",
|
|
15
|
+
function: { name: toolName, arguments: "{}" },
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
});
|
|
19
|
+
return new Agent_js_1.Agent({
|
|
20
|
+
id: name,
|
|
21
|
+
name,
|
|
22
|
+
model: provider,
|
|
23
|
+
memory: new in_memory_js_1.InMemory(),
|
|
24
|
+
instructions: `${name} instructions`,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
function agentWithFinal(name, content) {
|
|
28
|
+
const provider = new mock_provider_js_1.MockProvider();
|
|
29
|
+
provider.enqueueResponse({ content });
|
|
30
|
+
return new Agent_js_1.Agent({
|
|
31
|
+
id: name,
|
|
32
|
+
name,
|
|
33
|
+
model: provider,
|
|
34
|
+
memory: new in_memory_js_1.InMemory(),
|
|
35
|
+
instructions: `${name} instructions`,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
describe("HierarchicalTeam", () => {
|
|
39
|
+
it("supports handoff from manager to worker", async () => {
|
|
40
|
+
const manager = agentWithToolCall("Manager", "handoff_to_worker");
|
|
41
|
+
const worker = agentWithFinal("Worker", "worker-output");
|
|
42
|
+
const team = new HierarchicalTeam_js_1.HierarchicalTeam({
|
|
43
|
+
id: "test-hierarchical",
|
|
44
|
+
name: "test-hierarchical",
|
|
45
|
+
manager,
|
|
46
|
+
workers: [worker],
|
|
47
|
+
allowHandoff: true,
|
|
48
|
+
memory: new in_memory_js_1.InMemory(),
|
|
49
|
+
});
|
|
50
|
+
const result = await team.execute("customer request");
|
|
51
|
+
expect(result.content).toBe("worker-output");
|
|
52
|
+
});
|
|
53
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from "./types/index.js";
|
|
2
|
+
export * from "./agent-as-tool/AgentAsTool.js";
|
|
3
|
+
export * from "./router-team/RouterTeam.js";
|
|
4
|
+
export * from "./handoff-team/HandoffTeam.js";
|
|
5
|
+
export * from "./hierarchical-team/HierarchicalTeam.js";
|
|
6
|
+
export * from "./pipeline-team/PipelineTeam.js";
|
|
7
|
+
export * from "./committee-team/CommitteeTeam.js";
|
|
8
|
+
export * from "./utils/guardrails.js";
|
|
9
|
+
export * from "./utils/memory.js";
|
|
10
|
+
export * from "./utils/prompts.js";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./types/index.js"), exports);
|
|
18
|
+
__exportStar(require("./agent-as-tool/AgentAsTool.js"), exports);
|
|
19
|
+
__exportStar(require("./router-team/RouterTeam.js"), exports);
|
|
20
|
+
__exportStar(require("./handoff-team/HandoffTeam.js"), exports);
|
|
21
|
+
__exportStar(require("./hierarchical-team/HierarchicalTeam.js"), exports);
|
|
22
|
+
__exportStar(require("./pipeline-team/PipelineTeam.js"), exports);
|
|
23
|
+
__exportStar(require("./committee-team/CommitteeTeam.js"), exports);
|
|
24
|
+
__exportStar(require("./utils/guardrails.js"), exports);
|
|
25
|
+
__exportStar(require("./utils/memory.js"), exports);
|
|
26
|
+
__exportStar(require("./utils/prompts.js"), exports);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { AgentResult } from "../../agent/Agent.js";
|
|
2
|
+
import { BaseAgent } from "../../agent/BaseAgent.js";
|
|
3
|
+
import type { AgentExecuteOptions } from "../../agent/Agent.js";
|
|
4
|
+
import type { PipelineTeamConfig } from "../types/index.js";
|
|
5
|
+
export declare class PipelineTeam extends BaseAgent {
|
|
6
|
+
private readonly config;
|
|
7
|
+
readonly kind: "team:pipeline";
|
|
8
|
+
private readonly stages;
|
|
9
|
+
private readonly teamMemory?;
|
|
10
|
+
constructor(config: PipelineTeamConfig);
|
|
11
|
+
execute(input?: string, options?: AgentExecuteOptions): Promise<AgentResult>;
|
|
12
|
+
private buildEdges;
|
|
13
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PipelineTeam = void 0;
|
|
4
|
+
const BaseAgent_js_1 = require("../../agent/BaseAgent.js");
|
|
5
|
+
const HandoffTeam_js_1 = require("../handoff-team/HandoffTeam.js");
|
|
6
|
+
const index_js_1 = require("../../tracing/index.js");
|
|
7
|
+
class PipelineTeam extends BaseAgent_js_1.BaseAgent {
|
|
8
|
+
config;
|
|
9
|
+
kind = 'team:pipeline';
|
|
10
|
+
stages;
|
|
11
|
+
teamMemory;
|
|
12
|
+
constructor(config) {
|
|
13
|
+
super(config.id, config.name, undefined, config.memory ?? config.stages?.[0]?.config?.memory);
|
|
14
|
+
this.config = config;
|
|
15
|
+
this.stages = config.stages;
|
|
16
|
+
this.teamMemory = config.memory;
|
|
17
|
+
}
|
|
18
|
+
async execute(input, options) {
|
|
19
|
+
const correlationId = `pipeline_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
20
|
+
const startTime = Date.now();
|
|
21
|
+
return index_js_1.Tracing.withSpan({
|
|
22
|
+
kind: "agent",
|
|
23
|
+
name: `team:pipeline:${this.name}`,
|
|
24
|
+
correlationId,
|
|
25
|
+
executionId: options?.executionId,
|
|
26
|
+
data: { agentName: this.name, input },
|
|
27
|
+
}, async (teamSpan) => {
|
|
28
|
+
this.emit("agent:execution:start", {
|
|
29
|
+
correlationId,
|
|
30
|
+
executionId: options?.executionId,
|
|
31
|
+
data: {
|
|
32
|
+
agentId: this.id,
|
|
33
|
+
agentName: this.name,
|
|
34
|
+
input: input,
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
try {
|
|
38
|
+
const edges = this.buildEdges();
|
|
39
|
+
const team = new HandoffTeam_js_1.HandoffTeam({
|
|
40
|
+
id: `${this.config.id}-internal-handoff`,
|
|
41
|
+
name: `${this.config.name}-internal-handoff`,
|
|
42
|
+
agents: this.stages,
|
|
43
|
+
edges,
|
|
44
|
+
initialAgent: this.stages[0],
|
|
45
|
+
memory: this.teamMemory,
|
|
46
|
+
additionalPrompt: this.config.additionalPrompt,
|
|
47
|
+
maxTransfers: edges.length + 2,
|
|
48
|
+
});
|
|
49
|
+
const result = await team.execute(input, {
|
|
50
|
+
...(options ?? {}),
|
|
51
|
+
executionId: options?.executionId,
|
|
52
|
+
});
|
|
53
|
+
this.emit("agent:execution:end", {
|
|
54
|
+
correlationId,
|
|
55
|
+
executionId: options?.executionId,
|
|
56
|
+
data: {
|
|
57
|
+
agentId: this.id,
|
|
58
|
+
agentName: this.name,
|
|
59
|
+
status: result.truncated ? "truncated" : "success",
|
|
60
|
+
output: result.content,
|
|
61
|
+
durationMs: Date.now() - startTime,
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
await teamSpan.end({
|
|
65
|
+
status: result.truncated ? "cancelled" : "success",
|
|
66
|
+
data: { output: result.content },
|
|
67
|
+
});
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
72
|
+
this.emit("agent:execution:error", {
|
|
73
|
+
correlationId,
|
|
74
|
+
executionId: options?.executionId,
|
|
75
|
+
data: {
|
|
76
|
+
agentId: this.id,
|
|
77
|
+
agentName: this.name,
|
|
78
|
+
error: {
|
|
79
|
+
message: err.message,
|
|
80
|
+
stack: err.stack,
|
|
81
|
+
name: err.name,
|
|
82
|
+
},
|
|
83
|
+
durationMs: Date.now() - startTime,
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
await teamSpan.end({ status: "error" });
|
|
87
|
+
throw error;
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
buildEdges() {
|
|
92
|
+
const edges = this.stages.slice(0, -1).map((from, idx) => {
|
|
93
|
+
const to = this.stages[idx + 1];
|
|
94
|
+
return {
|
|
95
|
+
from,
|
|
96
|
+
to,
|
|
97
|
+
toolId: `next_${to.name.toLowerCase()}`,
|
|
98
|
+
description: `Pass work to ${to.name}`,
|
|
99
|
+
};
|
|
100
|
+
});
|
|
101
|
+
return edges;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
exports.PipelineTeam = PipelineTeam;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const Agent_js_1 = require("../../agent/Agent.js");
|
|
4
|
+
const in_memory_js_1 = require("../../agent/memory/in-memory.js");
|
|
5
|
+
const mock_provider_js_1 = require("../../__tests__/mocks/mock-provider.js");
|
|
6
|
+
const PipelineTeam_js_1 = require("./PipelineTeam.js");
|
|
7
|
+
function agentWithToolCall(name, toolName, repeats = 1) {
|
|
8
|
+
const provider = new mock_provider_js_1.MockProvider();
|
|
9
|
+
for (let i = 0; i < repeats; i++) {
|
|
10
|
+
provider.enqueueResponse({
|
|
11
|
+
content: "",
|
|
12
|
+
toolCalls: [
|
|
13
|
+
{
|
|
14
|
+
id: `call-${i + 1}`,
|
|
15
|
+
type: "function",
|
|
16
|
+
function: { name: toolName, arguments: "{}" },
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
return new Agent_js_1.Agent({
|
|
22
|
+
id: name,
|
|
23
|
+
name,
|
|
24
|
+
model: provider,
|
|
25
|
+
memory: new in_memory_js_1.InMemory(),
|
|
26
|
+
instructions: `${name} instructions`,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
function agentWithFinal(name, content) {
|
|
30
|
+
const provider = new mock_provider_js_1.MockProvider();
|
|
31
|
+
provider.enqueueResponse({ content });
|
|
32
|
+
return new Agent_js_1.Agent({
|
|
33
|
+
id: name,
|
|
34
|
+
name,
|
|
35
|
+
model: provider,
|
|
36
|
+
memory: new in_memory_js_1.InMemory(),
|
|
37
|
+
instructions: `${name} instructions`,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
describe("PipelineTeam", () => {
|
|
41
|
+
it("executes linear stages via handoff", async () => {
|
|
42
|
+
const stage1 = agentWithToolCall("Stage1", "next_stage2");
|
|
43
|
+
const stage2 = agentWithToolCall("Stage2", "next_stage3");
|
|
44
|
+
const stage3 = agentWithFinal("Stage3", "final-output");
|
|
45
|
+
const team = new PipelineTeam_js_1.PipelineTeam({
|
|
46
|
+
id: "test-pipeline",
|
|
47
|
+
name: "test-pipeline",
|
|
48
|
+
stages: [stage1, stage2, stage3],
|
|
49
|
+
memory: new in_memory_js_1.InMemory(),
|
|
50
|
+
});
|
|
51
|
+
const result = await team.execute("do work");
|
|
52
|
+
expect(result.content).toBe("final-output");
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { AgentResult } from "../../agent/Agent.js";
|
|
2
|
+
import { BaseAgent } from "../../agent/BaseAgent.js";
|
|
3
|
+
import type { AgentExecuteOptions } from "../../agent/Agent.js";
|
|
4
|
+
import type { RouterTeamConfig } from "../types/index.js";
|
|
5
|
+
export declare class RouterTeam extends BaseAgent {
|
|
6
|
+
private readonly config;
|
|
7
|
+
readonly kind: "team:router";
|
|
8
|
+
constructor(config: RouterTeamConfig);
|
|
9
|
+
/**
|
|
10
|
+
* Execute routing: choose an agent via model classification, then delegate execution.
|
|
11
|
+
*/
|
|
12
|
+
execute(input?: string, options?: AgentExecuteOptions): Promise<AgentResult>;
|
|
13
|
+
private selectAgent;
|
|
14
|
+
private extractAgentName;
|
|
15
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RouterTeam = void 0;
|
|
4
|
+
const BaseAgent_js_1 = require("../../agent/BaseAgent.js");
|
|
5
|
+
const prompts_js_1 = require("../utils/prompts.js");
|
|
6
|
+
const memory_js_1 = require("../utils/memory.js");
|
|
7
|
+
const guardrails_js_1 = require("../utils/guardrails.js");
|
|
8
|
+
const index_js_1 = require("../../tracing/index.js");
|
|
9
|
+
class RouterTeam extends BaseAgent_js_1.BaseAgent {
|
|
10
|
+
config;
|
|
11
|
+
kind = 'team:router';
|
|
12
|
+
constructor(config) {
|
|
13
|
+
super(config.id, config.name, undefined, config.memory ?? config.children?.[0]?.config?.memory);
|
|
14
|
+
this.config = config;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Execute routing: choose an agent via model classification, then delegate execution.
|
|
18
|
+
*/
|
|
19
|
+
async execute(input, options) {
|
|
20
|
+
const correlationId = `router_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
21
|
+
const startTime = Date.now();
|
|
22
|
+
return index_js_1.Tracing.withSpan({
|
|
23
|
+
kind: "agent",
|
|
24
|
+
name: `team:router:${this.name}`,
|
|
25
|
+
correlationId,
|
|
26
|
+
executionId: options?.executionId,
|
|
27
|
+
data: { agentName: this.name, input },
|
|
28
|
+
}, async (teamSpan) => {
|
|
29
|
+
this.emit("agent:execution:start", {
|
|
30
|
+
correlationId,
|
|
31
|
+
executionId: options?.executionId,
|
|
32
|
+
data: {
|
|
33
|
+
agentId: this.id,
|
|
34
|
+
agentName: this.name,
|
|
35
|
+
input: input,
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
try {
|
|
39
|
+
const selected = await this.selectAgent(input);
|
|
40
|
+
const memoryToUse = this.config.memory ?? selected.config.memory;
|
|
41
|
+
const restoreMemory = (0, memory_js_1.overrideAgentMemory)(selected, memoryToUse);
|
|
42
|
+
if (input) {
|
|
43
|
+
await this.addMessage({ role: "user", content: input });
|
|
44
|
+
}
|
|
45
|
+
const result = await selected.execute(undefined, {
|
|
46
|
+
...(options ?? {}),
|
|
47
|
+
executionId: options?.executionId,
|
|
48
|
+
});
|
|
49
|
+
restoreMemory();
|
|
50
|
+
this.emit("agent:execution:end", {
|
|
51
|
+
correlationId,
|
|
52
|
+
executionId: options?.executionId,
|
|
53
|
+
data: {
|
|
54
|
+
agentId: this.id,
|
|
55
|
+
agentName: this.name,
|
|
56
|
+
status: result.truncated ? "truncated" : "success",
|
|
57
|
+
output: result.content,
|
|
58
|
+
durationMs: Date.now() - startTime,
|
|
59
|
+
// Usage? Ideally aggregated, but for now passing result content is key
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
await teamSpan.end({
|
|
63
|
+
status: result.truncated ? "cancelled" : "success",
|
|
64
|
+
data: { output: result.content },
|
|
65
|
+
});
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
70
|
+
this.emit("agent:execution:error", {
|
|
71
|
+
correlationId,
|
|
72
|
+
executionId: options?.executionId,
|
|
73
|
+
data: {
|
|
74
|
+
agentId: this.id,
|
|
75
|
+
agentName: this.name,
|
|
76
|
+
error: {
|
|
77
|
+
message: err.message,
|
|
78
|
+
stack: err.stack,
|
|
79
|
+
name: err.name,
|
|
80
|
+
},
|
|
81
|
+
durationMs: Date.now() - startTime,
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
await teamSpan.end({ status: "error" });
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
async selectAgent(userInput) {
|
|
90
|
+
const system = (0, prompts_js_1.buildRouterSystemPrompt)(this.config.children, this.config.additionalPrompt);
|
|
91
|
+
const messages = [
|
|
92
|
+
{ role: "system", content: system },
|
|
93
|
+
{ role: "user", content: userInput ?? "" },
|
|
94
|
+
];
|
|
95
|
+
const routerResponseSchema = {
|
|
96
|
+
type: "object",
|
|
97
|
+
properties: {
|
|
98
|
+
agent: {
|
|
99
|
+
type: "string",
|
|
100
|
+
description: "The name of the agent to route to",
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
required: ["agent"],
|
|
104
|
+
additionalProperties: false,
|
|
105
|
+
};
|
|
106
|
+
const response = await (0, guardrails_js_1.enforceTimeout)(index_js_1.Tracing.withSpan({
|
|
107
|
+
kind: "llm",
|
|
108
|
+
name: "llm:router-selection",
|
|
109
|
+
data: {
|
|
110
|
+
provider: this.config.model.providerName,
|
|
111
|
+
model: this.config.model.modelName,
|
|
112
|
+
messagesCount: messages.length,
|
|
113
|
+
toolsCount: 0,
|
|
114
|
+
responseFormat: { type: "json", schema: routerResponseSchema },
|
|
115
|
+
},
|
|
116
|
+
}, async (llmSpan) => {
|
|
117
|
+
const resp = await this.config.model.generate(messages, undefined, {
|
|
118
|
+
responseFormat: { type: "json", schema: routerResponseSchema },
|
|
119
|
+
});
|
|
120
|
+
await llmSpan.end({
|
|
121
|
+
status: "success",
|
|
122
|
+
data: {
|
|
123
|
+
usage: resp.usage,
|
|
124
|
+
outputPreview: typeof resp.content === "string" ? resp.content.substring(0, 200) : "json_content",
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
return resp;
|
|
128
|
+
}), this.config.timeoutMs, "router-selection");
|
|
129
|
+
const agentName = this.extractAgentName(response.content);
|
|
130
|
+
const found = this.config.children.find((c) => c.name.toLowerCase() === agentName?.toLowerCase()) ??
|
|
131
|
+
this.config.fallback ??
|
|
132
|
+
this.config.children[0];
|
|
133
|
+
return found;
|
|
134
|
+
}
|
|
135
|
+
extractAgentName(content) {
|
|
136
|
+
if (!content)
|
|
137
|
+
return undefined;
|
|
138
|
+
const trimmed = content.trim();
|
|
139
|
+
if (!trimmed)
|
|
140
|
+
return undefined;
|
|
141
|
+
try {
|
|
142
|
+
const parsed = JSON.parse(trimmed);
|
|
143
|
+
if (parsed && typeof parsed.agent === "string") {
|
|
144
|
+
return parsed.agent;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
// ignore
|
|
149
|
+
}
|
|
150
|
+
return trimmed.split("\n")[0];
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
exports.RouterTeam = RouterTeam;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const in_memory_js_1 = require("../../agent/memory/in-memory.js");
|
|
4
|
+
const Agent_js_1 = require("../../agent/Agent.js");
|
|
5
|
+
const RouterTeam_js_1 = require("./RouterTeam.js");
|
|
6
|
+
const mock_provider_js_1 = require("../../__tests__/mocks/mock-provider.js");
|
|
7
|
+
function createAgent(name, content) {
|
|
8
|
+
const provider = new mock_provider_js_1.MockProvider();
|
|
9
|
+
provider.enqueueResponse({ content });
|
|
10
|
+
return new Agent_js_1.Agent({
|
|
11
|
+
id: name,
|
|
12
|
+
name,
|
|
13
|
+
model: provider,
|
|
14
|
+
memory: new in_memory_js_1.InMemory(),
|
|
15
|
+
instructions: `${name} instructions`,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
describe("RouterTeam", () => {
|
|
19
|
+
it("routes to the agent selected by the router model", async () => {
|
|
20
|
+
const routerModel = new mock_provider_js_1.MockProvider();
|
|
21
|
+
routerModel.enqueueResponse({ content: '{"agent":"Tech"}' });
|
|
22
|
+
const finance = createAgent("Finance", "finance-response");
|
|
23
|
+
const tech = createAgent("Tech", "tech-response");
|
|
24
|
+
const team = new RouterTeam_js_1.RouterTeam({
|
|
25
|
+
id: "test-router",
|
|
26
|
+
name: "test-router",
|
|
27
|
+
model: routerModel,
|
|
28
|
+
children: [finance, tech],
|
|
29
|
+
});
|
|
30
|
+
const result = await team.execute("System error");
|
|
31
|
+
expect(result.content).toBe("tech-response");
|
|
32
|
+
expect(routerModel.calls[0].messages[1].content).toBe("System error");
|
|
33
|
+
});
|
|
34
|
+
it("falls back to first agent if selection fails", async () => {
|
|
35
|
+
const routerModel = new mock_provider_js_1.MockProvider();
|
|
36
|
+
routerModel.enqueueResponse({ content: "unknown" });
|
|
37
|
+
const finance = createAgent("Finance", "finance-response");
|
|
38
|
+
const tech = createAgent("Tech", "tech-response");
|
|
39
|
+
const team = new RouterTeam_js_1.RouterTeam({
|
|
40
|
+
id: "test-router-2",
|
|
41
|
+
name: "test-router-2",
|
|
42
|
+
model: routerModel,
|
|
43
|
+
children: [finance, tech],
|
|
44
|
+
});
|
|
45
|
+
const result = await team.execute("Billing");
|
|
46
|
+
expect(result.content).toBe("finance-response");
|
|
47
|
+
});
|
|
48
|
+
it("uses team-level memory override during execution and restores agent memory", async () => {
|
|
49
|
+
const routerModel = new mock_provider_js_1.MockProvider();
|
|
50
|
+
routerModel.enqueueResponse({ content: '{"agent":"Tech"}' });
|
|
51
|
+
const originalMemory = new in_memory_js_1.InMemory();
|
|
52
|
+
const teamMemory = new in_memory_js_1.InMemory();
|
|
53
|
+
const tech = createAgent("Tech", "tech-response");
|
|
54
|
+
tech.config.memory = originalMemory;
|
|
55
|
+
const team = new RouterTeam_js_1.RouterTeam({
|
|
56
|
+
id: "test-router-memory",
|
|
57
|
+
name: "test-router-memory",
|
|
58
|
+
model: routerModel,
|
|
59
|
+
children: [tech],
|
|
60
|
+
memory: teamMemory,
|
|
61
|
+
});
|
|
62
|
+
await team.execute("Hello");
|
|
63
|
+
const teamMsgs = await teamMemory.getMessages();
|
|
64
|
+
expect(teamMsgs.some((m) => m.content === "Hello")).toBe(true);
|
|
65
|
+
// original memory stays empty (restored)
|
|
66
|
+
expect((await originalMemory.getMessages()).length).toBe(0);
|
|
67
|
+
expect(tech.config.memory).toBe(originalMemory);
|
|
68
|
+
});
|
|
69
|
+
});
|