veryfront 0.0.4 → 0.0.6

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/ai/dev.js ADDED
@@ -0,0 +1,839 @@
1
+ // src/ai/dev/testing/agent-tester.ts
2
+ async function testAgent(agent, testCases) {
3
+ const suite = {
4
+ name: agent.id,
5
+ results: [],
6
+ passed: true,
7
+ totalTime: 0
8
+ };
9
+ const suiteStartTime = Date.now();
10
+ for (const testCase of testCases) {
11
+ const result = await runTestCase(agent, testCase);
12
+ suite.results.push(result);
13
+ if (!result.passed) {
14
+ suite.passed = false;
15
+ }
16
+ }
17
+ suite.totalTime = Date.now() - suiteStartTime;
18
+ return suite;
19
+ }
20
+ async function runTestCase(agent, testCase) {
21
+ const startTime = Date.now();
22
+ try {
23
+ const timeout = testCase.timeout || 3e4;
24
+ const timeoutPromise = new Promise((_, reject) => {
25
+ setTimeout(() => reject(new Error("Test timeout")), timeout);
26
+ });
27
+ const responsePromise = agent.generate({
28
+ input: testCase.input
29
+ });
30
+ const response = await Promise.race([responsePromise, timeoutPromise]);
31
+ const executionTime = Date.now() - startTime;
32
+ const toolCalls = response.toolCalls.map((tc) => tc.name);
33
+ let passed = true;
34
+ let error;
35
+ if (testCase.expected) {
36
+ if (testCase.expected instanceof RegExp) {
37
+ passed = testCase.expected.test(response.text);
38
+ if (!passed) {
39
+ error = `Output "${response.text}" does not match pattern ${testCase.expected}`;
40
+ }
41
+ } else {
42
+ passed = response.text.includes(testCase.expected);
43
+ if (!passed) {
44
+ error = `Output does not contain expected text: "${testCase.expected}"`;
45
+ }
46
+ }
47
+ }
48
+ if (passed && testCase.expectToolCalls) {
49
+ const expectedTools = testCase.expectToolCalls;
50
+ const missingTools = expectedTools.filter((t) => !toolCalls.includes(t));
51
+ if (missingTools.length > 0) {
52
+ passed = false;
53
+ error = `Expected tool calls not found: ${missingTools.join(", ")}`;
54
+ }
55
+ }
56
+ if (passed && testCase.validate) {
57
+ try {
58
+ passed = await testCase.validate(response);
59
+ if (!passed) {
60
+ error = "Custom validation failed";
61
+ }
62
+ } catch (err) {
63
+ passed = false;
64
+ error = `Custom validation error: ${err instanceof Error ? err.message : String(err)}`;
65
+ }
66
+ }
67
+ return {
68
+ name: testCase.name,
69
+ passed,
70
+ response,
71
+ error,
72
+ executionTime,
73
+ toolCalls
74
+ };
75
+ } catch (err) {
76
+ return {
77
+ name: testCase.name,
78
+ passed: false,
79
+ error: err instanceof Error ? err.message : String(err),
80
+ executionTime: Date.now() - startTime,
81
+ toolCalls: []
82
+ };
83
+ }
84
+ }
85
+ function printTestResults(suite) {
86
+ console.log(`
87
+ === Test Suite: ${suite.name} ===
88
+ `);
89
+ const passed = suite.results.filter((r) => r.passed).length;
90
+ const total = suite.results.length;
91
+ suite.results.forEach((result, index) => {
92
+ const icon = result.passed ? "\u2705" : "\u274C";
93
+ console.log(`${icon} ${index + 1}. ${result.name}`);
94
+ if (!result.passed && result.error) {
95
+ console.log(` Error: ${result.error}`);
96
+ }
97
+ if (result.toolCalls.length > 0) {
98
+ console.log(` Tools used: ${result.toolCalls.join(", ")}`);
99
+ }
100
+ console.log(` Time: ${result.executionTime}ms
101
+ `);
102
+ });
103
+ console.log(`Results: ${passed}/${total} passed`);
104
+ console.log(`Total time: ${suite.totalTime}ms`);
105
+ console.log(`Status: ${suite.passed ? "\u2705 PASSED" : "\u274C FAILED"}
106
+ `);
107
+ }
108
+ function assertContains(response, text) {
109
+ return response.text.toLowerCase().includes(text.toLowerCase());
110
+ }
111
+ function assertToolCalled(response, toolName) {
112
+ return response.toolCalls.some((tc) => tc.name === toolName);
113
+ }
114
+ function assertCompleted(response) {
115
+ return response.status === "completed";
116
+ }
117
+
118
+ // src/ai/dev/testing/tool-tester.ts
119
+ async function testTool(tool, testCases) {
120
+ const results = [];
121
+ for (const testCase of testCases) {
122
+ const result = await runToolTest(tool, testCase);
123
+ results.push(result);
124
+ }
125
+ return results;
126
+ }
127
+ async function runToolTest(tool, testCase) {
128
+ const startTime = Date.now();
129
+ try {
130
+ const result = await tool.execute(testCase.input);
131
+ const executionTime = Date.now() - startTime;
132
+ if (testCase.shouldThrow) {
133
+ return {
134
+ name: testCase.name,
135
+ passed: false,
136
+ error: "Expected tool to throw error but it succeeded",
137
+ executionTime
138
+ };
139
+ }
140
+ let passed = true;
141
+ let error;
142
+ if (testCase.expectedOutput !== void 0) {
143
+ passed = deepMatch(result, testCase.expectedOutput);
144
+ if (!passed) {
145
+ error = `Output mismatch. Expected: ${JSON.stringify(testCase.expectedOutput)}, Got: ${JSON.stringify(result)}`;
146
+ }
147
+ }
148
+ if (passed && testCase.validate) {
149
+ try {
150
+ passed = await testCase.validate(result);
151
+ if (!passed) {
152
+ error = "Custom validation failed";
153
+ }
154
+ } catch (err) {
155
+ passed = false;
156
+ error = `Validation error: ${err instanceof Error ? err.message : String(err)}`;
157
+ }
158
+ }
159
+ return {
160
+ name: testCase.name,
161
+ passed,
162
+ result,
163
+ error,
164
+ executionTime
165
+ };
166
+ } catch (err) {
167
+ const executionTime = Date.now() - startTime;
168
+ const errorMessage = err instanceof Error ? err.message : String(err);
169
+ if (testCase.shouldThrow) {
170
+ let passed = true;
171
+ let error;
172
+ if (testCase.expectedError) {
173
+ if (testCase.expectedError instanceof RegExp) {
174
+ passed = testCase.expectedError.test(errorMessage);
175
+ } else {
176
+ passed = errorMessage.includes(testCase.expectedError);
177
+ }
178
+ if (!passed) {
179
+ error = `Error message mismatch. Expected pattern: ${testCase.expectedError}, Got: ${errorMessage}`;
180
+ }
181
+ }
182
+ return {
183
+ name: testCase.name,
184
+ passed,
185
+ error,
186
+ executionTime
187
+ };
188
+ }
189
+ return {
190
+ name: testCase.name,
191
+ passed: false,
192
+ error: `Unexpected error: ${errorMessage}`,
193
+ executionTime
194
+ };
195
+ }
196
+ }
197
+ function deepMatch(actual, expected) {
198
+ if (expected === actual)
199
+ return true;
200
+ if (typeof expected !== "object" || expected === null)
201
+ return false;
202
+ if (typeof actual !== "object" || actual === null)
203
+ return false;
204
+ for (const key in expected) {
205
+ if (!(key in actual))
206
+ return false;
207
+ const expectedValue = expected[key];
208
+ const actualValue = actual[key];
209
+ if (typeof expectedValue === "object" && expectedValue !== null) {
210
+ if (!deepMatch(actualValue, expectedValue))
211
+ return false;
212
+ } else {
213
+ if (actualValue !== expectedValue)
214
+ return false;
215
+ }
216
+ }
217
+ return true;
218
+ }
219
+ function printToolTestResults(toolId, results) {
220
+ console.log(`
221
+ === Tool Tests: ${toolId} ===
222
+ `);
223
+ const passed = results.filter((r) => r.passed).length;
224
+ const total = results.length;
225
+ results.forEach((result, index) => {
226
+ const icon = result.passed ? "\u2705" : "\u274C";
227
+ console.log(`${icon} ${index + 1}. ${result.name}`);
228
+ if (!result.passed && result.error) {
229
+ console.log(` Error: ${result.error}`);
230
+ }
231
+ if (result.result !== void 0) {
232
+ console.log(` Result: ${JSON.stringify(result.result)}`);
233
+ }
234
+ console.log(` Time: ${result.executionTime}ms
235
+ `);
236
+ });
237
+ console.log(`Results: ${passed}/${total} passed`);
238
+ console.log(`Status: ${passed === total ? "\u2705 ALL PASSED" : "\u274C SOME FAILED"}
239
+ `);
240
+ }
241
+
242
+ // src/ai/utils/zod-json-schema.ts
243
+ import { ZodFirstPartyTypeKind } from "zod";
244
+ function zodToJsonSchema(schema) {
245
+ if (!schema || typeof schema !== "object" || !("_def" in schema)) {
246
+ throw new Error("Invalid Zod schema: missing _def property");
247
+ }
248
+ const details = unwrapSchema(schema);
249
+ const json = convert(details.schema);
250
+ if (details.nullable) {
251
+ return { anyOf: [json, { type: "null" }] };
252
+ }
253
+ return json;
254
+ }
255
+ function isOptionalSchema(schema) {
256
+ const { optional } = unwrapSchema(schema);
257
+ return optional;
258
+ }
259
+ function convert(schema) {
260
+ switch (schema._def.typeName) {
261
+ case ZodFirstPartyTypeKind.ZodString:
262
+ return { type: "string" };
263
+ case ZodFirstPartyTypeKind.ZodNumber:
264
+ return { type: "number" };
265
+ case ZodFirstPartyTypeKind.ZodBoolean:
266
+ return { type: "boolean" };
267
+ case ZodFirstPartyTypeKind.ZodBigInt:
268
+ return { type: "integer" };
269
+ case ZodFirstPartyTypeKind.ZodLiteral: {
270
+ const literal = schema._def.value;
271
+ return {
272
+ const: literal,
273
+ type: typeof literal === "string" ? "string" : typeof literal === "number" ? "number" : typeof literal === "boolean" ? "boolean" : void 0
274
+ };
275
+ }
276
+ case ZodFirstPartyTypeKind.ZodEnum:
277
+ return {
278
+ type: "string",
279
+ enum: schema._def.values
280
+ };
281
+ case ZodFirstPartyTypeKind.ZodNativeEnum:
282
+ return {
283
+ enum: Object.values(schema._def.values).filter(
284
+ (value) => typeof value !== "number"
285
+ )
286
+ };
287
+ case ZodFirstPartyTypeKind.ZodObject: {
288
+ const obj = schema;
289
+ const properties = {};
290
+ const required = [];
291
+ const shape = typeof obj._def.shape === "function" ? obj._def.shape() : obj._def.shape;
292
+ for (const [key, value] of Object.entries(shape || {})) {
293
+ const zodSchema = value;
294
+ properties[key] = zodToJsonSchema(zodSchema);
295
+ if (!isOptionalSchema(zodSchema)) {
296
+ required.push(key);
297
+ }
298
+ }
299
+ const json = { type: "object", properties };
300
+ if (required.length > 0) {
301
+ json.required = required;
302
+ }
303
+ return json;
304
+ }
305
+ case ZodFirstPartyTypeKind.ZodArray: {
306
+ const array = schema;
307
+ return {
308
+ type: "array",
309
+ items: zodToJsonSchema(array._def.type)
310
+ };
311
+ }
312
+ case ZodFirstPartyTypeKind.ZodTuple: {
313
+ const tuple = schema;
314
+ return {
315
+ type: "array",
316
+ prefixItems: tuple._def.items.map((item) => zodToJsonSchema(item)),
317
+ minItems: tuple._def.items.length,
318
+ maxItems: tuple._def.items.length
319
+ };
320
+ }
321
+ case ZodFirstPartyTypeKind.ZodUnion: {
322
+ const union = schema;
323
+ return {
324
+ anyOf: union._def.options.map((option) => zodToJsonSchema(option))
325
+ };
326
+ }
327
+ case ZodFirstPartyTypeKind.ZodDiscriminatedUnion: {
328
+ const union = schema;
329
+ return {
330
+ anyOf: Array.from(union._def.options.values()).map((option) => zodToJsonSchema(option))
331
+ };
332
+ }
333
+ case ZodFirstPartyTypeKind.ZodRecord:
334
+ return {
335
+ type: "object",
336
+ additionalProperties: zodToJsonSchema(schema._def.valueType)
337
+ };
338
+ case ZodFirstPartyTypeKind.ZodDefault: {
339
+ const def = schema;
340
+ const inner = zodToJsonSchema(def._def.innerType);
341
+ const defaultValue = def._def.defaultValue();
342
+ if (typeof inner === "object" && !("anyOf" in inner)) {
343
+ inner.default = defaultValue;
344
+ }
345
+ return inner;
346
+ }
347
+ case ZodFirstPartyTypeKind.ZodLazy:
348
+ return convert(schema._def.getter());
349
+ case ZodFirstPartyTypeKind.ZodEffects:
350
+ return convert(schema._def.schema);
351
+ default:
352
+ return { type: "object" };
353
+ }
354
+ }
355
+ function unwrapSchema(schema) {
356
+ let current = schema;
357
+ let nullable = false;
358
+ let optional = false;
359
+ while (true) {
360
+ switch (current._def.typeName) {
361
+ case ZodFirstPartyTypeKind.ZodNullable:
362
+ nullable = true;
363
+ current = current._def.innerType;
364
+ continue;
365
+ case ZodFirstPartyTypeKind.ZodOptional:
366
+ optional = true;
367
+ current = current._def.innerType;
368
+ continue;
369
+ case ZodFirstPartyTypeKind.ZodEffects:
370
+ current = current._def.schema;
371
+ continue;
372
+ default:
373
+ return { schema: current, nullable, optional };
374
+ }
375
+ }
376
+ }
377
+
378
+ // src/core/utils/runtime-guards.ts
379
+ function hasDenoRuntime(global) {
380
+ return typeof global === "object" && global !== null && "Deno" in global && typeof global.Deno?.env?.get === "function";
381
+ }
382
+ function hasNodeProcess(global) {
383
+ return typeof global === "object" && global !== null && "process" in global && typeof global.process?.env === "object";
384
+ }
385
+
386
+ // src/core/utils/logger/env.ts
387
+ function getEnvironmentVariable(name) {
388
+ try {
389
+ if (typeof Deno !== "undefined" && hasDenoRuntime(globalThis)) {
390
+ const value = globalThis.Deno?.env.get(name);
391
+ return value === "" ? void 0 : value;
392
+ }
393
+ if (hasNodeProcess(globalThis)) {
394
+ const value = globalThis.process?.env[name];
395
+ return value === "" ? void 0 : value;
396
+ }
397
+ } catch {
398
+ return void 0;
399
+ }
400
+ return void 0;
401
+ }
402
+
403
+ // src/core/utils/logger/logger.ts
404
+ var cachedLogLevel;
405
+ function resolveLogLevel(force = false) {
406
+ if (force || cachedLogLevel === void 0) {
407
+ cachedLogLevel = getDefaultLevel();
408
+ }
409
+ return cachedLogLevel;
410
+ }
411
+ var ConsoleLogger = class {
412
+ constructor(prefix, level = resolveLogLevel()) {
413
+ this.prefix = prefix;
414
+ this.level = level;
415
+ }
416
+ setLevel(level) {
417
+ this.level = level;
418
+ }
419
+ getLevel() {
420
+ return this.level;
421
+ }
422
+ debug(message, ...args) {
423
+ if (this.level <= 0 /* DEBUG */) {
424
+ console.debug(`[${this.prefix}] DEBUG: ${message}`, ...args);
425
+ }
426
+ }
427
+ info(message, ...args) {
428
+ if (this.level <= 1 /* INFO */) {
429
+ console.log(`[${this.prefix}] ${message}`, ...args);
430
+ }
431
+ }
432
+ warn(message, ...args) {
433
+ if (this.level <= 2 /* WARN */) {
434
+ console.warn(`[${this.prefix}] WARN: ${message}`, ...args);
435
+ }
436
+ }
437
+ error(message, ...args) {
438
+ if (this.level <= 3 /* ERROR */) {
439
+ console.error(`[${this.prefix}] ERROR: ${message}`, ...args);
440
+ }
441
+ }
442
+ async time(label, fn) {
443
+ const start = performance.now();
444
+ try {
445
+ const result = await fn();
446
+ const end = performance.now();
447
+ this.debug(`${label} completed in ${(end - start).toFixed(2)}ms`);
448
+ return result;
449
+ } catch (error) {
450
+ const end = performance.now();
451
+ this.error(`${label} failed after ${(end - start).toFixed(2)}ms`, error);
452
+ throw error;
453
+ }
454
+ }
455
+ };
456
+ function parseLogLevel(levelString) {
457
+ if (!levelString)
458
+ return void 0;
459
+ const upper = levelString.toUpperCase();
460
+ switch (upper) {
461
+ case "DEBUG":
462
+ return 0 /* DEBUG */;
463
+ case "WARN":
464
+ return 2 /* WARN */;
465
+ case "ERROR":
466
+ return 3 /* ERROR */;
467
+ case "INFO":
468
+ return 1 /* INFO */;
469
+ default:
470
+ return void 0;
471
+ }
472
+ }
473
+ var getDefaultLevel = () => {
474
+ const envLevel = getEnvironmentVariable("LOG_LEVEL");
475
+ const parsedLevel = parseLogLevel(envLevel);
476
+ if (parsedLevel !== void 0)
477
+ return parsedLevel;
478
+ const debugFlag = getEnvironmentVariable("VERYFRONT_DEBUG");
479
+ if (debugFlag === "1" || debugFlag === "true")
480
+ return 0 /* DEBUG */;
481
+ return 1 /* INFO */;
482
+ };
483
+ var trackedLoggers = /* @__PURE__ */ new Set();
484
+ function createLogger(prefix) {
485
+ const logger2 = new ConsoleLogger(prefix);
486
+ trackedLoggers.add(logger2);
487
+ return logger2;
488
+ }
489
+ var cliLogger = createLogger("CLI");
490
+ var serverLogger = createLogger("SERVER");
491
+ var rendererLogger = createLogger("RENDERER");
492
+ var bundlerLogger = createLogger("BUNDLER");
493
+ var agentLogger = createLogger("AGENT");
494
+ var logger = createLogger("VERYFRONT");
495
+
496
+ // src/core/errors/veryfront-error.ts
497
+ function createError(error) {
498
+ return error;
499
+ }
500
+ function toError(veryfrontError) {
501
+ const error = new Error(veryfrontError.message);
502
+ error.name = `VeryfrontError[${veryfrontError.type}]`;
503
+ Object.defineProperty(error, "context", {
504
+ value: veryfrontError,
505
+ enumerable: false,
506
+ configurable: true
507
+ });
508
+ return error;
509
+ }
510
+
511
+ // src/ai/utils/tool.ts
512
+ var ToolRegistryClass = class {
513
+ constructor() {
514
+ this.tools = /* @__PURE__ */ new Map();
515
+ }
516
+ register(id, toolInstance) {
517
+ if (this.tools.has(id)) {
518
+ agentLogger.warn(`Tool "${id}" is already registered. Overwriting.`);
519
+ }
520
+ this.tools.set(id, toolInstance);
521
+ }
522
+ /**
523
+ * Get a tool by ID
524
+ */
525
+ get(id) {
526
+ return this.tools.get(id);
527
+ }
528
+ /**
529
+ * Check if a tool exists
530
+ */
531
+ has(id) {
532
+ return this.tools.has(id);
533
+ }
534
+ /**
535
+ * Get all tool IDs
536
+ */
537
+ getAllIds() {
538
+ return Array.from(this.tools.keys());
539
+ }
540
+ /**
541
+ * Get all tools
542
+ */
543
+ getAll() {
544
+ return new Map(this.tools);
545
+ }
546
+ /**
547
+ * Clear all tools (for testing)
548
+ */
549
+ clear() {
550
+ this.tools.clear();
551
+ }
552
+ getToolsForProvider() {
553
+ return Array.from(this.tools.values()).map(toolToProviderDefinition);
554
+ }
555
+ };
556
+ var toolRegistry = new ToolRegistryClass();
557
+ function toolToProviderDefinition(tool) {
558
+ const jsonSchema = tool.inputSchemaJson || zodToJsonSchema(tool.inputSchema);
559
+ agentLogger.info(
560
+ `[TOOL] Using ${tool.inputSchemaJson ? "pre-converted" : "runtime-converted"} schema for "${tool.id}"`
561
+ );
562
+ return {
563
+ name: tool.id,
564
+ description: tool.description,
565
+ parameters: jsonSchema
566
+ };
567
+ }
568
+
569
+ // src/ai/mcp/resource.ts
570
+ var ResourceRegistryClass = class {
571
+ constructor() {
572
+ this.resources = /* @__PURE__ */ new Map();
573
+ }
574
+ /**
575
+ * Register a resource
576
+ */
577
+ register(id, resourceInstance) {
578
+ if (this.resources.has(id)) {
579
+ agentLogger.warn(`Resource "${id}" is already registered. Overwriting.`);
580
+ }
581
+ this.resources.set(id, resourceInstance);
582
+ }
583
+ /**
584
+ * Get a resource by ID
585
+ */
586
+ get(id) {
587
+ return this.resources.get(id);
588
+ }
589
+ /**
590
+ * Get resource by pattern matching
591
+ */
592
+ findByPattern(uri) {
593
+ for (const resource of this.resources.values()) {
594
+ if (this.matchesPattern(uri, resource.pattern)) {
595
+ return resource;
596
+ }
597
+ }
598
+ return void 0;
599
+ }
600
+ /**
601
+ * Check if URI matches pattern
602
+ * Uses regex-based pattern matching with named capture groups.
603
+ * Supports Express-style patterns like "/users/:userId/profile"
604
+ */
605
+ matchesPattern(uri, pattern) {
606
+ const patternRegex = new RegExp(
607
+ "^" + pattern.replace(/:(\w+)/g, "(?<$1>[^/]+)") + "$"
608
+ );
609
+ return patternRegex.test(uri);
610
+ }
611
+ /**
612
+ * Extract params from URI using pattern
613
+ */
614
+ extractParams(uri, pattern) {
615
+ const patternRegex = new RegExp(
616
+ "^" + pattern.replace(/:(\w+)/g, "(?<$1>[^/]+)") + "$"
617
+ );
618
+ const match = uri.match(patternRegex);
619
+ return match?.groups || {};
620
+ }
621
+ /**
622
+ * Get all resources
623
+ */
624
+ getAll() {
625
+ return new Map(this.resources);
626
+ }
627
+ /**
628
+ * Clear all resources
629
+ */
630
+ clear() {
631
+ this.resources.clear();
632
+ }
633
+ };
634
+ var resourceRegistry = new ResourceRegistryClass();
635
+
636
+ // src/ai/mcp/prompt.ts
637
+ var PromptRegistryClass = class {
638
+ constructor() {
639
+ this.prompts = /* @__PURE__ */ new Map();
640
+ }
641
+ /**
642
+ * Register a prompt
643
+ */
644
+ register(id, promptInstance) {
645
+ if (this.prompts.has(id)) {
646
+ agentLogger.warn(`Prompt "${id}" is already registered. Overwriting.`);
647
+ }
648
+ this.prompts.set(id, promptInstance);
649
+ }
650
+ /**
651
+ * Get a prompt by ID
652
+ */
653
+ get(id) {
654
+ return this.prompts.get(id);
655
+ }
656
+ /**
657
+ * Get prompt content by ID
658
+ */
659
+ async getContent(id, variables) {
660
+ const promptInstance = this.get(id);
661
+ if (!promptInstance) {
662
+ throw toError(createError({
663
+ type: "agent",
664
+ message: `Prompt "${id}" not found`
665
+ }));
666
+ }
667
+ return await promptInstance.getContent(variables);
668
+ }
669
+ /**
670
+ * Get all prompts
671
+ */
672
+ getAll() {
673
+ return new Map(this.prompts);
674
+ }
675
+ /**
676
+ * Clear all prompts
677
+ */
678
+ clear() {
679
+ this.prompts.clear();
680
+ }
681
+ };
682
+ var promptRegistry = new PromptRegistryClass();
683
+
684
+ // src/ai/mcp/registry.ts
685
+ function getMCPRegistry() {
686
+ return {
687
+ tools: toolRegistry.getAll(),
688
+ resources: resourceRegistry.getAll(),
689
+ prompts: promptRegistry.getAll()
690
+ };
691
+ }
692
+ function getMCPStats() {
693
+ const registry = getMCPRegistry();
694
+ return {
695
+ tools: registry.tools.size,
696
+ resources: registry.resources.size,
697
+ prompts: registry.prompts.size,
698
+ total: registry.tools.size + registry.resources.size + registry.prompts.size
699
+ };
700
+ }
701
+
702
+ // src/ai/dev/debug/inspector.ts
703
+ async function inspectAgent(agent, input) {
704
+ const startTime = Date.now();
705
+ const _memoryStatsBefore = await agent.getMemoryStats();
706
+ const response = await agent.generate({ input });
707
+ const executionTime = Date.now() - startTime;
708
+ const memoryStatsAfter = await agent.getMemoryStats();
709
+ const availableTools = agent.config.tools ? Object.keys(agent.config.tools) : [];
710
+ return {
711
+ agent: {
712
+ id: agent.id,
713
+ model: agent.config.model,
714
+ maxSteps: agent.config.maxSteps || 20,
715
+ memoryType: agent.config.memory?.type || "conversation"
716
+ },
717
+ execution: {
718
+ input,
719
+ output: response.text,
720
+ status: response.status,
721
+ steps: response.toolCalls.length + 1,
722
+ // Tool calls + final response
723
+ executionTime
724
+ },
725
+ tools: {
726
+ called: response.toolCalls.map((tc) => ({
727
+ name: tc.name,
728
+ args: tc.args,
729
+ result: tc.result,
730
+ executionTime: tc.executionTime,
731
+ status: tc.status
732
+ })),
733
+ available: availableTools
734
+ },
735
+ memory: {
736
+ messagesCount: memoryStatsAfter.totalMessages,
737
+ estimatedTokens: memoryStatsAfter.estimatedTokens
738
+ },
739
+ usage: response.usage
740
+ };
741
+ }
742
+ function printInspectionReport(report) {
743
+ agentLogger.info("\n=== Agent Inspection Report ===\n");
744
+ agentLogger.info("Agent:");
745
+ agentLogger.info(` ID: ${report.agent.id}`);
746
+ agentLogger.info(` Model: ${report.agent.model}`);
747
+ agentLogger.info(` Max Steps: ${report.agent.maxSteps}`);
748
+ agentLogger.info(` Memory: ${report.agent.memoryType}
749
+ `);
750
+ agentLogger.info("Execution:");
751
+ agentLogger.info(
752
+ ` Input: ${typeof report.execution.input === "string" ? report.execution.input : `${report.execution.input.length} messages`}`
753
+ );
754
+ agentLogger.info(` Output: ${report.execution.output.substring(0, 100)}...`);
755
+ agentLogger.info(` Status: ${report.execution.status}`);
756
+ agentLogger.info(` Steps: ${report.execution.steps}`);
757
+ agentLogger.info(` Time: ${report.execution.executionTime}ms
758
+ `);
759
+ agentLogger.info("Tools:");
760
+ agentLogger.info(
761
+ ` Available: ${report.tools.available.length} (${report.tools.available.join(", ")})`
762
+ );
763
+ agentLogger.info(` Called: ${report.tools.called.length}`);
764
+ if (report.tools.called.length > 0) {
765
+ report.tools.called.forEach((tool, i) => {
766
+ agentLogger.info(` ${i + 1}. ${tool.name}(${JSON.stringify(tool.args)})`);
767
+ agentLogger.info(` Status: ${tool.status}`);
768
+ agentLogger.info(` Time: ${tool.executionTime}ms`);
769
+ agentLogger.info(` Result: ${JSON.stringify(tool.result).substring(0, 100)}...`);
770
+ });
771
+ }
772
+ agentLogger.info("");
773
+ agentLogger.info("Memory:");
774
+ agentLogger.info(` Messages: ${report.memory.messagesCount}`);
775
+ agentLogger.info(` Estimated Tokens: ${report.memory.estimatedTokens}
776
+ `);
777
+ if (report.usage) {
778
+ agentLogger.info("Token Usage:");
779
+ agentLogger.info(` Prompt: ${report.usage.promptTokens}`);
780
+ agentLogger.info(` Completion: ${report.usage.completionTokens}`);
781
+ agentLogger.info(` Total: ${report.usage.totalTokens}
782
+ `);
783
+ }
784
+ }
785
+ function getRegistryOverview() {
786
+ const registry = getMCPRegistry();
787
+ const stats = getMCPStats();
788
+ return {
789
+ tools: Array.from(registry.tools.values()).map((t) => ({
790
+ id: t.id,
791
+ description: t.description
792
+ })),
793
+ resources: Array.from(registry.resources.values()).map((r) => ({
794
+ id: r.id,
795
+ pattern: r.pattern,
796
+ description: r.description
797
+ })),
798
+ prompts: Array.from(registry.prompts.values()).map((p) => ({
799
+ id: p.id,
800
+ description: p.description
801
+ })),
802
+ stats
803
+ };
804
+ }
805
+ function printRegistryOverview() {
806
+ const overview = getRegistryOverview();
807
+ agentLogger.info("\n=== MCP Registry Overview ===\n");
808
+ agentLogger.info(`Total: ${overview.stats.total} items
809
+ `);
810
+ agentLogger.info(`Tools (${overview.stats.tools}):`);
811
+ overview.tools.forEach((t) => {
812
+ agentLogger.info(` \u2022 ${t.id}: ${t.description}`);
813
+ });
814
+ agentLogger.info("");
815
+ agentLogger.info(`Resources (${overview.stats.resources}):`);
816
+ overview.resources.forEach((r) => {
817
+ agentLogger.info(` \u2022 ${r.id} (${r.pattern}): ${r.description}`);
818
+ });
819
+ agentLogger.info("");
820
+ agentLogger.info(`Prompts (${overview.stats.prompts}):`);
821
+ overview.prompts.forEach((p) => {
822
+ agentLogger.info(` \u2022 ${p.id}: ${p.description}`);
823
+ });
824
+ agentLogger.info("");
825
+ }
826
+ export {
827
+ assertCompleted,
828
+ assertContains,
829
+ assertToolCalled,
830
+ getRegistryOverview,
831
+ inspectAgent,
832
+ printInspectionReport,
833
+ printRegistryOverview,
834
+ printTestResults,
835
+ printToolTestResults,
836
+ testAgent,
837
+ testTool
838
+ };
839
+ //# sourceMappingURL=dev.js.map