@nebulaos/core 0.2.4 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/Agent.d.ts +2 -1
- package/dist/agent/Agent.js +251 -235
- package/dist/multi-agent/committee-team/CommitteeTeam.js +9 -3
- package/dist/multi-agent/handoff-team/HandoffTeam.js +9 -3
- package/dist/multi-agent/hierarchical-team/HierarchicalTeam.js +9 -3
- package/dist/multi-agent/pipeline-team/PipelineTeam.js +9 -3
- package/dist/multi-agent/router-team/RouterTeam.js +14 -3
- package/dist/tracing/index.js +0 -2
- package/dist/workflow/execution/WorkflowTelemetry.js +13 -3
- package/package.json +4 -4
package/dist/agent/Agent.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IModel, Message, ToolCall, StreamChunk, ProviderResponse, ContentPart } from "./provider/index.js";
|
|
1
|
+
import { IModel, Message, ToolCall, TokenUsage, StreamChunk, ProviderResponse, ContentPart } from "./provider/index.js";
|
|
2
2
|
import { IMemory, MemoryExecutionContext } from "./memory/index.js";
|
|
3
3
|
import { Tool, ToolExecution } from "./tools/index.js";
|
|
4
4
|
import { ISkill } from "./skills/index.js";
|
|
@@ -51,6 +51,7 @@ export type AgentResult = {
|
|
|
51
51
|
llmCalls: number;
|
|
52
52
|
totalDurationMs: number;
|
|
53
53
|
truncated: boolean;
|
|
54
|
+
usage?: TokenUsage;
|
|
54
55
|
};
|
|
55
56
|
export type AgentStreamChunk = StreamChunk | {
|
|
56
57
|
type: "tool_result";
|
package/dist/agent/Agent.js
CHANGED
|
@@ -8,6 +8,7 @@ const agent_logger_js_1 = require("../logger/agent-logger.js");
|
|
|
8
8
|
const index_js_3 = require("../tracing/index.js");
|
|
9
9
|
const BaseAgent_js_1 = require("./BaseAgent.js");
|
|
10
10
|
const index_js_4 = require("../execution-context/index.js");
|
|
11
|
+
const types_1 = require("@nebulaos/types");
|
|
11
12
|
function generateCorrelationId() {
|
|
12
13
|
return `exec_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
13
14
|
}
|
|
@@ -155,262 +156,272 @@ class Agent extends BaseAgent_js_1.BaseAgent {
|
|
|
155
156
|
let llmCalls = 0;
|
|
156
157
|
let truncated = false;
|
|
157
158
|
let totalUsage = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };
|
|
158
|
-
const runWithExecutionContext = async () =>
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
159
|
+
const runWithExecutionContext = async () => {
|
|
160
|
+
const agentStart = {
|
|
161
|
+
agentName: this.name,
|
|
162
|
+
input,
|
|
163
|
+
};
|
|
164
|
+
return index_js_3.Tracing.withSpan({
|
|
165
|
+
kind: types_1.SpanType.agent,
|
|
166
|
+
name: `agent:${this.name}`,
|
|
166
167
|
correlationId,
|
|
167
168
|
executionId: options.executionId,
|
|
168
|
-
data:
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
169
|
+
data: agentStart,
|
|
170
|
+
}, async (agentSpan) => {
|
|
171
|
+
this.emit("agent:execution:start", {
|
|
172
|
+
correlationId,
|
|
173
|
+
executionId: options.executionId,
|
|
174
|
+
data: {
|
|
175
|
+
agentId: this.id,
|
|
176
|
+
agentName: this.name,
|
|
177
|
+
input,
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
try {
|
|
181
|
+
// Initialize skills if not already initialized
|
|
182
|
+
await this.initializeSkills();
|
|
183
|
+
if (input) {
|
|
184
|
+
await this.addMessage({ role: "user", content: input }, memoryCtx);
|
|
185
|
+
}
|
|
186
|
+
let step = 0;
|
|
187
|
+
while (step < maxSteps) {
|
|
188
|
+
step++;
|
|
189
|
+
llmCalls++;
|
|
190
|
+
let messages = await this.getMessagesWithContext(memoryCtx);
|
|
191
|
+
let tools = !options.disableTools && this.config.tools ? [...this.config.tools] : [];
|
|
192
|
+
// Apply Request Interceptors
|
|
193
|
+
let context = { messages, tools };
|
|
194
|
+
for (const interceptor of this.requestInterceptors) {
|
|
195
|
+
context = await interceptor(context);
|
|
196
|
+
}
|
|
197
|
+
messages = context.messages;
|
|
198
|
+
tools = context.tools;
|
|
199
|
+
this.validateMessagesForModel(messages, {
|
|
200
|
+
maxFileBytes: MAX_MESSAGE_FILE_BYTES_DEFAULT,
|
|
201
|
+
providerName: this.config.model.providerName,
|
|
202
|
+
modelName: this.config.model.modelName,
|
|
203
|
+
capabilities: this.config.model.capabilities,
|
|
204
|
+
});
|
|
205
|
+
const llmTools = tools.length > 0
|
|
206
|
+
? tools.map(t => t.toLLMDefinition())
|
|
207
|
+
: undefined;
|
|
208
|
+
this.emit("agent:llm:call", {
|
|
209
|
+
correlationId,
|
|
210
|
+
executionId: options.executionId,
|
|
211
|
+
data: {
|
|
212
|
+
agentId: this.id,
|
|
213
|
+
agentName: this.name,
|
|
214
|
+
step,
|
|
215
|
+
messages,
|
|
216
|
+
tools: llmTools,
|
|
217
|
+
responseFormat: options.responseFormat,
|
|
218
|
+
model: {
|
|
219
|
+
provider: this.config.model.providerName,
|
|
220
|
+
model: this.config.model.modelName,
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
});
|
|
224
|
+
// No SDK-side LLM span: the LLM Gateway creates its own span
|
|
225
|
+
// with richer data. We just call generate under the agent span so
|
|
226
|
+
// the provider can read the current trace context (traceparent).
|
|
227
|
+
const rawResponse = await this.config.model.generate(messages, llmTools, {
|
|
228
|
+
responseFormat: options.responseFormat,
|
|
229
|
+
});
|
|
230
|
+
let response = rawResponse;
|
|
231
|
+
this.emit("agent:llm:response", {
|
|
232
|
+
correlationId,
|
|
233
|
+
executionId: options.executionId,
|
|
234
|
+
data: {
|
|
235
|
+
agentId: this.id,
|
|
236
|
+
agentName: this.name,
|
|
237
|
+
step,
|
|
238
|
+
content: response.content,
|
|
239
|
+
toolCalls: response.toolCalls,
|
|
240
|
+
usage: response.usage,
|
|
241
|
+
model: {
|
|
242
|
+
provider: this.config.model.providerName,
|
|
243
|
+
model: this.config.model.modelName,
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
});
|
|
247
|
+
// Accumulate token usage
|
|
248
|
+
if (response.usage) {
|
|
249
|
+
totalUsage.promptTokens += response.usage.promptTokens;
|
|
250
|
+
totalUsage.completionTokens += response.usage.completionTokens;
|
|
251
|
+
totalUsage.totalTokens += response.usage.totalTokens;
|
|
252
|
+
if (response.usage.reasoningTokens) {
|
|
253
|
+
totalUsage.reasoningTokens = (totalUsage.reasoningTokens || 0) + response.usage.reasoningTokens;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
if (!response.toolCalls || response.toolCalls.length === 0 || options.disableTools) {
|
|
257
|
+
// Apply Response Interceptors (Final Answer)
|
|
258
|
+
for (const interceptor of this.responseInterceptors) {
|
|
259
|
+
response = await interceptor(response);
|
|
260
|
+
}
|
|
261
|
+
await this.addMessage({ role: "assistant", content: response.content }, memoryCtx);
|
|
262
|
+
const agentEnd = {
|
|
263
|
+
output: options.responseFormat?.type === "json"
|
|
264
|
+
? this.safeParseJson(response.content)
|
|
265
|
+
: response.content,
|
|
266
|
+
usage: totalUsage,
|
|
267
|
+
};
|
|
268
|
+
await agentSpan.end({
|
|
269
|
+
status: "success",
|
|
270
|
+
data: agentEnd,
|
|
271
|
+
});
|
|
272
|
+
return this.finishResult({
|
|
273
|
+
correlationId,
|
|
274
|
+
executionId: options.executionId,
|
|
275
|
+
content: options.responseFormat?.type === "json"
|
|
276
|
+
? this.safeParseJson(response.content)
|
|
277
|
+
: response.content,
|
|
278
|
+
toolExecutions,
|
|
279
|
+
toolCalls: options.disableTools ? response.toolCalls : undefined,
|
|
280
|
+
llmCalls,
|
|
281
|
+
totalDurationMs: Date.now() - startTime,
|
|
282
|
+
truncated: false,
|
|
283
|
+
totalUsage,
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
// Add assistant message with tool calls before executing tools
|
|
287
|
+
await this.addMessage({
|
|
288
|
+
role: "assistant",
|
|
289
|
+
content: response.content,
|
|
290
|
+
tool_calls: response.toolCalls
|
|
291
|
+
}, memoryCtx);
|
|
292
|
+
for (const toolCall of response.toolCalls) {
|
|
293
|
+
const parentExec = index_js_4.ExecutionContext.getOrUndefined();
|
|
294
|
+
const toolExecutionId = parentExec?.executionId || options.executionId ? (0, node_crypto_1.randomUUID)() : undefined;
|
|
295
|
+
const toolStart = {
|
|
296
|
+
toolName: toolCall.function.name,
|
|
297
|
+
toolCallId: toolCall.id,
|
|
298
|
+
args: toolCall.function.arguments,
|
|
299
|
+
};
|
|
300
|
+
await index_js_3.Tracing.withSpan({
|
|
301
|
+
kind: types_1.SpanType.tool,
|
|
302
|
+
name: `tool:${toolCall.function.name}`,
|
|
303
|
+
correlationId,
|
|
304
|
+
executionId: toolExecutionId ?? options.executionId,
|
|
305
|
+
data: toolStart,
|
|
306
|
+
}, async (toolSpan) => {
|
|
307
|
+
this.emit("agent:tool:call", {
|
|
308
|
+
correlationId,
|
|
309
|
+
executionId: options.executionId,
|
|
310
|
+
data: {
|
|
311
|
+
agentId: this.id,
|
|
312
|
+
agentName: this.name,
|
|
313
|
+
toolName: toolCall.function.name,
|
|
314
|
+
toolCallId: toolCall.id,
|
|
315
|
+
args: toolCall.function.arguments,
|
|
316
|
+
},
|
|
317
|
+
});
|
|
318
|
+
const execution = await this.executeToolCall(toolCall, toolExecutionId);
|
|
319
|
+
toolExecutions.push(execution);
|
|
320
|
+
collectedToolCalls.push(toolCall);
|
|
321
|
+
this.emit("agent:tool:result", {
|
|
322
|
+
correlationId,
|
|
323
|
+
executionId: options.executionId,
|
|
324
|
+
data: {
|
|
325
|
+
agentId: this.id,
|
|
326
|
+
agentName: this.name,
|
|
327
|
+
toolName: toolCall.function.name,
|
|
328
|
+
toolCallId: toolCall.id,
|
|
329
|
+
output: execution.output,
|
|
330
|
+
error: execution.error,
|
|
331
|
+
durationMs: execution.durationMs,
|
|
332
|
+
},
|
|
333
|
+
});
|
|
334
|
+
const toolEnd = execution.error
|
|
335
|
+
? { error: execution.error }
|
|
336
|
+
: { output: execution.output };
|
|
337
|
+
await toolSpan.end({
|
|
338
|
+
status: execution.error ? "error" : "success",
|
|
339
|
+
data: toolEnd,
|
|
340
|
+
});
|
|
341
|
+
await this.addMessage({
|
|
342
|
+
role: "tool",
|
|
343
|
+
tool_call_id: toolCall.id,
|
|
344
|
+
content: execution.error ? `Error: ${execution.error}` : JSON.stringify(execution.output),
|
|
345
|
+
}, memoryCtx);
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
truncated = true;
|
|
183
350
|
llmCalls++;
|
|
184
|
-
|
|
185
|
-
let
|
|
186
|
-
|
|
187
|
-
|
|
351
|
+
// Final run after max steps (force answer)
|
|
352
|
+
let finalMessages = await this.getMessagesWithContext(memoryCtx);
|
|
353
|
+
let finalTools = !options.disableTools && this.config.tools ? [...this.config.tools] : [];
|
|
354
|
+
// Interceptors for final run
|
|
355
|
+
let context = { messages: finalMessages, tools: finalTools };
|
|
188
356
|
for (const interceptor of this.requestInterceptors) {
|
|
189
357
|
context = await interceptor(context);
|
|
190
358
|
}
|
|
191
|
-
|
|
192
|
-
tools
|
|
193
|
-
this.validateMessagesForModel(
|
|
359
|
+
finalMessages = context.messages;
|
|
360
|
+
// We ignore tools for final run usually, but keep consistency
|
|
361
|
+
this.validateMessagesForModel(finalMessages, {
|
|
194
362
|
maxFileBytes: MAX_MESSAGE_FILE_BYTES_DEFAULT,
|
|
195
363
|
providerName: this.config.model.providerName,
|
|
196
364
|
modelName: this.config.model.modelName,
|
|
197
365
|
capabilities: this.config.model.capabilities,
|
|
198
366
|
});
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
367
|
+
let finalResponse = await this.config.model.generate(finalMessages);
|
|
368
|
+
// Response interceptors for final run
|
|
369
|
+
for (const interceptor of this.responseInterceptors) {
|
|
370
|
+
finalResponse = await interceptor(finalResponse);
|
|
371
|
+
}
|
|
372
|
+
await this.addMessage({ role: "assistant", content: finalResponse.content }, memoryCtx);
|
|
373
|
+
const agentEndTruncated = {
|
|
374
|
+
output: finalResponse.content,
|
|
375
|
+
usage: totalUsage,
|
|
376
|
+
};
|
|
377
|
+
await agentSpan.end({
|
|
378
|
+
status: truncated ? "cancelled" : "success",
|
|
379
|
+
data: agentEndTruncated,
|
|
380
|
+
});
|
|
381
|
+
return this.finishResult({
|
|
203
382
|
correlationId,
|
|
204
383
|
executionId: options.executionId,
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
model: {
|
|
213
|
-
provider: this.config.model.providerName,
|
|
214
|
-
model: this.config.model.modelName,
|
|
215
|
-
},
|
|
216
|
-
},
|
|
217
|
-
});
|
|
218
|
-
// No SDK-side LLM span: the LLM Gateway creates its own span
|
|
219
|
-
// with richer data. We just call generate under the agent span so
|
|
220
|
-
// the provider can read the current trace context (traceparent).
|
|
221
|
-
const rawResponse = await this.config.model.generate(messages, llmTools, {
|
|
222
|
-
responseFormat: options.responseFormat,
|
|
384
|
+
content: finalResponse.content,
|
|
385
|
+
toolExecutions,
|
|
386
|
+
toolCalls: collectedToolCalls,
|
|
387
|
+
llmCalls,
|
|
388
|
+
totalDurationMs: Date.now() - startTime,
|
|
389
|
+
truncated,
|
|
390
|
+
totalUsage,
|
|
223
391
|
});
|
|
224
|
-
|
|
225
|
-
|
|
392
|
+
}
|
|
393
|
+
catch (err) {
|
|
394
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
395
|
+
this.emit("agent:execution:error", {
|
|
226
396
|
correlationId,
|
|
227
397
|
executionId: options.executionId,
|
|
228
398
|
data: {
|
|
229
399
|
agentId: this.id,
|
|
230
400
|
agentName: this.name,
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
model: {
|
|
236
|
-
provider: this.config.model.providerName,
|
|
237
|
-
model: this.config.model.modelName,
|
|
401
|
+
error: {
|
|
402
|
+
message: error.message,
|
|
403
|
+
stack: error.stack,
|
|
404
|
+
name: error.name,
|
|
238
405
|
},
|
|
406
|
+
durationMs: Date.now() - startTime,
|
|
239
407
|
},
|
|
240
408
|
});
|
|
241
|
-
|
|
242
|
-
if (response.usage) {
|
|
243
|
-
totalUsage.promptTokens += response.usage.promptTokens;
|
|
244
|
-
totalUsage.completionTokens += response.usage.completionTokens;
|
|
245
|
-
totalUsage.totalTokens += response.usage.totalTokens;
|
|
246
|
-
if (response.usage.reasoningTokens) {
|
|
247
|
-
totalUsage.reasoningTokens = (totalUsage.reasoningTokens || 0) + response.usage.reasoningTokens;
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
if (!response.toolCalls || response.toolCalls.length === 0 || options.disableTools) {
|
|
251
|
-
// Apply Response Interceptors (Final Answer)
|
|
252
|
-
for (const interceptor of this.responseInterceptors) {
|
|
253
|
-
response = await interceptor(response);
|
|
254
|
-
}
|
|
255
|
-
await this.addMessage({ role: "assistant", content: response.content }, memoryCtx);
|
|
256
|
-
await agentSpan.end({
|
|
257
|
-
status: "success",
|
|
258
|
-
data: {
|
|
259
|
-
output: options.responseFormat?.type === "json"
|
|
260
|
-
? this.safeParseJson(response.content)
|
|
261
|
-
: response.content,
|
|
262
|
-
usage: totalUsage,
|
|
263
|
-
},
|
|
264
|
-
});
|
|
265
|
-
return this.finishResult({
|
|
266
|
-
correlationId,
|
|
267
|
-
executionId: options.executionId,
|
|
268
|
-
content: options.responseFormat?.type === "json"
|
|
269
|
-
? this.safeParseJson(response.content)
|
|
270
|
-
: response.content,
|
|
271
|
-
toolExecutions,
|
|
272
|
-
toolCalls: options.disableTools ? response.toolCalls : undefined,
|
|
273
|
-
llmCalls,
|
|
274
|
-
totalDurationMs: Date.now() - startTime,
|
|
275
|
-
truncated: false,
|
|
276
|
-
totalUsage,
|
|
277
|
-
});
|
|
278
|
-
}
|
|
279
|
-
// Add assistant message with tool calls before executing tools
|
|
280
|
-
await this.addMessage({
|
|
281
|
-
role: "assistant",
|
|
282
|
-
content: response.content,
|
|
283
|
-
tool_calls: response.toolCalls
|
|
284
|
-
}, memoryCtx);
|
|
285
|
-
for (const toolCall of response.toolCalls) {
|
|
286
|
-
const parentExec = index_js_4.ExecutionContext.getOrUndefined();
|
|
287
|
-
const toolExecutionId = parentExec?.executionId || options.executionId ? (0, node_crypto_1.randomUUID)() : undefined;
|
|
288
|
-
await index_js_3.Tracing.withSpan({
|
|
289
|
-
kind: "tool",
|
|
290
|
-
name: `tool:${toolCall.function.name}`,
|
|
291
|
-
correlationId,
|
|
292
|
-
executionId: toolExecutionId ?? options.executionId,
|
|
293
|
-
data: {
|
|
294
|
-
toolName: toolCall.function.name,
|
|
295
|
-
toolCallId: toolCall.id,
|
|
296
|
-
args: toolCall.function.arguments,
|
|
297
|
-
},
|
|
298
|
-
}, async (toolSpan) => {
|
|
299
|
-
this.emit("agent:tool:call", {
|
|
300
|
-
correlationId,
|
|
301
|
-
executionId: options.executionId,
|
|
302
|
-
data: {
|
|
303
|
-
agentId: this.id,
|
|
304
|
-
agentName: this.name,
|
|
305
|
-
toolName: toolCall.function.name,
|
|
306
|
-
toolCallId: toolCall.id,
|
|
307
|
-
args: toolCall.function.arguments,
|
|
308
|
-
},
|
|
309
|
-
});
|
|
310
|
-
const execution = await this.executeToolCall(toolCall, toolExecutionId);
|
|
311
|
-
toolExecutions.push(execution);
|
|
312
|
-
collectedToolCalls.push(toolCall);
|
|
313
|
-
this.emit("agent:tool:result", {
|
|
314
|
-
correlationId,
|
|
315
|
-
executionId: options.executionId,
|
|
316
|
-
data: {
|
|
317
|
-
agentId: this.id,
|
|
318
|
-
agentName: this.name,
|
|
319
|
-
toolName: toolCall.function.name,
|
|
320
|
-
toolCallId: toolCall.id,
|
|
321
|
-
output: execution.output,
|
|
322
|
-
error: execution.error,
|
|
323
|
-
durationMs: execution.durationMs,
|
|
324
|
-
},
|
|
325
|
-
});
|
|
326
|
-
await toolSpan.end({
|
|
327
|
-
status: execution.error ? "error" : "success",
|
|
328
|
-
data: {
|
|
329
|
-
output: execution.output,
|
|
330
|
-
error: execution.error,
|
|
331
|
-
},
|
|
332
|
-
});
|
|
333
|
-
await this.addMessage({
|
|
334
|
-
role: "tool",
|
|
335
|
-
tool_call_id: toolCall.id,
|
|
336
|
-
content: execution.error ? `Error: ${execution.error}` : JSON.stringify(execution.output),
|
|
337
|
-
}, memoryCtx);
|
|
338
|
-
});
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
truncated = true;
|
|
342
|
-
llmCalls++;
|
|
343
|
-
// Final run after max steps (force answer)
|
|
344
|
-
let finalMessages = await this.getMessagesWithContext(memoryCtx);
|
|
345
|
-
let finalTools = !options.disableTools && this.config.tools ? [...this.config.tools] : [];
|
|
346
|
-
// Interceptors for final run
|
|
347
|
-
let context = { messages: finalMessages, tools: finalTools };
|
|
348
|
-
for (const interceptor of this.requestInterceptors) {
|
|
349
|
-
context = await interceptor(context);
|
|
350
|
-
}
|
|
351
|
-
finalMessages = context.messages;
|
|
352
|
-
// We ignore tools for final run usually, but keep consistency
|
|
353
|
-
this.validateMessagesForModel(finalMessages, {
|
|
354
|
-
maxFileBytes: MAX_MESSAGE_FILE_BYTES_DEFAULT,
|
|
355
|
-
providerName: this.config.model.providerName,
|
|
356
|
-
modelName: this.config.model.modelName,
|
|
357
|
-
capabilities: this.config.model.capabilities,
|
|
358
|
-
});
|
|
359
|
-
let finalResponse = await this.config.model.generate(finalMessages);
|
|
360
|
-
// Response interceptors for final run
|
|
361
|
-
for (const interceptor of this.responseInterceptors) {
|
|
362
|
-
finalResponse = await interceptor(finalResponse);
|
|
363
|
-
}
|
|
364
|
-
await this.addMessage({ role: "assistant", content: finalResponse.content }, memoryCtx);
|
|
365
|
-
await agentSpan.end({
|
|
366
|
-
status: truncated ? "cancelled" : "success",
|
|
367
|
-
data: {
|
|
368
|
-
output: finalResponse.content,
|
|
369
|
-
usage: totalUsage,
|
|
370
|
-
},
|
|
371
|
-
});
|
|
372
|
-
return this.finishResult({
|
|
373
|
-
correlationId,
|
|
374
|
-
executionId: options.executionId,
|
|
375
|
-
content: finalResponse.content,
|
|
376
|
-
toolExecutions,
|
|
377
|
-
toolCalls: collectedToolCalls,
|
|
378
|
-
llmCalls,
|
|
379
|
-
totalDurationMs: Date.now() - startTime,
|
|
380
|
-
truncated,
|
|
381
|
-
totalUsage,
|
|
382
|
-
});
|
|
383
|
-
}
|
|
384
|
-
catch (err) {
|
|
385
|
-
const error = err instanceof Error ? err : new Error(String(err));
|
|
386
|
-
this.emit("agent:execution:error", {
|
|
387
|
-
correlationId,
|
|
388
|
-
executionId: options.executionId,
|
|
389
|
-
data: {
|
|
390
|
-
agentId: this.id,
|
|
391
|
-
agentName: this.name,
|
|
392
|
-
error: {
|
|
393
|
-
message: error.message,
|
|
394
|
-
stack: error.stack,
|
|
395
|
-
name: error.name,
|
|
396
|
-
},
|
|
397
|
-
durationMs: Date.now() - startTime,
|
|
398
|
-
},
|
|
399
|
-
});
|
|
400
|
-
await agentSpan.end({
|
|
401
|
-
status: "error",
|
|
402
|
-
data: {
|
|
409
|
+
const agentEndError = {
|
|
403
410
|
error: {
|
|
404
411
|
message: error.message,
|
|
405
412
|
name: error.name,
|
|
406
413
|
code: error.code,
|
|
407
414
|
status: error.status,
|
|
408
415
|
},
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
416
|
+
};
|
|
417
|
+
await agentSpan.end({
|
|
418
|
+
status: "error",
|
|
419
|
+
data: agentEndError,
|
|
420
|
+
});
|
|
421
|
+
throw err;
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
};
|
|
414
425
|
// Ensure execution hierarchy is available for tool sub-executions.
|
|
415
426
|
// IMPORTANT: Do NOT override an existing ExecutionContext (e.g. when this agent is a sub-execution inside a workflow).
|
|
416
427
|
const existingExecContext = index_js_4.ExecutionContext.getOrUndefined();
|
|
@@ -560,16 +571,17 @@ class Agent extends BaseAgent_js_1.BaseAgent {
|
|
|
560
571
|
}
|
|
561
572
|
await this.addMessage({ role: "assistant", content: fullContent || null, tool_calls: toolCalls }, memoryCtx);
|
|
562
573
|
for (const toolCall of toolCalls) {
|
|
574
|
+
const toolStartStream = {
|
|
575
|
+
toolName: toolCall.function.name,
|
|
576
|
+
toolCallId: toolCall.id,
|
|
577
|
+
args: toolCall.function.arguments,
|
|
578
|
+
};
|
|
563
579
|
const execution = await index_js_3.Tracing.withSpan({
|
|
564
|
-
kind:
|
|
580
|
+
kind: types_1.SpanType.tool,
|
|
565
581
|
name: `tool:${toolCall.function.name}`,
|
|
566
582
|
correlationId,
|
|
567
583
|
executionId: options.executionId,
|
|
568
|
-
data:
|
|
569
|
-
toolName: toolCall.function.name,
|
|
570
|
-
toolCallId: toolCall.id,
|
|
571
|
-
args: toolCall.function.arguments,
|
|
572
|
-
},
|
|
584
|
+
data: toolStartStream,
|
|
573
585
|
}, async (toolSpan) => {
|
|
574
586
|
this.emit("agent:tool:call", {
|
|
575
587
|
correlationId,
|
|
@@ -598,9 +610,12 @@ class Agent extends BaseAgent_js_1.BaseAgent {
|
|
|
598
610
|
durationMs: exec.durationMs,
|
|
599
611
|
},
|
|
600
612
|
});
|
|
613
|
+
const toolEndStream = exec.error
|
|
614
|
+
? { error: exec.error }
|
|
615
|
+
: { output: exec.output };
|
|
601
616
|
await toolSpan.end({
|
|
602
617
|
status: exec.error ? "error" : "success",
|
|
603
|
-
data:
|
|
618
|
+
data: toolEndStream,
|
|
604
619
|
});
|
|
605
620
|
return exec;
|
|
606
621
|
});
|
|
@@ -870,6 +885,7 @@ class Agent extends BaseAgent_js_1.BaseAgent {
|
|
|
870
885
|
llmCalls: params.llmCalls,
|
|
871
886
|
totalDurationMs: params.totalDurationMs,
|
|
872
887
|
truncated: params.truncated,
|
|
888
|
+
usage: params.totalUsage,
|
|
873
889
|
};
|
|
874
890
|
this.emit("agent:execution:end", {
|
|
875
891
|
correlationId: params.correlationId,
|
|
@@ -21,12 +21,16 @@ class CommitteeTeam extends BaseAgent_js_1.BaseAgent {
|
|
|
21
21
|
async execute(input, options) {
|
|
22
22
|
const correlationId = `committee_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
23
23
|
const startTime = Date.now();
|
|
24
|
+
const startData = {
|
|
25
|
+
agentName: this.name,
|
|
26
|
+
input,
|
|
27
|
+
};
|
|
24
28
|
return index_js_1.Tracing.withSpan({
|
|
25
29
|
kind: "agent",
|
|
26
30
|
name: `team:committee:${this.name}`,
|
|
27
31
|
correlationId,
|
|
28
32
|
executionId: options?.executionId,
|
|
29
|
-
data:
|
|
33
|
+
data: startData,
|
|
30
34
|
}, async (teamSpan) => {
|
|
31
35
|
this.emit("agent:execution:start", {
|
|
32
36
|
correlationId,
|
|
@@ -73,9 +77,10 @@ class CommitteeTeam extends BaseAgent_js_1.BaseAgent {
|
|
|
73
77
|
durationMs: Date.now() - startTime,
|
|
74
78
|
},
|
|
75
79
|
});
|
|
80
|
+
const endData = { output: result.content };
|
|
76
81
|
await teamSpan.end({
|
|
77
82
|
status: result.truncated ? "cancelled" : "success",
|
|
78
|
-
data:
|
|
83
|
+
data: endData,
|
|
79
84
|
});
|
|
80
85
|
return result;
|
|
81
86
|
}
|
|
@@ -95,7 +100,8 @@ class CommitteeTeam extends BaseAgent_js_1.BaseAgent {
|
|
|
95
100
|
durationMs: Date.now() - startTime,
|
|
96
101
|
},
|
|
97
102
|
});
|
|
98
|
-
|
|
103
|
+
const errorData = { error: { message: err.message, name: err.name } };
|
|
104
|
+
await teamSpan.end({ status: "error", data: errorData });
|
|
99
105
|
throw error;
|
|
100
106
|
}
|
|
101
107
|
});
|
|
@@ -23,12 +23,16 @@ class HandoffTeam extends BaseAgent_js_1.BaseAgent {
|
|
|
23
23
|
async execute(input, options) {
|
|
24
24
|
const correlationId = `handoff_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
25
25
|
const startTime = Date.now();
|
|
26
|
+
const startData = {
|
|
27
|
+
agentName: this.name,
|
|
28
|
+
input,
|
|
29
|
+
};
|
|
26
30
|
return index_js_2.Tracing.withSpan({
|
|
27
31
|
kind: "agent",
|
|
28
32
|
name: `team:handoff:${this.name}`,
|
|
29
33
|
correlationId,
|
|
30
34
|
executionId: options?.executionId,
|
|
31
|
-
data:
|
|
35
|
+
data: startData,
|
|
32
36
|
}, async (teamSpan) => {
|
|
33
37
|
this.emit("agent:execution:start", {
|
|
34
38
|
correlationId,
|
|
@@ -84,9 +88,10 @@ class HandoffTeam extends BaseAgent_js_1.BaseAgent {
|
|
|
84
88
|
durationMs: Date.now() - startTime,
|
|
85
89
|
},
|
|
86
90
|
});
|
|
91
|
+
const endData = { output: result.content };
|
|
87
92
|
await teamSpan.end({
|
|
88
93
|
status: result.truncated ? "cancelled" : "success",
|
|
89
|
-
data:
|
|
94
|
+
data: endData,
|
|
90
95
|
});
|
|
91
96
|
return result;
|
|
92
97
|
}
|
|
@@ -132,7 +137,8 @@ class HandoffTeam extends BaseAgent_js_1.BaseAgent {
|
|
|
132
137
|
durationMs: Date.now() - startTime,
|
|
133
138
|
},
|
|
134
139
|
});
|
|
135
|
-
|
|
140
|
+
const errorData = { error: { message: err.message, name: err.name } };
|
|
141
|
+
await teamSpan.end({ status: "error", data: errorData });
|
|
136
142
|
throw error;
|
|
137
143
|
}
|
|
138
144
|
});
|
|
@@ -26,12 +26,16 @@ class HierarchicalTeam extends BaseAgent_js_1.BaseAgent {
|
|
|
26
26
|
async execute(input, options) {
|
|
27
27
|
const correlationId = `hierarchical_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
28
28
|
const startTime = Date.now();
|
|
29
|
+
const startData = {
|
|
30
|
+
agentName: this.name,
|
|
31
|
+
input,
|
|
32
|
+
};
|
|
29
33
|
return index_js_1.Tracing.withSpan({
|
|
30
34
|
kind: "agent",
|
|
31
35
|
name: `team:hierarchical:${this.name}`,
|
|
32
36
|
correlationId,
|
|
33
37
|
executionId: options?.executionId,
|
|
34
|
-
data:
|
|
38
|
+
data: startData,
|
|
35
39
|
}, async (teamSpan) => {
|
|
36
40
|
this.emit("agent:execution:start", {
|
|
37
41
|
correlationId,
|
|
@@ -57,9 +61,10 @@ class HierarchicalTeam extends BaseAgent_js_1.BaseAgent {
|
|
|
57
61
|
durationMs: Date.now() - startTime,
|
|
58
62
|
},
|
|
59
63
|
});
|
|
64
|
+
const endData = { output: result.content };
|
|
60
65
|
await teamSpan.end({
|
|
61
66
|
status: result.truncated ? "cancelled" : "success",
|
|
62
|
-
data:
|
|
67
|
+
data: endData,
|
|
63
68
|
});
|
|
64
69
|
return result;
|
|
65
70
|
}
|
|
@@ -79,7 +84,8 @@ class HierarchicalTeam extends BaseAgent_js_1.BaseAgent {
|
|
|
79
84
|
durationMs: Date.now() - startTime,
|
|
80
85
|
},
|
|
81
86
|
});
|
|
82
|
-
|
|
87
|
+
const errorData = { error: { message: err.message, name: err.name } };
|
|
88
|
+
await teamSpan.end({ status: "error", data: errorData });
|
|
83
89
|
throw error;
|
|
84
90
|
}
|
|
85
91
|
});
|
|
@@ -18,12 +18,16 @@ class PipelineTeam extends BaseAgent_js_1.BaseAgent {
|
|
|
18
18
|
async execute(input, options) {
|
|
19
19
|
const correlationId = `pipeline_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
20
20
|
const startTime = Date.now();
|
|
21
|
+
const startData = {
|
|
22
|
+
agentName: this.name,
|
|
23
|
+
input,
|
|
24
|
+
};
|
|
21
25
|
return index_js_1.Tracing.withSpan({
|
|
22
26
|
kind: "agent",
|
|
23
27
|
name: `team:pipeline:${this.name}`,
|
|
24
28
|
correlationId,
|
|
25
29
|
executionId: options?.executionId,
|
|
26
|
-
data:
|
|
30
|
+
data: startData,
|
|
27
31
|
}, async (teamSpan) => {
|
|
28
32
|
this.emit("agent:execution:start", {
|
|
29
33
|
correlationId,
|
|
@@ -61,9 +65,10 @@ class PipelineTeam extends BaseAgent_js_1.BaseAgent {
|
|
|
61
65
|
durationMs: Date.now() - startTime,
|
|
62
66
|
},
|
|
63
67
|
});
|
|
68
|
+
const endData = { output: result.content };
|
|
64
69
|
await teamSpan.end({
|
|
65
70
|
status: result.truncated ? "cancelled" : "success",
|
|
66
|
-
data:
|
|
71
|
+
data: endData,
|
|
67
72
|
});
|
|
68
73
|
return result;
|
|
69
74
|
}
|
|
@@ -83,7 +88,8 @@ class PipelineTeam extends BaseAgent_js_1.BaseAgent {
|
|
|
83
88
|
durationMs: Date.now() - startTime,
|
|
84
89
|
},
|
|
85
90
|
});
|
|
86
|
-
|
|
91
|
+
const errorData = { error: { message: err.message, name: err.name } };
|
|
92
|
+
await teamSpan.end({ status: "error", data: errorData });
|
|
87
93
|
throw error;
|
|
88
94
|
}
|
|
89
95
|
});
|
|
@@ -19,12 +19,16 @@ class RouterTeam extends BaseAgent_js_1.BaseAgent {
|
|
|
19
19
|
async execute(input, options) {
|
|
20
20
|
const correlationId = `router_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
21
21
|
const startTime = Date.now();
|
|
22
|
+
const startData = {
|
|
23
|
+
agentName: this.name,
|
|
24
|
+
input,
|
|
25
|
+
};
|
|
22
26
|
return index_js_1.Tracing.withSpan({
|
|
23
27
|
kind: "agent",
|
|
24
28
|
name: `team:router:${this.name}`,
|
|
25
29
|
correlationId,
|
|
26
30
|
executionId: options?.executionId,
|
|
27
|
-
data:
|
|
31
|
+
data: startData,
|
|
28
32
|
}, async (teamSpan) => {
|
|
29
33
|
this.emit("agent:execution:start", {
|
|
30
34
|
correlationId,
|
|
@@ -59,9 +63,10 @@ class RouterTeam extends BaseAgent_js_1.BaseAgent {
|
|
|
59
63
|
// Usage? Ideally aggregated, but for now passing result content is key
|
|
60
64
|
},
|
|
61
65
|
});
|
|
66
|
+
const endData = { output: result.content, usage: result.usage };
|
|
62
67
|
await teamSpan.end({
|
|
63
68
|
status: result.truncated ? "cancelled" : "success",
|
|
64
|
-
data:
|
|
69
|
+
data: endData
|
|
65
70
|
});
|
|
66
71
|
return result;
|
|
67
72
|
}
|
|
@@ -81,7 +86,13 @@ class RouterTeam extends BaseAgent_js_1.BaseAgent {
|
|
|
81
86
|
durationMs: Date.now() - startTime,
|
|
82
87
|
},
|
|
83
88
|
});
|
|
84
|
-
|
|
89
|
+
const errorData = {
|
|
90
|
+
error: { message: err.message, name: err.name, code: err.code, status: err.status }
|
|
91
|
+
};
|
|
92
|
+
await teamSpan.end({
|
|
93
|
+
status: "error",
|
|
94
|
+
data: errorData
|
|
95
|
+
});
|
|
85
96
|
throw error;
|
|
86
97
|
}
|
|
87
98
|
});
|
package/dist/tracing/index.js
CHANGED
|
@@ -11,8 +11,12 @@ class WorkflowTelemetry {
|
|
|
11
11
|
data: { workflowId: input.workflowId, input: input.workflowInput },
|
|
12
12
|
}, async (span) => {
|
|
13
13
|
const result = await fn();
|
|
14
|
+
const endData = { output: result };
|
|
14
15
|
if (!span.isEnded)
|
|
15
|
-
await span.end({
|
|
16
|
+
await span.end({
|
|
17
|
+
status: "success",
|
|
18
|
+
data: endData
|
|
19
|
+
});
|
|
16
20
|
return result;
|
|
17
21
|
});
|
|
18
22
|
}
|
|
@@ -30,11 +34,17 @@ class WorkflowTelemetry {
|
|
|
30
34
|
}, async (span) => {
|
|
31
35
|
try {
|
|
32
36
|
const result = await fn();
|
|
33
|
-
|
|
37
|
+
const successData = { output: result };
|
|
38
|
+
await span.end({ status: "success", data: successData });
|
|
34
39
|
return result;
|
|
35
40
|
}
|
|
36
41
|
catch (e) {
|
|
37
|
-
|
|
42
|
+
const err = e instanceof Error ? e : new Error(String(e));
|
|
43
|
+
const errorData = { error: { message: err.message, name: err.name } };
|
|
44
|
+
await span.end({
|
|
45
|
+
status: "error",
|
|
46
|
+
data: errorData
|
|
47
|
+
});
|
|
38
48
|
throw e;
|
|
39
49
|
}
|
|
40
50
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nebulaos/core",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"description": "Core primitives for NebulaOS (Agent, Workflow, Providers)",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"uuid": "^9.0.1",
|
|
34
34
|
"zod": "^3.0.0",
|
|
35
35
|
"zod-to-json-schema": "^3.0.0",
|
|
36
|
-
"@nebulaos/types": "^0.1.
|
|
36
|
+
"@nebulaos/types": "^0.1.4"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@types/jest": "^30.0.0",
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"ts-jest": "^29.4.6",
|
|
45
45
|
"typescript": "^5.0.0",
|
|
46
46
|
"@nebulaos/oci": "0.0.1",
|
|
47
|
-
"@nebulaos/
|
|
48
|
-
"@nebulaos/
|
|
47
|
+
"@nebulaos/openai": "0.1.0",
|
|
48
|
+
"@nebulaos/google-gemini": "0.0.1"
|
|
49
49
|
},
|
|
50
50
|
"scripts": {
|
|
51
51
|
"build": "tsc",
|