@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
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2958 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
ActiveSpan: () => ActiveSpan,
|
|
24
|
+
Agent: () => Agent,
|
|
25
|
+
AgentAsTool: () => AgentAsTool,
|
|
26
|
+
AgentExecutionEndSchema: () => AgentExecutionEndSchema,
|
|
27
|
+
AgentExecutionErrorSchema: () => AgentExecutionErrorSchema,
|
|
28
|
+
AgentExecutionStartSchema: () => AgentExecutionStartSchema,
|
|
29
|
+
AgentLLMCallSchema: () => AgentLLMCallSchema,
|
|
30
|
+
AgentLLMResponseSchema: () => AgentLLMResponseSchema,
|
|
31
|
+
AgentLogger: () => AgentLogger,
|
|
32
|
+
AgentToolCallSchema: () => AgentToolCallSchema,
|
|
33
|
+
AgentToolResultSchema: () => AgentToolResultSchema,
|
|
34
|
+
BaseAgent: () => BaseAgent,
|
|
35
|
+
COLORS: () => COLORS,
|
|
36
|
+
CommitteeTeam: () => CommitteeTeam,
|
|
37
|
+
ConsoleLogger: () => ConsoleLogger,
|
|
38
|
+
ErrorSchema: () => ErrorSchema,
|
|
39
|
+
EventCommonSchema: () => EventCommonSchema,
|
|
40
|
+
GuardrailError: () => GuardrailError,
|
|
41
|
+
HandoffTeam: () => HandoffTeam,
|
|
42
|
+
HierarchicalTeam: () => HierarchicalTeam,
|
|
43
|
+
InMemory: () => InMemory,
|
|
44
|
+
KeywordScorer: () => KeywordScorer,
|
|
45
|
+
LOG_LEVEL_COLORS: () => LOG_LEVEL_COLORS,
|
|
46
|
+
ModelSchema: () => ModelSchema,
|
|
47
|
+
NebulaEventSchema: () => NebulaEventSchema,
|
|
48
|
+
PipelineTeam: () => PipelineTeam,
|
|
49
|
+
RegexPIIMasker: () => RegexPIIMasker,
|
|
50
|
+
RouterTeam: () => RouterTeam,
|
|
51
|
+
TREE_CHARS: () => TREE_CHARS,
|
|
52
|
+
Tool: () => Tool,
|
|
53
|
+
TraceContextSchema: () => TraceContextSchema,
|
|
54
|
+
Tracing: () => Tracing,
|
|
55
|
+
UsageSchema: () => UsageSchema,
|
|
56
|
+
Workflow: () => Workflow,
|
|
57
|
+
WorkflowExecutionEndSchema: () => WorkflowExecutionEndSchema,
|
|
58
|
+
WorkflowExecutionErrorSchema: () => WorkflowExecutionErrorSchema,
|
|
59
|
+
WorkflowExecutionStartSchema: () => WorkflowExecutionStartSchema,
|
|
60
|
+
WorkflowLogger: () => WorkflowLogger,
|
|
61
|
+
WorkflowStepSchema: () => WorkflowStepSchema,
|
|
62
|
+
agentAsToolConfigSchema: () => agentAsToolConfigSchema,
|
|
63
|
+
aggregationStrategySchema: () => aggregationStrategySchema,
|
|
64
|
+
buildHandoffSystemPrompt: () => buildHandoffSystemPrompt,
|
|
65
|
+
buildRouterSystemPrompt: () => buildRouterSystemPrompt,
|
|
66
|
+
calculateRetryDelay: () => calculateRetryDelay,
|
|
67
|
+
committeeTeamConfigSchema: () => committeeTeamConfigSchema,
|
|
68
|
+
delegationMemorySchema: () => delegationMemorySchema,
|
|
69
|
+
enforceAllowedTransition: () => enforceAllowedTransition,
|
|
70
|
+
enforceMaxTransfers: () => enforceMaxTransfers,
|
|
71
|
+
enforceTimeout: () => enforceTimeout,
|
|
72
|
+
formatError: () => formatError,
|
|
73
|
+
formatLogLine: () => formatLogLine,
|
|
74
|
+
formatMetadata: () => formatMetadata,
|
|
75
|
+
handoffEdgeSchema: () => handoffEdgeSchema,
|
|
76
|
+
handoffTeamConfigSchema: () => handoffTeamConfigSchema,
|
|
77
|
+
hierarchicalTeamConfigSchema: () => hierarchicalTeamConfigSchema,
|
|
78
|
+
isRetryableError: () => isRetryableError,
|
|
79
|
+
overrideAgentMemory: () => overrideAgentMemory,
|
|
80
|
+
pipelineTeamConfigSchema: () => pipelineTeamConfigSchema,
|
|
81
|
+
resolveDelegationMemory: () => resolveDelegationMemory,
|
|
82
|
+
routerTeamConfigSchema: () => routerTeamConfigSchema,
|
|
83
|
+
schemaToZod: () => schemaToZod,
|
|
84
|
+
z: () => import_zod4.z
|
|
85
|
+
});
|
|
86
|
+
module.exports = __toCommonJS(index_exports);
|
|
87
|
+
|
|
88
|
+
// agent/BaseAgent.ts
|
|
89
|
+
var import_events = require("events");
|
|
90
|
+
|
|
91
|
+
// tracing/index.ts
|
|
92
|
+
var import_node_async_hooks = require("async_hooks");
|
|
93
|
+
var import_node_crypto = require("crypto");
|
|
94
|
+
var ActiveSpan = class {
|
|
95
|
+
constructor(traceId, spanId, parentSpanId, kind, name, correlationId, runId, exporter) {
|
|
96
|
+
this.traceId = traceId;
|
|
97
|
+
this.spanId = spanId;
|
|
98
|
+
this.parentSpanId = parentSpanId;
|
|
99
|
+
this.kind = kind;
|
|
100
|
+
this.name = name;
|
|
101
|
+
this.correlationId = correlationId;
|
|
102
|
+
this.runId = runId;
|
|
103
|
+
this.exporter = exporter;
|
|
104
|
+
}
|
|
105
|
+
ended = false;
|
|
106
|
+
async end(input) {
|
|
107
|
+
if (this.ended) return;
|
|
108
|
+
this.ended = true;
|
|
109
|
+
const event = {
|
|
110
|
+
v: 1,
|
|
111
|
+
type: "telemetry:span:end",
|
|
112
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
113
|
+
trace: {
|
|
114
|
+
traceId: this.traceId,
|
|
115
|
+
spanId: this.spanId,
|
|
116
|
+
parentSpanId: this.parentSpanId
|
|
117
|
+
},
|
|
118
|
+
correlationId: this.correlationId,
|
|
119
|
+
runId: this.runId,
|
|
120
|
+
status: input.status,
|
|
121
|
+
span: {
|
|
122
|
+
kind: this.kind,
|
|
123
|
+
name: this.name,
|
|
124
|
+
// The contract expects a kind-specific shape, but we keep this generic here.
|
|
125
|
+
// The callers are responsible for providing kind-specific keys.
|
|
126
|
+
data: input.data
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
try {
|
|
130
|
+
await this.exporter.exportBatch([event]);
|
|
131
|
+
} catch {
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
get isEnded() {
|
|
135
|
+
return this.ended;
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
var storage = new import_node_async_hooks.AsyncLocalStorage();
|
|
139
|
+
var NoopTelemetryExporter = class {
|
|
140
|
+
async exportBatch(_events) {
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
var Tracing = class {
|
|
144
|
+
static exporter = new NoopTelemetryExporter();
|
|
145
|
+
static setExporter(exporter) {
|
|
146
|
+
this.exporter = exporter;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Gets the current trace context.
|
|
150
|
+
* Returns undefined if called outside of a traced execution.
|
|
151
|
+
*/
|
|
152
|
+
static getContext() {
|
|
153
|
+
return storage.getStore();
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Gets the current trace context or creates a dummy one if none exists.
|
|
157
|
+
* Useful for logging where you always want *some* ID.
|
|
158
|
+
*/
|
|
159
|
+
static getContextOrDummy() {
|
|
160
|
+
const context = storage.getStore();
|
|
161
|
+
if (context) return context;
|
|
162
|
+
return {
|
|
163
|
+
traceId: "no-trace",
|
|
164
|
+
spanId: "no-span"
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Runs a function inside a new telemetry span and exports span lifecycle events.
|
|
169
|
+
*/
|
|
170
|
+
static async withSpan(input, fn) {
|
|
171
|
+
const parent = storage.getStore();
|
|
172
|
+
const traceId = parent?.traceId ?? (0, import_node_crypto.randomUUID)();
|
|
173
|
+
const parentSpanId = parent?.spanId;
|
|
174
|
+
const spanId = (0, import_node_crypto.randomUUID)();
|
|
175
|
+
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
176
|
+
const startEvent = {
|
|
177
|
+
v: 1,
|
|
178
|
+
type: "telemetry:span:start",
|
|
179
|
+
timestamp: startedAt,
|
|
180
|
+
trace: {
|
|
181
|
+
traceId,
|
|
182
|
+
spanId,
|
|
183
|
+
parentSpanId
|
|
184
|
+
},
|
|
185
|
+
correlationId: input.correlationId,
|
|
186
|
+
runId: input.runId,
|
|
187
|
+
span: {
|
|
188
|
+
kind: input.kind,
|
|
189
|
+
name: input.name,
|
|
190
|
+
data: input.data ?? {}
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
try {
|
|
194
|
+
await this.exporter.exportBatch([startEvent]);
|
|
195
|
+
} catch {
|
|
196
|
+
}
|
|
197
|
+
const context = {
|
|
198
|
+
traceId,
|
|
199
|
+
spanId,
|
|
200
|
+
parentId: parentSpanId
|
|
201
|
+
};
|
|
202
|
+
const activeSpan = new ActiveSpan(
|
|
203
|
+
traceId,
|
|
204
|
+
spanId,
|
|
205
|
+
parentSpanId,
|
|
206
|
+
input.kind,
|
|
207
|
+
input.name,
|
|
208
|
+
input.correlationId,
|
|
209
|
+
input.runId,
|
|
210
|
+
this.exporter
|
|
211
|
+
);
|
|
212
|
+
return storage.run(context, async () => {
|
|
213
|
+
try {
|
|
214
|
+
const result = await fn(activeSpan);
|
|
215
|
+
if (!activeSpan.isEnded) await activeSpan.end({ status: "success" });
|
|
216
|
+
return result;
|
|
217
|
+
} catch (error) {
|
|
218
|
+
await activeSpan.end({ status: "error" });
|
|
219
|
+
throw error;
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
// agent/BaseAgent.ts
|
|
226
|
+
var BaseAgent = class {
|
|
227
|
+
name;
|
|
228
|
+
emitter = new import_events.EventEmitter();
|
|
229
|
+
piiMasker;
|
|
230
|
+
memory;
|
|
231
|
+
constructor(name, piiMasker, memory) {
|
|
232
|
+
this.name = name;
|
|
233
|
+
this.piiMasker = piiMasker;
|
|
234
|
+
this.memory = memory;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Adds a message to this agent's memory (if configured).
|
|
238
|
+
* Multi-agent teams MUST provide a memory implementation if they expect to be used
|
|
239
|
+
* through standardized execution surfaces (e.g., HTTP gateways).
|
|
240
|
+
*/
|
|
241
|
+
async addMessage(message) {
|
|
242
|
+
if (!this.memory) {
|
|
243
|
+
throw new Error(`Agent '${this.name}' does not have memory configured`);
|
|
244
|
+
}
|
|
245
|
+
await this.memory.addMessage(message);
|
|
246
|
+
}
|
|
247
|
+
// ==========================================================================
|
|
248
|
+
// Typed Event Emitter Methods
|
|
249
|
+
// ==========================================================================
|
|
250
|
+
/**
|
|
251
|
+
* Emits a typed event with automatic context injection (trace, timestamp).
|
|
252
|
+
*
|
|
253
|
+
* @param event The event name (e.g., 'agent:execution:start')
|
|
254
|
+
* @param payload The event payload containing 'data' and optional context like 'correlationId'
|
|
255
|
+
*/
|
|
256
|
+
emit(event, payload) {
|
|
257
|
+
const traceContext = Tracing.getContext();
|
|
258
|
+
let fullEvent = {
|
|
259
|
+
type: event,
|
|
260
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
261
|
+
trace: {
|
|
262
|
+
traceId: traceContext?.traceId || `fallback-${Date.now()}`,
|
|
263
|
+
spanId: traceContext?.spanId || `fallback-${Date.now()}`,
|
|
264
|
+
parentSpanId: traceContext?.parentId
|
|
265
|
+
},
|
|
266
|
+
correlationId: payload.correlationId,
|
|
267
|
+
runId: payload.runId,
|
|
268
|
+
data: payload.data
|
|
269
|
+
};
|
|
270
|
+
if (this.piiMasker) {
|
|
271
|
+
fullEvent = this.maskEventData(fullEvent);
|
|
272
|
+
}
|
|
273
|
+
return this.emitter.emit(event, fullEvent);
|
|
274
|
+
}
|
|
275
|
+
on(event, listener) {
|
|
276
|
+
this.emitter.on(event, listener);
|
|
277
|
+
return this;
|
|
278
|
+
}
|
|
279
|
+
once(event, listener) {
|
|
280
|
+
this.emitter.once(event, listener);
|
|
281
|
+
return this;
|
|
282
|
+
}
|
|
283
|
+
off(event, listener) {
|
|
284
|
+
this.emitter.off(event, listener);
|
|
285
|
+
return this;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Recursively masks PII in the event payload
|
|
289
|
+
*/
|
|
290
|
+
maskEventData(data) {
|
|
291
|
+
if (!this.piiMasker) return data;
|
|
292
|
+
if (typeof data === "string") {
|
|
293
|
+
return this.piiMasker.mask(data);
|
|
294
|
+
}
|
|
295
|
+
if (Array.isArray(data)) {
|
|
296
|
+
return data.map((item) => this.maskEventData(item));
|
|
297
|
+
}
|
|
298
|
+
if (typeof data === "object" && data !== null) {
|
|
299
|
+
if (data instanceof Date) return data;
|
|
300
|
+
if (data instanceof Error) {
|
|
301
|
+
const maskedError = {
|
|
302
|
+
name: data.name,
|
|
303
|
+
message: this.maskEventData(data.message),
|
|
304
|
+
stack: data.stack
|
|
305
|
+
};
|
|
306
|
+
return maskedError;
|
|
307
|
+
}
|
|
308
|
+
const maskedObj = {};
|
|
309
|
+
for (const key in data) {
|
|
310
|
+
if (Object.prototype.hasOwnProperty.call(data, key)) {
|
|
311
|
+
maskedObj[key] = this.maskEventData(data[key]);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return maskedObj;
|
|
315
|
+
}
|
|
316
|
+
return data;
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
// logger/styles.ts
|
|
321
|
+
var COLORS = {
|
|
322
|
+
// Foreground colors
|
|
323
|
+
black: "\x1B[30m",
|
|
324
|
+
red: "\x1B[31m",
|
|
325
|
+
green: "\x1B[32m",
|
|
326
|
+
yellow: "\x1B[33m",
|
|
327
|
+
blue: "\x1B[34m",
|
|
328
|
+
magenta: "\x1B[35m",
|
|
329
|
+
cyan: "\x1B[36m",
|
|
330
|
+
white: "\x1B[37m",
|
|
331
|
+
gray: "\x1B[90m",
|
|
332
|
+
// Bright variants
|
|
333
|
+
brightRed: "\x1B[91m",
|
|
334
|
+
brightGreen: "\x1B[92m",
|
|
335
|
+
brightYellow: "\x1B[93m",
|
|
336
|
+
brightBlue: "\x1B[94m",
|
|
337
|
+
brightMagenta: "\x1B[95m",
|
|
338
|
+
brightCyan: "\x1B[96m",
|
|
339
|
+
// Custom colors (256-color mode)
|
|
340
|
+
pink: "\x1B[38;5;213m",
|
|
341
|
+
// Rosa/Pink - estilo NestJS
|
|
342
|
+
// Styles
|
|
343
|
+
reset: "\x1B[0m",
|
|
344
|
+
bold: "\x1B[1m",
|
|
345
|
+
dim: "\x1B[2m",
|
|
346
|
+
italic: "\x1B[3m",
|
|
347
|
+
underline: "\x1B[4m"
|
|
348
|
+
};
|
|
349
|
+
var LOG_LEVEL_COLORS = {
|
|
350
|
+
debug: COLORS.pink,
|
|
351
|
+
// Rosa/Pink (NestJS style)
|
|
352
|
+
info: COLORS.brightGreen,
|
|
353
|
+
// Verde (success/positive)
|
|
354
|
+
warn: COLORS.brightYellow,
|
|
355
|
+
// Amarelo (warning)
|
|
356
|
+
error: COLORS.brightRed
|
|
357
|
+
// Vermelho (error)
|
|
358
|
+
};
|
|
359
|
+
var TREE_CHARS = {
|
|
360
|
+
branch: "\u251C\u2500",
|
|
361
|
+
last: "\u2514\u2500",
|
|
362
|
+
vertical: "\u2502 ",
|
|
363
|
+
space: " "
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
// logger/formatters.ts
|
|
367
|
+
function formatLogLine(level, entityName, message, entityType = null, trace) {
|
|
368
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").split(".")[0];
|
|
369
|
+
const levelColor = (level === "none" ? COLORS.reset : LOG_LEVEL_COLORS[level]) || COLORS.reset;
|
|
370
|
+
const levelUpper = level.toUpperCase();
|
|
371
|
+
let prefix;
|
|
372
|
+
if (entityName) {
|
|
373
|
+
const entityLabel = entityType === "workflow" ? "Workflow" : "Agent";
|
|
374
|
+
const entityColor = entityType === "workflow" ? COLORS.brightBlue : COLORS.green;
|
|
375
|
+
prefix = `${COLORS.bold}[Nebula ${levelUpper} | ${entityColor}${COLORS.italic}${entityLabel} ${entityName}${COLORS.reset}${levelColor}${COLORS.bold}]${COLORS.reset}`;
|
|
376
|
+
} else {
|
|
377
|
+
prefix = `${COLORS.bold}[Nebula ${levelUpper}]${COLORS.reset}`;
|
|
378
|
+
}
|
|
379
|
+
const timestampStr = `${COLORS.dim}${timestamp}${COLORS.reset}`;
|
|
380
|
+
return `${levelColor}${prefix} ${timestampStr} ${message}${COLORS.reset}`;
|
|
381
|
+
}
|
|
382
|
+
function formatMetadata(meta, isLastGroup = true) {
|
|
383
|
+
const entries = Object.entries(meta);
|
|
384
|
+
if (entries.length === 0) return [];
|
|
385
|
+
return entries.map(([key, value], index) => {
|
|
386
|
+
const isLast = index === entries.length - 1;
|
|
387
|
+
const char = isLast && isLastGroup ? TREE_CHARS.last : TREE_CHARS.branch;
|
|
388
|
+
const formattedValue = formatValue(value);
|
|
389
|
+
return ` ${COLORS.dim}${char}${COLORS.reset} ${COLORS.bold}${key}:${COLORS.reset} ${formattedValue}`;
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
function formatValue(value) {
|
|
393
|
+
if (value === null) return `${COLORS.dim}null${COLORS.reset}`;
|
|
394
|
+
if (value === void 0) return `${COLORS.dim}undefined${COLORS.reset}`;
|
|
395
|
+
if (typeof value === "string") {
|
|
396
|
+
if (value.includes("\u2713") || value.includes("Success")) {
|
|
397
|
+
return `${COLORS.green}${value}${COLORS.reset}`;
|
|
398
|
+
}
|
|
399
|
+
if (value.includes("\u274C") || value.includes("Error")) {
|
|
400
|
+
return `${COLORS.red}${value}${COLORS.reset}`;
|
|
401
|
+
}
|
|
402
|
+
return value;
|
|
403
|
+
}
|
|
404
|
+
if (typeof value === "number") {
|
|
405
|
+
return `${COLORS.yellow}${value}${COLORS.reset}`;
|
|
406
|
+
}
|
|
407
|
+
if (typeof value === "boolean") {
|
|
408
|
+
return value ? `${COLORS.green}${value}${COLORS.reset}` : `${COLORS.red}${value}${COLORS.reset}`;
|
|
409
|
+
}
|
|
410
|
+
try {
|
|
411
|
+
return `${COLORS.dim}${JSON.stringify(value)}${COLORS.reset}`;
|
|
412
|
+
} catch {
|
|
413
|
+
return `${COLORS.dim}[Object]${COLORS.reset}`;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
function formatError(error) {
|
|
417
|
+
const lines = [];
|
|
418
|
+
if (error instanceof Error) {
|
|
419
|
+
lines.push(` ${TREE_CHARS.branch} ${COLORS.red}${error.message}${COLORS.reset}`);
|
|
420
|
+
if (error.stack) {
|
|
421
|
+
const stackLines = error.stack.split("\n").slice(1, 4);
|
|
422
|
+
stackLines.forEach((line, index) => {
|
|
423
|
+
const isLast = index === stackLines.length - 1;
|
|
424
|
+
const char = isLast ? TREE_CHARS.last : TREE_CHARS.branch;
|
|
425
|
+
lines.push(` ${COLORS.dim}${char} ${line.trim()}${COLORS.reset}`);
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
} else {
|
|
429
|
+
lines.push(` ${TREE_CHARS.last} ${COLORS.red}${String(error)}${COLORS.reset}`);
|
|
430
|
+
}
|
|
431
|
+
return lines;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// logger/agent-logger.ts
|
|
435
|
+
var AgentLogger = class {
|
|
436
|
+
constructor(agent, logger) {
|
|
437
|
+
this.agent = agent;
|
|
438
|
+
this.logger = logger;
|
|
439
|
+
this.bindEvents();
|
|
440
|
+
}
|
|
441
|
+
bindEvents() {
|
|
442
|
+
this.agent.on("agent:llm:call", (event) => {
|
|
443
|
+
const { data, trace } = event;
|
|
444
|
+
this.logger.debug(`LLM Call #${data.step}`, {
|
|
445
|
+
"Messages": data.messages.length,
|
|
446
|
+
"Tools Available": data.tools?.length || 0
|
|
447
|
+
}, data.agentName, "agent", trace);
|
|
448
|
+
});
|
|
449
|
+
this.agent.on("agent:llm:response", (event) => {
|
|
450
|
+
const { data, trace } = event;
|
|
451
|
+
const usage = data.usage ? `${data.usage.promptTokens} prompt + ${data.usage.completionTokens} completion = ${data.usage.totalTokens} total` : "N/A";
|
|
452
|
+
const meta = {
|
|
453
|
+
"Tokens": usage,
|
|
454
|
+
"Tool Calls": data.toolCalls?.length || 0
|
|
455
|
+
};
|
|
456
|
+
if (data.content) {
|
|
457
|
+
meta["Content"] = data.content;
|
|
458
|
+
}
|
|
459
|
+
if (data.toolCalls && data.toolCalls.length > 0) {
|
|
460
|
+
data.toolCalls.forEach((tc, idx) => {
|
|
461
|
+
meta[`Tool ${idx + 1}`] = `${tc.function.name}(${tc.function.arguments})`;
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
this.logger.debug(`LLM Response (Step ${data.step})`, meta, data.agentName, "agent", trace);
|
|
465
|
+
});
|
|
466
|
+
this.agent.on("agent:tool:result", (event) => {
|
|
467
|
+
const { data, trace } = event;
|
|
468
|
+
const status = data.error ? "\u274C Failed" : "\u2713 Success";
|
|
469
|
+
const meta = {
|
|
470
|
+
"Duration": `${data.durationMs}ms`
|
|
471
|
+
};
|
|
472
|
+
if (data.error) {
|
|
473
|
+
meta["Error"] = data.error;
|
|
474
|
+
} else {
|
|
475
|
+
meta["Output"] = typeof data.output === "string" ? data.output : JSON.stringify(data.output);
|
|
476
|
+
}
|
|
477
|
+
this.logger.debug(`Tool Result: ${data.toolName} ${status}`, meta, data.agentName, "agent", trace);
|
|
478
|
+
});
|
|
479
|
+
this.agent.on("agent:execution:start", (event) => {
|
|
480
|
+
const { data, trace, correlationId } = event;
|
|
481
|
+
this.logger.info(`Execution Started`, {
|
|
482
|
+
"CorrelationId": correlationId,
|
|
483
|
+
"Input": data.input
|
|
484
|
+
}, data.agentName, "agent", trace);
|
|
485
|
+
});
|
|
486
|
+
this.agent.on("agent:execution:end", (event) => {
|
|
487
|
+
const { data, trace } = event;
|
|
488
|
+
const duration = (data.durationMs / 1e3).toFixed(2) + "s";
|
|
489
|
+
const usage = data.usage ? `${data.usage.totalTokens} tokens (${data.usage.promptTokens} prompt + ${data.usage.completionTokens} completion${data.usage.reasoningTokens ? ` + ${data.usage.reasoningTokens} reasoning` : ""})` : "N/A";
|
|
490
|
+
this.logger.info(`Execution Finished ${data.status === "success" ? "\u2713" : data.status === "truncated" ? "\u26A0" : "\u274C"}`, {
|
|
491
|
+
"Duration": duration,
|
|
492
|
+
"Usage": usage
|
|
493
|
+
}, data.agentName, "agent", trace);
|
|
494
|
+
});
|
|
495
|
+
this.agent.on("agent:tool:call", (event) => {
|
|
496
|
+
const { data, trace } = event;
|
|
497
|
+
let parsedInput = data.args;
|
|
498
|
+
if (typeof data.args === "string") {
|
|
499
|
+
try {
|
|
500
|
+
parsedInput = JSON.parse(data.args);
|
|
501
|
+
} catch {
|
|
502
|
+
parsedInput = data.args;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
this.logger.info(`Tool Call: ${data.toolName}`, {
|
|
506
|
+
"Input": typeof parsedInput === "string" ? parsedInput : JSON.stringify(parsedInput)
|
|
507
|
+
}, data.agentName, "agent", trace);
|
|
508
|
+
});
|
|
509
|
+
this.agent.on("agent:execution:error", (event) => {
|
|
510
|
+
const { data, trace } = event;
|
|
511
|
+
this.logger.error(
|
|
512
|
+
`Execution Error`,
|
|
513
|
+
data.error,
|
|
514
|
+
// Pass the sanitized error object
|
|
515
|
+
data.agentName,
|
|
516
|
+
"agent",
|
|
517
|
+
trace
|
|
518
|
+
);
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
};
|
|
522
|
+
|
|
523
|
+
// logger/workflow-logger.ts
|
|
524
|
+
var WorkflowLogger = class {
|
|
525
|
+
constructor(workflow, logger) {
|
|
526
|
+
this.workflow = workflow;
|
|
527
|
+
this.logger = logger;
|
|
528
|
+
this.bindEvents();
|
|
529
|
+
}
|
|
530
|
+
bindEvents() {
|
|
531
|
+
const workflowName = this.workflow.name || this.workflow.id;
|
|
532
|
+
this.workflow.on("workflow:step", (event) => {
|
|
533
|
+
const { data, trace } = event;
|
|
534
|
+
if (data.status === "running") {
|
|
535
|
+
this.logger.debug(`Step Started: ${data.stepName || data.nodeId}`, {
|
|
536
|
+
"Node ID": data.nodeId
|
|
537
|
+
}, workflowName, "workflow", trace);
|
|
538
|
+
} else if (data.status === "success") {
|
|
539
|
+
const duration = data.durationMs ? (data.durationMs / 1e3).toFixed(2) + "s" : "N/A";
|
|
540
|
+
this.logger.debug(`Step Completed: ${data.stepName || data.nodeId}`, {
|
|
541
|
+
"Duration": duration
|
|
542
|
+
}, workflowName, "workflow", trace);
|
|
543
|
+
} else if (data.status === "error") {
|
|
544
|
+
const duration = data.durationMs ? (data.durationMs / 1e3).toFixed(2) + "s" : "N/A";
|
|
545
|
+
this.logger.warn(`Step Failed: ${data.stepName || data.nodeId}`, {
|
|
546
|
+
"Duration": duration,
|
|
547
|
+
"Error": data.error?.message
|
|
548
|
+
}, workflowName, "workflow", trace);
|
|
549
|
+
}
|
|
550
|
+
});
|
|
551
|
+
this.workflow.on("workflow:execution:start", (event) => {
|
|
552
|
+
const { data, trace, runId } = event;
|
|
553
|
+
this.logger.info(`Execution Started`, {
|
|
554
|
+
"Workflow ID": data.workflowId,
|
|
555
|
+
"Execution ID": runId,
|
|
556
|
+
"Input": typeof data.input === "string" ? data.input : JSON.stringify(data.input)
|
|
557
|
+
}, workflowName, "workflow", trace);
|
|
558
|
+
});
|
|
559
|
+
this.workflow.on("workflow:execution:end", (event) => {
|
|
560
|
+
const { data, trace } = event;
|
|
561
|
+
const duration = (data.durationMs / 1e3).toFixed(2) + "s";
|
|
562
|
+
this.logger.info(`Execution Completed ${data.status === "success" ? "\u2713" : "\u274C"}`, {
|
|
563
|
+
"Duration": duration,
|
|
564
|
+
"Status": data.status,
|
|
565
|
+
"Output": typeof data.output === "string" ? data.output : JSON.stringify(data.output)
|
|
566
|
+
}, workflowName, "workflow", trace);
|
|
567
|
+
});
|
|
568
|
+
this.workflow.on("workflow:execution:error", (event) => {
|
|
569
|
+
const { data, trace } = event;
|
|
570
|
+
this.logger.error(
|
|
571
|
+
`Execution Error`,
|
|
572
|
+
data.error,
|
|
573
|
+
workflowName,
|
|
574
|
+
"workflow",
|
|
575
|
+
trace
|
|
576
|
+
);
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
};
|
|
580
|
+
|
|
581
|
+
// logger/index.ts
|
|
582
|
+
var LEVEL_WEIGHTS = {
|
|
583
|
+
debug: 0,
|
|
584
|
+
info: 1,
|
|
585
|
+
warn: 2,
|
|
586
|
+
error: 3,
|
|
587
|
+
none: 4
|
|
588
|
+
};
|
|
589
|
+
var ConsoleLogger = class {
|
|
590
|
+
constructor(minLevel = "info") {
|
|
591
|
+
this.minLevel = minLevel;
|
|
592
|
+
}
|
|
593
|
+
shouldLog(level) {
|
|
594
|
+
return LEVEL_WEIGHTS[level] >= LEVEL_WEIGHTS[this.minLevel];
|
|
595
|
+
}
|
|
596
|
+
debug(message, meta, entityName, entityType, trace) {
|
|
597
|
+
if (!this.shouldLog("debug")) return;
|
|
598
|
+
const mainLine = formatLogLine("debug", entityName || null, message, entityType || null, trace);
|
|
599
|
+
console.debug(mainLine);
|
|
600
|
+
if (meta && typeof meta === "object" && Object.keys(meta).length > 0) {
|
|
601
|
+
const metaLines = formatMetadata(meta);
|
|
602
|
+
metaLines.forEach((line) => console.debug(line));
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
info(message, meta, entityName, entityType, trace) {
|
|
606
|
+
if (!this.shouldLog("info")) return;
|
|
607
|
+
const mainLine = formatLogLine("info", entityName || null, message, entityType || null, trace);
|
|
608
|
+
console.info(mainLine);
|
|
609
|
+
if (meta && typeof meta === "object" && Object.keys(meta).length > 0) {
|
|
610
|
+
const metaLines = formatMetadata(meta);
|
|
611
|
+
metaLines.forEach((line) => console.info(line));
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
warn(message, meta, entityName, entityType, trace) {
|
|
615
|
+
if (!this.shouldLog("warn")) return;
|
|
616
|
+
const mainLine = formatLogLine("warn", entityName || null, message, entityType || null, trace);
|
|
617
|
+
console.warn(mainLine);
|
|
618
|
+
if (meta && typeof meta === "object" && Object.keys(meta).length > 0) {
|
|
619
|
+
const metaLines = formatMetadata(meta);
|
|
620
|
+
metaLines.forEach((line) => console.warn(line));
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
error(message, error, entityName, entityType, trace) {
|
|
624
|
+
if (!this.shouldLog("error")) return;
|
|
625
|
+
const mainLine = formatLogLine("error", entityName || null, message, entityType || null, trace);
|
|
626
|
+
console.error(mainLine);
|
|
627
|
+
if (error) {
|
|
628
|
+
const errorLines = formatError(error);
|
|
629
|
+
errorLines.forEach((line) => console.error(line));
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
};
|
|
633
|
+
|
|
634
|
+
// agent/Agent.ts
|
|
635
|
+
function generateCorrelationId() {
|
|
636
|
+
return `exec_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
637
|
+
}
|
|
638
|
+
var Agent = class extends BaseAgent {
|
|
639
|
+
constructor(config) {
|
|
640
|
+
super(config.name, config.piiMasker, config.memory);
|
|
641
|
+
this.config = config;
|
|
642
|
+
this.requestInterceptors = config.interceptors?.request || [];
|
|
643
|
+
this.responseInterceptors = config.interceptors?.response || [];
|
|
644
|
+
const logger = config.logger || new ConsoleLogger(config.logLevel || "error");
|
|
645
|
+
this.loggerAdapter = new AgentLogger(this, logger);
|
|
646
|
+
}
|
|
647
|
+
resolvedInstructions;
|
|
648
|
+
requestInterceptors = [];
|
|
649
|
+
responseInterceptors = [];
|
|
650
|
+
// @ts-ignore: used for side-effects (binding events)
|
|
651
|
+
loggerAdapter;
|
|
652
|
+
// ==========================================================================
|
|
653
|
+
// Instructions
|
|
654
|
+
// ==========================================================================
|
|
655
|
+
async resolveInstructions() {
|
|
656
|
+
if (this.resolvedInstructions !== void 0) return this.resolvedInstructions;
|
|
657
|
+
if (typeof this.config.instructions === "string") {
|
|
658
|
+
this.resolvedInstructions = this.config.instructions;
|
|
659
|
+
return this.resolvedInstructions;
|
|
660
|
+
}
|
|
661
|
+
if (this.isInstruction(this.config.instructions)) {
|
|
662
|
+
this.resolvedInstructions = await this.config.instructions.resolve();
|
|
663
|
+
return this.resolvedInstructions;
|
|
664
|
+
}
|
|
665
|
+
return "";
|
|
666
|
+
}
|
|
667
|
+
isInstruction(obj) {
|
|
668
|
+
return obj && typeof obj.resolve === "function";
|
|
669
|
+
}
|
|
670
|
+
clearInstructionsCache() {
|
|
671
|
+
this.resolvedInstructions = void 0;
|
|
672
|
+
}
|
|
673
|
+
// ==========================================================================
|
|
674
|
+
// Memory
|
|
675
|
+
// ==========================================================================
|
|
676
|
+
async addMessage(message) {
|
|
677
|
+
this.memory = this.config.memory;
|
|
678
|
+
await this.config.memory.addMessage(message);
|
|
679
|
+
}
|
|
680
|
+
async getMessages() {
|
|
681
|
+
const instructions = await this.resolveInstructions();
|
|
682
|
+
const msgs = await this.config.memory.getMessages();
|
|
683
|
+
if (instructions && !msgs.some((m) => m.role === "system")) {
|
|
684
|
+
msgs.unshift({ role: "system", content: instructions });
|
|
685
|
+
}
|
|
686
|
+
return msgs;
|
|
687
|
+
}
|
|
688
|
+
async execute(arg1 = {}, arg2 = {}) {
|
|
689
|
+
const input = typeof arg1 === "string" ? arg1 : void 0;
|
|
690
|
+
const options = typeof arg1 === "string" ? arg2 ?? {} : arg1 ?? {};
|
|
691
|
+
const startTime = Date.now();
|
|
692
|
+
const correlationId = generateCorrelationId();
|
|
693
|
+
const maxSteps = options.maxSteps ?? this.config.maxSteps ?? 10;
|
|
694
|
+
const toolExecutions = [];
|
|
695
|
+
const collectedToolCalls = [];
|
|
696
|
+
let llmCalls = 0;
|
|
697
|
+
let truncated = false;
|
|
698
|
+
let totalUsage = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };
|
|
699
|
+
return Tracing.withSpan(
|
|
700
|
+
{
|
|
701
|
+
kind: "agent",
|
|
702
|
+
name: `agent:${this.name}`,
|
|
703
|
+
correlationId,
|
|
704
|
+
data: { agentName: this.name, input }
|
|
705
|
+
},
|
|
706
|
+
async (agentSpan) => {
|
|
707
|
+
this.emit("agent:execution:start", {
|
|
708
|
+
correlationId,
|
|
709
|
+
data: {
|
|
710
|
+
agentName: this.name,
|
|
711
|
+
input
|
|
712
|
+
}
|
|
713
|
+
});
|
|
714
|
+
try {
|
|
715
|
+
if (input) {
|
|
716
|
+
await this.addMessage({ role: "user", content: input });
|
|
717
|
+
}
|
|
718
|
+
let step = 0;
|
|
719
|
+
while (step < maxSteps) {
|
|
720
|
+
step++;
|
|
721
|
+
llmCalls++;
|
|
722
|
+
let messages = await this.getMessages();
|
|
723
|
+
let tools = !options.disableTools && this.config.tools ? [...this.config.tools] : [];
|
|
724
|
+
let context2 = { messages, tools };
|
|
725
|
+
for (const interceptor of this.requestInterceptors) {
|
|
726
|
+
context2 = await interceptor(context2);
|
|
727
|
+
}
|
|
728
|
+
messages = context2.messages;
|
|
729
|
+
tools = context2.tools;
|
|
730
|
+
const llmTools = tools.length > 0 ? tools.map((t) => t.toLLMDefinition()) : void 0;
|
|
731
|
+
this.emit("agent:llm:call", {
|
|
732
|
+
correlationId,
|
|
733
|
+
data: {
|
|
734
|
+
agentName: this.name,
|
|
735
|
+
step,
|
|
736
|
+
messages,
|
|
737
|
+
tools: llmTools,
|
|
738
|
+
responseFormat: options.responseFormat,
|
|
739
|
+
model: {
|
|
740
|
+
provider: this.config.model.providerName,
|
|
741
|
+
model: this.config.model.modelName
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
});
|
|
745
|
+
const rawResponse = await Tracing.withSpan(
|
|
746
|
+
{
|
|
747
|
+
kind: "llm",
|
|
748
|
+
name: `llm:step${step}`,
|
|
749
|
+
correlationId,
|
|
750
|
+
data: {
|
|
751
|
+
provider: this.config.model.providerName,
|
|
752
|
+
model: this.config.model.modelName,
|
|
753
|
+
step,
|
|
754
|
+
messagesCount: messages.length,
|
|
755
|
+
toolsCount: llmTools?.length ?? 0,
|
|
756
|
+
responseFormat: options.responseFormat
|
|
757
|
+
}
|
|
758
|
+
},
|
|
759
|
+
async (llmSpan) => {
|
|
760
|
+
try {
|
|
761
|
+
const resp = await this.config.model.generate(messages, llmTools, {
|
|
762
|
+
responseFormat: options.responseFormat
|
|
763
|
+
});
|
|
764
|
+
await llmSpan.end({
|
|
765
|
+
status: "success",
|
|
766
|
+
data: {
|
|
767
|
+
usage: resp.usage,
|
|
768
|
+
toolCallsCount: resp.toolCalls?.length ?? 0,
|
|
769
|
+
outputPreview: typeof resp.content === "string" ? resp.content.substring(0, 200) : "json_content"
|
|
770
|
+
}
|
|
771
|
+
});
|
|
772
|
+
return resp;
|
|
773
|
+
} catch (e) {
|
|
774
|
+
await llmSpan.end({ status: "error" });
|
|
775
|
+
throw e;
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
);
|
|
779
|
+
let response = rawResponse;
|
|
780
|
+
this.emit("agent:llm:response", {
|
|
781
|
+
correlationId,
|
|
782
|
+
data: {
|
|
783
|
+
agentName: this.name,
|
|
784
|
+
step,
|
|
785
|
+
content: response.content,
|
|
786
|
+
toolCalls: response.toolCalls,
|
|
787
|
+
usage: response.usage,
|
|
788
|
+
model: {
|
|
789
|
+
provider: this.config.model.providerName,
|
|
790
|
+
model: this.config.model.modelName
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
});
|
|
794
|
+
if (response.usage) {
|
|
795
|
+
totalUsage.promptTokens += response.usage.promptTokens;
|
|
796
|
+
totalUsage.completionTokens += response.usage.completionTokens;
|
|
797
|
+
totalUsage.totalTokens += response.usage.totalTokens;
|
|
798
|
+
if (response.usage.reasoningTokens) {
|
|
799
|
+
totalUsage.reasoningTokens = (totalUsage.reasoningTokens || 0) + response.usage.reasoningTokens;
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
if (!response.toolCalls || response.toolCalls.length === 0 || options.disableTools) {
|
|
803
|
+
for (const interceptor of this.responseInterceptors) {
|
|
804
|
+
response = await interceptor(response);
|
|
805
|
+
}
|
|
806
|
+
await this.addMessage({ role: "assistant", content: response.content });
|
|
807
|
+
await agentSpan.end({
|
|
808
|
+
status: "success",
|
|
809
|
+
data: {
|
|
810
|
+
output: options.responseFormat?.type === "json" ? this.safeParseJson(response.content) : response.content,
|
|
811
|
+
usage: totalUsage
|
|
812
|
+
}
|
|
813
|
+
});
|
|
814
|
+
return this.finishResult({
|
|
815
|
+
correlationId,
|
|
816
|
+
content: options.responseFormat?.type === "json" ? this.safeParseJson(response.content) : response.content,
|
|
817
|
+
toolExecutions,
|
|
818
|
+
toolCalls: options.disableTools ? response.toolCalls : void 0,
|
|
819
|
+
llmCalls,
|
|
820
|
+
totalDurationMs: Date.now() - startTime,
|
|
821
|
+
truncated: false,
|
|
822
|
+
totalUsage
|
|
823
|
+
});
|
|
824
|
+
}
|
|
825
|
+
await this.addMessage({
|
|
826
|
+
role: "assistant",
|
|
827
|
+
content: response.content,
|
|
828
|
+
tool_calls: response.toolCalls
|
|
829
|
+
});
|
|
830
|
+
for (const toolCall of response.toolCalls) {
|
|
831
|
+
await Tracing.withSpan(
|
|
832
|
+
{
|
|
833
|
+
kind: "tool",
|
|
834
|
+
name: `tool:${toolCall.function.name}`,
|
|
835
|
+
correlationId,
|
|
836
|
+
data: {
|
|
837
|
+
toolName: toolCall.function.name,
|
|
838
|
+
toolCallId: toolCall.id,
|
|
839
|
+
args: toolCall.function.arguments
|
|
840
|
+
}
|
|
841
|
+
},
|
|
842
|
+
async (toolSpan) => {
|
|
843
|
+
this.emit("agent:tool:call", {
|
|
844
|
+
correlationId,
|
|
845
|
+
data: {
|
|
846
|
+
agentName: this.name,
|
|
847
|
+
toolName: toolCall.function.name,
|
|
848
|
+
toolCallId: toolCall.id,
|
|
849
|
+
args: toolCall.function.arguments
|
|
850
|
+
}
|
|
851
|
+
});
|
|
852
|
+
const execution = await this.executeToolCall(toolCall);
|
|
853
|
+
toolExecutions.push(execution);
|
|
854
|
+
collectedToolCalls.push(toolCall);
|
|
855
|
+
this.emit("agent:tool:result", {
|
|
856
|
+
correlationId,
|
|
857
|
+
data: {
|
|
858
|
+
agentName: this.name,
|
|
859
|
+
toolName: toolCall.function.name,
|
|
860
|
+
toolCallId: toolCall.id,
|
|
861
|
+
output: execution.output,
|
|
862
|
+
error: execution.error,
|
|
863
|
+
durationMs: execution.durationMs
|
|
864
|
+
}
|
|
865
|
+
});
|
|
866
|
+
await toolSpan.end({
|
|
867
|
+
status: execution.error ? "error" : "success",
|
|
868
|
+
data: {
|
|
869
|
+
output: execution.output,
|
|
870
|
+
error: execution.error
|
|
871
|
+
}
|
|
872
|
+
});
|
|
873
|
+
await this.addMessage({
|
|
874
|
+
role: "tool",
|
|
875
|
+
tool_call_id: toolCall.id,
|
|
876
|
+
content: execution.error ? `Error: ${execution.error}` : JSON.stringify(execution.output)
|
|
877
|
+
});
|
|
878
|
+
}
|
|
879
|
+
);
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
truncated = true;
|
|
883
|
+
llmCalls++;
|
|
884
|
+
let finalMessages = await this.getMessages();
|
|
885
|
+
let finalTools = !options.disableTools && this.config.tools ? [...this.config.tools] : [];
|
|
886
|
+
let context = { messages: finalMessages, tools: finalTools };
|
|
887
|
+
for (const interceptor of this.requestInterceptors) {
|
|
888
|
+
context = await interceptor(context);
|
|
889
|
+
}
|
|
890
|
+
finalMessages = context.messages;
|
|
891
|
+
let finalResponse = await this.config.model.generate(finalMessages);
|
|
892
|
+
for (const interceptor of this.responseInterceptors) {
|
|
893
|
+
finalResponse = await interceptor(finalResponse);
|
|
894
|
+
}
|
|
895
|
+
await this.addMessage({ role: "assistant", content: finalResponse.content });
|
|
896
|
+
await agentSpan.end({
|
|
897
|
+
status: truncated ? "cancelled" : "success",
|
|
898
|
+
data: {
|
|
899
|
+
output: finalResponse.content,
|
|
900
|
+
usage: totalUsage
|
|
901
|
+
}
|
|
902
|
+
});
|
|
903
|
+
return this.finishResult({
|
|
904
|
+
correlationId,
|
|
905
|
+
content: finalResponse.content,
|
|
906
|
+
toolExecutions,
|
|
907
|
+
toolCalls: collectedToolCalls,
|
|
908
|
+
llmCalls,
|
|
909
|
+
totalDurationMs: Date.now() - startTime,
|
|
910
|
+
truncated,
|
|
911
|
+
totalUsage
|
|
912
|
+
});
|
|
913
|
+
} catch (err) {
|
|
914
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
915
|
+
this.emit("agent:execution:error", {
|
|
916
|
+
correlationId,
|
|
917
|
+
data: {
|
|
918
|
+
agentName: this.name,
|
|
919
|
+
error: {
|
|
920
|
+
message: error.message,
|
|
921
|
+
stack: error.stack,
|
|
922
|
+
name: error.name
|
|
923
|
+
},
|
|
924
|
+
durationMs: Date.now() - startTime
|
|
925
|
+
}
|
|
926
|
+
});
|
|
927
|
+
await agentSpan.end({ status: "error" });
|
|
928
|
+
throw err;
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
);
|
|
932
|
+
}
|
|
933
|
+
async *executeStream(options = {}) {
|
|
934
|
+
const startTime = Date.now();
|
|
935
|
+
const correlationId = generateCorrelationId();
|
|
936
|
+
const maxSteps = options.maxSteps ?? this.config.maxSteps ?? 10;
|
|
937
|
+
const toolExecutions = [];
|
|
938
|
+
const collectedToolCalls = [];
|
|
939
|
+
let llmCalls = 0;
|
|
940
|
+
let truncated = false;
|
|
941
|
+
let totalUsage = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };
|
|
942
|
+
this.emit("agent:execution:start", {
|
|
943
|
+
correlationId,
|
|
944
|
+
data: {
|
|
945
|
+
agentName: this.name,
|
|
946
|
+
input: void 0
|
|
947
|
+
}
|
|
948
|
+
});
|
|
949
|
+
try {
|
|
950
|
+
let step = 0;
|
|
951
|
+
while (step < maxSteps) {
|
|
952
|
+
step++;
|
|
953
|
+
llmCalls++;
|
|
954
|
+
let messages = await this.getMessages();
|
|
955
|
+
let tools = !options.disableTools && this.config.tools ? [...this.config.tools] : [];
|
|
956
|
+
let context = { messages, tools };
|
|
957
|
+
for (const interceptor of this.requestInterceptors) {
|
|
958
|
+
context = await interceptor(context);
|
|
959
|
+
}
|
|
960
|
+
messages = context.messages;
|
|
961
|
+
tools = context.tools;
|
|
962
|
+
const llmTools = tools.length > 0 ? tools.map((t) => t.toLLMDefinition()) : void 0;
|
|
963
|
+
this.emit("agent:llm:call", {
|
|
964
|
+
correlationId,
|
|
965
|
+
data: {
|
|
966
|
+
agentName: this.name,
|
|
967
|
+
step,
|
|
968
|
+
messages,
|
|
969
|
+
tools: llmTools,
|
|
970
|
+
responseFormat: options.responseFormat,
|
|
971
|
+
model: {
|
|
972
|
+
provider: this.config.model.providerName,
|
|
973
|
+
model: this.config.model.modelName
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
});
|
|
977
|
+
const stream = this.config.model.generateStream(messages, llmTools, { responseFormat: options.responseFormat });
|
|
978
|
+
let fullContent = "";
|
|
979
|
+
let toolCallsBuffer = {};
|
|
980
|
+
let chunkUsage;
|
|
981
|
+
for await (const chunk of stream) {
|
|
982
|
+
yield chunk;
|
|
983
|
+
if (chunk.type === "content_delta") {
|
|
984
|
+
fullContent += chunk.delta;
|
|
985
|
+
} else if (chunk.type === "tool_call_start") {
|
|
986
|
+
toolCallsBuffer[chunk.index] = { id: chunk.id, name: chunk.name, args: "" };
|
|
987
|
+
} else if (chunk.type === "tool_call_delta") {
|
|
988
|
+
if (toolCallsBuffer[chunk.index]) {
|
|
989
|
+
toolCallsBuffer[chunk.index].args += chunk.args;
|
|
990
|
+
}
|
|
991
|
+
} else if (chunk.type === "finish") {
|
|
992
|
+
chunkUsage = chunk.usage;
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
if (chunkUsage) {
|
|
996
|
+
totalUsage.promptTokens += chunkUsage.promptTokens;
|
|
997
|
+
totalUsage.completionTokens += chunkUsage.completionTokens;
|
|
998
|
+
totalUsage.totalTokens += chunkUsage.totalTokens;
|
|
999
|
+
if (chunkUsage.reasoningTokens) {
|
|
1000
|
+
totalUsage.reasoningTokens = (totalUsage.reasoningTokens || 0) + chunkUsage.reasoningTokens;
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
const toolCalls = Object.values(toolCallsBuffer).map((tc) => ({
|
|
1004
|
+
id: tc.id,
|
|
1005
|
+
type: "function",
|
|
1006
|
+
function: { name: tc.name, arguments: tc.args }
|
|
1007
|
+
}));
|
|
1008
|
+
this.emit("agent:llm:response", {
|
|
1009
|
+
correlationId,
|
|
1010
|
+
data: {
|
|
1011
|
+
agentName: this.name,
|
|
1012
|
+
step,
|
|
1013
|
+
content: fullContent,
|
|
1014
|
+
toolCalls: toolCalls.length > 0 ? toolCalls : void 0,
|
|
1015
|
+
usage: chunkUsage,
|
|
1016
|
+
model: {
|
|
1017
|
+
provider: this.config.model.providerName,
|
|
1018
|
+
model: this.config.model.modelName
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
});
|
|
1022
|
+
if (toolCalls.length === 0 || options.disableTools) {
|
|
1023
|
+
await this.addMessage({ role: "assistant", content: fullContent });
|
|
1024
|
+
this.emit("agent:execution:end", {
|
|
1025
|
+
correlationId,
|
|
1026
|
+
data: {
|
|
1027
|
+
agentName: this.name,
|
|
1028
|
+
status: "success",
|
|
1029
|
+
output: options.responseFormat?.type === "json" ? this.safeParseJson(fullContent) : fullContent,
|
|
1030
|
+
durationMs: Date.now() - startTime,
|
|
1031
|
+
usage: totalUsage
|
|
1032
|
+
}
|
|
1033
|
+
});
|
|
1034
|
+
return;
|
|
1035
|
+
}
|
|
1036
|
+
await this.addMessage({ role: "assistant", content: fullContent || null, tool_calls: toolCalls });
|
|
1037
|
+
for (const toolCall of toolCalls) {
|
|
1038
|
+
const execution = await Tracing.withSpan(
|
|
1039
|
+
{
|
|
1040
|
+
kind: "tool",
|
|
1041
|
+
name: `tool:${toolCall.function.name}`,
|
|
1042
|
+
correlationId,
|
|
1043
|
+
data: {
|
|
1044
|
+
toolName: toolCall.function.name,
|
|
1045
|
+
toolCallId: toolCall.id,
|
|
1046
|
+
args: toolCall.function.arguments
|
|
1047
|
+
}
|
|
1048
|
+
},
|
|
1049
|
+
async (toolSpan) => {
|
|
1050
|
+
this.emit("agent:tool:call", {
|
|
1051
|
+
correlationId,
|
|
1052
|
+
data: {
|
|
1053
|
+
agentName: this.name,
|
|
1054
|
+
toolName: toolCall.function.name,
|
|
1055
|
+
toolCallId: toolCall.id,
|
|
1056
|
+
args: toolCall.function.arguments
|
|
1057
|
+
}
|
|
1058
|
+
});
|
|
1059
|
+
const exec = await this.executeToolCall(toolCall);
|
|
1060
|
+
toolExecutions.push(exec);
|
|
1061
|
+
collectedToolCalls.push(toolCall);
|
|
1062
|
+
this.emit("agent:tool:result", {
|
|
1063
|
+
correlationId,
|
|
1064
|
+
data: {
|
|
1065
|
+
agentName: this.name,
|
|
1066
|
+
toolName: toolCall.function.name,
|
|
1067
|
+
toolCallId: toolCall.id,
|
|
1068
|
+
output: exec.output,
|
|
1069
|
+
error: exec.error,
|
|
1070
|
+
durationMs: exec.durationMs
|
|
1071
|
+
}
|
|
1072
|
+
});
|
|
1073
|
+
await toolSpan.end({
|
|
1074
|
+
status: exec.error ? "error" : "success",
|
|
1075
|
+
data: { output: exec.output, error: exec.error }
|
|
1076
|
+
});
|
|
1077
|
+
return exec;
|
|
1078
|
+
}
|
|
1079
|
+
);
|
|
1080
|
+
yield {
|
|
1081
|
+
type: "tool_result",
|
|
1082
|
+
toolCallId: toolCall.id,
|
|
1083
|
+
result: execution.output
|
|
1084
|
+
};
|
|
1085
|
+
await this.addMessage({
|
|
1086
|
+
role: "tool",
|
|
1087
|
+
tool_call_id: toolCall.id,
|
|
1088
|
+
content: execution.error ? `Error: ${execution.error}` : JSON.stringify(execution.output)
|
|
1089
|
+
});
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
truncated = true;
|
|
1093
|
+
llmCalls++;
|
|
1094
|
+
let finalMessages = await this.getMessages();
|
|
1095
|
+
let finalTools = !options.disableTools && this.config.tools ? [...this.config.tools] : [];
|
|
1096
|
+
let finalContext = { messages: finalMessages, tools: finalTools };
|
|
1097
|
+
for (const interceptor of this.requestInterceptors) {
|
|
1098
|
+
finalContext = await interceptor(finalContext);
|
|
1099
|
+
}
|
|
1100
|
+
finalMessages = finalContext.messages;
|
|
1101
|
+
const finalResponse = await this.config.model.generate(finalMessages);
|
|
1102
|
+
if (finalResponse.usage) {
|
|
1103
|
+
totalUsage.promptTokens += finalResponse.usage.promptTokens;
|
|
1104
|
+
totalUsage.completionTokens += finalResponse.usage.completionTokens;
|
|
1105
|
+
totalUsage.totalTokens += finalResponse.usage.totalTokens;
|
|
1106
|
+
if (finalResponse.usage.reasoningTokens) {
|
|
1107
|
+
totalUsage.reasoningTokens = (totalUsage.reasoningTokens || 0) + finalResponse.usage.reasoningTokens;
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
await this.addMessage({ role: "assistant", content: finalResponse.content });
|
|
1111
|
+
this.emit("agent:execution:end", {
|
|
1112
|
+
correlationId,
|
|
1113
|
+
data: {
|
|
1114
|
+
agentName: this.name,
|
|
1115
|
+
status: truncated ? "truncated" : "success",
|
|
1116
|
+
output: finalResponse.content,
|
|
1117
|
+
durationMs: Date.now() - startTime,
|
|
1118
|
+
usage: totalUsage
|
|
1119
|
+
}
|
|
1120
|
+
});
|
|
1121
|
+
} catch (err) {
|
|
1122
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
1123
|
+
this.emit("agent:execution:error", {
|
|
1124
|
+
correlationId,
|
|
1125
|
+
data: {
|
|
1126
|
+
agentName: this.name,
|
|
1127
|
+
error: {
|
|
1128
|
+
message: error.message,
|
|
1129
|
+
stack: error.stack,
|
|
1130
|
+
name: error.name
|
|
1131
|
+
},
|
|
1132
|
+
durationMs: Date.now() - startTime
|
|
1133
|
+
}
|
|
1134
|
+
});
|
|
1135
|
+
yield { type: "error", error };
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
// ==========================================================================
|
|
1139
|
+
// Tools Execution
|
|
1140
|
+
// ==========================================================================
|
|
1141
|
+
async executeToolCall(toolCall) {
|
|
1142
|
+
const startTime = Date.now();
|
|
1143
|
+
const toolName = toolCall.function.name;
|
|
1144
|
+
const tool = this.config.tools?.find((t) => t.id === toolName);
|
|
1145
|
+
if (!tool) {
|
|
1146
|
+
return {
|
|
1147
|
+
id: toolCall.id,
|
|
1148
|
+
name: toolName,
|
|
1149
|
+
input: toolCall.function.arguments,
|
|
1150
|
+
output: null,
|
|
1151
|
+
durationMs: Date.now() - startTime,
|
|
1152
|
+
error: `Tool '${toolName}' not found`
|
|
1153
|
+
};
|
|
1154
|
+
}
|
|
1155
|
+
try {
|
|
1156
|
+
const output = await tool.execute({}, toolCall.function.arguments);
|
|
1157
|
+
return {
|
|
1158
|
+
id: toolCall.id,
|
|
1159
|
+
name: toolName,
|
|
1160
|
+
input: toolCall.function.arguments,
|
|
1161
|
+
output,
|
|
1162
|
+
durationMs: Date.now() - startTime
|
|
1163
|
+
};
|
|
1164
|
+
} catch (error) {
|
|
1165
|
+
return {
|
|
1166
|
+
id: toolCall.id,
|
|
1167
|
+
name: toolName,
|
|
1168
|
+
input: toolCall.function.arguments,
|
|
1169
|
+
output: null,
|
|
1170
|
+
durationMs: Date.now() - startTime,
|
|
1171
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1172
|
+
};
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
// ==========================================================================
|
|
1176
|
+
// Helpers
|
|
1177
|
+
// ==========================================================================
|
|
1178
|
+
safeParseJson(content) {
|
|
1179
|
+
if (!content) return null;
|
|
1180
|
+
try {
|
|
1181
|
+
return JSON.parse(content);
|
|
1182
|
+
} catch {
|
|
1183
|
+
return content;
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
finishResult(params) {
|
|
1187
|
+
const result = {
|
|
1188
|
+
content: params.content,
|
|
1189
|
+
toolExecutions: params.toolExecutions,
|
|
1190
|
+
toolCalls: params.toolCalls,
|
|
1191
|
+
llmCalls: params.llmCalls,
|
|
1192
|
+
totalDurationMs: params.totalDurationMs,
|
|
1193
|
+
truncated: params.truncated
|
|
1194
|
+
};
|
|
1195
|
+
this.emit("agent:execution:end", {
|
|
1196
|
+
correlationId: params.correlationId,
|
|
1197
|
+
data: {
|
|
1198
|
+
agentName: this.name,
|
|
1199
|
+
status: params.truncated ? "truncated" : "success",
|
|
1200
|
+
output: result.content,
|
|
1201
|
+
usage: params.totalUsage,
|
|
1202
|
+
durationMs: params.totalDurationMs
|
|
1203
|
+
}
|
|
1204
|
+
});
|
|
1205
|
+
return result;
|
|
1206
|
+
}
|
|
1207
|
+
};
|
|
1208
|
+
|
|
1209
|
+
// agent/memory/in-memory.ts
|
|
1210
|
+
var InMemory = class {
|
|
1211
|
+
constructor(options = {}) {
|
|
1212
|
+
this.options = options;
|
|
1213
|
+
}
|
|
1214
|
+
messages = [];
|
|
1215
|
+
async addMessage(message) {
|
|
1216
|
+
this.messages.push(message);
|
|
1217
|
+
if (this.options.maxMessages && this.messages.length > this.options.maxMessages) {
|
|
1218
|
+
const systemMessage = this.messages.find((m) => m.role === "system");
|
|
1219
|
+
const removeCount = this.messages.length - this.options.maxMessages;
|
|
1220
|
+
this.messages.splice(0, removeCount);
|
|
1221
|
+
if (systemMessage && !this.messages.includes(systemMessage)) {
|
|
1222
|
+
this.messages.unshift(systemMessage);
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
async getMessages() {
|
|
1227
|
+
return [...this.messages];
|
|
1228
|
+
}
|
|
1229
|
+
async clear() {
|
|
1230
|
+
this.messages = [];
|
|
1231
|
+
}
|
|
1232
|
+
};
|
|
1233
|
+
|
|
1234
|
+
// agent/tools/index.ts
|
|
1235
|
+
var import_zod_to_json_schema = require("zod-to-json-schema");
|
|
1236
|
+
function toJsonSchema(input) {
|
|
1237
|
+
const defaultSchema = { type: "object", properties: {}, required: [] };
|
|
1238
|
+
if (input && typeof input === "object" && "_def" in input) {
|
|
1239
|
+
try {
|
|
1240
|
+
const schema = (0, import_zod_to_json_schema.zodToJsonSchema)(input, {
|
|
1241
|
+
$refStrategy: "none",
|
|
1242
|
+
target: "openApi3"
|
|
1243
|
+
});
|
|
1244
|
+
return {
|
|
1245
|
+
type: "object",
|
|
1246
|
+
properties: schema.properties ?? {},
|
|
1247
|
+
required: schema.required ?? []
|
|
1248
|
+
};
|
|
1249
|
+
} catch {
|
|
1250
|
+
return defaultSchema;
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
if (input && typeof input === "object" && "type" in input) {
|
|
1254
|
+
const obj = input;
|
|
1255
|
+
return {
|
|
1256
|
+
type: "object",
|
|
1257
|
+
properties: obj.properties ?? {},
|
|
1258
|
+
required: obj.required ?? []
|
|
1259
|
+
};
|
|
1260
|
+
}
|
|
1261
|
+
return defaultSchema;
|
|
1262
|
+
}
|
|
1263
|
+
var Tool = class {
|
|
1264
|
+
id;
|
|
1265
|
+
description;
|
|
1266
|
+
inputSchema;
|
|
1267
|
+
handler;
|
|
1268
|
+
constructor(config) {
|
|
1269
|
+
this.id = config.id;
|
|
1270
|
+
this.description = config.description;
|
|
1271
|
+
this.inputSchema = config.inputSchema;
|
|
1272
|
+
this.handler = config.handler;
|
|
1273
|
+
}
|
|
1274
|
+
/**
|
|
1275
|
+
* Converte a tool para o formato esperado pelo LLM
|
|
1276
|
+
*/
|
|
1277
|
+
toLLMDefinition() {
|
|
1278
|
+
return {
|
|
1279
|
+
type: "function",
|
|
1280
|
+
function: {
|
|
1281
|
+
name: this.id,
|
|
1282
|
+
description: this.description,
|
|
1283
|
+
parameters: this.inputSchema ? toJsonSchema(this.inputSchema) : void 0
|
|
1284
|
+
}
|
|
1285
|
+
};
|
|
1286
|
+
}
|
|
1287
|
+
/**
|
|
1288
|
+
* Executa a tool com validação de input
|
|
1289
|
+
*/
|
|
1290
|
+
async execute(context, input) {
|
|
1291
|
+
let parsedInput = input;
|
|
1292
|
+
if (this.inputSchema) {
|
|
1293
|
+
if (typeof input === "string") {
|
|
1294
|
+
try {
|
|
1295
|
+
parsedInput = JSON.parse(input);
|
|
1296
|
+
} catch {
|
|
1297
|
+
throw new Error(`Invalid JSON input for tool ${this.id}`);
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
const result = this.inputSchema.safeParse(parsedInput);
|
|
1301
|
+
if (!result.success) {
|
|
1302
|
+
throw new Error(`Invalid input for tool ${this.id}: ${result.error.message}`);
|
|
1303
|
+
}
|
|
1304
|
+
parsedInput = result.data;
|
|
1305
|
+
}
|
|
1306
|
+
if (this.handler) {
|
|
1307
|
+
return this.handler(context, parsedInput);
|
|
1308
|
+
}
|
|
1309
|
+
throw new Error(`Tool ${this.id} has no handler implementation.`);
|
|
1310
|
+
}
|
|
1311
|
+
};
|
|
1312
|
+
|
|
1313
|
+
// workflow/Workflow.ts
|
|
1314
|
+
var import_uuid = require("uuid");
|
|
1315
|
+
var import_promises = require("timers/promises");
|
|
1316
|
+
var import_events2 = require("events");
|
|
1317
|
+
|
|
1318
|
+
// workflow/adapters.ts
|
|
1319
|
+
function calculateRetryDelay(policy, attempt) {
|
|
1320
|
+
const { backoff, initialDelay, maxDelay = 6e4 } = policy;
|
|
1321
|
+
let delay;
|
|
1322
|
+
switch (backoff) {
|
|
1323
|
+
case "exponential":
|
|
1324
|
+
delay = initialDelay * Math.pow(2, attempt - 1);
|
|
1325
|
+
break;
|
|
1326
|
+
case "linear":
|
|
1327
|
+
delay = initialDelay * attempt;
|
|
1328
|
+
break;
|
|
1329
|
+
case "fixed":
|
|
1330
|
+
default:
|
|
1331
|
+
delay = initialDelay;
|
|
1332
|
+
}
|
|
1333
|
+
return Math.min(delay, maxDelay);
|
|
1334
|
+
}
|
|
1335
|
+
function isRetryableError(error, policy) {
|
|
1336
|
+
if (!policy.retryableErrors || policy.retryableErrors.length === 0) {
|
|
1337
|
+
return true;
|
|
1338
|
+
}
|
|
1339
|
+
return policy.retryableErrors.some(
|
|
1340
|
+
(pattern) => error.message.includes(pattern) || error.name.includes(pattern)
|
|
1341
|
+
);
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
// workflow/Workflow.ts
|
|
1345
|
+
var Workflow = class _Workflow {
|
|
1346
|
+
id;
|
|
1347
|
+
name;
|
|
1348
|
+
description;
|
|
1349
|
+
config;
|
|
1350
|
+
steps = [];
|
|
1351
|
+
hasStartStep = false;
|
|
1352
|
+
hasFinishStep = false;
|
|
1353
|
+
emitter = new import_events2.EventEmitter();
|
|
1354
|
+
/**
|
|
1355
|
+
* Construtor compatível com assinatura antiga (string) e nova (config)
|
|
1356
|
+
*/
|
|
1357
|
+
constructor(idOrConfig) {
|
|
1358
|
+
if (typeof idOrConfig === "string") {
|
|
1359
|
+
this.config = { id: idOrConfig };
|
|
1360
|
+
} else {
|
|
1361
|
+
this.config = idOrConfig;
|
|
1362
|
+
}
|
|
1363
|
+
this.id = this.config.id;
|
|
1364
|
+
this.name = this.config.name;
|
|
1365
|
+
this.description = this.config.description;
|
|
1366
|
+
if (this.config.logLevel && this.config.logLevel !== "none") {
|
|
1367
|
+
const logger = new ConsoleLogger(this.config.logLevel);
|
|
1368
|
+
new WorkflowLogger(this, logger);
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
/**
|
|
1372
|
+
* start() - obrigatório se inputSchema existir
|
|
1373
|
+
*/
|
|
1374
|
+
start(handler) {
|
|
1375
|
+
if (this.hasStartStep) throw new Error("Workflow already has a start step");
|
|
1376
|
+
if (this.steps.length > 0) throw new Error("start() deve ser chamado antes dos steps");
|
|
1377
|
+
this.hasStartStep = true;
|
|
1378
|
+
this.steps.push({ id: (0, import_uuid.v4)(), name: "__start__", handler, type: "start" });
|
|
1379
|
+
return this;
|
|
1380
|
+
}
|
|
1381
|
+
/**
|
|
1382
|
+
* step() - step linear
|
|
1383
|
+
*/
|
|
1384
|
+
step(name, handler) {
|
|
1385
|
+
if (this.config.inputSchema && !this.hasStartStep) {
|
|
1386
|
+
throw new Error("start() deve ser chamado antes de step() quando h\xE1 inputSchema");
|
|
1387
|
+
}
|
|
1388
|
+
if (this.hasFinishStep) throw new Error("N\xE3o \xE9 poss\xEDvel adicionar steps ap\xF3s finish()");
|
|
1389
|
+
this.steps.push({ id: (0, import_uuid.v4)(), name, handler, type: "standard" });
|
|
1390
|
+
return this;
|
|
1391
|
+
}
|
|
1392
|
+
then(name, handler) {
|
|
1393
|
+
return this.step(name, handler);
|
|
1394
|
+
}
|
|
1395
|
+
/**
|
|
1396
|
+
* branch() - retorna chave do branch
|
|
1397
|
+
*/
|
|
1398
|
+
branch(name, handler, branches) {
|
|
1399
|
+
if (this.hasFinishStep) throw new Error("N\xE3o \xE9 poss\xEDvel adicionar steps ap\xF3s finish()");
|
|
1400
|
+
const branchWorkflows = {};
|
|
1401
|
+
for (const [key, config] of Object.entries(branches)) {
|
|
1402
|
+
const branchWf = new _Workflow({ id: `${this.id}-branch-${key}` });
|
|
1403
|
+
config(branchWf);
|
|
1404
|
+
branchWorkflows[key] = branchWf;
|
|
1405
|
+
}
|
|
1406
|
+
this.steps.push({
|
|
1407
|
+
id: (0, import_uuid.v4)(),
|
|
1408
|
+
name,
|
|
1409
|
+
handler,
|
|
1410
|
+
type: "branch",
|
|
1411
|
+
branches: branchWorkflows
|
|
1412
|
+
});
|
|
1413
|
+
return this;
|
|
1414
|
+
}
|
|
1415
|
+
/**
|
|
1416
|
+
* parallel() - executa workflows em paralelo
|
|
1417
|
+
*/
|
|
1418
|
+
parallel(name, workflows) {
|
|
1419
|
+
if (this.hasFinishStep) throw new Error("N\xE3o \xE9 poss\xEDvel adicionar steps ap\xF3s finish()");
|
|
1420
|
+
const parallelWfs = workflows.map((config, index) => {
|
|
1421
|
+
const wf = new _Workflow({ id: `${this.id}-parallel-${index}` });
|
|
1422
|
+
config(wf);
|
|
1423
|
+
return wf;
|
|
1424
|
+
});
|
|
1425
|
+
this.steps.push({
|
|
1426
|
+
id: (0, import_uuid.v4)(),
|
|
1427
|
+
name,
|
|
1428
|
+
handler: async ({ input }) => input,
|
|
1429
|
+
type: "parallel",
|
|
1430
|
+
parallelWorkflows: parallelWfs
|
|
1431
|
+
});
|
|
1432
|
+
return this;
|
|
1433
|
+
}
|
|
1434
|
+
/**
|
|
1435
|
+
* finish() - obrigatório se outputSchema existir
|
|
1436
|
+
*/
|
|
1437
|
+
finish(handler) {
|
|
1438
|
+
if (this.hasFinishStep) throw new Error("Workflow already has a finish step");
|
|
1439
|
+
this.hasFinishStep = true;
|
|
1440
|
+
this.steps.push({ id: (0, import_uuid.v4)(), name: "__finish__", handler, type: "finish" });
|
|
1441
|
+
return this;
|
|
1442
|
+
}
|
|
1443
|
+
// =============================================================================
|
|
1444
|
+
// Event Methods (Composition over Inheritance)
|
|
1445
|
+
// =============================================================================
|
|
1446
|
+
on(event, listener) {
|
|
1447
|
+
this.emitter.on(event, listener);
|
|
1448
|
+
return this;
|
|
1449
|
+
}
|
|
1450
|
+
once(event, listener) {
|
|
1451
|
+
this.emitter.once(event, listener);
|
|
1452
|
+
return this;
|
|
1453
|
+
}
|
|
1454
|
+
off(event, listener) {
|
|
1455
|
+
this.emitter.off(event, listener);
|
|
1456
|
+
return this;
|
|
1457
|
+
}
|
|
1458
|
+
emit(event, payload) {
|
|
1459
|
+
const traceContext = Tracing.getContext();
|
|
1460
|
+
const fullEvent = {
|
|
1461
|
+
type: event,
|
|
1462
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1463
|
+
trace: {
|
|
1464
|
+
traceId: traceContext?.traceId || `fallback-${Date.now()}`,
|
|
1465
|
+
spanId: traceContext?.spanId || `fallback-${Date.now()}`,
|
|
1466
|
+
parentSpanId: traceContext?.parentId
|
|
1467
|
+
},
|
|
1468
|
+
correlationId: payload.correlationId,
|
|
1469
|
+
runId: payload.runId,
|
|
1470
|
+
data: payload.data
|
|
1471
|
+
};
|
|
1472
|
+
this.emitter.emit(event, fullEvent);
|
|
1473
|
+
}
|
|
1474
|
+
// =============================================================================
|
|
1475
|
+
// Execution
|
|
1476
|
+
// =============================================================================
|
|
1477
|
+
/**
|
|
1478
|
+
* Execução síncrona
|
|
1479
|
+
*/
|
|
1480
|
+
async run(input, options) {
|
|
1481
|
+
if (this.config.outputSchema && !this.hasFinishStep) {
|
|
1482
|
+
throw new Error("finish() deve ser chamado quando h\xE1 outputSchema");
|
|
1483
|
+
}
|
|
1484
|
+
if (this.config.inputSchema) {
|
|
1485
|
+
const parsed = this.config.inputSchema.safeParse(input);
|
|
1486
|
+
if (!parsed.success) {
|
|
1487
|
+
throw new Error(`Input validation failed: ${parsed.error.message}`);
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
const executionId = options?.executionId || (0, import_uuid.v4)();
|
|
1491
|
+
const startTime = Date.now();
|
|
1492
|
+
let currentInput = input;
|
|
1493
|
+
const state = {};
|
|
1494
|
+
return Tracing.withSpan(
|
|
1495
|
+
{
|
|
1496
|
+
kind: "workflow",
|
|
1497
|
+
name: `workflow:${this.id}`,
|
|
1498
|
+
runId: executionId,
|
|
1499
|
+
data: { workflowId: this.id, input }
|
|
1500
|
+
},
|
|
1501
|
+
async (workflowSpan) => {
|
|
1502
|
+
this.emit("workflow:execution:start", {
|
|
1503
|
+
runId: executionId,
|
|
1504
|
+
data: {
|
|
1505
|
+
workflowId: this.id,
|
|
1506
|
+
input
|
|
1507
|
+
}
|
|
1508
|
+
});
|
|
1509
|
+
if (this.config.stateStore) {
|
|
1510
|
+
await this.saveState(executionId, {
|
|
1511
|
+
workflowId: this.id,
|
|
1512
|
+
executionId,
|
|
1513
|
+
status: "running",
|
|
1514
|
+
currentStep: 0,
|
|
1515
|
+
stepStates: {},
|
|
1516
|
+
input,
|
|
1517
|
+
startedAt: /* @__PURE__ */ new Date(),
|
|
1518
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
1519
|
+
});
|
|
1520
|
+
}
|
|
1521
|
+
try {
|
|
1522
|
+
let stepIndex = 0;
|
|
1523
|
+
for (const step of this.steps) {
|
|
1524
|
+
const result = await Tracing.withSpan(
|
|
1525
|
+
{
|
|
1526
|
+
kind: "workflow",
|
|
1527
|
+
name: `workflow:step:${step.name}`,
|
|
1528
|
+
runId: executionId,
|
|
1529
|
+
data: { workflowId: this.id, input: currentInput, stepName: step.name }
|
|
1530
|
+
},
|
|
1531
|
+
async (stepSpan) => {
|
|
1532
|
+
try {
|
|
1533
|
+
const out = await this.executeStepWithRetry(executionId, step, currentInput, state);
|
|
1534
|
+
await stepSpan.end({ status: "success", data: { output: out } });
|
|
1535
|
+
return out;
|
|
1536
|
+
} catch (e) {
|
|
1537
|
+
await stepSpan.end({ status: "error" });
|
|
1538
|
+
throw e;
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
);
|
|
1542
|
+
if (step.type === "start" || step.type === "standard") {
|
|
1543
|
+
currentInput = result;
|
|
1544
|
+
state[step.name] = result;
|
|
1545
|
+
} else if (step.type === "branch") {
|
|
1546
|
+
const branchKey = result;
|
|
1547
|
+
const branchWf = step.branches?.[branchKey];
|
|
1548
|
+
if (branchWf) {
|
|
1549
|
+
const branchResult = await branchWf.run(currentInput);
|
|
1550
|
+
currentInput = branchResult;
|
|
1551
|
+
state[step.name] = branchKey;
|
|
1552
|
+
state[branchKey] = branchResult;
|
|
1553
|
+
}
|
|
1554
|
+
} else if (step.type === "parallel") {
|
|
1555
|
+
if (step.parallelWorkflows) {
|
|
1556
|
+
const results = await Promise.all(step.parallelWorkflows.map((wf) => wf.run(currentInput)));
|
|
1557
|
+
currentInput = results;
|
|
1558
|
+
state[step.name] = results;
|
|
1559
|
+
}
|
|
1560
|
+
} else if (step.type === "finish") {
|
|
1561
|
+
currentInput = result;
|
|
1562
|
+
}
|
|
1563
|
+
if (this.config.stateStore) {
|
|
1564
|
+
await this.saveState(executionId, {
|
|
1565
|
+
workflowId: this.id,
|
|
1566
|
+
executionId,
|
|
1567
|
+
status: "running",
|
|
1568
|
+
currentStep: stepIndex,
|
|
1569
|
+
stepStates: { ...state },
|
|
1570
|
+
input,
|
|
1571
|
+
startedAt: /* @__PURE__ */ new Date(),
|
|
1572
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
1573
|
+
});
|
|
1574
|
+
}
|
|
1575
|
+
stepIndex++;
|
|
1576
|
+
}
|
|
1577
|
+
const output = currentInput;
|
|
1578
|
+
if (this.config.outputSchema) {
|
|
1579
|
+
const parsed = this.config.outputSchema.safeParse(output);
|
|
1580
|
+
if (!parsed.success) {
|
|
1581
|
+
throw new Error(`Output validation failed: ${parsed.error.message}`);
|
|
1582
|
+
}
|
|
1583
|
+
}
|
|
1584
|
+
if (this.config.stateStore) {
|
|
1585
|
+
await this.saveState(executionId, {
|
|
1586
|
+
workflowId: this.id,
|
|
1587
|
+
executionId,
|
|
1588
|
+
status: "completed",
|
|
1589
|
+
currentStep: this.steps.length,
|
|
1590
|
+
stepStates: state,
|
|
1591
|
+
input,
|
|
1592
|
+
output,
|
|
1593
|
+
startedAt: /* @__PURE__ */ new Date(),
|
|
1594
|
+
updatedAt: /* @__PURE__ */ new Date(),
|
|
1595
|
+
completedAt: /* @__PURE__ */ new Date()
|
|
1596
|
+
});
|
|
1597
|
+
}
|
|
1598
|
+
this.emit("workflow:execution:end", {
|
|
1599
|
+
runId: executionId,
|
|
1600
|
+
data: {
|
|
1601
|
+
workflowId: this.id,
|
|
1602
|
+
status: "success",
|
|
1603
|
+
output,
|
|
1604
|
+
durationMs: Date.now() - startTime
|
|
1605
|
+
}
|
|
1606
|
+
});
|
|
1607
|
+
await workflowSpan.end({ status: "success", data: { output } });
|
|
1608
|
+
return output;
|
|
1609
|
+
} catch (error) {
|
|
1610
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
1611
|
+
this.emit("workflow:execution:error", {
|
|
1612
|
+
runId: executionId,
|
|
1613
|
+
data: {
|
|
1614
|
+
workflowId: this.id,
|
|
1615
|
+
error: {
|
|
1616
|
+
message: err.message,
|
|
1617
|
+
stack: err.stack,
|
|
1618
|
+
name: err.name
|
|
1619
|
+
},
|
|
1620
|
+
durationMs: Date.now() - startTime
|
|
1621
|
+
}
|
|
1622
|
+
});
|
|
1623
|
+
if (this.config.stateStore) {
|
|
1624
|
+
await this.saveState(executionId, {
|
|
1625
|
+
workflowId: this.id,
|
|
1626
|
+
executionId,
|
|
1627
|
+
status: "failed",
|
|
1628
|
+
currentStep: 0,
|
|
1629
|
+
stepStates: state,
|
|
1630
|
+
input,
|
|
1631
|
+
startedAt: /* @__PURE__ */ new Date(),
|
|
1632
|
+
updatedAt: /* @__PURE__ */ new Date(),
|
|
1633
|
+
completedAt: /* @__PURE__ */ new Date(),
|
|
1634
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1635
|
+
});
|
|
1636
|
+
}
|
|
1637
|
+
await workflowSpan.end({ status: "error" });
|
|
1638
|
+
throw error;
|
|
1639
|
+
}
|
|
1640
|
+
}
|
|
1641
|
+
);
|
|
1642
|
+
}
|
|
1643
|
+
async executeStepWithRetry(executionId, step, currentInput, state) {
|
|
1644
|
+
const stepStartTime = Date.now();
|
|
1645
|
+
this.emit("workflow:step", {
|
|
1646
|
+
runId: executionId,
|
|
1647
|
+
data: {
|
|
1648
|
+
workflowId: this.id,
|
|
1649
|
+
nodeId: step.id,
|
|
1650
|
+
stepName: step.name,
|
|
1651
|
+
status: "running"
|
|
1652
|
+
}
|
|
1653
|
+
});
|
|
1654
|
+
const policy = this.config.retryPolicy;
|
|
1655
|
+
if (!policy) {
|
|
1656
|
+
try {
|
|
1657
|
+
const result = await step.handler({ input: currentInput, state });
|
|
1658
|
+
this.emit("workflow:step", {
|
|
1659
|
+
runId: executionId,
|
|
1660
|
+
data: {
|
|
1661
|
+
workflowId: this.id,
|
|
1662
|
+
nodeId: step.id,
|
|
1663
|
+
stepName: step.name,
|
|
1664
|
+
status: "success",
|
|
1665
|
+
durationMs: Date.now() - stepStartTime
|
|
1666
|
+
}
|
|
1667
|
+
});
|
|
1668
|
+
return result;
|
|
1669
|
+
} catch (err) {
|
|
1670
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
1671
|
+
this.emit("workflow:step", {
|
|
1672
|
+
runId: executionId,
|
|
1673
|
+
data: {
|
|
1674
|
+
workflowId: this.id,
|
|
1675
|
+
nodeId: step.id,
|
|
1676
|
+
stepName: step.name,
|
|
1677
|
+
status: "error",
|
|
1678
|
+
error: {
|
|
1679
|
+
message: error.message,
|
|
1680
|
+
stack: error.stack,
|
|
1681
|
+
name: error.name
|
|
1682
|
+
},
|
|
1683
|
+
durationMs: Date.now() - stepStartTime
|
|
1684
|
+
}
|
|
1685
|
+
});
|
|
1686
|
+
throw error;
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1689
|
+
let lastError;
|
|
1690
|
+
for (let attempt = 1; attempt <= policy.maxAttempts; attempt++) {
|
|
1691
|
+
try {
|
|
1692
|
+
const result = await step.handler({ input: currentInput, state });
|
|
1693
|
+
this.emit("workflow:step", {
|
|
1694
|
+
runId: executionId,
|
|
1695
|
+
data: {
|
|
1696
|
+
workflowId: this.id,
|
|
1697
|
+
nodeId: step.id,
|
|
1698
|
+
stepName: step.name,
|
|
1699
|
+
status: "success",
|
|
1700
|
+
durationMs: Date.now() - stepStartTime
|
|
1701
|
+
}
|
|
1702
|
+
});
|
|
1703
|
+
return result;
|
|
1704
|
+
} catch (err) {
|
|
1705
|
+
lastError = err instanceof Error ? err : new Error(String(err));
|
|
1706
|
+
if (!isRetryableError(lastError, policy) || attempt >= policy.maxAttempts) {
|
|
1707
|
+
this.emit("workflow:step", {
|
|
1708
|
+
runId: executionId,
|
|
1709
|
+
data: {
|
|
1710
|
+
workflowId: this.id,
|
|
1711
|
+
nodeId: step.id,
|
|
1712
|
+
stepName: step.name,
|
|
1713
|
+
status: "error",
|
|
1714
|
+
error: {
|
|
1715
|
+
message: lastError.message,
|
|
1716
|
+
stack: lastError.stack,
|
|
1717
|
+
name: lastError.name
|
|
1718
|
+
},
|
|
1719
|
+
durationMs: Date.now() - stepStartTime
|
|
1720
|
+
}
|
|
1721
|
+
});
|
|
1722
|
+
throw lastError;
|
|
1723
|
+
}
|
|
1724
|
+
const delay = calculateRetryDelay(policy, attempt);
|
|
1725
|
+
await (0, import_promises.setTimeout)(delay);
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1728
|
+
throw lastError;
|
|
1729
|
+
}
|
|
1730
|
+
async saveState(executionId, state) {
|
|
1731
|
+
if (this.config.stateStore) {
|
|
1732
|
+
await this.config.stateStore.save(executionId, state);
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1735
|
+
/**
|
|
1736
|
+
* Enfileira execução assíncrona (requer queueAdapter)
|
|
1737
|
+
*/
|
|
1738
|
+
async enqueue(input) {
|
|
1739
|
+
if (!this.config.queueAdapter) {
|
|
1740
|
+
throw new Error("Queue adapter n\xE3o configurado. N\xE3o \xE9 poss\xEDvel enfileirar.");
|
|
1741
|
+
}
|
|
1742
|
+
if (this.config.inputSchema) {
|
|
1743
|
+
const parsed = this.config.inputSchema.safeParse(input);
|
|
1744
|
+
if (!parsed.success) {
|
|
1745
|
+
throw new Error(`Input validation failed: ${parsed.error.message}`);
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
const executionId = (0, import_uuid.v4)();
|
|
1749
|
+
if (this.config.stateStore) {
|
|
1750
|
+
await this.saveState(executionId, {
|
|
1751
|
+
workflowId: this.id,
|
|
1752
|
+
executionId,
|
|
1753
|
+
status: "pending",
|
|
1754
|
+
currentStep: 0,
|
|
1755
|
+
stepStates: {},
|
|
1756
|
+
input,
|
|
1757
|
+
startedAt: /* @__PURE__ */ new Date(),
|
|
1758
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
1759
|
+
});
|
|
1760
|
+
}
|
|
1761
|
+
const firstStep = this.steps[0];
|
|
1762
|
+
if (firstStep) {
|
|
1763
|
+
await this.config.queueAdapter.enqueue({
|
|
1764
|
+
executionId,
|
|
1765
|
+
workflowId: this.id,
|
|
1766
|
+
stepId: firstStep.id,
|
|
1767
|
+
stepName: firstStep.name,
|
|
1768
|
+
input,
|
|
1769
|
+
attempt: 1,
|
|
1770
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
1771
|
+
});
|
|
1772
|
+
}
|
|
1773
|
+
return { executionId };
|
|
1774
|
+
}
|
|
1775
|
+
/**
|
|
1776
|
+
* Consulta status (requer queueAdapter ou stateStore)
|
|
1777
|
+
*/
|
|
1778
|
+
async getStatus(executionId) {
|
|
1779
|
+
if (this.config.queueAdapter?.getStatus) {
|
|
1780
|
+
return this.config.queueAdapter.getStatus(executionId);
|
|
1781
|
+
}
|
|
1782
|
+
if (this.config.stateStore) {
|
|
1783
|
+
const state = await this.config.stateStore.load(executionId);
|
|
1784
|
+
if (!state) throw new Error(`Execution ${executionId} not found`);
|
|
1785
|
+
return {
|
|
1786
|
+
status: state.status,
|
|
1787
|
+
currentStep: this.steps[state.currentStep]?.name,
|
|
1788
|
+
progress: this.steps.length ? state.currentStep / this.steps.length : 0
|
|
1789
|
+
};
|
|
1790
|
+
}
|
|
1791
|
+
throw new Error("Queue adapter ou state store necess\xE1rio para getStatus()");
|
|
1792
|
+
}
|
|
1793
|
+
};
|
|
1794
|
+
|
|
1795
|
+
// events/schemas.ts
|
|
1796
|
+
var import_zod = require("zod");
|
|
1797
|
+
var TraceContextSchema = import_zod.z.object({
|
|
1798
|
+
traceId: import_zod.z.string().describe("Unique identifier for the trace"),
|
|
1799
|
+
spanId: import_zod.z.string().describe("Unique identifier for the current span"),
|
|
1800
|
+
parentSpanId: import_zod.z.string().optional().describe("Identifier of the parent span, if any")
|
|
1801
|
+
});
|
|
1802
|
+
var EventCommonSchema = import_zod.z.object({
|
|
1803
|
+
type: import_zod.z.string().describe("Event type identifier (e.g., 'agent:execution:start')"),
|
|
1804
|
+
timestamp: import_zod.z.string().datetime().describe("ISO 8601 timestamp of when the event occurred"),
|
|
1805
|
+
trace: TraceContextSchema,
|
|
1806
|
+
correlationId: import_zod.z.string().optional().describe("Optional external correlation ID"),
|
|
1807
|
+
runId: import_zod.z.string().optional().describe("Logical execution run ID")
|
|
1808
|
+
});
|
|
1809
|
+
var UsageSchema = import_zod.z.object({
|
|
1810
|
+
promptTokens: import_zod.z.number(),
|
|
1811
|
+
completionTokens: import_zod.z.number(),
|
|
1812
|
+
totalTokens: import_zod.z.number(),
|
|
1813
|
+
reasoningTokens: import_zod.z.number().optional()
|
|
1814
|
+
});
|
|
1815
|
+
var ErrorSchema = import_zod.z.object({
|
|
1816
|
+
name: import_zod.z.string().optional(),
|
|
1817
|
+
message: import_zod.z.string(),
|
|
1818
|
+
code: import_zod.z.string().optional(),
|
|
1819
|
+
stack: import_zod.z.string().optional(),
|
|
1820
|
+
details: import_zod.z.any().optional()
|
|
1821
|
+
});
|
|
1822
|
+
var ModelSchema = import_zod.z.object({
|
|
1823
|
+
provider: import_zod.z.string(),
|
|
1824
|
+
model: import_zod.z.string(),
|
|
1825
|
+
temperature: import_zod.z.number().optional(),
|
|
1826
|
+
maxTokens: import_zod.z.number().optional(),
|
|
1827
|
+
topP: import_zod.z.number().optional(),
|
|
1828
|
+
frequencyPenalty: import_zod.z.number().optional(),
|
|
1829
|
+
presencePenalty: import_zod.z.number().optional()
|
|
1830
|
+
}).passthrough();
|
|
1831
|
+
var AgentExecutionStartSchema = EventCommonSchema.extend({
|
|
1832
|
+
type: import_zod.z.literal("agent:execution:start"),
|
|
1833
|
+
data: import_zod.z.object({
|
|
1834
|
+
agentName: import_zod.z.string(),
|
|
1835
|
+
input: import_zod.z.any().optional().describe("Input arguments for the execution"),
|
|
1836
|
+
metadata: import_zod.z.record(import_zod.z.any()).optional()
|
|
1837
|
+
})
|
|
1838
|
+
});
|
|
1839
|
+
var AgentExecutionEndSchema = EventCommonSchema.extend({
|
|
1840
|
+
type: import_zod.z.literal("agent:execution:end"),
|
|
1841
|
+
data: import_zod.z.object({
|
|
1842
|
+
agentName: import_zod.z.string(),
|
|
1843
|
+
status: import_zod.z.enum(["success", "error", "truncated"]),
|
|
1844
|
+
output: import_zod.z.any().optional().describe("Final output of the execution"),
|
|
1845
|
+
durationMs: import_zod.z.number(),
|
|
1846
|
+
usage: UsageSchema.optional().describe("Total token usage for this execution")
|
|
1847
|
+
})
|
|
1848
|
+
});
|
|
1849
|
+
var AgentExecutionErrorSchema = EventCommonSchema.extend({
|
|
1850
|
+
type: import_zod.z.literal("agent:execution:error"),
|
|
1851
|
+
data: import_zod.z.object({
|
|
1852
|
+
agentName: import_zod.z.string(),
|
|
1853
|
+
error: ErrorSchema,
|
|
1854
|
+
durationMs: import_zod.z.number().optional()
|
|
1855
|
+
})
|
|
1856
|
+
});
|
|
1857
|
+
var AgentLLMCallSchema = EventCommonSchema.extend({
|
|
1858
|
+
type: import_zod.z.literal("agent:llm:call"),
|
|
1859
|
+
data: import_zod.z.object({
|
|
1860
|
+
agentName: import_zod.z.string(),
|
|
1861
|
+
step: import_zod.z.number().int().positive().describe("Current execution step"),
|
|
1862
|
+
model: ModelSchema,
|
|
1863
|
+
messages: import_zod.z.array(import_zod.z.any()).describe("Messages sent to the LLM"),
|
|
1864
|
+
tools: import_zod.z.array(import_zod.z.any()).optional().describe("Tools definitions sent to the LLM"),
|
|
1865
|
+
responseFormat: import_zod.z.any().optional()
|
|
1866
|
+
})
|
|
1867
|
+
});
|
|
1868
|
+
var AgentLLMResponseSchema = EventCommonSchema.extend({
|
|
1869
|
+
type: import_zod.z.literal("agent:llm:response"),
|
|
1870
|
+
data: import_zod.z.object({
|
|
1871
|
+
agentName: import_zod.z.string(),
|
|
1872
|
+
step: import_zod.z.number().int().positive(),
|
|
1873
|
+
model: ModelSchema,
|
|
1874
|
+
content: import_zod.z.any().describe("Content returned by the LLM"),
|
|
1875
|
+
toolCalls: import_zod.z.array(import_zod.z.any()).optional(),
|
|
1876
|
+
finishReason: import_zod.z.string().optional(),
|
|
1877
|
+
usage: UsageSchema.optional(),
|
|
1878
|
+
durationMs: import_zod.z.number().optional()
|
|
1879
|
+
})
|
|
1880
|
+
});
|
|
1881
|
+
var AgentToolCallSchema = EventCommonSchema.extend({
|
|
1882
|
+
type: import_zod.z.literal("agent:tool:call"),
|
|
1883
|
+
data: import_zod.z.object({
|
|
1884
|
+
agentName: import_zod.z.string(),
|
|
1885
|
+
toolName: import_zod.z.string(),
|
|
1886
|
+
toolCallId: import_zod.z.string(),
|
|
1887
|
+
args: import_zod.z.any().describe("Arguments passed to the tool")
|
|
1888
|
+
})
|
|
1889
|
+
});
|
|
1890
|
+
var AgentToolResultSchema = EventCommonSchema.extend({
|
|
1891
|
+
type: import_zod.z.literal("agent:tool:result"),
|
|
1892
|
+
data: import_zod.z.object({
|
|
1893
|
+
agentName: import_zod.z.string(),
|
|
1894
|
+
toolName: import_zod.z.string(),
|
|
1895
|
+
toolCallId: import_zod.z.string(),
|
|
1896
|
+
output: import_zod.z.any().optional().describe("Result returned by the tool"),
|
|
1897
|
+
error: import_zod.z.string().optional().describe("Error message if tool failed"),
|
|
1898
|
+
durationMs: import_zod.z.number().optional()
|
|
1899
|
+
})
|
|
1900
|
+
});
|
|
1901
|
+
var WorkflowExecutionStartSchema = EventCommonSchema.extend({
|
|
1902
|
+
type: import_zod.z.literal("workflow:execution:start"),
|
|
1903
|
+
data: import_zod.z.object({
|
|
1904
|
+
workflowId: import_zod.z.string(),
|
|
1905
|
+
input: import_zod.z.any().optional(),
|
|
1906
|
+
metadata: import_zod.z.record(import_zod.z.any()).optional()
|
|
1907
|
+
})
|
|
1908
|
+
});
|
|
1909
|
+
var WorkflowExecutionEndSchema = EventCommonSchema.extend({
|
|
1910
|
+
type: import_zod.z.literal("workflow:execution:end"),
|
|
1911
|
+
data: import_zod.z.object({
|
|
1912
|
+
workflowId: import_zod.z.string(),
|
|
1913
|
+
status: import_zod.z.enum(["success", "error", "truncated"]),
|
|
1914
|
+
output: import_zod.z.any().optional(),
|
|
1915
|
+
durationMs: import_zod.z.number()
|
|
1916
|
+
})
|
|
1917
|
+
});
|
|
1918
|
+
var WorkflowExecutionErrorSchema = EventCommonSchema.extend({
|
|
1919
|
+
type: import_zod.z.literal("workflow:execution:error"),
|
|
1920
|
+
data: import_zod.z.object({
|
|
1921
|
+
workflowId: import_zod.z.string(),
|
|
1922
|
+
error: ErrorSchema,
|
|
1923
|
+
durationMs: import_zod.z.number().optional()
|
|
1924
|
+
})
|
|
1925
|
+
});
|
|
1926
|
+
var WorkflowStepSchema = EventCommonSchema.extend({
|
|
1927
|
+
type: import_zod.z.literal("workflow:step"),
|
|
1928
|
+
data: import_zod.z.object({
|
|
1929
|
+
workflowId: import_zod.z.string(),
|
|
1930
|
+
stepName: import_zod.z.string().optional(),
|
|
1931
|
+
nodeId: import_zod.z.string().optional(),
|
|
1932
|
+
status: import_zod.z.enum(["running", "success", "error"]),
|
|
1933
|
+
durationMs: import_zod.z.number().optional(),
|
|
1934
|
+
output: import_zod.z.any().optional(),
|
|
1935
|
+
error: ErrorSchema.optional()
|
|
1936
|
+
})
|
|
1937
|
+
});
|
|
1938
|
+
var NebulaEventSchema = import_zod.z.discriminatedUnion("type", [
|
|
1939
|
+
AgentExecutionStartSchema,
|
|
1940
|
+
AgentExecutionEndSchema,
|
|
1941
|
+
AgentExecutionErrorSchema,
|
|
1942
|
+
AgentLLMCallSchema,
|
|
1943
|
+
AgentLLMResponseSchema,
|
|
1944
|
+
AgentToolCallSchema,
|
|
1945
|
+
AgentToolResultSchema,
|
|
1946
|
+
WorkflowExecutionStartSchema,
|
|
1947
|
+
WorkflowExecutionEndSchema,
|
|
1948
|
+
WorkflowExecutionErrorSchema,
|
|
1949
|
+
WorkflowStepSchema
|
|
1950
|
+
]);
|
|
1951
|
+
|
|
1952
|
+
// lgpd/index.ts
|
|
1953
|
+
var RegexPIIMasker = class _RegexPIIMasker {
|
|
1954
|
+
// Regex padrões para dados sensíveis brasileiros
|
|
1955
|
+
static PATTERNS = {
|
|
1956
|
+
CPF: /\b\d{3}\.?\d{3}\.?\d{3}-?\d{2}\b/g,
|
|
1957
|
+
CNPJ: /\b\d{2}\.?\d{3}\.?\d{3}\/?\d{4}-?\d{2}\b/g,
|
|
1958
|
+
EMAIL: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g,
|
|
1959
|
+
PHONE: /\b(\(?\d{2}\)?\s?)?(\d{4,5}-?\d{4})\b/g
|
|
1960
|
+
};
|
|
1961
|
+
mask(text) {
|
|
1962
|
+
let masked = text;
|
|
1963
|
+
masked = masked.replace(_RegexPIIMasker.PATTERNS.CPF, "[CPF]");
|
|
1964
|
+
masked = masked.replace(_RegexPIIMasker.PATTERNS.CNPJ, "[CNPJ]");
|
|
1965
|
+
masked = masked.replace(_RegexPIIMasker.PATTERNS.EMAIL, "[EMAIL]");
|
|
1966
|
+
masked = masked.replace(_RegexPIIMasker.PATTERNS.PHONE, "[PHONE]");
|
|
1967
|
+
return masked;
|
|
1968
|
+
}
|
|
1969
|
+
};
|
|
1970
|
+
|
|
1971
|
+
// eval/index.ts
|
|
1972
|
+
var KeywordScorer = class {
|
|
1973
|
+
constructor(keywords) {
|
|
1974
|
+
this.keywords = keywords;
|
|
1975
|
+
}
|
|
1976
|
+
name = "KeywordScorer";
|
|
1977
|
+
async evaluate(input, output) {
|
|
1978
|
+
const lowerOutput = output.toLowerCase();
|
|
1979
|
+
const found = this.keywords.filter((k) => lowerOutput.includes(k.toLowerCase()));
|
|
1980
|
+
const score = found.length / this.keywords.length;
|
|
1981
|
+
return {
|
|
1982
|
+
score,
|
|
1983
|
+
passed: score === 1,
|
|
1984
|
+
reason: `Found ${found.length}/${this.keywords.length} keywords: ${found.join(", ")}`
|
|
1985
|
+
};
|
|
1986
|
+
}
|
|
1987
|
+
};
|
|
1988
|
+
|
|
1989
|
+
// utils/schema-to-zod.ts
|
|
1990
|
+
var import_zod2 = require("zod");
|
|
1991
|
+
function schemaToZod(shape) {
|
|
1992
|
+
const zodShape = {};
|
|
1993
|
+
for (const [key, value] of Object.entries(shape)) {
|
|
1994
|
+
if (typeof value === "string") {
|
|
1995
|
+
let schema = import_zod2.z.any();
|
|
1996
|
+
const isOptional = value.endsWith("?");
|
|
1997
|
+
const type = isOptional ? value.slice(0, -1) : value;
|
|
1998
|
+
switch (type) {
|
|
1999
|
+
case "string":
|
|
2000
|
+
schema = import_zod2.z.string();
|
|
2001
|
+
break;
|
|
2002
|
+
case "number":
|
|
2003
|
+
schema = import_zod2.z.number();
|
|
2004
|
+
break;
|
|
2005
|
+
case "boolean":
|
|
2006
|
+
schema = import_zod2.z.boolean();
|
|
2007
|
+
break;
|
|
2008
|
+
case "array":
|
|
2009
|
+
schema = import_zod2.z.array(import_zod2.z.any());
|
|
2010
|
+
break;
|
|
2011
|
+
// Simplificado
|
|
2012
|
+
default:
|
|
2013
|
+
schema = import_zod2.z.any();
|
|
2014
|
+
}
|
|
2015
|
+
if (isOptional) schema = schema.optional();
|
|
2016
|
+
zodShape[key] = schema;
|
|
2017
|
+
} else {
|
|
2018
|
+
zodShape[key] = value;
|
|
2019
|
+
}
|
|
2020
|
+
}
|
|
2021
|
+
return import_zod2.z.object(zodShape);
|
|
2022
|
+
}
|
|
2023
|
+
|
|
2024
|
+
// index.ts
|
|
2025
|
+
var import_zod4 = require("zod");
|
|
2026
|
+
|
|
2027
|
+
// multi-agent/types/index.ts
|
|
2028
|
+
var import_zod3 = require("zod");
|
|
2029
|
+
var agentRef = import_zod3.z.any();
|
|
2030
|
+
var memoryRef = import_zod3.z.any();
|
|
2031
|
+
var delegationMemorySchema = import_zod3.z.union([
|
|
2032
|
+
import_zod3.z.object({ type: import_zod3.z.literal("shared") }),
|
|
2033
|
+
import_zod3.z.object({ type: import_zod3.z.literal("isolated") }),
|
|
2034
|
+
import_zod3.z.object({
|
|
2035
|
+
type: import_zod3.z.literal("custom"),
|
|
2036
|
+
memory: memoryRef
|
|
2037
|
+
})
|
|
2038
|
+
]);
|
|
2039
|
+
var handoffEdgeSchema = import_zod3.z.object({
|
|
2040
|
+
from: agentRef,
|
|
2041
|
+
to: agentRef,
|
|
2042
|
+
toolId: import_zod3.z.string(),
|
|
2043
|
+
description: import_zod3.z.string().optional()
|
|
2044
|
+
});
|
|
2045
|
+
var routerTeamConfigSchema = import_zod3.z.object({
|
|
2046
|
+
model: import_zod3.z.any(),
|
|
2047
|
+
children: import_zod3.z.array(agentRef).min(1),
|
|
2048
|
+
fallback: agentRef.optional(),
|
|
2049
|
+
memory: memoryRef.optional(),
|
|
2050
|
+
additionalPrompt: import_zod3.z.string().optional(),
|
|
2051
|
+
maxRetries: import_zod3.z.number().int().positive().optional(),
|
|
2052
|
+
timeoutMs: import_zod3.z.number().int().positive().optional()
|
|
2053
|
+
});
|
|
2054
|
+
var handoffTeamConfigSchema = import_zod3.z.object({
|
|
2055
|
+
agents: import_zod3.z.array(agentRef).min(1),
|
|
2056
|
+
edges: import_zod3.z.array(handoffEdgeSchema).min(1),
|
|
2057
|
+
initialAgent: agentRef,
|
|
2058
|
+
memory: memoryRef.optional(),
|
|
2059
|
+
additionalPrompt: import_zod3.z.string().optional(),
|
|
2060
|
+
maxTransfers: import_zod3.z.number().int().positive().optional(),
|
|
2061
|
+
timeoutMs: import_zod3.z.number().int().positive().optional(),
|
|
2062
|
+
tokenBudget: import_zod3.z.number().positive().optional(),
|
|
2063
|
+
allowedTransitions: import_zod3.z.record(import_zod3.z.array(import_zod3.z.string())).optional(),
|
|
2064
|
+
onTransfer: import_zod3.z.function().optional()
|
|
2065
|
+
});
|
|
2066
|
+
var agentAsToolConfigSchema = import_zod3.z.object({
|
|
2067
|
+
agent: agentRef,
|
|
2068
|
+
id: import_zod3.z.string().optional(),
|
|
2069
|
+
description: import_zod3.z.string().optional(),
|
|
2070
|
+
additionalPrompt: import_zod3.z.string().optional(),
|
|
2071
|
+
memory: delegationMemorySchema.optional(),
|
|
2072
|
+
inputSchema: import_zod3.z.custom().optional()
|
|
2073
|
+
});
|
|
2074
|
+
var hierarchicalTeamConfigSchema = import_zod3.z.object({
|
|
2075
|
+
manager: agentRef,
|
|
2076
|
+
workers: import_zod3.z.array(agentRef).min(1),
|
|
2077
|
+
memory: memoryRef.optional(),
|
|
2078
|
+
additionalPrompt: import_zod3.z.string().optional(),
|
|
2079
|
+
allowHandoff: import_zod3.z.boolean().optional(),
|
|
2080
|
+
workerCollaboration: import_zod3.z.boolean().optional()
|
|
2081
|
+
});
|
|
2082
|
+
var pipelineTeamConfigSchema = import_zod3.z.object({
|
|
2083
|
+
stages: import_zod3.z.array(agentRef).min(1),
|
|
2084
|
+
memory: memoryRef.optional(),
|
|
2085
|
+
additionalPrompt: import_zod3.z.string().optional()
|
|
2086
|
+
});
|
|
2087
|
+
var committeeTeamConfigSchema = import_zod3.z.object({
|
|
2088
|
+
coordinator: agentRef,
|
|
2089
|
+
members: import_zod3.z.array(agentRef).min(1),
|
|
2090
|
+
strategy: import_zod3.z.enum(["vote", "summarize", "confidence", "first"]),
|
|
2091
|
+
memory: memoryRef.optional(),
|
|
2092
|
+
additionalPrompt: import_zod3.z.string().optional(),
|
|
2093
|
+
parallel: import_zod3.z.boolean().optional()
|
|
2094
|
+
});
|
|
2095
|
+
var aggregationStrategySchema = import_zod3.z.enum([
|
|
2096
|
+
"vote",
|
|
2097
|
+
"summarize",
|
|
2098
|
+
"confidence",
|
|
2099
|
+
"first"
|
|
2100
|
+
]);
|
|
2101
|
+
|
|
2102
|
+
// multi-agent/utils/memory.ts
|
|
2103
|
+
function overrideAgentMemory(agent, memory) {
|
|
2104
|
+
const original = agent.config.memory;
|
|
2105
|
+
if (memory) {
|
|
2106
|
+
agent.config.memory = memory;
|
|
2107
|
+
}
|
|
2108
|
+
return () => {
|
|
2109
|
+
agent.config.memory = original;
|
|
2110
|
+
};
|
|
2111
|
+
}
|
|
2112
|
+
async function resolveDelegationMemory(agent, config, callingMemory) {
|
|
2113
|
+
const original = agent.config.memory;
|
|
2114
|
+
if (!config) {
|
|
2115
|
+
return { memory: original, restore: () => {
|
|
2116
|
+
} };
|
|
2117
|
+
}
|
|
2118
|
+
if (config.type === "shared") {
|
|
2119
|
+
const memory = original;
|
|
2120
|
+
if (callingMemory) {
|
|
2121
|
+
const msgs = await callingMemory.getMessages();
|
|
2122
|
+
for (const msg of msgs) {
|
|
2123
|
+
await memory.addMessage(msg);
|
|
2124
|
+
}
|
|
2125
|
+
}
|
|
2126
|
+
agent.config.memory = memory;
|
|
2127
|
+
return { memory, restore: () => agent.config.memory = original };
|
|
2128
|
+
}
|
|
2129
|
+
if (config.type === "custom") {
|
|
2130
|
+
agent.config.memory = config.memory;
|
|
2131
|
+
return { memory: config.memory, restore: () => agent.config.memory = original };
|
|
2132
|
+
}
|
|
2133
|
+
const isolated = new InMemory();
|
|
2134
|
+
agent.config.memory = isolated;
|
|
2135
|
+
return { memory: isolated, restore: () => agent.config.memory = original };
|
|
2136
|
+
}
|
|
2137
|
+
|
|
2138
|
+
// multi-agent/agent-as-tool/AgentAsTool.ts
|
|
2139
|
+
var AgentAsTool = class extends Tool {
|
|
2140
|
+
callingMemory;
|
|
2141
|
+
target;
|
|
2142
|
+
memoryConfig;
|
|
2143
|
+
extraPrompt;
|
|
2144
|
+
constructor(config) {
|
|
2145
|
+
const toolId = config.id ?? `delegate_${config.agent.name.toLowerCase().replace(/\s+/g, "_")}`;
|
|
2146
|
+
const description = config.description ?? `Delegate to specialist agent: ${config.agent.name}`;
|
|
2147
|
+
super({
|
|
2148
|
+
id: toolId,
|
|
2149
|
+
description,
|
|
2150
|
+
inputSchema: config.inputSchema,
|
|
2151
|
+
handler: async (_, input) => {
|
|
2152
|
+
return this.runDelegated(input);
|
|
2153
|
+
}
|
|
2154
|
+
});
|
|
2155
|
+
this.target = config.agent;
|
|
2156
|
+
this.memoryConfig = config.memory;
|
|
2157
|
+
this.extraPrompt = config.additionalPrompt;
|
|
2158
|
+
}
|
|
2159
|
+
/**
|
|
2160
|
+
* Allows orchestrators to set the calling agent/team memory when using
|
|
2161
|
+
* `memory: { type: "shared" }`.
|
|
2162
|
+
*/
|
|
2163
|
+
setCallingMemory(memory) {
|
|
2164
|
+
this.callingMemory = memory;
|
|
2165
|
+
}
|
|
2166
|
+
async runDelegated(input) {
|
|
2167
|
+
const { restore } = await resolveDelegationMemory(
|
|
2168
|
+
this.target,
|
|
2169
|
+
this.memoryConfig,
|
|
2170
|
+
this.callingMemory
|
|
2171
|
+
);
|
|
2172
|
+
try {
|
|
2173
|
+
const formattedInput = typeof input === "string" ? input : JSON.stringify(input);
|
|
2174
|
+
const userContent = this.extraPrompt ? `${this.extraPrompt}
|
|
2175
|
+
Input: ${formattedInput}` : formattedInput;
|
|
2176
|
+
await this.target.config.memory.addMessage({
|
|
2177
|
+
role: "user",
|
|
2178
|
+
content: userContent
|
|
2179
|
+
});
|
|
2180
|
+
const result = await this.target.execute();
|
|
2181
|
+
return result.content;
|
|
2182
|
+
} finally {
|
|
2183
|
+
restore();
|
|
2184
|
+
}
|
|
2185
|
+
}
|
|
2186
|
+
};
|
|
2187
|
+
|
|
2188
|
+
// multi-agent/utils/prompts.ts
|
|
2189
|
+
function buildRouterSystemPrompt(agents, additionalPrompt) {
|
|
2190
|
+
const lines = agents.map(
|
|
2191
|
+
(a) => `- ${a.name}: ${a.config?.instructions ?? a.name}`
|
|
2192
|
+
);
|
|
2193
|
+
return [
|
|
2194
|
+
"You are a routing controller.",
|
|
2195
|
+
"Choose the best agent for the user request.",
|
|
2196
|
+
'Respond ONLY with JSON: {"agent": "<name>"}.',
|
|
2197
|
+
additionalPrompt ? `Guidance: ${additionalPrompt}` : "",
|
|
2198
|
+
"Available agents:",
|
|
2199
|
+
...lines
|
|
2200
|
+
].filter(Boolean).join("\n");
|
|
2201
|
+
}
|
|
2202
|
+
function buildHandoffSystemPrompt(additionalPrompt) {
|
|
2203
|
+
return [
|
|
2204
|
+
"You are coordinating handoffs between agents.",
|
|
2205
|
+
additionalPrompt ? `Guidance: ${additionalPrompt}` : ""
|
|
2206
|
+
].filter(Boolean).join("\n");
|
|
2207
|
+
}
|
|
2208
|
+
|
|
2209
|
+
// multi-agent/utils/guardrails.ts
|
|
2210
|
+
var GuardrailError = class extends Error {
|
|
2211
|
+
constructor(message) {
|
|
2212
|
+
super(message);
|
|
2213
|
+
this.name = "GuardrailError";
|
|
2214
|
+
}
|
|
2215
|
+
};
|
|
2216
|
+
function enforceMaxTransfers(current, max) {
|
|
2217
|
+
if (max !== void 0 && current >= max) {
|
|
2218
|
+
throw new GuardrailError(`Max transfers exceeded (${max})`);
|
|
2219
|
+
}
|
|
2220
|
+
}
|
|
2221
|
+
function enforceAllowedTransition(from, to, allowed) {
|
|
2222
|
+
if (!allowed) return;
|
|
2223
|
+
const allowedTargets = allowed[from];
|
|
2224
|
+
if (allowedTargets && !allowedTargets.includes(to)) {
|
|
2225
|
+
throw new GuardrailError(`Transition from '${from}' to '${to}' is not allowed`);
|
|
2226
|
+
}
|
|
2227
|
+
}
|
|
2228
|
+
function enforceTimeout(promise, timeoutMs, label = "operation") {
|
|
2229
|
+
if (!timeoutMs) return promise;
|
|
2230
|
+
return Promise.race([
|
|
2231
|
+
promise,
|
|
2232
|
+
new Promise(
|
|
2233
|
+
(_, reject) => setTimeout(() => reject(new GuardrailError(`${label} timed out after ${timeoutMs}ms`)), timeoutMs)
|
|
2234
|
+
)
|
|
2235
|
+
]);
|
|
2236
|
+
}
|
|
2237
|
+
|
|
2238
|
+
// multi-agent/router-team/RouterTeam.ts
|
|
2239
|
+
var RouterTeam = class extends BaseAgent {
|
|
2240
|
+
constructor(config) {
|
|
2241
|
+
super(
|
|
2242
|
+
config.name,
|
|
2243
|
+
void 0,
|
|
2244
|
+
config.memory ?? config.children?.[0]?.config?.memory
|
|
2245
|
+
);
|
|
2246
|
+
this.config = config;
|
|
2247
|
+
}
|
|
2248
|
+
/**
|
|
2249
|
+
* Execute routing: choose an agent via model classification, then delegate execution.
|
|
2250
|
+
*/
|
|
2251
|
+
async execute(input, _options) {
|
|
2252
|
+
const correlationId = `router_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
2253
|
+
const startTime = Date.now();
|
|
2254
|
+
return Tracing.withSpan(
|
|
2255
|
+
{
|
|
2256
|
+
kind: "agent",
|
|
2257
|
+
name: `team:router:${this.name}`,
|
|
2258
|
+
correlationId,
|
|
2259
|
+
data: { agentName: this.name, input }
|
|
2260
|
+
},
|
|
2261
|
+
async (teamSpan) => {
|
|
2262
|
+
this.emit("agent:execution:start", {
|
|
2263
|
+
correlationId,
|
|
2264
|
+
data: {
|
|
2265
|
+
agentName: this.name,
|
|
2266
|
+
input
|
|
2267
|
+
}
|
|
2268
|
+
});
|
|
2269
|
+
try {
|
|
2270
|
+
const selected = await this.selectAgent(input);
|
|
2271
|
+
const memoryToUse = this.config.memory ?? selected.config.memory;
|
|
2272
|
+
const restoreMemory = overrideAgentMemory(selected, memoryToUse);
|
|
2273
|
+
if (input) {
|
|
2274
|
+
await this.addMessage({ role: "user", content: input });
|
|
2275
|
+
}
|
|
2276
|
+
const result = await selected.execute();
|
|
2277
|
+
restoreMemory();
|
|
2278
|
+
this.emit("agent:execution:end", {
|
|
2279
|
+
correlationId,
|
|
2280
|
+
data: {
|
|
2281
|
+
agentName: this.name,
|
|
2282
|
+
status: result.truncated ? "truncated" : "success",
|
|
2283
|
+
output: result.content,
|
|
2284
|
+
durationMs: Date.now() - startTime
|
|
2285
|
+
// Usage? Ideally aggregated, but for now passing result content is key
|
|
2286
|
+
}
|
|
2287
|
+
});
|
|
2288
|
+
await teamSpan.end({
|
|
2289
|
+
status: result.truncated ? "cancelled" : "success",
|
|
2290
|
+
data: { output: result.content }
|
|
2291
|
+
});
|
|
2292
|
+
return result;
|
|
2293
|
+
} catch (error) {
|
|
2294
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
2295
|
+
this.emit("agent:execution:error", {
|
|
2296
|
+
correlationId,
|
|
2297
|
+
data: {
|
|
2298
|
+
agentName: this.name,
|
|
2299
|
+
error: {
|
|
2300
|
+
message: err.message,
|
|
2301
|
+
stack: err.stack,
|
|
2302
|
+
name: err.name
|
|
2303
|
+
},
|
|
2304
|
+
durationMs: Date.now() - startTime
|
|
2305
|
+
}
|
|
2306
|
+
});
|
|
2307
|
+
await teamSpan.end({ status: "error" });
|
|
2308
|
+
throw error;
|
|
2309
|
+
}
|
|
2310
|
+
}
|
|
2311
|
+
);
|
|
2312
|
+
}
|
|
2313
|
+
async selectAgent(userInput) {
|
|
2314
|
+
const system = buildRouterSystemPrompt(
|
|
2315
|
+
this.config.children,
|
|
2316
|
+
this.config.additionalPrompt
|
|
2317
|
+
);
|
|
2318
|
+
const messages = [
|
|
2319
|
+
{ role: "system", content: system },
|
|
2320
|
+
{ role: "user", content: userInput ?? "" }
|
|
2321
|
+
];
|
|
2322
|
+
const routerResponseSchema = {
|
|
2323
|
+
type: "object",
|
|
2324
|
+
properties: {
|
|
2325
|
+
agent: {
|
|
2326
|
+
type: "string",
|
|
2327
|
+
description: "The name of the agent to route to"
|
|
2328
|
+
}
|
|
2329
|
+
},
|
|
2330
|
+
required: ["agent"],
|
|
2331
|
+
additionalProperties: false
|
|
2332
|
+
};
|
|
2333
|
+
const response = await enforceTimeout(
|
|
2334
|
+
Tracing.withSpan(
|
|
2335
|
+
{
|
|
2336
|
+
kind: "llm",
|
|
2337
|
+
name: "llm:router-selection",
|
|
2338
|
+
data: {
|
|
2339
|
+
provider: this.config.model.providerName,
|
|
2340
|
+
model: this.config.model.modelName,
|
|
2341
|
+
messagesCount: messages.length,
|
|
2342
|
+
toolsCount: 0,
|
|
2343
|
+
responseFormat: { type: "json", schema: routerResponseSchema }
|
|
2344
|
+
}
|
|
2345
|
+
},
|
|
2346
|
+
async (llmSpan) => {
|
|
2347
|
+
const resp = await this.config.model.generate(messages, void 0, {
|
|
2348
|
+
responseFormat: { type: "json", schema: routerResponseSchema }
|
|
2349
|
+
});
|
|
2350
|
+
await llmSpan.end({
|
|
2351
|
+
status: "success",
|
|
2352
|
+
data: {
|
|
2353
|
+
usage: resp.usage,
|
|
2354
|
+
outputPreview: typeof resp.content === "string" ? resp.content.substring(0, 200) : "json_content"
|
|
2355
|
+
}
|
|
2356
|
+
});
|
|
2357
|
+
return resp;
|
|
2358
|
+
}
|
|
2359
|
+
),
|
|
2360
|
+
this.config.timeoutMs,
|
|
2361
|
+
"router-selection"
|
|
2362
|
+
);
|
|
2363
|
+
const agentName = this.extractAgentName(response.content);
|
|
2364
|
+
const found = this.config.children.find(
|
|
2365
|
+
(c) => c.name.toLowerCase() === agentName?.toLowerCase()
|
|
2366
|
+
) ?? this.config.fallback ?? this.config.children[0];
|
|
2367
|
+
return found;
|
|
2368
|
+
}
|
|
2369
|
+
extractAgentName(content) {
|
|
2370
|
+
if (!content) return void 0;
|
|
2371
|
+
const trimmed = content.trim();
|
|
2372
|
+
if (!trimmed) return void 0;
|
|
2373
|
+
try {
|
|
2374
|
+
const parsed = JSON.parse(trimmed);
|
|
2375
|
+
if (parsed && typeof parsed.agent === "string") {
|
|
2376
|
+
return parsed.agent;
|
|
2377
|
+
}
|
|
2378
|
+
} catch {
|
|
2379
|
+
}
|
|
2380
|
+
return trimmed.split("\n")[0];
|
|
2381
|
+
}
|
|
2382
|
+
};
|
|
2383
|
+
|
|
2384
|
+
// multi-agent/handoff-team/HandoffTeam.ts
|
|
2385
|
+
var HandoffTeam = class extends BaseAgent {
|
|
2386
|
+
constructor(config) {
|
|
2387
|
+
super(config.name, void 0, config.memory ?? config.initialAgent.config.memory);
|
|
2388
|
+
this.config = config;
|
|
2389
|
+
this.edgeMap = this.buildEdgeMap(config.edges);
|
|
2390
|
+
this.agentByName = new Map(
|
|
2391
|
+
config.agents.map((a) => [a.name.toLowerCase(), a])
|
|
2392
|
+
);
|
|
2393
|
+
}
|
|
2394
|
+
edgeMap;
|
|
2395
|
+
agentByName;
|
|
2396
|
+
async execute(input, _options) {
|
|
2397
|
+
const correlationId = `handoff_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
2398
|
+
const startTime = Date.now();
|
|
2399
|
+
return Tracing.withSpan(
|
|
2400
|
+
{
|
|
2401
|
+
kind: "agent",
|
|
2402
|
+
name: `team:handoff:${this.name}`,
|
|
2403
|
+
correlationId,
|
|
2404
|
+
data: { agentName: this.name, input }
|
|
2405
|
+
},
|
|
2406
|
+
async (teamSpan) => {
|
|
2407
|
+
this.emit("agent:execution:start", {
|
|
2408
|
+
correlationId,
|
|
2409
|
+
data: {
|
|
2410
|
+
agentName: this.name,
|
|
2411
|
+
input
|
|
2412
|
+
}
|
|
2413
|
+
});
|
|
2414
|
+
try {
|
|
2415
|
+
const teamMemory = this.config.memory ?? this.config.initialAgent.config.memory;
|
|
2416
|
+
let current = this.config.initialAgent;
|
|
2417
|
+
let transfers = 0;
|
|
2418
|
+
if (input) {
|
|
2419
|
+
await this.addMessage({ role: "user", content: input });
|
|
2420
|
+
}
|
|
2421
|
+
let lastResult;
|
|
2422
|
+
while (true) {
|
|
2423
|
+
enforceMaxTransfers(transfers, this.config.maxTransfers);
|
|
2424
|
+
const { tools, restoreTools } = this.attachHandoffTools(current);
|
|
2425
|
+
const restoreMemory = overrideAgentMemory(current, teamMemory);
|
|
2426
|
+
try {
|
|
2427
|
+
const result = await enforceTimeout(
|
|
2428
|
+
current.execute(),
|
|
2429
|
+
this.config.timeoutMs,
|
|
2430
|
+
"handoff-execution"
|
|
2431
|
+
);
|
|
2432
|
+
lastResult = result;
|
|
2433
|
+
const handoff = this.findHandoffSignal(result, tools);
|
|
2434
|
+
if (!handoff) {
|
|
2435
|
+
this.emit("agent:execution:end", {
|
|
2436
|
+
correlationId,
|
|
2437
|
+
data: {
|
|
2438
|
+
agentName: this.name,
|
|
2439
|
+
status: result.truncated ? "truncated" : "success",
|
|
2440
|
+
output: result.content,
|
|
2441
|
+
durationMs: Date.now() - startTime
|
|
2442
|
+
}
|
|
2443
|
+
});
|
|
2444
|
+
await teamSpan.end({
|
|
2445
|
+
status: result.truncated ? "cancelled" : "success",
|
|
2446
|
+
data: { output: result.content }
|
|
2447
|
+
});
|
|
2448
|
+
return result;
|
|
2449
|
+
}
|
|
2450
|
+
transfers++;
|
|
2451
|
+
enforceAllowedTransition(
|
|
2452
|
+
current.name,
|
|
2453
|
+
handoff.to,
|
|
2454
|
+
this.config.allowedTransitions
|
|
2455
|
+
);
|
|
2456
|
+
if (this.config.onTransfer) {
|
|
2457
|
+
const target = this.agentByName.get(handoff.to.toLowerCase());
|
|
2458
|
+
if (target) {
|
|
2459
|
+
await this.config.onTransfer(current, target);
|
|
2460
|
+
}
|
|
2461
|
+
}
|
|
2462
|
+
const next = this.agentByName.get(handoff.to.toLowerCase());
|
|
2463
|
+
if (!next) {
|
|
2464
|
+
throw new Error(`Handoff target not found: ${handoff.to}`);
|
|
2465
|
+
}
|
|
2466
|
+
current = next;
|
|
2467
|
+
continue;
|
|
2468
|
+
} finally {
|
|
2469
|
+
restoreTools();
|
|
2470
|
+
restoreMemory();
|
|
2471
|
+
}
|
|
2472
|
+
}
|
|
2473
|
+
} catch (error) {
|
|
2474
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
2475
|
+
this.emit("agent:execution:error", {
|
|
2476
|
+
correlationId,
|
|
2477
|
+
data: {
|
|
2478
|
+
agentName: this.name,
|
|
2479
|
+
error: {
|
|
2480
|
+
message: err.message,
|
|
2481
|
+
stack: err.stack,
|
|
2482
|
+
name: err.name
|
|
2483
|
+
},
|
|
2484
|
+
durationMs: Date.now() - startTime
|
|
2485
|
+
}
|
|
2486
|
+
});
|
|
2487
|
+
await teamSpan.end({ status: "error" });
|
|
2488
|
+
throw error;
|
|
2489
|
+
}
|
|
2490
|
+
}
|
|
2491
|
+
);
|
|
2492
|
+
}
|
|
2493
|
+
buildEdgeMap(edges) {
|
|
2494
|
+
const map = /* @__PURE__ */ new Map();
|
|
2495
|
+
edges.forEach((edge) => {
|
|
2496
|
+
const list = map.get(edge.from) ?? [];
|
|
2497
|
+
list.push(edge);
|
|
2498
|
+
map.set(edge.from, list);
|
|
2499
|
+
});
|
|
2500
|
+
return map;
|
|
2501
|
+
}
|
|
2502
|
+
attachHandoffTools(agent) {
|
|
2503
|
+
const edges = this.edgeMap.get(agent) ?? [];
|
|
2504
|
+
const newTools = edges.map(
|
|
2505
|
+
(edge) => new Tool({
|
|
2506
|
+
id: edge.toolId,
|
|
2507
|
+
description: edge.description ?? `Transfer control to ${edge.to.name} (${edge.to.config.instructions})`,
|
|
2508
|
+
handler: async () => ({
|
|
2509
|
+
handoff: true,
|
|
2510
|
+
to: edge.to.name
|
|
2511
|
+
})
|
|
2512
|
+
})
|
|
2513
|
+
);
|
|
2514
|
+
const originalTools = agent.config.tools ?? [];
|
|
2515
|
+
agent.config.tools = [...originalTools, ...newTools];
|
|
2516
|
+
return {
|
|
2517
|
+
tools: newTools,
|
|
2518
|
+
restoreTools: () => {
|
|
2519
|
+
agent.config.tools = originalTools;
|
|
2520
|
+
}
|
|
2521
|
+
};
|
|
2522
|
+
}
|
|
2523
|
+
findHandoffSignal(result, tools) {
|
|
2524
|
+
if (!result.toolExecutions?.length) return void 0;
|
|
2525
|
+
const toolIds = new Set(tools.map((t) => t.id));
|
|
2526
|
+
for (const exec of result.toolExecutions) {
|
|
2527
|
+
if (toolIds.has(exec.name) && exec.output && exec.output.handoff) {
|
|
2528
|
+
return exec.output;
|
|
2529
|
+
}
|
|
2530
|
+
}
|
|
2531
|
+
return void 0;
|
|
2532
|
+
}
|
|
2533
|
+
};
|
|
2534
|
+
|
|
2535
|
+
// multi-agent/hierarchical-team/HierarchicalTeam.ts
|
|
2536
|
+
var HierarchicalTeam = class extends BaseAgent {
|
|
2537
|
+
constructor(config) {
|
|
2538
|
+
super(config.name, void 0, config.memory ?? config.manager.config.memory);
|
|
2539
|
+
this.config = config;
|
|
2540
|
+
this.manager = config.manager;
|
|
2541
|
+
this.workers = config.workers;
|
|
2542
|
+
this.teamMemory = config.memory;
|
|
2543
|
+
this.allowHandoff = config.allowHandoff ?? false;
|
|
2544
|
+
this.workerCollaboration = config.workerCollaboration ?? false;
|
|
2545
|
+
}
|
|
2546
|
+
manager;
|
|
2547
|
+
workers;
|
|
2548
|
+
teamMemory;
|
|
2549
|
+
allowHandoff;
|
|
2550
|
+
workerCollaboration;
|
|
2551
|
+
async execute(input, _options) {
|
|
2552
|
+
const correlationId = `hierarchical_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
2553
|
+
const startTime = Date.now();
|
|
2554
|
+
return Tracing.withSpan(
|
|
2555
|
+
{
|
|
2556
|
+
kind: "agent",
|
|
2557
|
+
name: `team:hierarchical:${this.name}`,
|
|
2558
|
+
correlationId,
|
|
2559
|
+
data: { agentName: this.name, input }
|
|
2560
|
+
},
|
|
2561
|
+
async (teamSpan) => {
|
|
2562
|
+
this.emit("agent:execution:start", {
|
|
2563
|
+
correlationId,
|
|
2564
|
+
data: {
|
|
2565
|
+
agentName: this.name,
|
|
2566
|
+
input
|
|
2567
|
+
}
|
|
2568
|
+
});
|
|
2569
|
+
try {
|
|
2570
|
+
const result = this.allowHandoff ? await this.executeWithHandoff(input) : await this.executeDelegationOnly(input);
|
|
2571
|
+
this.emit("agent:execution:end", {
|
|
2572
|
+
correlationId,
|
|
2573
|
+
data: {
|
|
2574
|
+
agentName: this.name,
|
|
2575
|
+
status: result.truncated ? "truncated" : "success",
|
|
2576
|
+
output: result.content,
|
|
2577
|
+
durationMs: Date.now() - startTime
|
|
2578
|
+
}
|
|
2579
|
+
});
|
|
2580
|
+
await teamSpan.end({
|
|
2581
|
+
status: result.truncated ? "cancelled" : "success",
|
|
2582
|
+
data: { output: result.content }
|
|
2583
|
+
});
|
|
2584
|
+
return result;
|
|
2585
|
+
} catch (error) {
|
|
2586
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
2587
|
+
this.emit("agent:execution:error", {
|
|
2588
|
+
correlationId,
|
|
2589
|
+
data: {
|
|
2590
|
+
agentName: this.name,
|
|
2591
|
+
error: {
|
|
2592
|
+
message: err.message,
|
|
2593
|
+
stack: err.stack,
|
|
2594
|
+
name: err.name
|
|
2595
|
+
},
|
|
2596
|
+
durationMs: Date.now() - startTime
|
|
2597
|
+
}
|
|
2598
|
+
});
|
|
2599
|
+
await teamSpan.end({ status: "error" });
|
|
2600
|
+
throw error;
|
|
2601
|
+
}
|
|
2602
|
+
}
|
|
2603
|
+
);
|
|
2604
|
+
}
|
|
2605
|
+
async executeDelegationOnly(input) {
|
|
2606
|
+
const teamMemory = this.teamMemory ?? this.manager.config.memory;
|
|
2607
|
+
const tools = this.buildWorkerTools(teamMemory);
|
|
2608
|
+
const originalTools = this.manager.config.tools ?? [];
|
|
2609
|
+
this.manager.config.tools = [...originalTools, ...tools];
|
|
2610
|
+
const restoreMemory = overrideAgentMemory(this.manager, teamMemory);
|
|
2611
|
+
try {
|
|
2612
|
+
if (input) {
|
|
2613
|
+
await this.addMessage({ role: "user", content: input });
|
|
2614
|
+
}
|
|
2615
|
+
return await this.manager.execute();
|
|
2616
|
+
} finally {
|
|
2617
|
+
this.manager.config.tools = originalTools;
|
|
2618
|
+
restoreMemory();
|
|
2619
|
+
tools.forEach((t) => t.setCallingMemory(void 0));
|
|
2620
|
+
}
|
|
2621
|
+
}
|
|
2622
|
+
async executeWithHandoff(input) {
|
|
2623
|
+
const teamMemory = this.teamMemory ?? this.manager.config.memory;
|
|
2624
|
+
if (this.workerCollaboration) {
|
|
2625
|
+
this.workers.forEach((worker) => {
|
|
2626
|
+
const originalTools = worker.config.tools ?? [];
|
|
2627
|
+
const peerTools = this.workers.filter((w) => w !== worker).map(
|
|
2628
|
+
(w) => new AgentAsTool({
|
|
2629
|
+
agent: w,
|
|
2630
|
+
memory: { type: "shared" },
|
|
2631
|
+
additionalPrompt: "Use this to consult another specialist."
|
|
2632
|
+
})
|
|
2633
|
+
);
|
|
2634
|
+
worker.config.tools = [...originalTools, ...peerTools];
|
|
2635
|
+
});
|
|
2636
|
+
}
|
|
2637
|
+
const team = new HandoffTeam({
|
|
2638
|
+
name: `${this.config.name}-internal-handoff`,
|
|
2639
|
+
agents: [this.manager, ...this.workers],
|
|
2640
|
+
edges: [
|
|
2641
|
+
...this.workers.map((w) => ({
|
|
2642
|
+
from: this.manager,
|
|
2643
|
+
to: w,
|
|
2644
|
+
toolId: `handoff_to_${w.name.toLowerCase()}`,
|
|
2645
|
+
description: `Pass control to worker ${w.name}`
|
|
2646
|
+
})),
|
|
2647
|
+
...this.workers.map((w) => ({
|
|
2648
|
+
from: w,
|
|
2649
|
+
to: this.manager,
|
|
2650
|
+
toolId: `back_to_manager`,
|
|
2651
|
+
description: `Return control to manager`
|
|
2652
|
+
}))
|
|
2653
|
+
],
|
|
2654
|
+
initialAgent: this.manager,
|
|
2655
|
+
memory: teamMemory,
|
|
2656
|
+
additionalPrompt: this.config.additionalPrompt,
|
|
2657
|
+
maxTransfers: 10
|
|
2658
|
+
});
|
|
2659
|
+
return team.execute(input);
|
|
2660
|
+
}
|
|
2661
|
+
buildWorkerTools(teamMemory) {
|
|
2662
|
+
return this.workers.map((worker) => {
|
|
2663
|
+
const tool = new AgentAsTool({
|
|
2664
|
+
agent: worker,
|
|
2665
|
+
id: `delegate_${worker.name.toLowerCase()}`,
|
|
2666
|
+
memory: { type: "shared" },
|
|
2667
|
+
additionalPrompt: "Delegate a subtask to this specialist."
|
|
2668
|
+
});
|
|
2669
|
+
tool.setCallingMemory(teamMemory);
|
|
2670
|
+
return tool;
|
|
2671
|
+
});
|
|
2672
|
+
}
|
|
2673
|
+
};
|
|
2674
|
+
|
|
2675
|
+
// multi-agent/pipeline-team/PipelineTeam.ts
|
|
2676
|
+
var PipelineTeam = class extends BaseAgent {
|
|
2677
|
+
constructor(config) {
|
|
2678
|
+
super(config.name, void 0, config.memory ?? config.stages?.[0]?.config?.memory);
|
|
2679
|
+
this.config = config;
|
|
2680
|
+
this.stages = config.stages;
|
|
2681
|
+
this.teamMemory = config.memory;
|
|
2682
|
+
}
|
|
2683
|
+
stages;
|
|
2684
|
+
teamMemory;
|
|
2685
|
+
async execute(input, _options) {
|
|
2686
|
+
const correlationId = `pipeline_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
2687
|
+
const startTime = Date.now();
|
|
2688
|
+
return Tracing.withSpan(
|
|
2689
|
+
{
|
|
2690
|
+
kind: "agent",
|
|
2691
|
+
name: `team:pipeline:${this.name}`,
|
|
2692
|
+
correlationId,
|
|
2693
|
+
data: { agentName: this.name, input }
|
|
2694
|
+
},
|
|
2695
|
+
async (teamSpan) => {
|
|
2696
|
+
this.emit("agent:execution:start", {
|
|
2697
|
+
correlationId,
|
|
2698
|
+
data: {
|
|
2699
|
+
agentName: this.name,
|
|
2700
|
+
input
|
|
2701
|
+
}
|
|
2702
|
+
});
|
|
2703
|
+
try {
|
|
2704
|
+
const edges = this.buildEdges();
|
|
2705
|
+
const team = new HandoffTeam({
|
|
2706
|
+
name: `${this.config.name}-internal-handoff`,
|
|
2707
|
+
agents: this.stages,
|
|
2708
|
+
edges,
|
|
2709
|
+
initialAgent: this.stages[0],
|
|
2710
|
+
memory: this.teamMemory,
|
|
2711
|
+
additionalPrompt: this.config.additionalPrompt,
|
|
2712
|
+
maxTransfers: edges.length + 2
|
|
2713
|
+
});
|
|
2714
|
+
const result = await team.execute(input);
|
|
2715
|
+
this.emit("agent:execution:end", {
|
|
2716
|
+
correlationId,
|
|
2717
|
+
data: {
|
|
2718
|
+
agentName: this.name,
|
|
2719
|
+
status: result.truncated ? "truncated" : "success",
|
|
2720
|
+
output: result.content,
|
|
2721
|
+
durationMs: Date.now() - startTime
|
|
2722
|
+
}
|
|
2723
|
+
});
|
|
2724
|
+
await teamSpan.end({
|
|
2725
|
+
status: result.truncated ? "cancelled" : "success",
|
|
2726
|
+
data: { output: result.content }
|
|
2727
|
+
});
|
|
2728
|
+
return result;
|
|
2729
|
+
} catch (error) {
|
|
2730
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
2731
|
+
this.emit("agent:execution:error", {
|
|
2732
|
+
correlationId,
|
|
2733
|
+
data: {
|
|
2734
|
+
agentName: this.name,
|
|
2735
|
+
error: {
|
|
2736
|
+
message: err.message,
|
|
2737
|
+
stack: err.stack,
|
|
2738
|
+
name: err.name
|
|
2739
|
+
},
|
|
2740
|
+
durationMs: Date.now() - startTime
|
|
2741
|
+
}
|
|
2742
|
+
});
|
|
2743
|
+
await teamSpan.end({ status: "error" });
|
|
2744
|
+
throw error;
|
|
2745
|
+
}
|
|
2746
|
+
}
|
|
2747
|
+
);
|
|
2748
|
+
}
|
|
2749
|
+
buildEdges() {
|
|
2750
|
+
const edges = this.stages.slice(0, -1).map((from, idx) => {
|
|
2751
|
+
const to = this.stages[idx + 1];
|
|
2752
|
+
return {
|
|
2753
|
+
from,
|
|
2754
|
+
to,
|
|
2755
|
+
toolId: `next_${to.name.toLowerCase()}`,
|
|
2756
|
+
description: `Pass work to ${to.name}`
|
|
2757
|
+
};
|
|
2758
|
+
});
|
|
2759
|
+
return edges;
|
|
2760
|
+
}
|
|
2761
|
+
};
|
|
2762
|
+
|
|
2763
|
+
// multi-agent/committee-team/CommitteeTeam.ts
|
|
2764
|
+
var CommitteeTeam = class extends BaseAgent {
|
|
2765
|
+
constructor(config) {
|
|
2766
|
+
super(config.name, void 0, config.memory ?? config.coordinator.config.memory);
|
|
2767
|
+
this.config = config;
|
|
2768
|
+
this.coordinator = config.coordinator;
|
|
2769
|
+
this.members = config.members;
|
|
2770
|
+
this.strategy = config.strategy;
|
|
2771
|
+
this.teamMemory = config.memory;
|
|
2772
|
+
}
|
|
2773
|
+
coordinator;
|
|
2774
|
+
members;
|
|
2775
|
+
strategy;
|
|
2776
|
+
teamMemory;
|
|
2777
|
+
async execute(input, _options) {
|
|
2778
|
+
const correlationId = `committee_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
2779
|
+
const startTime = Date.now();
|
|
2780
|
+
return Tracing.withSpan(
|
|
2781
|
+
{
|
|
2782
|
+
kind: "agent",
|
|
2783
|
+
name: `team:committee:${this.name}`,
|
|
2784
|
+
correlationId,
|
|
2785
|
+
data: { agentName: this.name, input }
|
|
2786
|
+
},
|
|
2787
|
+
async (teamSpan) => {
|
|
2788
|
+
this.emit("agent:execution:start", {
|
|
2789
|
+
correlationId,
|
|
2790
|
+
data: {
|
|
2791
|
+
agentName: this.name,
|
|
2792
|
+
input
|
|
2793
|
+
}
|
|
2794
|
+
});
|
|
2795
|
+
try {
|
|
2796
|
+
const teamMemory = this.teamMemory ?? this.coordinator.config.memory;
|
|
2797
|
+
const opinions = await this.collectOpinions(teamMemory, input);
|
|
2798
|
+
const aggregated = this.aggregate(opinions);
|
|
2799
|
+
const restoreMemory = overrideAgentMemory(this.coordinator, teamMemory);
|
|
2800
|
+
let result;
|
|
2801
|
+
try {
|
|
2802
|
+
await this.addMessage({
|
|
2803
|
+
role: "user",
|
|
2804
|
+
content: `Members opinions:
|
|
2805
|
+
${opinions.map((o) => `- ${o.agent}: ${o.content}`).join("\n")}
|
|
2806
|
+
Strategy: ${this.strategy}`
|
|
2807
|
+
});
|
|
2808
|
+
if (input) {
|
|
2809
|
+
await this.addMessage({ role: "user", content: input });
|
|
2810
|
+
}
|
|
2811
|
+
const coordinatorResult = await this.coordinator.execute();
|
|
2812
|
+
result = coordinatorResult ?? this.buildResult(aggregated);
|
|
2813
|
+
} finally {
|
|
2814
|
+
restoreMemory();
|
|
2815
|
+
}
|
|
2816
|
+
this.emit("agent:execution:end", {
|
|
2817
|
+
correlationId,
|
|
2818
|
+
data: {
|
|
2819
|
+
agentName: this.name,
|
|
2820
|
+
status: result.truncated ? "truncated" : "success",
|
|
2821
|
+
output: result.content,
|
|
2822
|
+
durationMs: Date.now() - startTime
|
|
2823
|
+
}
|
|
2824
|
+
});
|
|
2825
|
+
await teamSpan.end({
|
|
2826
|
+
status: result.truncated ? "cancelled" : "success",
|
|
2827
|
+
data: { output: result.content }
|
|
2828
|
+
});
|
|
2829
|
+
return result;
|
|
2830
|
+
} catch (error) {
|
|
2831
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
2832
|
+
this.emit("agent:execution:error", {
|
|
2833
|
+
correlationId,
|
|
2834
|
+
data: {
|
|
2835
|
+
agentName: this.name,
|
|
2836
|
+
error: {
|
|
2837
|
+
message: err.message,
|
|
2838
|
+
stack: err.stack,
|
|
2839
|
+
name: err.name
|
|
2840
|
+
},
|
|
2841
|
+
durationMs: Date.now() - startTime
|
|
2842
|
+
}
|
|
2843
|
+
});
|
|
2844
|
+
await teamSpan.end({ status: "error" });
|
|
2845
|
+
throw error;
|
|
2846
|
+
}
|
|
2847
|
+
}
|
|
2848
|
+
);
|
|
2849
|
+
}
|
|
2850
|
+
async collectOpinions(memory, input) {
|
|
2851
|
+
const opinions = [];
|
|
2852
|
+
for (const member of this.members) {
|
|
2853
|
+
const restoreMemory = overrideAgentMemory(member, memory);
|
|
2854
|
+
try {
|
|
2855
|
+
if (input) {
|
|
2856
|
+
await memory.addMessage({ role: "user", content: input });
|
|
2857
|
+
}
|
|
2858
|
+
const result = await member.execute();
|
|
2859
|
+
opinions.push({ agent: member.name, content: result.content });
|
|
2860
|
+
} finally {
|
|
2861
|
+
restoreMemory();
|
|
2862
|
+
}
|
|
2863
|
+
}
|
|
2864
|
+
return opinions;
|
|
2865
|
+
}
|
|
2866
|
+
aggregate(opinions) {
|
|
2867
|
+
if (this.strategy === "first") {
|
|
2868
|
+
return opinions[0]?.content;
|
|
2869
|
+
}
|
|
2870
|
+
if (this.strategy === "vote") {
|
|
2871
|
+
const counts = opinions.reduce((acc, o) => {
|
|
2872
|
+
const key = String(o.content);
|
|
2873
|
+
acc[key] = (acc[key] || 0) + 1;
|
|
2874
|
+
return acc;
|
|
2875
|
+
}, {});
|
|
2876
|
+
return Object.entries(counts).sort((a, b) => b[1] - a[1])[0]?.[0];
|
|
2877
|
+
}
|
|
2878
|
+
if (this.strategy === "confidence") {
|
|
2879
|
+
return opinions[0]?.content;
|
|
2880
|
+
}
|
|
2881
|
+
return opinions.map((o) => `${o.agent}: ${o.content}`).join(" | ");
|
|
2882
|
+
}
|
|
2883
|
+
buildResult(content) {
|
|
2884
|
+
return {
|
|
2885
|
+
content,
|
|
2886
|
+
toolExecutions: [],
|
|
2887
|
+
llmCalls: 0,
|
|
2888
|
+
totalDurationMs: 0,
|
|
2889
|
+
truncated: false
|
|
2890
|
+
};
|
|
2891
|
+
}
|
|
2892
|
+
};
|
|
2893
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
2894
|
+
0 && (module.exports = {
|
|
2895
|
+
ActiveSpan,
|
|
2896
|
+
Agent,
|
|
2897
|
+
AgentAsTool,
|
|
2898
|
+
AgentExecutionEndSchema,
|
|
2899
|
+
AgentExecutionErrorSchema,
|
|
2900
|
+
AgentExecutionStartSchema,
|
|
2901
|
+
AgentLLMCallSchema,
|
|
2902
|
+
AgentLLMResponseSchema,
|
|
2903
|
+
AgentLogger,
|
|
2904
|
+
AgentToolCallSchema,
|
|
2905
|
+
AgentToolResultSchema,
|
|
2906
|
+
BaseAgent,
|
|
2907
|
+
COLORS,
|
|
2908
|
+
CommitteeTeam,
|
|
2909
|
+
ConsoleLogger,
|
|
2910
|
+
ErrorSchema,
|
|
2911
|
+
EventCommonSchema,
|
|
2912
|
+
GuardrailError,
|
|
2913
|
+
HandoffTeam,
|
|
2914
|
+
HierarchicalTeam,
|
|
2915
|
+
InMemory,
|
|
2916
|
+
KeywordScorer,
|
|
2917
|
+
LOG_LEVEL_COLORS,
|
|
2918
|
+
ModelSchema,
|
|
2919
|
+
NebulaEventSchema,
|
|
2920
|
+
PipelineTeam,
|
|
2921
|
+
RegexPIIMasker,
|
|
2922
|
+
RouterTeam,
|
|
2923
|
+
TREE_CHARS,
|
|
2924
|
+
Tool,
|
|
2925
|
+
TraceContextSchema,
|
|
2926
|
+
Tracing,
|
|
2927
|
+
UsageSchema,
|
|
2928
|
+
Workflow,
|
|
2929
|
+
WorkflowExecutionEndSchema,
|
|
2930
|
+
WorkflowExecutionErrorSchema,
|
|
2931
|
+
WorkflowExecutionStartSchema,
|
|
2932
|
+
WorkflowLogger,
|
|
2933
|
+
WorkflowStepSchema,
|
|
2934
|
+
agentAsToolConfigSchema,
|
|
2935
|
+
aggregationStrategySchema,
|
|
2936
|
+
buildHandoffSystemPrompt,
|
|
2937
|
+
buildRouterSystemPrompt,
|
|
2938
|
+
calculateRetryDelay,
|
|
2939
|
+
committeeTeamConfigSchema,
|
|
2940
|
+
delegationMemorySchema,
|
|
2941
|
+
enforceAllowedTransition,
|
|
2942
|
+
enforceMaxTransfers,
|
|
2943
|
+
enforceTimeout,
|
|
2944
|
+
formatError,
|
|
2945
|
+
formatLogLine,
|
|
2946
|
+
formatMetadata,
|
|
2947
|
+
handoffEdgeSchema,
|
|
2948
|
+
handoffTeamConfigSchema,
|
|
2949
|
+
hierarchicalTeamConfigSchema,
|
|
2950
|
+
isRetryableError,
|
|
2951
|
+
overrideAgentMemory,
|
|
2952
|
+
pipelineTeamConfigSchema,
|
|
2953
|
+
resolveDelegationMemory,
|
|
2954
|
+
routerTeamConfigSchema,
|
|
2955
|
+
schemaToZod,
|
|
2956
|
+
z
|
|
2957
|
+
});
|
|
2958
|
+
//# sourceMappingURL=index.cjs.map
|