@opperai/agents 0.3.0-beta.1 → 0.4.0
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 +9 -5
- package/dist/index.cjs +173 -141
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +270 -50
- package/dist/index.d.ts +270 -50
- package/dist/index.js +172 -141
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -48,10 +48,13 @@ const agent = new Agent<string, OutputType>({
|
|
|
48
48
|
outputSchema: Output,
|
|
49
49
|
});
|
|
50
50
|
|
|
51
|
-
const result = await agent.
|
|
52
|
-
// => { message: "Hi Ada!" }
|
|
51
|
+
const { result, usage } = await agent.run("Say hi to Ada");
|
|
52
|
+
// result => { message: "Hi Ada!" }
|
|
53
|
+
// usage => { requests, inputTokens, outputTokens, totalTokens }
|
|
53
54
|
```
|
|
54
55
|
|
|
56
|
+
> **Note:** `agent.process(input)` also works if you only need the result without usage stats.
|
|
57
|
+
|
|
55
58
|
## Tools
|
|
56
59
|
|
|
57
60
|
Define tools with Zod schemas. Results are discriminated unions that never throw.
|
|
@@ -72,7 +75,7 @@ const agent = new Agent<string, { answer: number }>({
|
|
|
72
75
|
outputSchema: z.object({ answer: z.number() }),
|
|
73
76
|
});
|
|
74
77
|
|
|
75
|
-
const
|
|
78
|
+
const { result } = await agent.run("What is (5 + 3)? Return JSON with answer.");
|
|
76
79
|
```
|
|
77
80
|
|
|
78
81
|
Decorator tools and extraction:
|
|
@@ -111,9 +114,10 @@ const Coordinator = new Agent<string, string>({
|
|
|
111
114
|
tools: [Summarize.asTool("summarize")],
|
|
112
115
|
});
|
|
113
116
|
|
|
114
|
-
const
|
|
117
|
+
const { result, usage } = await Coordinator.run(
|
|
115
118
|
"Summarize: Opper helps you build agents.",
|
|
116
119
|
);
|
|
120
|
+
// usage includes aggregated stats from nested Summarize agent
|
|
117
121
|
```
|
|
118
122
|
|
|
119
123
|
## MCP Integration
|
|
@@ -131,7 +135,7 @@ const agent = new Agent<string, string>({
|
|
|
131
135
|
tools: [mcp(fsServer)],
|
|
132
136
|
});
|
|
133
137
|
|
|
134
|
-
const
|
|
138
|
+
const { result } = await agent.run("Read README.md and summarize it.");
|
|
135
139
|
```
|
|
136
140
|
|
|
137
141
|
## Hooks & Context
|
package/dist/index.cjs
CHANGED
|
@@ -121,7 +121,8 @@ var init_tool = __esm({
|
|
|
121
121
|
output,
|
|
122
122
|
...init.startedAt !== void 0 && { startedAt: init.startedAt },
|
|
123
123
|
finishedAt: init.finishedAt ?? Date.now(),
|
|
124
|
-
metadata: init.metadata ?? {}
|
|
124
|
+
metadata: init.metadata ?? {},
|
|
125
|
+
...init.usage !== void 0 && { usage: init.usage }
|
|
125
126
|
};
|
|
126
127
|
exports.ToolResultSuccessSchema.parse(result);
|
|
127
128
|
return result;
|
|
@@ -133,7 +134,8 @@ var init_tool = __esm({
|
|
|
133
134
|
error,
|
|
134
135
|
...init.startedAt !== void 0 && { startedAt: init.startedAt },
|
|
135
136
|
finishedAt: init.finishedAt ?? Date.now(),
|
|
136
|
-
metadata: init.metadata ?? {}
|
|
137
|
+
metadata: init.metadata ?? {},
|
|
138
|
+
...init.usage !== void 0 && { usage: init.usage }
|
|
137
139
|
};
|
|
138
140
|
exports.ToolResultFailureSchema.parse(result);
|
|
139
141
|
return result;
|
|
@@ -188,14 +190,43 @@ var init_tool = __esm({
|
|
|
188
190
|
var context_exports = {};
|
|
189
191
|
__export(context_exports, {
|
|
190
192
|
AgentContext: () => exports.AgentContext,
|
|
193
|
+
BaseUsageSchema: () => exports.BaseUsageSchema,
|
|
191
194
|
ExecutionCycleSchema: () => exports.ExecutionCycleSchema,
|
|
192
|
-
UsageSchema: () => exports.UsageSchema
|
|
195
|
+
UsageSchema: () => exports.UsageSchema,
|
|
196
|
+
addUsage: () => addUsage,
|
|
197
|
+
createEmptyUsage: () => createEmptyUsage
|
|
193
198
|
});
|
|
194
|
-
|
|
199
|
+
function createEmptyUsage() {
|
|
200
|
+
return {
|
|
201
|
+
requests: 0,
|
|
202
|
+
inputTokens: 0,
|
|
203
|
+
outputTokens: 0,
|
|
204
|
+
totalTokens: 0,
|
|
205
|
+
cost: {
|
|
206
|
+
generation: 0,
|
|
207
|
+
platform: 0,
|
|
208
|
+
total: 0
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
function addUsage(a, b) {
|
|
213
|
+
return {
|
|
214
|
+
requests: a.requests + b.requests,
|
|
215
|
+
inputTokens: a.inputTokens + b.inputTokens,
|
|
216
|
+
outputTokens: a.outputTokens + b.outputTokens,
|
|
217
|
+
totalTokens: a.totalTokens + b.totalTokens,
|
|
218
|
+
cost: {
|
|
219
|
+
generation: a.cost.generation + b.cost.generation,
|
|
220
|
+
platform: a.cost.platform + b.cost.platform,
|
|
221
|
+
total: a.cost.total + b.cost.total
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
exports.BaseUsageSchema = void 0; exports.UsageSchema = void 0; exports.ExecutionCycleSchema = void 0; exports.AgentContext = void 0;
|
|
195
226
|
var init_context = __esm({
|
|
196
227
|
"src/base/context.ts"() {
|
|
197
228
|
init_tool();
|
|
198
|
-
exports.
|
|
229
|
+
exports.BaseUsageSchema = zod.z.object({
|
|
199
230
|
requests: zod.z.number().int().nonnegative().default(0),
|
|
200
231
|
inputTokens: zod.z.number().int().nonnegative().default(0),
|
|
201
232
|
outputTokens: zod.z.number().int().nonnegative().default(0),
|
|
@@ -206,6 +237,13 @@ var init_context = __esm({
|
|
|
206
237
|
total: zod.z.number().nonnegative().default(0)
|
|
207
238
|
}).default({ generation: 0, platform: 0, total: 0 })
|
|
208
239
|
});
|
|
240
|
+
exports.UsageSchema = exports.BaseUsageSchema.extend({
|
|
241
|
+
/**
|
|
242
|
+
* Optional breakdown of usage by source (agent name).
|
|
243
|
+
* Only present when nested agents are used.
|
|
244
|
+
*/
|
|
245
|
+
breakdown: zod.z.record(zod.z.string(), zod.z.lazy(() => exports.BaseUsageSchema)).optional()
|
|
246
|
+
});
|
|
209
247
|
exports.ExecutionCycleSchema = zod.z.object({
|
|
210
248
|
iteration: zod.z.number().int().nonnegative(),
|
|
211
249
|
thought: zod.z.unknown().nullable().optional(),
|
|
@@ -247,10 +285,42 @@ var init_context = __esm({
|
|
|
247
285
|
generation: this.usage.cost.generation + next.cost.generation,
|
|
248
286
|
platform: this.usage.cost.platform + next.cost.platform,
|
|
249
287
|
total: this.usage.cost.total + next.cost.total
|
|
250
|
-
}
|
|
288
|
+
},
|
|
289
|
+
// Preserve existing breakdown
|
|
290
|
+
...this.usage.breakdown && { breakdown: this.usage.breakdown }
|
|
251
291
|
};
|
|
252
292
|
this.touch();
|
|
253
293
|
}
|
|
294
|
+
/**
|
|
295
|
+
* Update usage with source tracking for nested agent aggregation.
|
|
296
|
+
* This method updates the total usage AND tracks it by source in the breakdown.
|
|
297
|
+
*
|
|
298
|
+
* @param source - The source name (typically the agent/tool name)
|
|
299
|
+
* @param delta - The usage to add
|
|
300
|
+
*/
|
|
301
|
+
updateUsageWithSource(source, delta) {
|
|
302
|
+
this.updateUsage(delta);
|
|
303
|
+
if (!this.usage.breakdown) {
|
|
304
|
+
this.usage.breakdown = {};
|
|
305
|
+
}
|
|
306
|
+
const existing = this.usage.breakdown[source] ?? createEmptyUsage();
|
|
307
|
+
this.usage.breakdown[source] = addUsage(existing, delta);
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Clean up the usage breakdown if it only contains the parent agent.
|
|
311
|
+
* This ensures breakdown is only present when there are nested agents.
|
|
312
|
+
*
|
|
313
|
+
* @param parentAgentName - The name of the parent agent to check for
|
|
314
|
+
*/
|
|
315
|
+
cleanupBreakdownIfOnlyParent(parentAgentName) {
|
|
316
|
+
if (!this.usage.breakdown) {
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
const sources = Object.keys(this.usage.breakdown);
|
|
320
|
+
if (sources.length === 1 && sources[0] === parentAgentName) {
|
|
321
|
+
delete this.usage.breakdown;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
254
324
|
addCycle(cycle) {
|
|
255
325
|
const parsed = exports.ExecutionCycleSchema.parse(cycle);
|
|
256
326
|
this.executionHistory.push(parsed);
|
|
@@ -296,6 +366,18 @@ var init_context = __esm({
|
|
|
296
366
|
this.touch();
|
|
297
367
|
}
|
|
298
368
|
snapshot() {
|
|
369
|
+
const usageCopy = {
|
|
370
|
+
...this.usage,
|
|
371
|
+
cost: { ...this.usage.cost },
|
|
372
|
+
...this.usage.breakdown && {
|
|
373
|
+
breakdown: Object.fromEntries(
|
|
374
|
+
Object.entries(this.usage.breakdown).map(([key, value]) => [
|
|
375
|
+
key,
|
|
376
|
+
{ ...value, cost: { ...value.cost } }
|
|
377
|
+
])
|
|
378
|
+
)
|
|
379
|
+
}
|
|
380
|
+
};
|
|
299
381
|
return {
|
|
300
382
|
agentName: this.agentName,
|
|
301
383
|
sessionId: this.sessionId,
|
|
@@ -303,7 +385,7 @@ var init_context = __esm({
|
|
|
303
385
|
iteration: this.iteration,
|
|
304
386
|
goal: this.goal,
|
|
305
387
|
executionHistory: [...this.executionHistory],
|
|
306
|
-
usage:
|
|
388
|
+
usage: usageCopy,
|
|
307
389
|
toolCalls: [...this.toolCalls],
|
|
308
390
|
metadata: { ...this.metadata },
|
|
309
391
|
startedAt: this.startedAt,
|
|
@@ -490,82 +572,6 @@ var HookManager = class {
|
|
|
490
572
|
};
|
|
491
573
|
var createHookManager = (logger) => new HookManager(logger);
|
|
492
574
|
|
|
493
|
-
// src/base/events.ts
|
|
494
|
-
var AgentEvents = {
|
|
495
|
-
StreamStart: HookEvents.StreamStart,
|
|
496
|
-
StreamChunk: HookEvents.StreamChunk,
|
|
497
|
-
StreamEnd: HookEvents.StreamEnd,
|
|
498
|
-
StreamError: HookEvents.StreamError
|
|
499
|
-
};
|
|
500
|
-
var AgentEventEmitter = class {
|
|
501
|
-
registry = /* @__PURE__ */ new Map();
|
|
502
|
-
logger;
|
|
503
|
-
constructor(logger) {
|
|
504
|
-
this.logger = logger ?? getDefaultLogger();
|
|
505
|
-
}
|
|
506
|
-
on(event, listener) {
|
|
507
|
-
const listeners = this.registry.get(event) ?? /* @__PURE__ */ new Set();
|
|
508
|
-
listeners.add(listener);
|
|
509
|
-
this.registry.set(event, listeners);
|
|
510
|
-
return () => this.off(event, listener);
|
|
511
|
-
}
|
|
512
|
-
once(event, listener) {
|
|
513
|
-
const wrapper = (payload) => {
|
|
514
|
-
try {
|
|
515
|
-
listener(payload);
|
|
516
|
-
} finally {
|
|
517
|
-
this.off(event, wrapper);
|
|
518
|
-
}
|
|
519
|
-
};
|
|
520
|
-
return this.on(event, wrapper);
|
|
521
|
-
}
|
|
522
|
-
off(event, listener) {
|
|
523
|
-
const listeners = this.registry.get(event);
|
|
524
|
-
if (!listeners) {
|
|
525
|
-
return;
|
|
526
|
-
}
|
|
527
|
-
listeners.delete(listener);
|
|
528
|
-
if (listeners.size === 0) {
|
|
529
|
-
this.registry.delete(event);
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
emit(event, payload) {
|
|
533
|
-
const listeners = Array.from(
|
|
534
|
-
this.registry.get(event) ?? /* @__PURE__ */ new Set()
|
|
535
|
-
);
|
|
536
|
-
if (listeners.length === 0) {
|
|
537
|
-
return;
|
|
538
|
-
}
|
|
539
|
-
for (const listener of listeners) {
|
|
540
|
-
try {
|
|
541
|
-
listener(payload);
|
|
542
|
-
} catch (error) {
|
|
543
|
-
this.logger.warn(`Agent event listener failed for "${event}"`, {
|
|
544
|
-
event,
|
|
545
|
-
error: error instanceof Error ? error.message : String(error)
|
|
546
|
-
});
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
removeAllListeners(event) {
|
|
551
|
-
if (event) {
|
|
552
|
-
this.registry.delete(event);
|
|
553
|
-
return;
|
|
554
|
-
}
|
|
555
|
-
this.registry.clear();
|
|
556
|
-
}
|
|
557
|
-
listenerCount(event) {
|
|
558
|
-
if (event) {
|
|
559
|
-
return this.registry.get(event)?.size ?? 0;
|
|
560
|
-
}
|
|
561
|
-
let total = 0;
|
|
562
|
-
for (const listeners of this.registry.values()) {
|
|
563
|
-
total += listeners.size;
|
|
564
|
-
}
|
|
565
|
-
return total;
|
|
566
|
-
}
|
|
567
|
-
};
|
|
568
|
-
|
|
569
575
|
// src/base/agent.ts
|
|
570
576
|
init_tool();
|
|
571
577
|
function sanitizeId(name) {
|
|
@@ -950,10 +956,6 @@ var BaseAgent = class {
|
|
|
950
956
|
* Hook manager for lifecycle events
|
|
951
957
|
*/
|
|
952
958
|
hooks;
|
|
953
|
-
/**
|
|
954
|
-
* Event dispatcher for runtime events (notably streaming)
|
|
955
|
-
*/
|
|
956
|
-
events;
|
|
957
959
|
/**
|
|
958
960
|
* Registry of available tools
|
|
959
961
|
*/
|
|
@@ -1008,7 +1010,6 @@ var BaseAgent = class {
|
|
|
1008
1010
|
this.enableStreaming = config.enableStreaming ?? false;
|
|
1009
1011
|
this.metadata = { ...config.metadata ?? {} };
|
|
1010
1012
|
this.hooks = new HookManager();
|
|
1011
|
-
this.events = new AgentEventEmitter();
|
|
1012
1013
|
this.tools = /* @__PURE__ */ new Map();
|
|
1013
1014
|
this.baseTools = /* @__PURE__ */ new Map();
|
|
1014
1015
|
this.toolProviders = /* @__PURE__ */ new Set();
|
|
@@ -1059,11 +1060,37 @@ var BaseAgent = class {
|
|
|
1059
1060
|
* Main entry point for agent execution.
|
|
1060
1061
|
* Orchestrates lifecycle: context initialization, hook triggering, loop execution, teardown.
|
|
1061
1062
|
*
|
|
1063
|
+
* **Note:** This method will be removed in a future update.
|
|
1064
|
+
* Consider using {@link run} instead, which returns both result and usage statistics.
|
|
1065
|
+
*
|
|
1062
1066
|
* @param input - Input to process
|
|
1063
1067
|
* @param parentSpanId - Optional parent span ID for tracing
|
|
1064
1068
|
* @returns Processed output
|
|
1065
1069
|
*/
|
|
1066
1070
|
async process(input, parentSpanId) {
|
|
1071
|
+
const { result } = await this.executeProcess(input, parentSpanId);
|
|
1072
|
+
return result;
|
|
1073
|
+
}
|
|
1074
|
+
/**
|
|
1075
|
+
* Process input and return both result and usage statistics.
|
|
1076
|
+
* This is the recommended method for agent execution.
|
|
1077
|
+
*
|
|
1078
|
+
* @param input - Input to process
|
|
1079
|
+
* @param parentSpanId - Optional parent span ID for tracing
|
|
1080
|
+
* @returns Object containing the result and usage statistics
|
|
1081
|
+
*/
|
|
1082
|
+
async run(input, parentSpanId) {
|
|
1083
|
+
return this.executeProcess(input, parentSpanId);
|
|
1084
|
+
}
|
|
1085
|
+
/**
|
|
1086
|
+
* Internal method that executes the process and returns both result and usage.
|
|
1087
|
+
* This is the core implementation shared by process() and run().
|
|
1088
|
+
*
|
|
1089
|
+
* @param input - Input to process
|
|
1090
|
+
* @param parentSpanId - Optional parent span ID for tracing
|
|
1091
|
+
* @returns Object containing the result and usage statistics
|
|
1092
|
+
*/
|
|
1093
|
+
async executeProcess(input, parentSpanId) {
|
|
1067
1094
|
const validatedInput = this.inputSchema ? this.inputSchema.parse(input) : input;
|
|
1068
1095
|
const context = await this.initializeContext(validatedInput, parentSpanId);
|
|
1069
1096
|
try {
|
|
@@ -1075,7 +1102,8 @@ var BaseAgent = class {
|
|
|
1075
1102
|
context,
|
|
1076
1103
|
result: validatedOutput
|
|
1077
1104
|
});
|
|
1078
|
-
|
|
1105
|
+
context.cleanupBreakdownIfOnlyParent(this.name);
|
|
1106
|
+
return { result: validatedOutput, usage: context.usage };
|
|
1079
1107
|
} catch (error) {
|
|
1080
1108
|
await this.triggerHook(HookEvents.AgentEnd, {
|
|
1081
1109
|
context,
|
|
@@ -1165,6 +1193,8 @@ var BaseAgent = class {
|
|
|
1165
1193
|
}
|
|
1166
1194
|
/**
|
|
1167
1195
|
* Convert this agent into a tool that can be used by other agents.
|
|
1196
|
+
* When used as a tool, the nested agent's usage statistics are propagated
|
|
1197
|
+
* back to the parent agent for aggregation.
|
|
1168
1198
|
*
|
|
1169
1199
|
* @param toolName - Optional custom name for the tool (defaults to agent name)
|
|
1170
1200
|
* @param toolDescription - Optional custom description (defaults to agent description)
|
|
@@ -1184,8 +1214,8 @@ var BaseAgent = class {
|
|
|
1184
1214
|
execute: async (input, executionContext) => {
|
|
1185
1215
|
try {
|
|
1186
1216
|
const parentSpanId = executionContext.spanId ?? executionContext.agentContext.parentSpanId ?? void 0;
|
|
1187
|
-
const result = await this.
|
|
1188
|
-
return exports.ToolResultFactory.success(tool2.name, result);
|
|
1217
|
+
const { result, usage } = await this.run(input, parentSpanId);
|
|
1218
|
+
return exports.ToolResultFactory.success(tool2.name, result, { usage });
|
|
1189
1219
|
} catch (error) {
|
|
1190
1220
|
return exports.ToolResultFactory.failure(
|
|
1191
1221
|
tool2.name,
|
|
@@ -1208,32 +1238,34 @@ var BaseAgent = class {
|
|
|
1208
1238
|
}
|
|
1209
1239
|
/**
|
|
1210
1240
|
* Register an event listener.
|
|
1241
|
+
* This is equivalent to registerHook() - both methods use the unified hook system.
|
|
1211
1242
|
*
|
|
1212
|
-
* @param event - Event name
|
|
1243
|
+
* @param event - Event name (any HookEvents value)
|
|
1213
1244
|
* @param listener - Listener callback
|
|
1214
1245
|
* @returns Cleanup function to unregister the listener
|
|
1215
1246
|
*/
|
|
1216
1247
|
on(event, listener) {
|
|
1217
|
-
return this.
|
|
1248
|
+
return this.hooks.on(event, listener);
|
|
1218
1249
|
}
|
|
1219
1250
|
/**
|
|
1220
1251
|
* Register a one-time event listener that removes itself after the first call.
|
|
1252
|
+
* This is equivalent to calling registerHook() with a self-removing handler.
|
|
1221
1253
|
*
|
|
1222
|
-
* @param event - Event name
|
|
1254
|
+
* @param event - Event name (any HookEvents value)
|
|
1223
1255
|
* @param listener - Listener callback
|
|
1224
1256
|
* @returns Cleanup function (no-op once listener fires)
|
|
1225
1257
|
*/
|
|
1226
1258
|
once(event, listener) {
|
|
1227
|
-
return this.
|
|
1259
|
+
return this.hooks.once(event, listener);
|
|
1228
1260
|
}
|
|
1229
1261
|
/**
|
|
1230
1262
|
* Remove a previously registered event listener.
|
|
1231
1263
|
*
|
|
1232
|
-
* @param event - Event name
|
|
1264
|
+
* @param event - Event name (any HookEvents value)
|
|
1233
1265
|
* @param listener - Listener callback to remove
|
|
1234
1266
|
*/
|
|
1235
1267
|
off(event, listener) {
|
|
1236
|
-
this.
|
|
1268
|
+
this.hooks.off(event, listener);
|
|
1237
1269
|
}
|
|
1238
1270
|
/**
|
|
1239
1271
|
* Trigger a hook event with a payload.
|
|
@@ -1249,15 +1281,6 @@ var BaseAgent = class {
|
|
|
1249
1281
|
console.warn(`Hook error for event ${event}:`, error);
|
|
1250
1282
|
}
|
|
1251
1283
|
}
|
|
1252
|
-
/**
|
|
1253
|
-
* Emit a runtime event to listeners.
|
|
1254
|
-
*
|
|
1255
|
-
* @param event - Event name
|
|
1256
|
-
* @param payload - Event payload
|
|
1257
|
-
*/
|
|
1258
|
-
emitAgentEvent(event, payload) {
|
|
1259
|
-
this.events.emit(event, payload);
|
|
1260
|
-
}
|
|
1261
1284
|
/**
|
|
1262
1285
|
* Execute a tool with proper context, hooks, and error handling.
|
|
1263
1286
|
*
|
|
@@ -1443,6 +1466,11 @@ var BaseAgent = class {
|
|
|
1443
1466
|
|
|
1444
1467
|
// src/index.ts
|
|
1445
1468
|
init_context();
|
|
1469
|
+
|
|
1470
|
+
// src/base/events.ts
|
|
1471
|
+
var AgentEvents = HookEvents;
|
|
1472
|
+
|
|
1473
|
+
// src/index.ts
|
|
1446
1474
|
init_result();
|
|
1447
1475
|
init_tool();
|
|
1448
1476
|
var ThoughtSchema = zod.z.object({
|
|
@@ -1611,7 +1639,7 @@ var mergeSchemaDefaults = (schema, value) => {
|
|
|
1611
1639
|
|
|
1612
1640
|
// package.json
|
|
1613
1641
|
var package_default = {
|
|
1614
|
-
version: "0.
|
|
1642
|
+
version: "0.4.0"};
|
|
1615
1643
|
|
|
1616
1644
|
// src/utils/version.ts
|
|
1617
1645
|
var SDK_NAME = "@opperai/agents";
|
|
@@ -2281,7 +2309,7 @@ var Agent = class extends BaseAgent {
|
|
|
2281
2309
|
model: this.model,
|
|
2282
2310
|
...context.parentSpanId && { parentSpanId: context.parentSpanId }
|
|
2283
2311
|
});
|
|
2284
|
-
context.
|
|
2312
|
+
context.updateUsageWithSource(this.name, {
|
|
2285
2313
|
requests: 1,
|
|
2286
2314
|
inputTokens: response.usage.inputTokens,
|
|
2287
2315
|
outputTokens: response.usage.outputTokens,
|
|
@@ -2333,10 +2361,6 @@ var Agent = class extends BaseAgent {
|
|
|
2333
2361
|
context,
|
|
2334
2362
|
callType: "think"
|
|
2335
2363
|
});
|
|
2336
|
-
this.emitAgentEvent(HookEvents.StreamStart, {
|
|
2337
|
-
context,
|
|
2338
|
-
callType: "think"
|
|
2339
|
-
});
|
|
2340
2364
|
try {
|
|
2341
2365
|
const streamResponse = await this.opperClient.stream({
|
|
2342
2366
|
name: spanName,
|
|
@@ -2373,7 +2397,6 @@ var Agent = class extends BaseAgent {
|
|
|
2373
2397
|
fieldBuffers: feedResult.snapshot
|
|
2374
2398
|
};
|
|
2375
2399
|
await this.triggerHook(HookEvents.StreamChunk, chunkPayload);
|
|
2376
|
-
this.emitAgentEvent(HookEvents.StreamChunk, chunkPayload);
|
|
2377
2400
|
}
|
|
2378
2401
|
const fieldBuffers = assembler.snapshot();
|
|
2379
2402
|
const endPayload = {
|
|
@@ -2382,7 +2405,6 @@ var Agent = class extends BaseAgent {
|
|
|
2382
2405
|
fieldBuffers
|
|
2383
2406
|
};
|
|
2384
2407
|
await this.triggerHook(HookEvents.StreamEnd, endPayload);
|
|
2385
|
-
this.emitAgentEvent(HookEvents.StreamEnd, endPayload);
|
|
2386
2408
|
const finalize = assembler.finalize();
|
|
2387
2409
|
let decision;
|
|
2388
2410
|
if (finalize.type === "structured" && finalize.structured) {
|
|
@@ -2399,7 +2421,7 @@ var Agent = class extends BaseAgent {
|
|
|
2399
2421
|
streamSpanId
|
|
2400
2422
|
);
|
|
2401
2423
|
if (!usageTracked) {
|
|
2402
|
-
context.
|
|
2424
|
+
context.updateUsageWithSource(this.name, {
|
|
2403
2425
|
requests: 1,
|
|
2404
2426
|
inputTokens: 0,
|
|
2405
2427
|
outputTokens: 0,
|
|
@@ -2444,11 +2466,6 @@ var Agent = class extends BaseAgent {
|
|
|
2444
2466
|
callType: "think",
|
|
2445
2467
|
error
|
|
2446
2468
|
});
|
|
2447
|
-
this.emitAgentEvent(HookEvents.StreamError, {
|
|
2448
|
-
context,
|
|
2449
|
-
callType: "think",
|
|
2450
|
-
error
|
|
2451
|
-
});
|
|
2452
2469
|
this.logger.error("Think step failed", error);
|
|
2453
2470
|
throw new Error(
|
|
2454
2471
|
`Think step failed: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -2506,12 +2523,30 @@ The memory you write persists across all process() calls on this agent.`;
|
|
|
2506
2523
|
* Build dynamic context for the think step
|
|
2507
2524
|
*/
|
|
2508
2525
|
async buildThinkContext(input, context) {
|
|
2509
|
-
const availableTools = Array.from(this.tools.values()).map((tool2) =>
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2526
|
+
const availableTools = Array.from(this.tools.values()).map((tool2) => {
|
|
2527
|
+
let parameters = {};
|
|
2528
|
+
if (tool2.schema) {
|
|
2529
|
+
parameters = schemaToJson(tool2.schema);
|
|
2530
|
+
} else if (tool2.metadata?.["parameters"] && typeof tool2.metadata["parameters"] === "object") {
|
|
2531
|
+
parameters = tool2.metadata["parameters"];
|
|
2532
|
+
}
|
|
2533
|
+
let returns = void 0;
|
|
2534
|
+
if (tool2.outputSchema) {
|
|
2535
|
+
returns = schemaToJson(tool2.outputSchema);
|
|
2536
|
+
} else if (tool2.metadata?.["outputSchema"] && typeof tool2.metadata["outputSchema"] === "object") {
|
|
2537
|
+
returns = tool2.metadata["outputSchema"];
|
|
2538
|
+
}
|
|
2539
|
+
return {
|
|
2540
|
+
name: tool2.name,
|
|
2541
|
+
description: tool2.description || "",
|
|
2542
|
+
// Include parameters (from Zod schema or MCP metadata)
|
|
2543
|
+
parameters,
|
|
2544
|
+
// Include output schema if defined (helps LLM understand what tool returns)
|
|
2545
|
+
...returns !== void 0 ? { returns } : {},
|
|
2546
|
+
// Include examples if defined (helps LLM understand expected behavior)
|
|
2547
|
+
...tool2.examples ? { examples: tool2.examples } : {}
|
|
2548
|
+
};
|
|
2549
|
+
});
|
|
2515
2550
|
const executionHistory = context.getLastNCycles(3).map((cycle) => {
|
|
2516
2551
|
const thought = typeof cycle.thought === "object" && cycle.thought !== null ? cycle.thought["reasoning"] || "" : String(cycle.thought || "");
|
|
2517
2552
|
const results = Array.isArray(cycle.results) ? cycle.results.map((r) => {
|
|
@@ -2581,6 +2616,9 @@ The memory you write persists across all process() calls on this agent.`;
|
|
|
2581
2616
|
context,
|
|
2582
2617
|
{ spanId: toolSpan.id }
|
|
2583
2618
|
);
|
|
2619
|
+
if (result.usage) {
|
|
2620
|
+
context.updateUsageWithSource(toolCall.toolName, result.usage);
|
|
2621
|
+
}
|
|
2584
2622
|
const endTime = /* @__PURE__ */ new Date();
|
|
2585
2623
|
const durationMs = endTime.getTime() - startTime.getTime();
|
|
2586
2624
|
if (result.success) {
|
|
@@ -2839,7 +2877,7 @@ Follow any instructions provided for formatting and style.`;
|
|
|
2839
2877
|
callOptions.outputSchema = this.outputSchema;
|
|
2840
2878
|
}
|
|
2841
2879
|
const response = await this.opperClient.call(callOptions);
|
|
2842
|
-
context.
|
|
2880
|
+
context.updateUsageWithSource(this.name, {
|
|
2843
2881
|
requests: 1,
|
|
2844
2882
|
inputTokens: response.usage.inputTokens,
|
|
2845
2883
|
outputTokens: response.usage.outputTokens,
|
|
@@ -2869,10 +2907,6 @@ Follow any instructions provided for formatting and style.`;
|
|
|
2869
2907
|
context,
|
|
2870
2908
|
callType: "final_result"
|
|
2871
2909
|
});
|
|
2872
|
-
this.emitAgentEvent(HookEvents.StreamStart, {
|
|
2873
|
-
context,
|
|
2874
|
-
callType: "final_result"
|
|
2875
|
-
});
|
|
2876
2910
|
try {
|
|
2877
2911
|
const sanitizedName = this.name.toLowerCase().replace(/[\s-]/g, "_");
|
|
2878
2912
|
const functionName = `generate_final_result_${sanitizedName}`;
|
|
@@ -2911,7 +2945,6 @@ Follow any instructions provided for formatting and style.`;
|
|
|
2911
2945
|
fieldBuffers: feedResult.snapshot
|
|
2912
2946
|
};
|
|
2913
2947
|
await this.triggerHook(HookEvents.StreamChunk, chunkPayload);
|
|
2914
|
-
this.emitAgentEvent(HookEvents.StreamChunk, chunkPayload);
|
|
2915
2948
|
}
|
|
2916
2949
|
const fieldBuffers = assembler.snapshot();
|
|
2917
2950
|
const endPayload = {
|
|
@@ -2920,7 +2953,6 @@ Follow any instructions provided for formatting and style.`;
|
|
|
2920
2953
|
fieldBuffers
|
|
2921
2954
|
};
|
|
2922
2955
|
await this.triggerHook(HookEvents.StreamEnd, endPayload);
|
|
2923
|
-
this.emitAgentEvent(HookEvents.StreamEnd, endPayload);
|
|
2924
2956
|
const finalize = assembler.finalize();
|
|
2925
2957
|
let result;
|
|
2926
2958
|
if (this.outputSchema) {
|
|
@@ -2944,7 +2976,7 @@ Follow any instructions provided for formatting and style.`;
|
|
|
2944
2976
|
streamSpanId
|
|
2945
2977
|
);
|
|
2946
2978
|
if (!usageTracked) {
|
|
2947
|
-
context.
|
|
2979
|
+
context.updateUsageWithSource(this.name, {
|
|
2948
2980
|
requests: 1,
|
|
2949
2981
|
inputTokens: 0,
|
|
2950
2982
|
outputTokens: 0,
|
|
@@ -2968,11 +3000,6 @@ Follow any instructions provided for formatting and style.`;
|
|
|
2968
3000
|
callType: "final_result",
|
|
2969
3001
|
error
|
|
2970
3002
|
});
|
|
2971
|
-
this.emitAgentEvent(HookEvents.StreamError, {
|
|
2972
|
-
context,
|
|
2973
|
-
callType: "final_result",
|
|
2974
|
-
error
|
|
2975
|
-
});
|
|
2976
3003
|
this.logger.error("Failed to generate final result", error);
|
|
2977
3004
|
throw new Error(
|
|
2978
3005
|
`Failed to generate final result: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -3008,7 +3035,7 @@ Follow any instructions provided for formatting and style.`;
|
|
|
3008
3035
|
const fallbackTotal = record["total_tokens"];
|
|
3009
3036
|
const totalTokensRaw = typeof primaryTotal === "number" && Number.isFinite(primaryTotal) ? primaryTotal : typeof fallbackTotal === "number" && Number.isFinite(fallbackTotal) ? fallbackTotal : void 0;
|
|
3010
3037
|
if (totalTokensRaw !== void 0) {
|
|
3011
|
-
context.
|
|
3038
|
+
context.updateUsageWithSource(this.name, {
|
|
3012
3039
|
requests: 1,
|
|
3013
3040
|
inputTokens: 0,
|
|
3014
3041
|
outputTokens: 0,
|
|
@@ -3460,6 +3487,8 @@ function createToolDefinition(options, methodName, propertyKey, method, callTarg
|
|
|
3460
3487
|
name,
|
|
3461
3488
|
description,
|
|
3462
3489
|
...options.schema && { schema: options.schema },
|
|
3490
|
+
...options.outputSchema && { outputSchema: options.outputSchema },
|
|
3491
|
+
...options.examples && { examples: options.examples },
|
|
3463
3492
|
...options.timeoutMs !== void 0 && { timeoutMs: options.timeoutMs },
|
|
3464
3493
|
metadata: {
|
|
3465
3494
|
...options.metadata,
|
|
@@ -3476,6 +3505,8 @@ function createFunctionTool(fn, options = {}) {
|
|
|
3476
3505
|
name,
|
|
3477
3506
|
description,
|
|
3478
3507
|
...options.schema && { schema: options.schema },
|
|
3508
|
+
...options.outputSchema && { outputSchema: options.outputSchema },
|
|
3509
|
+
...options.examples && { examples: options.examples },
|
|
3479
3510
|
...options.timeoutMs !== void 0 && { timeoutMs: options.timeoutMs },
|
|
3480
3511
|
metadata: {
|
|
3481
3512
|
...options.metadata,
|
|
@@ -3793,7 +3824,6 @@ var ToolRunner = class {
|
|
|
3793
3824
|
|
|
3794
3825
|
exports.Agent = Agent;
|
|
3795
3826
|
exports.AgentDecisionSchema = AgentDecisionSchema;
|
|
3796
|
-
exports.AgentEventEmitter = AgentEventEmitter;
|
|
3797
3827
|
exports.AgentEvents = AgentEvents;
|
|
3798
3828
|
exports.BaseAgent = BaseAgent;
|
|
3799
3829
|
exports.ConsoleLogger = ConsoleLogger;
|
|
@@ -3819,7 +3849,9 @@ exports.ThoughtSchema = ThoughtSchema;
|
|
|
3819
3849
|
exports.ToolCallSchema = ToolCallSchema;
|
|
3820
3850
|
exports.ToolExecutionSummarySchema = ToolExecutionSummarySchema;
|
|
3821
3851
|
exports.ToolRunner = ToolRunner;
|
|
3852
|
+
exports.addUsage = addUsage;
|
|
3822
3853
|
exports.createAgentDecisionWithOutputSchema = createAgentDecisionWithOutputSchema;
|
|
3854
|
+
exports.createEmptyUsage = createEmptyUsage;
|
|
3823
3855
|
exports.createFunctionTool = createFunctionTool;
|
|
3824
3856
|
exports.createHookManager = createHookManager;
|
|
3825
3857
|
exports.createInMemoryStore = createInMemoryStore;
|