@opperai/agents 0.1.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/dist/index.cjs ADDED
@@ -0,0 +1,2656 @@
1
+ 'use strict';
2
+
3
+ var crypto = require('crypto');
4
+ var zod = require('zod');
5
+ var opperai = require('opperai');
6
+ var zodToJsonSchema = require('zod-to-json-schema');
7
+ var index_js = require('@modelcontextprotocol/sdk/client/index.js');
8
+ var sse_js = require('@modelcontextprotocol/sdk/client/sse.js');
9
+ var stdio_js = require('@modelcontextprotocol/sdk/client/stdio.js');
10
+ var streamableHttp_js = require('@modelcontextprotocol/sdk/client/streamableHttp.js');
11
+
12
+ var __defProp = Object.defineProperty;
13
+ var __getOwnPropNames = Object.getOwnPropertyNames;
14
+ var __esm = (fn, res) => function __init() {
15
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
16
+ };
17
+ var __export = (target, all) => {
18
+ for (var name in all)
19
+ __defProp(target, name, { get: all[name], enumerable: true });
20
+ };
21
+
22
+ // src/base/result.ts
23
+ exports.Result = void 0; exports.ok = void 0; exports.err = void 0;
24
+ var init_result = __esm({
25
+ "src/base/result.ts"() {
26
+ exports.Result = {
27
+ ok(value) {
28
+ return { ok: true, value };
29
+ },
30
+ err(error) {
31
+ return { ok: false, error };
32
+ },
33
+ isOk(result) {
34
+ return result.ok;
35
+ },
36
+ isErr(result) {
37
+ return !result.ok;
38
+ },
39
+ map(result, mapper) {
40
+ if (result.ok) {
41
+ return exports.Result.ok(mapper(result.value));
42
+ }
43
+ return result;
44
+ },
45
+ mapError(result, mapper) {
46
+ if (!result.ok) {
47
+ return exports.Result.err(mapper(result.error));
48
+ }
49
+ return result;
50
+ },
51
+ unwrapOr(result, fallback) {
52
+ return result.ok ? result.value : fallback;
53
+ }
54
+ };
55
+ exports.ok = exports.Result.ok;
56
+ exports.err = exports.Result.err;
57
+ }
58
+ });
59
+ exports.ToolMetadataSchema = void 0; exports.ToolCallRecordSchema = void 0; var toolResultBaseSchema; exports.ToolResultSuccessSchema = void 0; exports.ToolResultFailureSchema = void 0; exports.ToolResultSchema = void 0; exports.ToolResultFactory = void 0; exports.createToolCallRecord = void 0; exports.validateToolInput = void 0; exports.coerceToolDefinition = void 0; exports.isToolProvider = void 0; exports.normalizeToolEntries = void 0;
60
+ var init_tool = __esm({
61
+ "src/base/tool.ts"() {
62
+ init_result();
63
+ exports.ToolMetadataSchema = zod.z.record(zod.z.string(), zod.z.unknown());
64
+ exports.ToolCallRecordSchema = zod.z.object({
65
+ id: zod.z.string().optional().default(() => crypto.randomUUID()),
66
+ toolName: zod.z.string(),
67
+ input: zod.z.unknown(),
68
+ output: zod.z.unknown().optional(),
69
+ success: zod.z.boolean().optional(),
70
+ error: zod.z.union([zod.z.string(), zod.z.object({ message: zod.z.string() }).passthrough()]).optional(),
71
+ startedAt: zod.z.number().default(() => Date.now()),
72
+ finishedAt: zod.z.number().optional(),
73
+ metadata: exports.ToolMetadataSchema.default({})
74
+ });
75
+ toolResultBaseSchema = zod.z.object({
76
+ toolName: zod.z.string(),
77
+ metadata: exports.ToolMetadataSchema.default({}),
78
+ startedAt: zod.z.number().optional(),
79
+ finishedAt: zod.z.number().optional()
80
+ });
81
+ exports.ToolResultSuccessSchema = toolResultBaseSchema.extend({
82
+ success: zod.z.literal(true),
83
+ output: zod.z.any()
84
+ }).refine((data) => data.output !== void 0, {
85
+ message: "output is required"
86
+ });
87
+ exports.ToolResultFailureSchema = toolResultBaseSchema.extend({
88
+ success: zod.z.literal(false),
89
+ error: zod.z.union([zod.z.string(), zod.z.instanceof(Error)])
90
+ });
91
+ exports.ToolResultSchema = zod.z.union([
92
+ exports.ToolResultSuccessSchema,
93
+ exports.ToolResultFailureSchema
94
+ ]);
95
+ exports.ToolResultFactory = {
96
+ success(toolName, output, init = {}) {
97
+ const result = {
98
+ success: true,
99
+ toolName,
100
+ output,
101
+ ...init.startedAt !== void 0 && { startedAt: init.startedAt },
102
+ finishedAt: init.finishedAt ?? Date.now(),
103
+ metadata: init.metadata ?? {}
104
+ };
105
+ exports.ToolResultSuccessSchema.parse(result);
106
+ return result;
107
+ },
108
+ failure(toolName, error, init = {}) {
109
+ const result = {
110
+ success: false,
111
+ toolName,
112
+ error,
113
+ ...init.startedAt !== void 0 && { startedAt: init.startedAt },
114
+ finishedAt: init.finishedAt ?? Date.now(),
115
+ metadata: init.metadata ?? {}
116
+ };
117
+ exports.ToolResultFailureSchema.parse(result);
118
+ return result;
119
+ },
120
+ isSuccess(result) {
121
+ return result.success;
122
+ },
123
+ isFailure(result) {
124
+ return !result.success;
125
+ }
126
+ };
127
+ exports.createToolCallRecord = (input) => exports.ToolCallRecordSchema.parse(input);
128
+ exports.validateToolInput = (schema, payload) => {
129
+ const parsed = schema.safeParse(payload);
130
+ if (!parsed.success) {
131
+ return exports.err(parsed.error);
132
+ }
133
+ return exports.ok(parsed.data);
134
+ };
135
+ exports.coerceToolDefinition = (definition) => {
136
+ if (!definition.name || definition.name.trim().length === 0) {
137
+ throw new Error("Tool definition requires a non-empty name");
138
+ }
139
+ if (!definition.metadata) {
140
+ definition.metadata = {};
141
+ }
142
+ return definition;
143
+ };
144
+ exports.isToolProvider = (value) => {
145
+ if (typeof value !== "object" || value === null) {
146
+ return false;
147
+ }
148
+ const candidate = value;
149
+ return typeof candidate.setup === "function" && typeof candidate.teardown === "function";
150
+ };
151
+ exports.normalizeToolEntries = (entries) => {
152
+ const tools = [];
153
+ const providers = [];
154
+ for (const entry of entries) {
155
+ if (exports.isToolProvider(entry)) {
156
+ providers.push(entry);
157
+ } else {
158
+ tools.push(entry);
159
+ }
160
+ }
161
+ return { tools, providers };
162
+ };
163
+ }
164
+ });
165
+
166
+ // src/base/context.ts
167
+ var context_exports = {};
168
+ __export(context_exports, {
169
+ AgentContext: () => exports.AgentContext,
170
+ ExecutionCycleSchema: () => exports.ExecutionCycleSchema,
171
+ UsageSchema: () => exports.UsageSchema
172
+ });
173
+ exports.UsageSchema = void 0; exports.ExecutionCycleSchema = void 0; exports.AgentContext = void 0;
174
+ var init_context = __esm({
175
+ "src/base/context.ts"() {
176
+ init_tool();
177
+ exports.UsageSchema = zod.z.object({
178
+ requests: zod.z.number().int().nonnegative().default(0),
179
+ inputTokens: zod.z.number().int().nonnegative().default(0),
180
+ outputTokens: zod.z.number().int().nonnegative().default(0),
181
+ totalTokens: zod.z.number().int().nonnegative().default(0),
182
+ cost: zod.z.object({
183
+ generation: zod.z.number().nonnegative().default(0),
184
+ platform: zod.z.number().nonnegative().default(0),
185
+ total: zod.z.number().nonnegative().default(0)
186
+ }).default({ generation: 0, platform: 0, total: 0 })
187
+ });
188
+ exports.ExecutionCycleSchema = zod.z.object({
189
+ iteration: zod.z.number().int().nonnegative(),
190
+ thought: zod.z.unknown().nullable().optional(),
191
+ toolCalls: zod.z.array(exports.ToolCallRecordSchema).default([]),
192
+ results: zod.z.array(zod.z.unknown()).default([]),
193
+ timestamp: zod.z.number().default(() => Date.now())
194
+ });
195
+ exports.AgentContext = class {
196
+ agentName;
197
+ sessionId;
198
+ parentSpanId;
199
+ iteration = 0;
200
+ goal;
201
+ executionHistory = [];
202
+ toolCalls = [];
203
+ usage;
204
+ metadata;
205
+ startedAt;
206
+ updatedAt;
207
+ constructor(options) {
208
+ const now = Date.now();
209
+ this.agentName = options.agentName;
210
+ this.sessionId = options.sessionId ?? crypto.randomUUID();
211
+ this.parentSpanId = options.parentSpanId ?? null;
212
+ this.goal = options.goal;
213
+ this.metadata = { ...options.metadata ?? {} };
214
+ this.startedAt = now;
215
+ this.updatedAt = now;
216
+ this.usage = exports.UsageSchema.parse({});
217
+ }
218
+ updateUsage(delta) {
219
+ const next = exports.UsageSchema.parse(delta);
220
+ this.usage = {
221
+ requests: this.usage.requests + next.requests,
222
+ inputTokens: this.usage.inputTokens + next.inputTokens,
223
+ outputTokens: this.usage.outputTokens + next.outputTokens,
224
+ totalTokens: this.usage.totalTokens + next.totalTokens,
225
+ cost: {
226
+ generation: this.usage.cost.generation + next.cost.generation,
227
+ platform: this.usage.cost.platform + next.cost.platform,
228
+ total: this.usage.cost.total + next.cost.total
229
+ }
230
+ };
231
+ this.touch();
232
+ }
233
+ addCycle(cycle) {
234
+ const parsed = exports.ExecutionCycleSchema.parse(cycle);
235
+ this.executionHistory.push(parsed);
236
+ this.touch();
237
+ return parsed;
238
+ }
239
+ recordToolCall(call) {
240
+ const parsed = exports.ToolCallRecordSchema.parse(call);
241
+ this.toolCalls.push(parsed);
242
+ this.touch();
243
+ return parsed;
244
+ }
245
+ getContextSize() {
246
+ return this.usage.totalTokens;
247
+ }
248
+ getLastNCycles(count = 3) {
249
+ if (count <= 0) {
250
+ return [];
251
+ }
252
+ return this.executionHistory.slice(-count);
253
+ }
254
+ getLastIterationsSummary(count = 2) {
255
+ return this.getLastNCycles(count).map((cycle) => {
256
+ const thought = typeof cycle.thought === "object" && cycle.thought !== null ? { ...cycle.thought } : { text: cycle.thought };
257
+ return {
258
+ iteration: cycle.iteration,
259
+ thought,
260
+ toolCalls: cycle.toolCalls.map((call) => ({
261
+ toolName: call.toolName,
262
+ ...call.success !== void 0 && { success: call.success }
263
+ })),
264
+ results: [...cycle.results]
265
+ };
266
+ });
267
+ }
268
+ setMetadata(key, value) {
269
+ this.metadata[key] = value;
270
+ this.touch();
271
+ }
272
+ clearHistory() {
273
+ this.executionHistory.length = 0;
274
+ this.toolCalls.length = 0;
275
+ this.touch();
276
+ }
277
+ snapshot() {
278
+ return {
279
+ agentName: this.agentName,
280
+ sessionId: this.sessionId,
281
+ parentSpanId: this.parentSpanId,
282
+ iteration: this.iteration,
283
+ goal: this.goal,
284
+ executionHistory: [...this.executionHistory],
285
+ usage: { ...this.usage },
286
+ toolCalls: [...this.toolCalls],
287
+ metadata: { ...this.metadata },
288
+ startedAt: this.startedAt,
289
+ updatedAt: this.updatedAt
290
+ };
291
+ }
292
+ touch() {
293
+ this.updatedAt = Date.now();
294
+ }
295
+ };
296
+ }
297
+ });
298
+
299
+ // src/utils/logger.ts
300
+ var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
301
+ LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG";
302
+ LogLevel2[LogLevel2["INFO"] = 1] = "INFO";
303
+ LogLevel2[LogLevel2["WARN"] = 2] = "WARN";
304
+ LogLevel2[LogLevel2["ERROR"] = 3] = "ERROR";
305
+ LogLevel2[LogLevel2["SILENT"] = 4] = "SILENT";
306
+ return LogLevel2;
307
+ })(LogLevel || {});
308
+ var formatMeta = (meta) => {
309
+ if (!meta) {
310
+ return "";
311
+ }
312
+ try {
313
+ return ` ${JSON.stringify(meta)}`;
314
+ } catch {
315
+ return " [unserializable meta]";
316
+ }
317
+ };
318
+ var writeToStdout = (level, message, meta) => {
319
+ const suffix = formatMeta(meta);
320
+ process.stdout.write(`[${level}] ${message}${suffix}
321
+ `);
322
+ };
323
+ var ConsoleLogger = class {
324
+ level;
325
+ constructor(level = 1 /* INFO */) {
326
+ this.level = level;
327
+ }
328
+ debug(message, meta) {
329
+ if (this.level <= 0 /* DEBUG */) {
330
+ writeToStdout("DEBUG", message, meta);
331
+ }
332
+ }
333
+ info(message, meta) {
334
+ if (this.level <= 1 /* INFO */) {
335
+ writeToStdout("INFO", message, meta);
336
+ }
337
+ }
338
+ warn(message, meta) {
339
+ if (this.level <= 2 /* WARN */) {
340
+ console.warn(`[WARN] ${message}`, meta ? meta : "");
341
+ }
342
+ }
343
+ error(message, error, meta) {
344
+ if (this.level <= 3 /* ERROR */) {
345
+ if (error) {
346
+ console.error(`[ERROR] ${message}`, error, meta ? meta : "");
347
+ } else {
348
+ console.error(`[ERROR] ${message}`, meta ? meta : "");
349
+ }
350
+ }
351
+ }
352
+ getLevel() {
353
+ return this.level;
354
+ }
355
+ setLevel(level) {
356
+ this.level = level;
357
+ }
358
+ };
359
+ var SilentLogger = class {
360
+ debug(message, meta) {
361
+ }
362
+ info(message, meta) {
363
+ }
364
+ warn(message, meta) {
365
+ }
366
+ error(message, error, meta) {
367
+ }
368
+ getLevel() {
369
+ return 4 /* SILENT */;
370
+ }
371
+ setLevel(level) {
372
+ }
373
+ };
374
+ var defaultLogger = new ConsoleLogger(2 /* WARN */);
375
+ function getDefaultLogger() {
376
+ return defaultLogger;
377
+ }
378
+ function setDefaultLogger(logger) {
379
+ defaultLogger = logger;
380
+ }
381
+
382
+ // src/base/hooks.ts
383
+ var HookEvents = {
384
+ AgentStart: "agent:start",
385
+ AgentEnd: "agent:end",
386
+ LoopStart: "loop:start",
387
+ LoopEnd: "loop:end",
388
+ LlmCall: "llm:call",
389
+ LlmResponse: "llm:response",
390
+ ThinkEnd: "think:end",
391
+ BeforeTool: "tool:before",
392
+ AfterTool: "tool:after",
393
+ ToolError: "tool:error",
394
+ MemoryRead: "memory:read",
395
+ MemoryWrite: "memory:write",
396
+ MemoryError: "memory:error"
397
+ };
398
+ var HookManager = class {
399
+ registry = /* @__PURE__ */ new Map();
400
+ logger;
401
+ constructor(logger) {
402
+ this.logger = logger ?? getDefaultLogger();
403
+ }
404
+ on(event, handler) {
405
+ const existing = this.registry.get(event) ?? /* @__PURE__ */ new Set();
406
+ existing.add(handler);
407
+ this.registry.set(event, existing);
408
+ return () => existing.delete(handler);
409
+ }
410
+ once(event, handler) {
411
+ const disposable = async (payload) => {
412
+ await handler(payload);
413
+ this.off(event, disposable);
414
+ };
415
+ return this.on(event, disposable);
416
+ }
417
+ off(event, handler) {
418
+ const listeners = this.registry.get(event);
419
+ if (!listeners) {
420
+ return;
421
+ }
422
+ listeners.delete(handler);
423
+ if (listeners.size === 0) {
424
+ this.registry.delete(event);
425
+ }
426
+ }
427
+ clear() {
428
+ this.registry.clear();
429
+ }
430
+ listenerCount(event) {
431
+ if (event) {
432
+ return this.registry.get(event)?.size ?? 0;
433
+ }
434
+ let total = 0;
435
+ for (const listeners of this.registry.values()) {
436
+ total += listeners.size;
437
+ }
438
+ return total;
439
+ }
440
+ async emit(event, payload) {
441
+ const listeners = Array.from(
442
+ this.registry.get(event) ?? /* @__PURE__ */ new Set()
443
+ );
444
+ if (listeners.length === 0) {
445
+ return;
446
+ }
447
+ for (const [index, listener] of listeners.entries()) {
448
+ try {
449
+ await Promise.resolve(listener(payload));
450
+ } catch (error) {
451
+ this.logger.warn(`Hook handler failed for event "${event}"`, {
452
+ event,
453
+ handlerIndex: index,
454
+ error: error instanceof Error ? error.message : String(error)
455
+ });
456
+ }
457
+ }
458
+ }
459
+ registerMany(registrations) {
460
+ const cleanups = registrations.map(
461
+ ({ event, handler }) => this.on(event, handler)
462
+ );
463
+ return () => cleanups.forEach((dispose) => dispose());
464
+ }
465
+ };
466
+ var createHookManager = (logger) => new HookManager(logger);
467
+
468
+ // src/base/agent.ts
469
+ init_tool();
470
+ var MemoryEntryMetadataSchema = zod.z.object({
471
+ createdAt: zod.z.number(),
472
+ updatedAt: zod.z.number(),
473
+ accessCount: zod.z.number().default(0)
474
+ });
475
+ var MemoryEntrySchema = zod.z.object({
476
+ key: zod.z.string(),
477
+ description: zod.z.string(),
478
+ value: zod.z.unknown(),
479
+ metadata: MemoryEntryMetadataSchema
480
+ });
481
+ var InMemoryStore = class {
482
+ store = /* @__PURE__ */ new Map();
483
+ /**
484
+ * Check if memory has any entries
485
+ */
486
+ async hasEntries() {
487
+ return this.store.size > 0;
488
+ }
489
+ /**
490
+ * List memory catalog (summaries without values) for LLM consumption
491
+ */
492
+ async listEntries() {
493
+ const catalog = [];
494
+ for (const entry of this.store.values()) {
495
+ catalog.push({
496
+ key: entry.key,
497
+ description: entry.description,
498
+ metadata: { ...entry.metadata }
499
+ });
500
+ }
501
+ return catalog;
502
+ }
503
+ /**
504
+ * Read values from memory by keys
505
+ */
506
+ async read(keys) {
507
+ const keysToRead = keys ?? Array.from(this.store.keys());
508
+ const snapshot = {};
509
+ for (const key of keysToRead) {
510
+ const entry = this.store.get(key);
511
+ if (entry) {
512
+ entry.metadata.accessCount += 1;
513
+ entry.metadata.updatedAt = Date.now();
514
+ snapshot[key] = entry.value;
515
+ }
516
+ }
517
+ return snapshot;
518
+ }
519
+ /**
520
+ * Write a value to memory with description
521
+ */
522
+ async write(key, value, description, metadata) {
523
+ const now = Date.now();
524
+ const existing = this.store.get(key);
525
+ const entry = {
526
+ key,
527
+ description: description ?? existing?.description ?? key,
528
+ value,
529
+ metadata: existing ? {
530
+ createdAt: existing.metadata.createdAt,
531
+ updatedAt: now,
532
+ accessCount: existing.metadata.accessCount,
533
+ ...metadata ?? {}
534
+ } : {
535
+ createdAt: now,
536
+ updatedAt: now,
537
+ accessCount: 0,
538
+ ...metadata ?? {}
539
+ }
540
+ };
541
+ this.store.set(key, entry);
542
+ return { ...entry, metadata: { ...entry.metadata } };
543
+ }
544
+ /**
545
+ * Delete a memory entry by key
546
+ */
547
+ async delete(key) {
548
+ return this.store.delete(key);
549
+ }
550
+ /**
551
+ * Clear all memory entries
552
+ */
553
+ async clear() {
554
+ const count = this.store.size;
555
+ this.store.clear();
556
+ return count;
557
+ }
558
+ /**
559
+ * Get the current size of the memory store
560
+ *
561
+ * @returns Number of entries in memory
562
+ */
563
+ get size() {
564
+ return this.store.size;
565
+ }
566
+ };
567
+ var createInMemoryStore = () => new InMemoryStore();
568
+
569
+ // src/base/agent.ts
570
+ var DEFAULT_MODEL = "gcp/gemini-flash-latest";
571
+ var BaseAgent = class {
572
+ /**
573
+ * Agent name
574
+ */
575
+ name;
576
+ /**
577
+ * Agent description
578
+ */
579
+ description;
580
+ /**
581
+ * Agent instructions
582
+ */
583
+ instructions;
584
+ /**
585
+ * Maximum iterations for the agent loop
586
+ */
587
+ maxIterations;
588
+ /**
589
+ * Model identifier
590
+ */
591
+ model;
592
+ /**
593
+ * Input validation schema
594
+ */
595
+ inputSchema;
596
+ /**
597
+ * Output validation schema
598
+ */
599
+ outputSchema;
600
+ /**
601
+ * Whether memory is enabled
602
+ */
603
+ enableMemory;
604
+ /**
605
+ * Memory instance for persistent storage (null if disabled or initialization failed)
606
+ */
607
+ memory;
608
+ /**
609
+ * Agent metadata
610
+ */
611
+ metadata;
612
+ /**
613
+ * Hook manager for lifecycle events
614
+ */
615
+ hooks;
616
+ /**
617
+ * Registry of available tools
618
+ */
619
+ tools;
620
+ /**
621
+ * Baseline tools registered directly on the agent
622
+ */
623
+ baseTools;
624
+ /**
625
+ * Registered tool providers that can expand into tools at runtime
626
+ */
627
+ toolProviders;
628
+ /**
629
+ * Active tools supplied by providers for the current execution
630
+ */
631
+ providerToolRegistry;
632
+ /**
633
+ * Opper client configuration
634
+ */
635
+ opperConfig;
636
+ constructor(config) {
637
+ this.name = config.name;
638
+ this.description = config.description;
639
+ this.instructions = config.instructions;
640
+ this.maxIterations = config.maxIterations ?? 25;
641
+ this.model = config.model ?? DEFAULT_MODEL;
642
+ this.inputSchema = config.inputSchema;
643
+ this.outputSchema = config.outputSchema;
644
+ this.enableMemory = config.enableMemory ?? false;
645
+ this.metadata = { ...config.metadata ?? {} };
646
+ this.hooks = new HookManager();
647
+ this.tools = /* @__PURE__ */ new Map();
648
+ this.baseTools = /* @__PURE__ */ new Map();
649
+ this.toolProviders = /* @__PURE__ */ new Set();
650
+ this.providerToolRegistry = /* @__PURE__ */ new Map();
651
+ this.opperConfig = {
652
+ apiKey: config.opperConfig?.apiKey ?? process.env["OPPER_API_KEY"],
653
+ baseUrl: config.opperConfig?.baseUrl,
654
+ ...config.opperConfig
655
+ };
656
+ this.memory = this.initializeMemory(config);
657
+ if (config.tools) {
658
+ this.registerTools(config.tools);
659
+ }
660
+ }
661
+ /**
662
+ * Initialize memory subsystem with graceful degradation
663
+ *
664
+ * @param config - Agent configuration
665
+ * @returns Memory instance or null
666
+ */
667
+ initializeMemory(config) {
668
+ if (!this.enableMemory && !config.memory) {
669
+ return null;
670
+ }
671
+ try {
672
+ return config.memory ?? new InMemoryStore();
673
+ } catch (error) {
674
+ console.warn(
675
+ `[${this.name}] Memory initialization failed, continuing without memory:`,
676
+ error
677
+ );
678
+ return null;
679
+ }
680
+ }
681
+ /**
682
+ * Main entry point for agent execution.
683
+ * Orchestrates lifecycle: context initialization, hook triggering, loop execution, teardown.
684
+ *
685
+ * @param input - Input to process
686
+ * @param parentSpanId - Optional parent span ID for tracing
687
+ * @returns Processed output
688
+ */
689
+ async process(input, parentSpanId) {
690
+ const validatedInput = this.inputSchema ? this.inputSchema.parse(input) : input;
691
+ const context = await this.initializeContext(validatedInput, parentSpanId);
692
+ try {
693
+ await this.activateToolProviders();
694
+ await this.triggerHook(HookEvents.AgentStart, { context });
695
+ const result = await this.runLoop(validatedInput, context);
696
+ const validatedOutput = this.outputSchema ? this.outputSchema.parse(result) : result;
697
+ await this.triggerHook(HookEvents.AgentEnd, {
698
+ context,
699
+ result: validatedOutput
700
+ });
701
+ return validatedOutput;
702
+ } catch (error) {
703
+ await this.triggerHook(HookEvents.AgentEnd, {
704
+ context,
705
+ error
706
+ });
707
+ throw error;
708
+ } finally {
709
+ await this.deactivateToolProviders();
710
+ await this.teardownContext(context);
711
+ }
712
+ }
713
+ /**
714
+ * Initialize agent context before execution.
715
+ * Can be overridden for custom initialization logic.
716
+ *
717
+ * @param input - Agent input
718
+ * @param parentSpanId - Optional parent span ID
719
+ * @returns Initialized context
720
+ */
721
+ async initializeContext(input, parentSpanId) {
722
+ const context = new (await Promise.resolve().then(() => (init_context(), context_exports))).AgentContext({
723
+ agentName: this.name,
724
+ parentSpanId: parentSpanId ?? null,
725
+ goal: input,
726
+ metadata: { ...this.metadata }
727
+ });
728
+ return context;
729
+ }
730
+ /**
731
+ * Teardown agent context after execution.
732
+ * Can be overridden for custom cleanup logic.
733
+ *
734
+ * @param context - Agent context to teardown
735
+ */
736
+ async teardownContext(context) {
737
+ }
738
+ /**
739
+ * Add a tool to the agent's tool registry.
740
+ *
741
+ * @param tool - Tool to add
742
+ */
743
+ addTool(tool2) {
744
+ const coerced = exports.coerceToolDefinition(tool2);
745
+ if (this.tools.has(coerced.name)) {
746
+ console.warn(
747
+ `[${this.name}] Tool "${coerced.name}" already registered. Overwriting existing definition.`
748
+ );
749
+ }
750
+ const typedTool = coerced;
751
+ this.baseTools.set(coerced.name, typedTool);
752
+ this.tools.set(coerced.name, typedTool);
753
+ }
754
+ /**
755
+ * Remove a tool from the agent's tool registry.
756
+ *
757
+ * @param toolName - Name of tool to remove
758
+ * @returns True if tool was removed, false if not found
759
+ */
760
+ removeTool(toolName) {
761
+ this.baseTools.delete(toolName);
762
+ return this.tools.delete(toolName);
763
+ }
764
+ /**
765
+ * Get a tool by name.
766
+ *
767
+ * @param toolName - Name of tool to retrieve
768
+ * @returns Tool instance or undefined
769
+ */
770
+ getTool(toolName) {
771
+ return this.tools.get(toolName);
772
+ }
773
+ /**
774
+ * Get all registered tools.
775
+ *
776
+ * @returns Array of all tools
777
+ */
778
+ getTools() {
779
+ return Array.from(this.tools.values());
780
+ }
781
+ /**
782
+ * Register a tool provider that expands into tools at runtime.
783
+ *
784
+ * @param provider - Tool provider to add
785
+ */
786
+ addToolProvider(provider) {
787
+ this.toolProviders.add(provider);
788
+ }
789
+ /**
790
+ * Convert this agent into a tool that can be used by other agents.
791
+ *
792
+ * @param toolName - Optional custom name for the tool (defaults to agent name)
793
+ * @param toolDescription - Optional custom description (defaults to agent description)
794
+ * @returns Tool wrapping this agent
795
+ */
796
+ asTool(toolName, toolDescription) {
797
+ const tool2 = {
798
+ name: toolName ?? this.name,
799
+ description: toolDescription ?? this.description ?? `Agent: ${this.name}`,
800
+ ...this.inputSchema && { schema: this.inputSchema },
801
+ metadata: {
802
+ isAgent: true,
803
+ agentName: this.name
804
+ },
805
+ execute: async (input, executionContext) => {
806
+ try {
807
+ const parentSpanId = executionContext.spanId ?? executionContext.agentContext.parentSpanId ?? void 0;
808
+ const result = await this.process(input, parentSpanId);
809
+ return exports.ToolResultFactory.success(tool2.name, result);
810
+ } catch (error) {
811
+ return exports.ToolResultFactory.failure(
812
+ tool2.name,
813
+ error instanceof Error ? error : new Error(String(error))
814
+ );
815
+ }
816
+ }
817
+ };
818
+ return tool2;
819
+ }
820
+ /**
821
+ * Register a hook handler for a specific event.
822
+ *
823
+ * @param event - Hook event name
824
+ * @param handler - Hook handler function
825
+ * @returns Cleanup function to unregister the hook
826
+ */
827
+ registerHook(event, handler) {
828
+ return this.hooks.on(event, handler);
829
+ }
830
+ /**
831
+ * Trigger a hook event with a payload.
832
+ * Swallows errors to prevent hook failures from breaking agent execution.
833
+ *
834
+ * @param event - Hook event name
835
+ * @param payload - Event payload
836
+ */
837
+ async triggerHook(event, payload) {
838
+ try {
839
+ await this.hooks.emit(event, payload);
840
+ } catch (error) {
841
+ console.warn(`Hook error for event ${event}:`, error);
842
+ }
843
+ }
844
+ /**
845
+ * Execute a tool with proper context, hooks, and error handling.
846
+ *
847
+ * @param toolName - Name of tool to execute
848
+ * @param input - Tool input
849
+ * @param context - Agent context
850
+ * @param options - Optional execution options (signal, span ID)
851
+ * @returns Tool execution result
852
+ */
853
+ async executeTool(toolName, input, context, options) {
854
+ const tool2 = this.tools.get(toolName);
855
+ if (!tool2) {
856
+ const failure = exports.ToolResultFactory.failure(
857
+ toolName,
858
+ new Error(`Tool "${toolName}" not found in agent registry`)
859
+ );
860
+ const timestamp = Date.now();
861
+ context.recordToolCall({
862
+ toolName,
863
+ input,
864
+ success: false,
865
+ error: failure.error instanceof Error ? failure.error.message : String(failure.error),
866
+ startedAt: timestamp,
867
+ finishedAt: timestamp,
868
+ metadata: {}
869
+ });
870
+ await this.triggerHook(HookEvents.ToolError, {
871
+ context,
872
+ toolName,
873
+ error: failure.error
874
+ });
875
+ return failure;
876
+ }
877
+ const executionContext = {
878
+ agentContext: context,
879
+ ...options?.signal && { signal: options.signal },
880
+ ...options?.spanId && { spanId: options.spanId },
881
+ metadata: {}
882
+ };
883
+ const startedAt = Date.now();
884
+ try {
885
+ await this.triggerHook(HookEvents.BeforeTool, {
886
+ context,
887
+ tool: tool2,
888
+ input
889
+ });
890
+ const result = await tool2.execute(input, executionContext);
891
+ const finishedAt = Date.now();
892
+ const record = context.recordToolCall({
893
+ toolName: tool2.name,
894
+ input,
895
+ ...result.success && { output: result.output },
896
+ success: result.success,
897
+ ...!result.success && {
898
+ error: result.error instanceof Error ? result.error.message : String(result.error)
899
+ },
900
+ startedAt,
901
+ finishedAt,
902
+ metadata: {}
903
+ });
904
+ await this.triggerHook(HookEvents.AfterTool, {
905
+ context,
906
+ tool: tool2,
907
+ result,
908
+ record
909
+ });
910
+ return result;
911
+ } catch (error) {
912
+ const failure = exports.ToolResultFactory.failure(
913
+ toolName,
914
+ error instanceof Error ? error : new Error(String(error)),
915
+ {
916
+ startedAt,
917
+ finishedAt: Date.now()
918
+ }
919
+ );
920
+ const record = context.recordToolCall({
921
+ toolName: tool2.name,
922
+ input,
923
+ success: false,
924
+ error: failure.error instanceof Error ? failure.error.message : String(failure.error),
925
+ startedAt,
926
+ finishedAt: failure.finishedAt,
927
+ metadata: {}
928
+ });
929
+ await this.triggerHook(HookEvents.ToolError, {
930
+ context,
931
+ tool: tool2,
932
+ toolName: tool2.name,
933
+ error
934
+ });
935
+ await this.triggerHook(HookEvents.AfterTool, {
936
+ context,
937
+ tool: tool2,
938
+ result: failure,
939
+ record
940
+ });
941
+ return failure;
942
+ }
943
+ }
944
+ registerTools(entries) {
945
+ const { tools, providers } = exports.normalizeToolEntries(entries);
946
+ for (const tool2 of tools) {
947
+ this.addTool(tool2);
948
+ }
949
+ for (const provider of providers) {
950
+ this.toolProviders.add(provider);
951
+ }
952
+ }
953
+ async activateToolProviders() {
954
+ const activationPromises = Array.from(this.toolProviders).filter((provider) => !this.providerToolRegistry.has(provider)).map(async (provider) => {
955
+ try {
956
+ const baseAgent = this;
957
+ const providedTools = await provider.setup(baseAgent) ?? [];
958
+ const normalizedTools = providedTools.map(
959
+ (tool2) => exports.coerceToolDefinition(tool2)
960
+ );
961
+ this.providerToolRegistry.set(provider, normalizedTools);
962
+ for (const tool2 of normalizedTools) {
963
+ if (this.tools.has(tool2.name)) {
964
+ console.warn(
965
+ `[${this.name}] Tool "${tool2.name}" from provider overwrites existing tool.`
966
+ );
967
+ }
968
+ this.tools.set(tool2.name, tool2);
969
+ }
970
+ } catch (error) {
971
+ console.warn(
972
+ `[${this.name}] Failed to activate tool provider:`,
973
+ error
974
+ );
975
+ }
976
+ });
977
+ await Promise.allSettled(activationPromises);
978
+ }
979
+ async deactivateToolProviders() {
980
+ const teardownEntries = Array.from(this.providerToolRegistry.entries());
981
+ this.providerToolRegistry.clear();
982
+ const teardownPromises = teardownEntries.map(async ([provider, tools]) => {
983
+ for (const tool2 of tools) {
984
+ this.tools.delete(tool2.name);
985
+ const baseTool = this.baseTools.get(tool2.name);
986
+ if (baseTool) {
987
+ this.tools.set(tool2.name, baseTool);
988
+ }
989
+ }
990
+ try {
991
+ await provider.teardown();
992
+ } catch (error) {
993
+ console.warn(
994
+ `[${this.name}] Error while tearing down tool provider:`,
995
+ error
996
+ );
997
+ }
998
+ });
999
+ await Promise.allSettled(teardownPromises);
1000
+ }
1001
+ };
1002
+
1003
+ // src/index.ts
1004
+ init_context();
1005
+ init_result();
1006
+ init_tool();
1007
+ var ThoughtSchema = zod.z.object({
1008
+ /**
1009
+ * The reasoning or internal monologue of the agent
1010
+ */
1011
+ reasoning: zod.z.string(),
1012
+ /**
1013
+ * Planned next action(s)
1014
+ */
1015
+ plan: zod.z.string().optional(),
1016
+ /**
1017
+ * Confidence level (0-1)
1018
+ */
1019
+ confidence: zod.z.number().min(0).max(1).optional(),
1020
+ /**
1021
+ * Additional metadata
1022
+ */
1023
+ metadata: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
1024
+ });
1025
+ var ToolCallSchema = zod.z.object({
1026
+ /**
1027
+ * Unique identifier for this tool call
1028
+ */
1029
+ id: zod.z.string(),
1030
+ /**
1031
+ * Name of the tool to invoke
1032
+ */
1033
+ toolName: zod.z.string(),
1034
+ /**
1035
+ * Arguments to pass to the tool
1036
+ */
1037
+ arguments: zod.z.unknown()
1038
+ });
1039
+ var MemoryUpdateSchema = zod.z.object({
1040
+ /**
1041
+ * Value to store for this key
1042
+ */
1043
+ value: zod.z.unknown(),
1044
+ /**
1045
+ * Optional description of the memory entry
1046
+ */
1047
+ description: zod.z.string().optional(),
1048
+ /**
1049
+ * Optional metadata for the memory entry
1050
+ */
1051
+ metadata: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
1052
+ });
1053
+ var AgentDecisionSchema = zod.z.object({
1054
+ /**
1055
+ * Agent's internal reasoning
1056
+ */
1057
+ reasoning: zod.z.string(),
1058
+ /**
1059
+ * Tool calls to execute (if any)
1060
+ * Empty array signals task completion
1061
+ */
1062
+ toolCalls: zod.z.array(ToolCallSchema).default([]),
1063
+ /**
1064
+ * Memory keys to read during this iteration
1065
+ */
1066
+ memoryReads: zod.z.array(zod.z.string()).default([]),
1067
+ /**
1068
+ * Memory entries to write/update (key -> payload)
1069
+ */
1070
+ memoryUpdates: zod.z.record(MemoryUpdateSchema).default({})
1071
+ });
1072
+ var ToolExecutionSummarySchema = zod.z.object({
1073
+ /**
1074
+ * Tool name
1075
+ */
1076
+ toolName: zod.z.string(),
1077
+ /**
1078
+ * Whether execution succeeded
1079
+ */
1080
+ success: zod.z.boolean(),
1081
+ /**
1082
+ * Output if successful
1083
+ */
1084
+ output: zod.z.unknown().optional(),
1085
+ /**
1086
+ * Error message if failed
1087
+ */
1088
+ error: zod.z.string().optional()
1089
+ });
1090
+ var isPlainRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
1091
+ var isZodSchema = (value) => typeof value === "object" && value !== null && "_def" in value && typeof value.parse === "function";
1092
+ var readTokenCount = (usage, key) => {
1093
+ if (!usage) {
1094
+ return 0;
1095
+ }
1096
+ const value = usage[key];
1097
+ return typeof value === "number" && Number.isFinite(value) ? value : 0;
1098
+ };
1099
+ var extractUsage = (response) => {
1100
+ const usageRecord = isPlainRecord(response.usage) ? response.usage : void 0;
1101
+ return {
1102
+ inputTokens: readTokenCount(usageRecord, "input_tokens"),
1103
+ outputTokens: readTokenCount(usageRecord, "output_tokens")
1104
+ };
1105
+ };
1106
+ var extractCost = (response) => {
1107
+ const costRecord = isPlainRecord(response.cost) ? response.cost : void 0;
1108
+ return {
1109
+ generation: readTokenCount(costRecord, "generation"),
1110
+ platform: readTokenCount(costRecord, "platform"),
1111
+ total: readTokenCount(costRecord, "total")
1112
+ };
1113
+ };
1114
+ var DEFAULT_RETRY_CONFIG = {
1115
+ maxRetries: 3,
1116
+ initialDelayMs: 1e3,
1117
+ backoffMultiplier: 2,
1118
+ maxDelayMs: 1e4
1119
+ };
1120
+ var OpperClient = class {
1121
+ client;
1122
+ logger;
1123
+ retryConfig;
1124
+ constructor(apiKey, options = {}) {
1125
+ this.client = new opperai.Opper({
1126
+ httpBearer: apiKey ?? process.env["OPPER_HTTP_BEARER"] ?? ""
1127
+ });
1128
+ this.logger = options.logger ?? getDefaultLogger();
1129
+ this.retryConfig = {
1130
+ ...DEFAULT_RETRY_CONFIG,
1131
+ ...options.retryConfig ?? {}
1132
+ };
1133
+ }
1134
+ /**
1135
+ * Make a call to Opper with retry logic
1136
+ */
1137
+ async call(options) {
1138
+ return this.withRetry(async () => {
1139
+ const inputSchema = this.toJsonSchema(options.inputSchema);
1140
+ const outputSchema = this.toJsonSchema(options.outputSchema);
1141
+ const response = await this.client.call({
1142
+ name: options.name,
1143
+ instructions: options.instructions,
1144
+ input: options.input,
1145
+ ...inputSchema && { inputSchema },
1146
+ ...outputSchema && { outputSchema },
1147
+ ...options.model && { model: options.model },
1148
+ ...options.parentSpanId && { parentSpanId: options.parentSpanId }
1149
+ });
1150
+ const usagePayload = extractUsage(response);
1151
+ const costPayload = extractCost(response);
1152
+ const usage = {
1153
+ inputTokens: usagePayload.inputTokens,
1154
+ outputTokens: usagePayload.outputTokens,
1155
+ totalTokens: usagePayload.inputTokens + usagePayload.outputTokens,
1156
+ cost: costPayload
1157
+ };
1158
+ const result = {
1159
+ ...response.jsonPayload !== void 0 && response.jsonPayload !== null ? { jsonPayload: response.jsonPayload } : {},
1160
+ ...response.message !== void 0 && response.message !== null ? { message: response.message } : {},
1161
+ spanId: response.spanId,
1162
+ usage
1163
+ };
1164
+ return result;
1165
+ }, options.name);
1166
+ }
1167
+ /**
1168
+ * Create a span for tracing
1169
+ */
1170
+ async createSpan(options) {
1171
+ return this.withRetry(async () => {
1172
+ const span = await this.client.spans.create({
1173
+ name: options.name,
1174
+ ...options.input !== void 0 && { input: options.input },
1175
+ ...options.parentSpanId && { parentId: options.parentSpanId }
1176
+ });
1177
+ return {
1178
+ id: span.id,
1179
+ name: options.name,
1180
+ input: options.input
1181
+ };
1182
+ }, `create-span:${options.name}`);
1183
+ }
1184
+ /**
1185
+ * Update a span with output or error
1186
+ */
1187
+ async updateSpan(spanId, output, options) {
1188
+ return this.withRetry(async () => {
1189
+ const serializedOutput = output !== void 0 && output !== null ? typeof output === "object" ? JSON.stringify(output) : String(output) : void 0;
1190
+ await this.client.spans.update(spanId, {
1191
+ ...serializedOutput !== void 0 && { output: serializedOutput },
1192
+ ...options?.error && { error: options.error }
1193
+ });
1194
+ }, `update-span:${spanId}`);
1195
+ }
1196
+ /**
1197
+ * Get the underlying Opper client
1198
+ */
1199
+ getClient() {
1200
+ return this.client;
1201
+ }
1202
+ /**
1203
+ * Execute a function with retry logic and exponential backoff
1204
+ */
1205
+ async withRetry(fn, operationName) {
1206
+ let lastError;
1207
+ let delay = this.retryConfig.initialDelayMs;
1208
+ for (let attempt = 0; attempt <= this.retryConfig.maxRetries; attempt++) {
1209
+ try {
1210
+ return await fn();
1211
+ } catch (error) {
1212
+ lastError = error instanceof Error ? error : new Error(String(error));
1213
+ if (attempt === this.retryConfig.maxRetries) {
1214
+ break;
1215
+ }
1216
+ if (!this.isRetryableError(error)) {
1217
+ throw lastError;
1218
+ }
1219
+ this.logger.warn(
1220
+ `Opper operation "${operationName}" failed (attempt ${attempt + 1}/${this.retryConfig.maxRetries + 1}), retrying in ${delay}ms`,
1221
+ {
1222
+ error: lastError.message,
1223
+ attempt: attempt + 1,
1224
+ delayMs: delay
1225
+ }
1226
+ );
1227
+ await this.sleep(delay);
1228
+ delay = Math.min(
1229
+ delay * this.retryConfig.backoffMultiplier,
1230
+ this.retryConfig.maxDelayMs
1231
+ );
1232
+ }
1233
+ }
1234
+ this.logger.error(
1235
+ `Opper operation "${operationName}" failed after ${this.retryConfig.maxRetries + 1} attempts`,
1236
+ lastError
1237
+ );
1238
+ throw lastError;
1239
+ }
1240
+ /**
1241
+ * Check if an error is retryable
1242
+ */
1243
+ isRetryableError(error) {
1244
+ if (!(error instanceof Error)) {
1245
+ return false;
1246
+ }
1247
+ const errorMessage = error.message.toLowerCase();
1248
+ const retryablePatterns = [
1249
+ "network",
1250
+ "timeout",
1251
+ "econnreset",
1252
+ "enotfound",
1253
+ "econnrefused",
1254
+ "etimedout",
1255
+ "rate limit",
1256
+ "429",
1257
+ "500",
1258
+ "502",
1259
+ "503",
1260
+ "504"
1261
+ ];
1262
+ return retryablePatterns.some((pattern) => errorMessage.includes(pattern));
1263
+ }
1264
+ /**
1265
+ * Convert Zod schema to JSON Schema
1266
+ */
1267
+ toJsonSchema(schema) {
1268
+ if (!schema) {
1269
+ return void 0;
1270
+ }
1271
+ if (isZodSchema(schema)) {
1272
+ try {
1273
+ return zodToJsonSchema.zodToJsonSchema(schema);
1274
+ } catch (error) {
1275
+ this.logger.warn("Failed to convert Zod schema to JSON Schema", {
1276
+ error: error instanceof Error ? error.message : String(error)
1277
+ });
1278
+ return void 0;
1279
+ }
1280
+ }
1281
+ if (isPlainRecord(schema)) {
1282
+ return schema;
1283
+ }
1284
+ this.logger.warn("Unsupported schema type provided to OpperClient", {
1285
+ schemaType: typeof schema
1286
+ });
1287
+ return void 0;
1288
+ }
1289
+ /**
1290
+ * Sleep for specified milliseconds
1291
+ */
1292
+ sleep(ms) {
1293
+ return new Promise((resolve) => setTimeout(resolve, ms));
1294
+ }
1295
+ };
1296
+ function createOpperClient(apiKey, options) {
1297
+ return new OpperClient(apiKey, options);
1298
+ }
1299
+ var SchemaValidationError = class extends Error {
1300
+ issues;
1301
+ constructor(message, issues) {
1302
+ super(message);
1303
+ this.name = "SchemaValidationError";
1304
+ this.issues = issues;
1305
+ }
1306
+ };
1307
+ var validateSchema = (schema, value, options = {}) => {
1308
+ const result = schema.safeParse(value);
1309
+ if (!result.success) {
1310
+ throw new SchemaValidationError(
1311
+ options.message ?? "Schema validation failed",
1312
+ result.error.issues
1313
+ );
1314
+ }
1315
+ return result.data;
1316
+ };
1317
+ var isSchemaValid = (schema, value) => {
1318
+ return schema.safeParse(value).success;
1319
+ };
1320
+ var schemaToJson = (schema, options = {}) => {
1321
+ return zodToJsonSchema.zodToJsonSchema(schema, options);
1322
+ };
1323
+ var getSchemaDefault = (schema) => {
1324
+ const result = schema.safeParse(void 0);
1325
+ return result.success ? result.data : void 0;
1326
+ };
1327
+ var mergeSchemaDefaults = (schema, value) => {
1328
+ const defaults = getSchemaDefault(schema);
1329
+ if (defaults && typeof defaults === "object") {
1330
+ return validateSchema(schema, { ...defaults, ...value });
1331
+ }
1332
+ return validateSchema(schema, value);
1333
+ };
1334
+
1335
+ // src/core/agent.ts
1336
+ var isToolSuccessResult = (value) => {
1337
+ if (typeof value !== "object" || value === null) {
1338
+ return false;
1339
+ }
1340
+ const candidate = value;
1341
+ return candidate.success === true && typeof candidate.toolName === "string" && "output" in candidate;
1342
+ };
1343
+ var Agent = class extends BaseAgent {
1344
+ opperClient;
1345
+ logger;
1346
+ verbose;
1347
+ constructor(config) {
1348
+ super(config);
1349
+ this.logger = config.logger ?? getDefaultLogger();
1350
+ this.verbose = config.verbose ?? false;
1351
+ if (this.verbose) {
1352
+ try {
1353
+ this.logger.setLevel?.(1 /* INFO */);
1354
+ } catch {
1355
+ }
1356
+ }
1357
+ this.opperClient = config.opperClient ?? new OpperClient(this.opperConfig.apiKey, {
1358
+ logger: this.logger
1359
+ });
1360
+ }
1361
+ /**
1362
+ * Serialize input for passing to LLM or spans
1363
+ */
1364
+ serializeInput(input) {
1365
+ if (typeof input === "string") {
1366
+ return input;
1367
+ }
1368
+ if (typeof input === "object" && input !== null) {
1369
+ return JSON.stringify(input);
1370
+ }
1371
+ return String(input);
1372
+ }
1373
+ /**
1374
+ * Main agent loop: think → tool execution → memory handling → repeat until complete
1375
+ */
1376
+ async runLoop(input, context) {
1377
+ this.log("Starting agent loop", {
1378
+ goal: input,
1379
+ maxIterations: this.maxIterations,
1380
+ tools: Array.from(this.tools.keys())
1381
+ });
1382
+ const parentSpan = await this.opperClient.createSpan({
1383
+ name: `${this.name}_execution`,
1384
+ input: this.serializeInput(input),
1385
+ ...context.parentSpanId ? { parentSpanId: context.parentSpanId } : {}
1386
+ });
1387
+ context.parentSpanId = parentSpan.id;
1388
+ try {
1389
+ while (context.iteration < this.maxIterations) {
1390
+ const currentIteration = context.iteration + 1;
1391
+ this.log(`Iteration ${currentIteration}/${this.maxIterations}`, {
1392
+ toolsAvailable: this.tools.size
1393
+ });
1394
+ await this.triggerHook(HookEvents.LoopStart, { context });
1395
+ let loopComplete = false;
1396
+ try {
1397
+ const { decision, spanId: thinkSpanId } = await this.think(
1398
+ input,
1399
+ context
1400
+ );
1401
+ const memoryResults = await this.handleMemoryActions(
1402
+ decision,
1403
+ context,
1404
+ thinkSpanId
1405
+ );
1406
+ const toolCallStartIndex = context.toolCalls.length;
1407
+ const toolResults = await this.executeToolCalls(
1408
+ decision,
1409
+ context,
1410
+ thinkSpanId
1411
+ );
1412
+ const combinedResults = [...memoryResults, ...toolResults];
1413
+ const newToolCalls = context.toolCalls.slice(toolCallStartIndex);
1414
+ context.addCycle({
1415
+ iteration: currentIteration,
1416
+ thought: {
1417
+ reasoning: decision.reasoning,
1418
+ memoryReads: decision.memoryReads,
1419
+ memoryUpdates: decision.memoryUpdates
1420
+ },
1421
+ toolCalls: newToolCalls,
1422
+ results: combinedResults,
1423
+ timestamp: Date.now()
1424
+ });
1425
+ context.iteration = currentIteration;
1426
+ const hasToolCalls = decision.toolCalls.length > 0;
1427
+ const hasMemoryReads = this.enableMemory && (decision.memoryReads?.length ?? 0) > 0;
1428
+ loopComplete = !hasToolCalls && !hasMemoryReads;
1429
+ } finally {
1430
+ await this.triggerHook(HookEvents.LoopEnd, { context });
1431
+ }
1432
+ if (loopComplete) {
1433
+ this.log("Loop complete, generating final result", {
1434
+ iteration: context.iteration + 1
1435
+ });
1436
+ break;
1437
+ }
1438
+ }
1439
+ if (context.iteration >= this.maxIterations) {
1440
+ throw new Error(
1441
+ `Agent exceeded maximum iterations (${this.maxIterations}) without completing the task`
1442
+ );
1443
+ }
1444
+ const result = await this.generateFinalResult(input, context);
1445
+ await this.opperClient.updateSpan(parentSpan.id, result);
1446
+ return result;
1447
+ } catch (error) {
1448
+ await this.opperClient.updateSpan(parentSpan.id, void 0, {
1449
+ error: error instanceof Error ? error.message : String(error)
1450
+ });
1451
+ throw error;
1452
+ }
1453
+ }
1454
+ /**
1455
+ * Think step: Call LLM to decide next action
1456
+ */
1457
+ async think(input, context) {
1458
+ const spanName = "think";
1459
+ this.log("Think step", { iteration: context.iteration });
1460
+ await this.triggerHook(HookEvents.LlmCall, { context, callType: "think" });
1461
+ try {
1462
+ const instructions = this.buildThinkInstructions();
1463
+ const thinkContext = await this.buildThinkContext(input, context);
1464
+ const response = await this.opperClient.call({
1465
+ name: spanName,
1466
+ instructions,
1467
+ input: thinkContext,
1468
+ outputSchema: AgentDecisionSchema,
1469
+ model: this.model,
1470
+ ...context.parentSpanId && { parentSpanId: context.parentSpanId }
1471
+ });
1472
+ context.updateUsage({
1473
+ requests: 1,
1474
+ inputTokens: response.usage.inputTokens,
1475
+ outputTokens: response.usage.outputTokens,
1476
+ totalTokens: response.usage.totalTokens,
1477
+ cost: response.usage.cost
1478
+ });
1479
+ const decision = AgentDecisionSchema.parse(response.jsonPayload);
1480
+ await this.triggerHook(HookEvents.LlmResponse, {
1481
+ context,
1482
+ callType: "think",
1483
+ response
1484
+ });
1485
+ await this.triggerHook(HookEvents.ThinkEnd, {
1486
+ context,
1487
+ thought: { reasoning: decision.reasoning }
1488
+ });
1489
+ this.log("Think result", {
1490
+ reasoning: decision.reasoning,
1491
+ toolCalls: decision.toolCalls.length,
1492
+ memoryReads: decision.memoryReads?.length ?? 0,
1493
+ memoryWrites: Object.keys(decision.memoryUpdates ?? {}).length
1494
+ });
1495
+ return { decision, spanId: response.spanId };
1496
+ } catch (error) {
1497
+ this.logger.error("Think step failed", error);
1498
+ throw new Error(
1499
+ `Think step failed: ${error instanceof Error ? error.message : String(error)}`
1500
+ );
1501
+ }
1502
+ }
1503
+ /**
1504
+ * Build static instructions for the think step
1505
+ */
1506
+ buildThinkInstructions() {
1507
+ let instructions = `You are in a Think-Act reasoning loop.
1508
+
1509
+ YOUR TASK:
1510
+ 1. Analyze the current situation
1511
+ 2. Decide if the goal is complete or more actions are needed
1512
+ 3. If more actions needed: specify tools to call
1513
+ 4. If goal complete: return empty tool_calls list
1514
+
1515
+ IMPORTANT:
1516
+ - Return empty toolCalls array when task is COMPLETE
1517
+ - Only use available tools
1518
+ - Provide clear reasoning for each decision`;
1519
+ if (this.enableMemory) {
1520
+ instructions += `
1521
+
1522
+ MEMORY SYSTEM:
1523
+ You have access to a persistent memory system that works across iterations.
1524
+
1525
+ Memory Operations:
1526
+ 1. READ: Add keys to memoryReads when you need to load existing entries
1527
+ 2. WRITE: Populate memoryUpdates with key-value pairs (with optional description/metadata)
1528
+ Example: memoryUpdates = { "favorite_color": { "value": "blue", "description": "User likes blue" } }
1529
+
1530
+ When to use memory:
1531
+ - Save important calculations, decisions, or user preferences
1532
+ - Load memory when you need information from earlier in the conversation
1533
+ - Use descriptive keys like "budget_total", "user_favorite_city", etc.
1534
+ - When a key appears in memory_catalog and you need its value, add it to memoryReads before continuing
1535
+
1536
+ The memory you write persists across all process() calls on this agent.`;
1537
+ }
1538
+ return instructions;
1539
+ }
1540
+ /**
1541
+ * Build dynamic context for the think step
1542
+ */
1543
+ async buildThinkContext(input, context) {
1544
+ const availableTools = Array.from(this.tools.values()).map((tool2) => ({
1545
+ name: tool2.name,
1546
+ description: tool2.description || "",
1547
+ // Convert Zod schema to JSON Schema for LLM consumption
1548
+ parameters: tool2.schema ? schemaToJson(tool2.schema) : {}
1549
+ }));
1550
+ const executionHistory = context.getLastNCycles(3).map((cycle) => {
1551
+ const thought = typeof cycle.thought === "object" && cycle.thought !== null ? cycle.thought["reasoning"] || "" : String(cycle.thought || "");
1552
+ const results = Array.isArray(cycle.results) ? cycle.results.map((r) => {
1553
+ const result = r;
1554
+ let actualOutput = result.output;
1555
+ if (result.success && isToolSuccessResult(actualOutput)) {
1556
+ actualOutput = actualOutput.output;
1557
+ }
1558
+ return {
1559
+ tool: result.toolName,
1560
+ success: result.success,
1561
+ // Serialize result properly - use JSON for objects, String for primitives
1562
+ result: result.success ? typeof actualOutput === "object" ? JSON.stringify(actualOutput) : String(actualOutput) : void 0,
1563
+ error: !result.success ? result.error : void 0
1564
+ };
1565
+ }) : [];
1566
+ return {
1567
+ iteration: cycle.iteration,
1568
+ thought,
1569
+ results
1570
+ };
1571
+ });
1572
+ let memoryCatalog = null;
1573
+ if (this.enableMemory && this.memory && await this.memory.hasEntries()) {
1574
+ memoryCatalog = await this.memory.listEntries();
1575
+ }
1576
+ const loadedMemory = context.metadata["current_memory"] ?? null;
1577
+ return {
1578
+ goal: this.serializeInput(input),
1579
+ agent_description: this.description || "",
1580
+ instructions: this.instructions || "No specific instructions.",
1581
+ available_tools: availableTools,
1582
+ execution_history: executionHistory,
1583
+ current_iteration: context.iteration + 1,
1584
+ max_iterations: this.maxIterations,
1585
+ memory_catalog: memoryCatalog,
1586
+ loaded_memory: loadedMemory
1587
+ };
1588
+ }
1589
+ /**
1590
+ * Execute all tool calls from a decision
1591
+ */
1592
+ async executeToolCalls(decision, context, parentSpanId) {
1593
+ if (decision.toolCalls.length === 0) {
1594
+ return [];
1595
+ }
1596
+ this.log(`Executing ${decision.toolCalls.length} tool call(s)`);
1597
+ const results = [];
1598
+ for (const toolCall of decision.toolCalls) {
1599
+ this.log(`Action: ${toolCall.toolName}`, {
1600
+ parameters: toolCall.arguments
1601
+ });
1602
+ const toolSpan = await this.opperClient.createSpan({
1603
+ name: `tool_${toolCall.toolName}`,
1604
+ input: toolCall.arguments,
1605
+ ...parentSpanId ? { parentSpanId } : context.parentSpanId ? { parentSpanId: context.parentSpanId } : {}
1606
+ });
1607
+ try {
1608
+ const result = await this.executeTool(
1609
+ toolCall.toolName,
1610
+ toolCall.arguments,
1611
+ context,
1612
+ { spanId: toolSpan.id }
1613
+ );
1614
+ if (result.success) {
1615
+ await this.opperClient.updateSpan(toolSpan.id, result.output);
1616
+ } else {
1617
+ await this.opperClient.updateSpan(toolSpan.id, void 0, {
1618
+ error: result.error instanceof Error ? result.error.message : String(result.error)
1619
+ });
1620
+ }
1621
+ const summary = {
1622
+ toolName: toolCall.toolName,
1623
+ success: result.success,
1624
+ ...result.success && { output: result.output },
1625
+ ...!result.success && {
1626
+ error: result.error instanceof Error ? result.error.message : String(result.error)
1627
+ }
1628
+ };
1629
+ results.push(ToolExecutionSummarySchema.parse(summary));
1630
+ this.log(
1631
+ `Tool ${toolCall.toolName} ${result.success ? "succeeded" : "failed"}`,
1632
+ {
1633
+ success: result.success
1634
+ }
1635
+ );
1636
+ } catch (error) {
1637
+ await this.opperClient.updateSpan(toolSpan.id, void 0, {
1638
+ error: error instanceof Error ? error.message : String(error)
1639
+ });
1640
+ const summary = {
1641
+ toolName: toolCall.toolName,
1642
+ success: false,
1643
+ error: error instanceof Error ? error.message : String(error)
1644
+ };
1645
+ results.push(ToolExecutionSummarySchema.parse(summary));
1646
+ this.logger.warn(`Tool ${toolCall.toolName} threw error`, {
1647
+ error: error instanceof Error ? error.message : String(error)
1648
+ });
1649
+ }
1650
+ }
1651
+ return results;
1652
+ }
1653
+ /**
1654
+ * Handle memory operations from a decision
1655
+ * Supports read and write operations with graceful degradation
1656
+ */
1657
+ async handleMemoryActions(decision, context, parentSpanId) {
1658
+ if (!this.enableMemory || !this.memory) {
1659
+ return [];
1660
+ }
1661
+ const hasReads = Array.isArray(decision.memoryReads) && decision.memoryReads.length > 0;
1662
+ const updateEntries = Object.entries(decision.memoryUpdates ?? {}).filter(
1663
+ ([key, update]) => typeof key === "string" && key.length > 0 && typeof update === "object" && update !== null && "value" in update
1664
+ );
1665
+ const hasWrites = updateEntries.length > 0;
1666
+ if (!hasReads && !hasWrites) {
1667
+ return [];
1668
+ }
1669
+ this.log("Handling memory operations", {
1670
+ reads: decision.memoryReads?.length ?? 0,
1671
+ writes: updateEntries.length
1672
+ });
1673
+ const spanParentId = parentSpanId ?? context.parentSpanId ?? void 0;
1674
+ const summaries = [];
1675
+ if (hasReads) {
1676
+ try {
1677
+ const keySet = new Set(
1678
+ decision.memoryReads.filter(
1679
+ (key) => typeof key === "string" && key.length > 0
1680
+ )
1681
+ );
1682
+ const keys = Array.from(keySet);
1683
+ if (keys.length > 0) {
1684
+ const memoryReadSpan = await this.opperClient.createSpan({
1685
+ name: "memory_read",
1686
+ input: keys,
1687
+ ...spanParentId && { parentSpanId: spanParentId }
1688
+ });
1689
+ const memoryData = await this.memory.read(keys);
1690
+ await this.opperClient.updateSpan(memoryReadSpan.id, memoryData);
1691
+ context.setMetadata("current_memory", memoryData);
1692
+ this.log(`Loaded ${Object.keys(memoryData).length} memory entries`, {
1693
+ keys
1694
+ });
1695
+ summaries.push(
1696
+ ToolExecutionSummarySchema.parse({
1697
+ toolName: "memory_read",
1698
+ success: true,
1699
+ output: { keys, data: memoryData }
1700
+ })
1701
+ );
1702
+ for (const key of keys) {
1703
+ await this.triggerHook(HookEvents.MemoryRead, {
1704
+ context,
1705
+ key,
1706
+ value: memoryData[key]
1707
+ });
1708
+ }
1709
+ }
1710
+ } catch (error) {
1711
+ await this.triggerHook(HookEvents.MemoryError, {
1712
+ context,
1713
+ operation: "read",
1714
+ error
1715
+ });
1716
+ this.logger.warn("Memory read failed", {
1717
+ error: error instanceof Error ? error.message : String(error)
1718
+ });
1719
+ summaries.push(
1720
+ ToolExecutionSummarySchema.parse({
1721
+ toolName: "memory_read",
1722
+ success: false,
1723
+ error: error instanceof Error ? error.message : String(error)
1724
+ })
1725
+ );
1726
+ }
1727
+ }
1728
+ if (hasWrites) {
1729
+ try {
1730
+ const memoryWriteSpan = await this.opperClient.createSpan({
1731
+ name: "memory_write",
1732
+ input: updateEntries.map(([key]) => key),
1733
+ ...spanParentId && { parentSpanId: spanParentId }
1734
+ });
1735
+ for (const [key, update] of updateEntries) {
1736
+ const castUpdate = update;
1737
+ await this.memory.write(
1738
+ key,
1739
+ castUpdate.value,
1740
+ castUpdate.description ?? key,
1741
+ castUpdate.metadata
1742
+ );
1743
+ await this.triggerHook(HookEvents.MemoryWrite, {
1744
+ context,
1745
+ key,
1746
+ value: castUpdate.value
1747
+ });
1748
+ }
1749
+ await this.opperClient.updateSpan(
1750
+ memoryWriteSpan.id,
1751
+ `Successfully wrote ${updateEntries.length} keys`
1752
+ );
1753
+ this.log(`Wrote ${updateEntries.length} memory entries`);
1754
+ summaries.push(
1755
+ ToolExecutionSummarySchema.parse({
1756
+ toolName: "memory_write",
1757
+ success: true,
1758
+ output: {
1759
+ keys: updateEntries.map(([key]) => key)
1760
+ }
1761
+ })
1762
+ );
1763
+ } catch (error) {
1764
+ await this.triggerHook(HookEvents.MemoryError, {
1765
+ context,
1766
+ operation: "write",
1767
+ error
1768
+ });
1769
+ this.logger.warn("Memory write failed", {
1770
+ error: error instanceof Error ? error.message : String(error)
1771
+ });
1772
+ summaries.push(
1773
+ ToolExecutionSummarySchema.parse({
1774
+ toolName: "memory_write",
1775
+ success: false,
1776
+ error: error instanceof Error ? error.message : String(error)
1777
+ })
1778
+ );
1779
+ }
1780
+ }
1781
+ return summaries;
1782
+ }
1783
+ /**
1784
+ * Generate final result based on execution history
1785
+ */
1786
+ async generateFinalResult(input, context) {
1787
+ this.log("Generating final result", { totalIterations: context.iteration });
1788
+ const finalContext = {
1789
+ goal: this.serializeInput(input),
1790
+ instructions: this.instructions || "No specific instructions.",
1791
+ execution_history: context.executionHistory.map((cycle) => {
1792
+ const results = Array.isArray(cycle.results) ? cycle.results : [];
1793
+ return {
1794
+ iteration: cycle.iteration,
1795
+ actions_taken: results.map(
1796
+ (r) => r.toolName
1797
+ ),
1798
+ results: results.filter((r) => r.success).map((r) => {
1799
+ const result = r;
1800
+ let actualOutput = result.output;
1801
+ if (isToolSuccessResult(actualOutput)) {
1802
+ actualOutput = actualOutput.output;
1803
+ }
1804
+ return {
1805
+ tool: result.toolName,
1806
+ // Serialize result properly - use JSON for objects, String for primitives
1807
+ result: typeof actualOutput === "object" ? JSON.stringify(actualOutput) : String(actualOutput)
1808
+ };
1809
+ })
1810
+ };
1811
+ }),
1812
+ total_iterations: context.iteration
1813
+ };
1814
+ const instructions = `Generate the final result based on the execution history.
1815
+ Follow any instructions provided for formatting and style.`;
1816
+ try {
1817
+ const callOptions = {
1818
+ name: "generate_final_result",
1819
+ instructions,
1820
+ input: finalContext,
1821
+ model: this.model
1822
+ };
1823
+ if (context.parentSpanId) {
1824
+ callOptions.parentSpanId = context.parentSpanId;
1825
+ }
1826
+ if (this.outputSchema) {
1827
+ callOptions.outputSchema = this.outputSchema;
1828
+ }
1829
+ const response = await this.opperClient.call(callOptions);
1830
+ context.updateUsage({
1831
+ requests: 1,
1832
+ inputTokens: response.usage.inputTokens,
1833
+ outputTokens: response.usage.outputTokens,
1834
+ totalTokens: response.usage.totalTokens,
1835
+ cost: response.usage.cost
1836
+ });
1837
+ if (this.outputSchema) {
1838
+ const parsed = this.outputSchema.parse(response.jsonPayload);
1839
+ this.log("Final result generated (schema-validated)");
1840
+ return parsed;
1841
+ }
1842
+ this.log("Final result generated");
1843
+ return response.message;
1844
+ } catch (error) {
1845
+ this.logger.error("Failed to generate final result", error);
1846
+ throw new Error(
1847
+ `Failed to generate final result: ${error instanceof Error ? error.message : String(error)}`
1848
+ );
1849
+ }
1850
+ }
1851
+ /**
1852
+ * Log helper
1853
+ */
1854
+ log(message, data) {
1855
+ if (this.verbose) {
1856
+ this.logger.info(`[${this.name}] ${message}`, data);
1857
+ }
1858
+ }
1859
+ };
1860
+ var DEFAULT_CLIENT_INFO = {
1861
+ name: "opper-agent-ts-mcp-client",
1862
+ version: "0.0.0"
1863
+ };
1864
+ var MCPClient = class _MCPClient {
1865
+ config;
1866
+ client;
1867
+ transport;
1868
+ connected;
1869
+ toolCache;
1870
+ constructor(config, options = {}) {
1871
+ this.config = config;
1872
+ this.client = new index_js.Client(options.clientInfo ?? DEFAULT_CLIENT_INFO, {
1873
+ enforceStrictCapabilities: false
1874
+ });
1875
+ this.transport = null;
1876
+ this.connected = false;
1877
+ this.toolCache = null;
1878
+ }
1879
+ static fromConfig(config, options) {
1880
+ return new _MCPClient(config, options);
1881
+ }
1882
+ async connect() {
1883
+ if (this.connected) {
1884
+ return;
1885
+ }
1886
+ const transport = this.createTransport();
1887
+ this.transport = transport;
1888
+ try {
1889
+ await this.client.connect(transport);
1890
+ this.connected = true;
1891
+ } catch (error) {
1892
+ await transport.close().catch(() => {
1893
+ });
1894
+ this.transport = null;
1895
+ throw error;
1896
+ }
1897
+ }
1898
+ async disconnect() {
1899
+ if (!this.connected) {
1900
+ return;
1901
+ }
1902
+ await this.client.close().catch(() => {
1903
+ });
1904
+ await this.transport?.close().catch(() => {
1905
+ });
1906
+ this.transport = null;
1907
+ this.connected = false;
1908
+ this.toolCache = null;
1909
+ }
1910
+ async listTools() {
1911
+ const session = this.ensureConnected();
1912
+ if (this.toolCache) {
1913
+ return this.toolCache;
1914
+ }
1915
+ const response = await session.listTools({});
1916
+ const tools = response.tools?.map((tool2) => {
1917
+ const parameters = tool2.inputSchema ?? {};
1918
+ const outputSchema = tool2["outputSchema"];
1919
+ const normalized = {
1920
+ name: tool2.name,
1921
+ description: tool2.description ?? "",
1922
+ parameters
1923
+ };
1924
+ if (outputSchema) {
1925
+ normalized.outputSchema = outputSchema;
1926
+ }
1927
+ return normalized;
1928
+ }) ?? [];
1929
+ this.toolCache = tools;
1930
+ return tools;
1931
+ }
1932
+ async callTool(toolName, args) {
1933
+ const session = this.ensureConnected();
1934
+ const response = await session.callTool({
1935
+ name: toolName,
1936
+ arguments: args
1937
+ });
1938
+ return response;
1939
+ }
1940
+ get isConnected() {
1941
+ return this.connected;
1942
+ }
1943
+ ensureConnected() {
1944
+ if (!this.connected) {
1945
+ throw new Error(`MCP server "${this.config.name}" is not connected`);
1946
+ }
1947
+ return this.client;
1948
+ }
1949
+ createTransport() {
1950
+ if (this.config.transport === "stdio") {
1951
+ const stdioOptions = {
1952
+ command: this.config.command
1953
+ };
1954
+ if (this.config.args.length > 0) {
1955
+ stdioOptions.args = this.config.args;
1956
+ }
1957
+ if (Object.keys(this.config.env).length > 0) {
1958
+ stdioOptions.env = this.config.env;
1959
+ }
1960
+ if (this.config.cwd) {
1961
+ stdioOptions.cwd = this.config.cwd;
1962
+ }
1963
+ if (this.config.stderr) {
1964
+ stdioOptions.stderr = this.config.stderr;
1965
+ }
1966
+ return new stdio_js.StdioClientTransport(stdioOptions);
1967
+ }
1968
+ if (this.config.transport === "streamable-http") {
1969
+ const options2 = {};
1970
+ const headers2 = this.config.headers;
1971
+ if (headers2 && Object.keys(headers2).length > 0) {
1972
+ options2.requestInit = { headers: headers2 };
1973
+ }
1974
+ if (this.config.sessionId) {
1975
+ options2.sessionId = this.config.sessionId;
1976
+ }
1977
+ return new streamableHttp_js.StreamableHTTPClientTransport(
1978
+ new URL(this.config.url),
1979
+ options2
1980
+ );
1981
+ }
1982
+ const headers = this.config.headers ?? {};
1983
+ const headerEntries = Object.entries(headers);
1984
+ const options = {};
1985
+ if (headerEntries.length > 0) {
1986
+ options.eventSourceInit = {
1987
+ fetch: async (url, init) => {
1988
+ const mergedHeaders = new Headers(init?.headers ?? {});
1989
+ for (const [key, value] of headerEntries) {
1990
+ mergedHeaders.set(key, value);
1991
+ }
1992
+ if (!mergedHeaders.has("Accept")) {
1993
+ mergedHeaders.set("Accept", "text/event-stream");
1994
+ }
1995
+ return fetch(url, {
1996
+ ...init,
1997
+ headers: mergedHeaders
1998
+ });
1999
+ }
2000
+ };
2001
+ }
2002
+ if (headerEntries.length > 0 || this.config.method === "POST") {
2003
+ options.requestInit = {
2004
+ ...this.config.method ? { method: this.config.method } : {},
2005
+ ...headerEntries.length > 0 ? { headers } : {}
2006
+ };
2007
+ }
2008
+ return new sse_js.SSEClientTransport(new URL(this.config.url), options);
2009
+ }
2010
+ };
2011
+ var MCPTransportSchema = zod.z.enum(["stdio", "http-sse", "streamable-http"]);
2012
+ var MCPBaseConfigSchema = zod.z.object({
2013
+ name: zod.z.string().min(1, "name is required"),
2014
+ transport: MCPTransportSchema,
2015
+ timeout: zod.z.number().positive("timeout must be positive").default(30),
2016
+ metadata: zod.z.record(zod.z.string(), zod.z.unknown()).default({})
2017
+ });
2018
+ var MCPStdIoConfigSchema = MCPBaseConfigSchema.extend({
2019
+ transport: zod.z.literal("stdio"),
2020
+ command: zod.z.string().min(1, "command is required for stdio transport"),
2021
+ args: zod.z.array(zod.z.string()).default([]),
2022
+ env: zod.z.record(zod.z.string(), zod.z.string()).default({}),
2023
+ cwd: zod.z.string().optional(),
2024
+ stderr: zod.z.union([zod.z.literal("inherit"), zod.z.literal("pipe"), zod.z.literal("ignore")]).optional()
2025
+ });
2026
+ var MCPHttpSseConfigSchema = MCPBaseConfigSchema.extend({
2027
+ transport: zod.z.literal("http-sse"),
2028
+ url: zod.z.string().url("url must be a valid HTTP(S) URL"),
2029
+ headers: zod.z.record(zod.z.string(), zod.z.string()).default({}),
2030
+ method: zod.z.enum(["GET", "POST"]).default("GET")
2031
+ });
2032
+ var MCPStreamableHttpConfigSchema = MCPBaseConfigSchema.extend({
2033
+ transport: zod.z.literal("streamable-http"),
2034
+ url: zod.z.string().url("url must be a valid HTTP(S) URL"),
2035
+ headers: zod.z.record(zod.z.string(), zod.z.string()).default({}),
2036
+ sessionId: zod.z.string().optional()
2037
+ });
2038
+ var MCPConfigVariants = zod.z.discriminatedUnion("transport", [
2039
+ MCPStdIoConfigSchema,
2040
+ MCPHttpSseConfigSchema,
2041
+ MCPStreamableHttpConfigSchema
2042
+ ]);
2043
+ var MCPServerConfigSchema = MCPConfigVariants.superRefine(
2044
+ (value, ctx) => {
2045
+ if (value.transport === "http-sse" || value.transport === "streamable-http") {
2046
+ if (!value.url) {
2047
+ ctx.addIssue({
2048
+ code: zod.z.ZodIssueCode.custom,
2049
+ message: `url is required for ${value.transport} transport`,
2050
+ path: ["url"]
2051
+ });
2052
+ } else if (!value.url.startsWith("http://") && !value.url.startsWith("https://")) {
2053
+ ctx.addIssue({
2054
+ code: zod.z.ZodIssueCode.custom,
2055
+ message: "url must start with http:// or https://",
2056
+ path: ["url"]
2057
+ });
2058
+ }
2059
+ }
2060
+ }
2061
+ );
2062
+ var MCPconfig = (config) => MCPServerConfigSchema.parse(config);
2063
+ var createMCPServerConfig = MCPconfig;
2064
+
2065
+ // src/mcp/provider.ts
2066
+ init_tool();
2067
+ var isRecord = (value) => typeof value === "object" && value !== null;
2068
+ var MCPToolProvider = class {
2069
+ configs;
2070
+ namePrefix;
2071
+ clientOptions;
2072
+ clientFactory;
2073
+ logger;
2074
+ clients;
2075
+ constructor(configs, options = {}) {
2076
+ if (configs.length === 0) {
2077
+ throw new Error(
2078
+ "MCPToolProvider requires at least one server configuration"
2079
+ );
2080
+ }
2081
+ this.configs = configs;
2082
+ this.namePrefix = options.namePrefix ?? void 0;
2083
+ this.clientOptions = options.clientOptions ?? void 0;
2084
+ this.clientFactory = options.clientFactory ?? ((config, factoryOptions) => MCPClient.fromConfig(config, factoryOptions));
2085
+ this.logger = options.logger ?? {
2086
+ warn: (message, context) => console.warn(`[MCPToolProvider] ${message}`, context),
2087
+ error: (message, context) => console.error(`[MCPToolProvider] ${message}`, context),
2088
+ debug: () => {
2089
+ }
2090
+ };
2091
+ this.clients = /* @__PURE__ */ new Map();
2092
+ }
2093
+ async setup(agent) {
2094
+ const tools = [];
2095
+ for (const config of this.configs) {
2096
+ let client = null;
2097
+ try {
2098
+ client = this.clientFactory(config, this.clientOptions);
2099
+ await client.connect();
2100
+ this.clients.set(config.name, client);
2101
+ const mcpTools = await client.listTools();
2102
+ for (const mcpTool of mcpTools) {
2103
+ tools.push(this.wrapTool(config, client, mcpTool));
2104
+ }
2105
+ this.logger?.debug?.("Registered MCP server tools", {
2106
+ server: config.name,
2107
+ toolCount: mcpTools.length
2108
+ });
2109
+ } catch (error) {
2110
+ this.logger?.warn?.("Failed to initialize MCP server", {
2111
+ server: config.name,
2112
+ error: error instanceof Error ? error.message : String(error)
2113
+ });
2114
+ if (client) {
2115
+ await client.disconnect().catch(() => {
2116
+ });
2117
+ this.clients.delete(config.name);
2118
+ }
2119
+ }
2120
+ }
2121
+ return tools;
2122
+ }
2123
+ async teardown() {
2124
+ const disconnects = Array.from(this.clients.entries()).map(
2125
+ async ([serverName, client]) => {
2126
+ try {
2127
+ await client.disconnect();
2128
+ this.logger?.debug?.("Disconnected MCP server", {
2129
+ server: serverName
2130
+ });
2131
+ } catch (error) {
2132
+ this.logger?.warn?.("Error disconnecting MCP server", {
2133
+ server: serverName,
2134
+ error: error instanceof Error ? error.message : String(error)
2135
+ });
2136
+ } finally {
2137
+ this.clients.delete(serverName);
2138
+ }
2139
+ }
2140
+ );
2141
+ await Promise.allSettled(disconnects);
2142
+ }
2143
+ wrapTool(config, client, mcpTool) {
2144
+ const prefix = this.namePrefix ?? config.name;
2145
+ const toolName = `${prefix}:${mcpTool.name}`;
2146
+ return {
2147
+ name: toolName,
2148
+ description: mcpTool.description,
2149
+ metadata: {
2150
+ provider: "mcp",
2151
+ server: config.name,
2152
+ originalToolName: mcpTool.name,
2153
+ parameters: mcpTool.parameters,
2154
+ outputSchema: mcpTool.outputSchema
2155
+ },
2156
+ execute: async (input, context) => {
2157
+ const startedAt = Date.now();
2158
+ const args = isRecord(input) ? input : input === void 0 ? {} : { value: input };
2159
+ try {
2160
+ const result = await client.callTool(mcpTool.name, args);
2161
+ return exports.ToolResultFactory.success(toolName, result, {
2162
+ metadata: {
2163
+ provider: "mcp",
2164
+ server: config.name,
2165
+ tool: mcpTool.name
2166
+ },
2167
+ startedAt,
2168
+ finishedAt: Date.now()
2169
+ });
2170
+ } catch (error) {
2171
+ const failure = error instanceof Error ? error : new Error(String(error));
2172
+ return exports.ToolResultFactory.failure(toolName, failure, {
2173
+ metadata: {
2174
+ provider: "mcp",
2175
+ server: config.name,
2176
+ tool: mcpTool.name
2177
+ },
2178
+ startedAt,
2179
+ finishedAt: Date.now()
2180
+ });
2181
+ }
2182
+ }
2183
+ };
2184
+ }
2185
+ };
2186
+ var mcp = (...configs) => {
2187
+ if (configs.length === 0) {
2188
+ throw new Error("At least one MCP server configuration is required");
2189
+ }
2190
+ const parsedConfigs = configs.map(
2191
+ (config) => MCPServerConfigSchema.parse(config)
2192
+ );
2193
+ return new MCPToolProvider(parsedConfigs);
2194
+ };
2195
+
2196
+ // src/utils/tool-decorators.ts
2197
+ init_tool();
2198
+ var reflectWithMetadata = Reflect;
2199
+ var ReflectMetadata = {
2200
+ define: (metadataKey, metadataValue, target, propertyKey) => {
2201
+ if (typeof reflectWithMetadata.defineMetadata === "function") {
2202
+ reflectWithMetadata.defineMetadata(
2203
+ metadataKey,
2204
+ metadataValue,
2205
+ target,
2206
+ propertyKey
2207
+ );
2208
+ }
2209
+ },
2210
+ get: (metadataKey, target, propertyKey) => {
2211
+ if (typeof reflectWithMetadata.getMetadata === "function") {
2212
+ return reflectWithMetadata.getMetadata(metadataKey, target, propertyKey);
2213
+ }
2214
+ return void 0;
2215
+ }
2216
+ };
2217
+ var TOOL_METADATA_KEY = "opper:tool";
2218
+ var toolMetadataStore = /* @__PURE__ */ new WeakMap();
2219
+ function setToolMetadata(target, propertyKey, metadata) {
2220
+ ReflectMetadata.define(TOOL_METADATA_KEY, metadata, target, propertyKey);
2221
+ let metadataForTarget = toolMetadataStore.get(target);
2222
+ if (!metadataForTarget) {
2223
+ metadataForTarget = /* @__PURE__ */ new Map();
2224
+ toolMetadataStore.set(target, metadataForTarget);
2225
+ }
2226
+ metadataForTarget.set(
2227
+ propertyKey,
2228
+ metadata
2229
+ );
2230
+ }
2231
+ function getToolMetadata(target, propertyKey) {
2232
+ const metadata = ReflectMetadata.get(
2233
+ TOOL_METADATA_KEY,
2234
+ target,
2235
+ propertyKey
2236
+ );
2237
+ if (metadata) {
2238
+ return metadata;
2239
+ }
2240
+ const metadataForTarget = toolMetadataStore.get(target);
2241
+ return metadataForTarget?.get(propertyKey);
2242
+ }
2243
+ function isStage3DecoratorContext(value) {
2244
+ return typeof value === "object" && value !== null && "kind" in value;
2245
+ }
2246
+ function createExecuteWrapper(toolName, method, options, callTargetRef) {
2247
+ return async (input, context) => {
2248
+ const startedAt = Date.now();
2249
+ try {
2250
+ if (options.schema) {
2251
+ options.schema.parse(input);
2252
+ }
2253
+ const invocationTarget = callTargetRef.current;
2254
+ const result = await Promise.resolve(
2255
+ method.call(invocationTarget, input, context)
2256
+ );
2257
+ return exports.ToolResultFactory.success(toolName, result, {
2258
+ startedAt,
2259
+ finishedAt: Date.now(),
2260
+ ...options.metadata && { metadata: options.metadata }
2261
+ });
2262
+ } catch (error) {
2263
+ return exports.ToolResultFactory.failure(
2264
+ toolName,
2265
+ error instanceof Error ? error : new Error(String(error)),
2266
+ {
2267
+ startedAt,
2268
+ finishedAt: Date.now(),
2269
+ ...options.metadata && { metadata: options.metadata }
2270
+ }
2271
+ );
2272
+ }
2273
+ };
2274
+ }
2275
+ function normalizePropertyKey(propertyKey) {
2276
+ return typeof propertyKey === "symbol" ? propertyKey.description ?? propertyKey.toString() : propertyKey;
2277
+ }
2278
+ function createToolDefinition(options, methodName, propertyKey, method, callTargetRef) {
2279
+ const name = options.name ?? methodName;
2280
+ const description = options.description ?? extractJSDocDescription(method) ?? `Tool: ${normalizePropertyKey(propertyKey)}`;
2281
+ return {
2282
+ name,
2283
+ description,
2284
+ ...options.schema && { schema: options.schema },
2285
+ ...options.timeoutMs !== void 0 && { timeoutMs: options.timeoutMs },
2286
+ metadata: {
2287
+ ...options.metadata,
2288
+ isDecorated: true,
2289
+ propertyKey: normalizePropertyKey(propertyKey)
2290
+ },
2291
+ execute: createExecuteWrapper(name, method, options, callTargetRef)
2292
+ };
2293
+ }
2294
+ function createFunctionTool(fn, options = {}) {
2295
+ const name = options.name ?? (fn.name || "anonymous_tool");
2296
+ const description = options.description ?? extractJSDocDescription(fn) ?? `Tool: ${name}`;
2297
+ const tool2 = {
2298
+ name,
2299
+ description,
2300
+ ...options.schema && { schema: options.schema },
2301
+ ...options.timeoutMs !== void 0 && { timeoutMs: options.timeoutMs },
2302
+ metadata: {
2303
+ ...options.metadata,
2304
+ isFunction: true,
2305
+ functionName: fn.name
2306
+ },
2307
+ execute: async (input, context) => {
2308
+ const startedAt = Date.now();
2309
+ try {
2310
+ if (options.schema) {
2311
+ options.schema.parse(input);
2312
+ }
2313
+ let result;
2314
+ if (options.timeoutMs !== void 0) {
2315
+ result = await executeWithTimeout(
2316
+ fn(input, context),
2317
+ options.timeoutMs,
2318
+ name
2319
+ );
2320
+ } else {
2321
+ result = await Promise.resolve(fn(input, context));
2322
+ }
2323
+ return exports.ToolResultFactory.success(name, result, {
2324
+ startedAt,
2325
+ finishedAt: Date.now(),
2326
+ ...options.metadata && { metadata: options.metadata }
2327
+ });
2328
+ } catch (error) {
2329
+ return exports.ToolResultFactory.failure(
2330
+ name,
2331
+ error instanceof Error ? error : new Error(String(error)),
2332
+ {
2333
+ startedAt,
2334
+ finishedAt: Date.now(),
2335
+ ...options.metadata && { metadata: options.metadata }
2336
+ }
2337
+ );
2338
+ }
2339
+ }
2340
+ };
2341
+ return tool2;
2342
+ }
2343
+ function tool(options) {
2344
+ const decoratorOptions = options ?? {};
2345
+ function decorator(...decoratorArgs) {
2346
+ if (decoratorArgs.length === 2 && isStage3DecoratorContext(decoratorArgs[1])) {
2347
+ const [method, context] = decoratorArgs;
2348
+ if (context.kind !== "method") {
2349
+ throw new Error("@tool can only be applied to methods.");
2350
+ }
2351
+ if (context.name === void 0) {
2352
+ throw new Error("@tool requires a named method to attach metadata.");
2353
+ }
2354
+ const propertyKey2 = context.name;
2355
+ const inferredName = typeof propertyKey2 === "string" && propertyKey2.length > 0 ? propertyKey2 : method.name || "anonymous_tool";
2356
+ const callTargetRef2 = {};
2357
+ const toolMetadata2 = createToolDefinition(
2358
+ decoratorOptions,
2359
+ inferredName,
2360
+ propertyKey2,
2361
+ method,
2362
+ callTargetRef2
2363
+ );
2364
+ const registerMetadata = (target2) => {
2365
+ callTargetRef2.current = target2;
2366
+ setToolMetadata(target2, propertyKey2, toolMetadata2);
2367
+ };
2368
+ if (typeof context.addInitializer === "function") {
2369
+ context.addInitializer(function() {
2370
+ const target2 = context.static ? this : Object.getPrototypeOf(this);
2371
+ if (target2) {
2372
+ registerMetadata(target2);
2373
+ }
2374
+ });
2375
+ }
2376
+ return;
2377
+ }
2378
+ const [target, propertyKey, descriptor] = decoratorArgs;
2379
+ const resolvedDescriptor = descriptor ?? Object.getOwnPropertyDescriptor(target, propertyKey) ?? (() => {
2380
+ const value = target[propertyKey];
2381
+ if (typeof value === "function") {
2382
+ return { value };
2383
+ }
2384
+ return void 0;
2385
+ })();
2386
+ if (!resolvedDescriptor || typeof resolvedDescriptor.value !== "function") {
2387
+ throw new Error(
2388
+ `@tool can only be applied to methods, not ${typeof resolvedDescriptor?.value}`
2389
+ );
2390
+ }
2391
+ const originalMethod = resolvedDescriptor.value;
2392
+ const callTargetRef = { current: target };
2393
+ const toolMetadata = createToolDefinition(
2394
+ decoratorOptions,
2395
+ normalizePropertyKey(propertyKey),
2396
+ propertyKey,
2397
+ originalMethod,
2398
+ callTargetRef
2399
+ );
2400
+ setToolMetadata(target, propertyKey, toolMetadata);
2401
+ return resolvedDescriptor;
2402
+ }
2403
+ return decorator;
2404
+ }
2405
+ function extractTools(instance) {
2406
+ const tools = [];
2407
+ const prototype = Object.getPrototypeOf(instance);
2408
+ const propertyKeys = [
2409
+ ...Object.getOwnPropertyNames(prototype),
2410
+ ...Object.getOwnPropertySymbols(prototype)
2411
+ ];
2412
+ for (const propertyKey of propertyKeys) {
2413
+ if (propertyKey === "constructor") continue;
2414
+ const toolMetadata = getToolMetadata(prototype, propertyKey);
2415
+ if (toolMetadata) {
2416
+ const instanceMethod = instance[propertyKey];
2417
+ if (typeof instanceMethod !== "function") {
2418
+ continue;
2419
+ }
2420
+ const tool2 = {
2421
+ ...toolMetadata,
2422
+ execute: async (input, context) => {
2423
+ const startedAt = Date.now();
2424
+ try {
2425
+ if (toolMetadata.schema) {
2426
+ toolMetadata.schema.parse(input);
2427
+ }
2428
+ const result = await Promise.resolve(
2429
+ instanceMethod.call(instance, input, context)
2430
+ );
2431
+ return exports.ToolResultFactory.success(toolMetadata.name, result, {
2432
+ startedAt,
2433
+ finishedAt: Date.now(),
2434
+ ...toolMetadata.metadata && { metadata: toolMetadata.metadata }
2435
+ });
2436
+ } catch (error) {
2437
+ return exports.ToolResultFactory.failure(
2438
+ toolMetadata.name,
2439
+ error instanceof Error ? error : new Error(String(error)),
2440
+ {
2441
+ startedAt,
2442
+ finishedAt: Date.now(),
2443
+ ...toolMetadata.metadata && {
2444
+ metadata: toolMetadata.metadata
2445
+ }
2446
+ }
2447
+ );
2448
+ }
2449
+ }
2450
+ };
2451
+ tools.push(tool2);
2452
+ }
2453
+ }
2454
+ return tools;
2455
+ }
2456
+ async function executeWithTimeout(promise, timeoutMs, toolName) {
2457
+ return Promise.race([
2458
+ Promise.resolve(promise),
2459
+ new Promise((_, reject) => {
2460
+ setTimeout(() => {
2461
+ reject(new Error(`Tool "${toolName}" timed out after ${timeoutMs}ms`));
2462
+ }, timeoutMs);
2463
+ })
2464
+ ]);
2465
+ }
2466
+ function extractJSDocDescription(fn) {
2467
+ const source = fn.toString();
2468
+ const match = /\/\*\*\s*\n\s*\*\s*(.+?)\s*\n/.exec(source);
2469
+ return match?.[1];
2470
+ }
2471
+
2472
+ // src/utils/tool-runner.ts
2473
+ init_tool();
2474
+ var ToolRunner = class {
2475
+ /**
2476
+ * Execute a tool with the given input and context
2477
+ *
2478
+ * @param tool - Tool to execute
2479
+ * @param input - Input data
2480
+ * @param context - Agent execution context
2481
+ * @param options - Execution options
2482
+ * @returns Tool execution result
2483
+ */
2484
+ static async execute(tool2, input, context, options = {}) {
2485
+ if (options.signal?.aborted) {
2486
+ return exports.ToolResultFactory.failure(
2487
+ tool2.name,
2488
+ new Error(`Tool "${tool2.name}" execution was aborted`)
2489
+ );
2490
+ }
2491
+ if (tool2.schema) {
2492
+ const validation = tool2.schema.safeParse(input);
2493
+ if (!validation.success) {
2494
+ return exports.ToolResultFactory.failure(
2495
+ tool2.name,
2496
+ new Error(
2497
+ `Invalid input for tool "${tool2.name}": ${validation.error.message}`
2498
+ )
2499
+ );
2500
+ }
2501
+ }
2502
+ const executionContext = {
2503
+ agentContext: context,
2504
+ ...options.signal && { signal: options.signal },
2505
+ metadata: options.metadata ?? {}
2506
+ };
2507
+ try {
2508
+ const timeoutMs = options.timeoutMs ?? tool2.timeoutMs;
2509
+ let result;
2510
+ if (timeoutMs !== void 0) {
2511
+ result = await this.executeWithTimeout(
2512
+ Promise.resolve(tool2.execute(input, executionContext)),
2513
+ timeoutMs,
2514
+ tool2.name
2515
+ );
2516
+ } else {
2517
+ result = await Promise.resolve(tool2.execute(input, executionContext));
2518
+ }
2519
+ return result;
2520
+ } catch (error) {
2521
+ return exports.ToolResultFactory.failure(
2522
+ tool2.name,
2523
+ error instanceof Error ? error : new Error(String(error))
2524
+ );
2525
+ }
2526
+ }
2527
+ /**
2528
+ * Execute multiple tools in parallel
2529
+ *
2530
+ * @param executions - Array of tool execution tuples [tool, input, context, options?]
2531
+ * @returns Array of results in same order as input
2532
+ */
2533
+ static async executeParallel(executions) {
2534
+ return Promise.all(
2535
+ executions.map(
2536
+ ([tool2, input, context, options]) => this.execute(tool2, input, context, options)
2537
+ )
2538
+ );
2539
+ }
2540
+ /**
2541
+ * Execute multiple tools sequentially, stopping on first failure
2542
+ *
2543
+ * @param executions - Array of tool execution tuples
2544
+ * @returns Array of results up to first failure (inclusive)
2545
+ */
2546
+ static async executeSequential(executions) {
2547
+ const results = [];
2548
+ for (const [tool2, input, context, options] of executions) {
2549
+ const result = await this.execute(tool2, input, context, options);
2550
+ results.push(result);
2551
+ if (!result.success) {
2552
+ break;
2553
+ }
2554
+ }
2555
+ return results;
2556
+ }
2557
+ /**
2558
+ * Execute a tool with timeout
2559
+ *
2560
+ * @param promise - Tool execution promise
2561
+ * @param timeoutMs - Timeout in milliseconds
2562
+ * @param toolName - Tool name for error messages
2563
+ * @returns Result or rejects with timeout error
2564
+ */
2565
+ static async executeWithTimeout(promise, timeoutMs, toolName) {
2566
+ return Promise.race([
2567
+ promise,
2568
+ new Promise((_, reject) => {
2569
+ setTimeout(() => {
2570
+ reject(
2571
+ new Error(`Tool "${toolName}" timed out after ${timeoutMs}ms`)
2572
+ );
2573
+ }, timeoutMs);
2574
+ })
2575
+ ]);
2576
+ }
2577
+ /**
2578
+ * Validate tool input without executing
2579
+ *
2580
+ * @param tool - Tool to validate input for
2581
+ * @param input - Input to validate
2582
+ * @returns true if valid, Error if invalid
2583
+ */
2584
+ static validate(tool2, input) {
2585
+ if (!tool2.schema) {
2586
+ return true;
2587
+ }
2588
+ const validation = tool2.schema.safeParse(input);
2589
+ if (!validation.success) {
2590
+ return new Error(
2591
+ `Invalid input for tool "${tool2.name}": ${validation.error.message}`
2592
+ );
2593
+ }
2594
+ return true;
2595
+ }
2596
+ /**
2597
+ * Check if a result indicates success
2598
+ *
2599
+ * @param result - Tool result to check
2600
+ * @returns true if success, false if failure
2601
+ */
2602
+ static isSuccess(result) {
2603
+ return result.success === true;
2604
+ }
2605
+ /**
2606
+ * Check if a result indicates failure
2607
+ *
2608
+ * @param result - Tool result to check
2609
+ * @returns true if failure, false if success
2610
+ */
2611
+ static isFailure(result) {
2612
+ return result.success === false;
2613
+ }
2614
+ };
2615
+
2616
+ exports.Agent = Agent;
2617
+ exports.AgentDecisionSchema = AgentDecisionSchema;
2618
+ exports.BaseAgent = BaseAgent;
2619
+ exports.ConsoleLogger = ConsoleLogger;
2620
+ exports.DEFAULT_MODEL = DEFAULT_MODEL;
2621
+ exports.DEFAULT_RETRY_CONFIG = DEFAULT_RETRY_CONFIG;
2622
+ exports.HookEvents = HookEvents;
2623
+ exports.HookManager = HookManager;
2624
+ exports.InMemoryStore = InMemoryStore;
2625
+ exports.LogLevel = LogLevel;
2626
+ exports.MCPClient = MCPClient;
2627
+ exports.MCPServerConfigSchema = MCPServerConfigSchema;
2628
+ exports.MCPToolProvider = MCPToolProvider;
2629
+ exports.MCPconfig = MCPconfig;
2630
+ exports.MemoryEntryMetadataSchema = MemoryEntryMetadataSchema;
2631
+ exports.MemoryEntrySchema = MemoryEntrySchema;
2632
+ exports.MemoryUpdateSchema = MemoryUpdateSchema;
2633
+ exports.OpperClient = OpperClient;
2634
+ exports.SchemaValidationError = SchemaValidationError;
2635
+ exports.SilentLogger = SilentLogger;
2636
+ exports.ThoughtSchema = ThoughtSchema;
2637
+ exports.ToolCallSchema = ToolCallSchema;
2638
+ exports.ToolExecutionSummarySchema = ToolExecutionSummarySchema;
2639
+ exports.ToolRunner = ToolRunner;
2640
+ exports.createFunctionTool = createFunctionTool;
2641
+ exports.createHookManager = createHookManager;
2642
+ exports.createInMemoryStore = createInMemoryStore;
2643
+ exports.createMCPServerConfig = createMCPServerConfig;
2644
+ exports.createOpperClient = createOpperClient;
2645
+ exports.extractTools = extractTools;
2646
+ exports.getDefaultLogger = getDefaultLogger;
2647
+ exports.getSchemaDefault = getSchemaDefault;
2648
+ exports.isSchemaValid = isSchemaValid;
2649
+ exports.mcp = mcp;
2650
+ exports.mergeSchemaDefaults = mergeSchemaDefaults;
2651
+ exports.schemaToJson = schemaToJson;
2652
+ exports.setDefaultLogger = setDefaultLogger;
2653
+ exports.tool = tool;
2654
+ exports.validateSchema = validateSchema;
2655
+ //# sourceMappingURL=index.cjs.map
2656
+ //# sourceMappingURL=index.cjs.map