@iqai/adk-cli 0.1.1 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -8,7 +8,7 @@ import { program } from "commander";
8
8
  // package.json
9
9
  var package_default = {
10
10
  name: "@iqai/adk-cli",
11
- version: "0.1.1",
11
+ version: "0.2.1",
12
12
  description: "CLI tool for creating, running, and testing ADK agents",
13
13
  main: "dist/index.js",
14
14
  types: "dist/index.d.ts",
@@ -143,21 +143,7 @@ async function detectAvailablePackageManagers() {
143
143
  }
144
144
  async function createProject(projectName, options) {
145
145
  console.clear();
146
- console.log(
147
- chalk.magentaBright(dedent`
148
- ╔══════════════════════════════════════════════════════╗
149
- ║ ║
150
- ║ █████╗ ██████╗ ██╗ ██╗ ████████╗███████╗ ║
151
- ║ ██╔══██╗██╔══██╗██║ ██╔╝ ╚══██╔══╝██╔════╝ ║
152
- ║ ███████║██║ ██║█████╔╝ ██║ ███████╗ ║
153
- ║ ██╔══██║██║ ██║██╔═██╗ ██║ ╚════██║ ║
154
- ║ ██║ ██║██████╔╝██║ ██╗ ██║ ███████║ ║
155
- ║ ╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝ ║
156
- ║ ║
157
- ╚══════════════════════════════════════════════════════╝
158
- `)
159
- );
160
- intro(chalk.bgMagenta.bold(" \u2728 Let's build something amazing! "));
146
+ intro(chalk.magentaBright("\u{1F9E0} Create new ADK-TS project"));
161
147
  let finalProjectName = projectName;
162
148
  if (!finalProjectName) {
163
149
  const response = await text({
@@ -305,7 +291,59 @@ import { existsSync as existsSync3 } from "fs";
305
291
  import { resolve } from "path";
306
292
  import chalk2 from "chalk";
307
293
 
308
- // src/server.ts
294
+ // src/server/index.ts
295
+ import { serve } from "@hono/node-server";
296
+ import { InMemorySessionService } from "@iqai/adk";
297
+ import { Hono } from "hono";
298
+
299
+ // src/server/routes.ts
300
+ import { cors } from "hono/cors";
301
+ function setupRoutes(app, agentManager, sessionManager, agentsDir) {
302
+ app.use("/*", cors());
303
+ app.get("/health", (c) => c.json({ status: "ok" }));
304
+ app.get("/api/agents", (c) => {
305
+ const agentsList = Array.from(
306
+ agentManager.getAgents().values()
307
+ ).map((agent) => ({
308
+ path: agent.absolutePath,
309
+ name: agent.name,
310
+ directory: agent.absolutePath,
311
+ relativePath: agent.relativePath
312
+ }));
313
+ return c.json({ agents: agentsList });
314
+ });
315
+ app.post("/api/agents/refresh", (c) => {
316
+ agentManager.scanAgents(agentsDir);
317
+ const agentsList = Array.from(
318
+ agentManager.getAgents().values()
319
+ ).map((agent) => ({
320
+ path: agent.absolutePath,
321
+ name: agent.name,
322
+ directory: agent.absolutePath,
323
+ relativePath: agent.relativePath
324
+ }));
325
+ return c.json({ agents: agentsList });
326
+ });
327
+ app.get("/api/agents/:id/messages", async (c) => {
328
+ const agentPath = decodeURIComponent(c.req.param("id"));
329
+ const loadedAgent = agentManager.getLoadedAgents().get(agentPath);
330
+ if (!loadedAgent) {
331
+ return c.json({ messages: [] });
332
+ }
333
+ const messages = await sessionManager.getSessionMessages(loadedAgent);
334
+ const response = { messages };
335
+ return c.json(response);
336
+ });
337
+ app.post("/api/agents/:id/message", async (c) => {
338
+ const agentPath = decodeURIComponent(c.req.param("id"));
339
+ const { message } = await c.req.json();
340
+ const response = await agentManager.sendMessageToAgent(agentPath, message);
341
+ const messageResponse = { response };
342
+ return c.json(messageResponse);
343
+ });
344
+ }
345
+
346
+ // src/server/services.ts
309
347
  import {
310
348
  existsSync as existsSync2,
311
349
  mkdirSync,
@@ -316,91 +354,14 @@ import {
316
354
  } from "fs";
317
355
  import { dirname, join as join2, relative } from "path";
318
356
  import { pathToFileURL } from "url";
319
- import { serve } from "@hono/node-server";
320
- import { AgentBuilder, InMemorySessionService } from "@iqai/adk";
321
- import { Hono } from "hono";
322
- import { cors } from "hono/cors";
323
- var ADKServer = class {
324
- agents = /* @__PURE__ */ new Map();
325
- loadedAgents = /* @__PURE__ */ new Map();
326
- sessionService;
327
- app;
328
- server;
329
- agentsDir;
330
- port;
331
- host;
332
- quiet;
333
- constructor(agentsDir, port = 8042, host = "localhost", quiet = false) {
334
- this.agentsDir = agentsDir;
335
- this.port = port;
336
- this.host = host;
357
+ import { AgentBuilder } from "@iqai/adk";
358
+ var AgentScanner = class {
359
+ constructor(quiet = false) {
337
360
  this.quiet = quiet;
338
- this.sessionService = new InMemorySessionService();
339
- this.app = new Hono();
340
- this.setupRoutes();
341
- this.scanAgents();
342
361
  }
343
- setupRoutes() {
344
- this.app.use("/*", cors());
345
- this.app.get("/health", (c) => c.json({ status: "ok" }));
346
- this.app.get("/api/agents", (c) => {
347
- const agentsList = Array.from(this.agents.values()).map((agent) => ({
348
- path: agent.absolutePath,
349
- name: agent.name,
350
- directory: agent.absolutePath,
351
- relativePath: agent.relativePath
352
- }));
353
- return c.json({ agents: agentsList });
354
- });
355
- this.app.post("/api/agents/refresh", (c) => {
356
- this.scanAgents();
357
- const agentsList = Array.from(this.agents.values()).map((agent) => ({
358
- path: agent.absolutePath,
359
- name: agent.name,
360
- directory: agent.absolutePath,
361
- relativePath: agent.relativePath
362
- }));
363
- return c.json({ agents: agentsList });
364
- });
365
- this.app.get("/api/agents/:id/messages", async (c) => {
366
- const agentPath = decodeURIComponent(c.req.param("id"));
367
- const loadedAgent = this.loadedAgents.get(agentPath);
368
- if (!loadedAgent) {
369
- return c.json({ messages: [] });
370
- }
371
- try {
372
- const session = await this.sessionService.getSession(
373
- loadedAgent.appName,
374
- loadedAgent.userId,
375
- loadedAgent.sessionId
376
- );
377
- if (!session || !session.events) {
378
- return c.json({ messages: [] });
379
- }
380
- const messages = session.events.map((event, index) => ({
381
- id: index + 1,
382
- type: event.author === "user" ? "user" : "assistant",
383
- content: event.content?.parts?.map(
384
- (part) => typeof part === "object" && "text" in part ? part.text : ""
385
- ).join("") || "",
386
- timestamp: new Date(event.timestamp || Date.now()).toISOString()
387
- }));
388
- return c.json({ messages });
389
- } catch (error) {
390
- console.error("Error fetching messages:", error);
391
- return c.json({ messages: [] });
392
- }
393
- });
394
- this.app.post("/api/agents/:id/message", async (c) => {
395
- const agentPath = decodeURIComponent(c.req.param("id"));
396
- const { message } = await c.req.json();
397
- const response = await this.sendMessageToAgent(agentPath, message);
398
- return c.json({ response });
399
- });
400
- }
401
- scanAgents() {
402
- this.agents.clear();
403
- const scanDir = !this.agentsDir || !existsSync2(this.agentsDir) ? process.cwd() : this.agentsDir;
362
+ scanAgents(agentsDir, loadedAgents) {
363
+ const agents = /* @__PURE__ */ new Map();
364
+ const scanDir = !agentsDir || !existsSync2(agentsDir) ? process.cwd() : agentsDir;
404
365
  const shouldSkipDirectory = (dirName) => {
405
366
  const skipDirs = [
406
367
  "node_modules",
@@ -427,7 +388,7 @@ var ADKServer = class {
427
388
  }
428
389
  } else if (item === "agent.ts" || item === "agent.js") {
429
390
  const relativePath = relative(scanDir, dir);
430
- const loadedAgent = this.loadedAgents.get(relativePath);
391
+ const loadedAgent = loadedAgents.get(relativePath);
431
392
  let agentName = relativePath.split("/").pop() || "unknown";
432
393
  if (loadedAgent?.agent?.name) {
433
394
  agentName = loadedAgent.agent.name;
@@ -438,7 +399,7 @@ var ADKServer = class {
438
399
  } catch {
439
400
  }
440
401
  }
441
- this.agents.set(relativePath, {
402
+ agents.set(relativePath, {
442
403
  relativePath,
443
404
  name: agentName,
444
405
  absolutePath: dir,
@@ -449,9 +410,225 @@ var ADKServer = class {
449
410
  };
450
411
  scanDirectory(scanDir);
451
412
  if (!this.quiet) {
452
- console.log(`\u2705 Agent scan complete. Found ${this.agents.size} agents.`);
413
+ console.log(`\u2705 Agent scan complete. Found ${agents.size} agents.`);
414
+ }
415
+ return agents;
416
+ }
417
+ extractAgentNameFromFile(filePath) {
418
+ try {
419
+ const content = readFileSync(filePath, "utf-8");
420
+ const nameMatch = content.match(/name\s*:\s*["']([^"']+)["']/);
421
+ if (nameMatch?.[1]) {
422
+ return nameMatch[1];
423
+ }
424
+ return null;
425
+ } catch {
426
+ return null;
427
+ }
428
+ }
429
+ };
430
+ var AgentLoader = class {
431
+ constructor(quiet = false) {
432
+ this.quiet = quiet;
433
+ }
434
+ /**
435
+ * Import a TypeScript file by compiling it on-demand
436
+ */
437
+ async importTypeScriptFile(filePath) {
438
+ const startDir = dirname(filePath);
439
+ let projectRoot = startDir;
440
+ while (projectRoot !== "/" && projectRoot !== dirname(projectRoot)) {
441
+ if (existsSync2(join2(projectRoot, "package.json")) || existsSync2(join2(projectRoot, ".env"))) {
442
+ break;
443
+ }
444
+ projectRoot = dirname(projectRoot);
445
+ }
446
+ if (projectRoot === "/") {
447
+ projectRoot = startDir;
448
+ }
449
+ try {
450
+ const { build } = await import("esbuild");
451
+ const cacheDir = join2(projectRoot, ".adk-cache");
452
+ if (!existsSync2(cacheDir)) {
453
+ mkdirSync(cacheDir, { recursive: true });
454
+ }
455
+ const outFile = join2(cacheDir, `agent-${Date.now()}.mjs`);
456
+ const plugin = {
457
+ name: "externalize-bare-imports",
458
+ setup(build2) {
459
+ build2.onResolve({ filter: /.*/ }, (args) => {
460
+ if (args.path.startsWith(".") || args.path.startsWith("/") || args.path.startsWith("..")) {
461
+ return;
462
+ }
463
+ return { path: args.path, external: true };
464
+ });
465
+ }
466
+ };
467
+ const tsconfigPath = join2(projectRoot, "tsconfig.json");
468
+ await build({
469
+ entryPoints: [filePath],
470
+ outfile: outFile,
471
+ bundle: true,
472
+ format: "esm",
473
+ platform: "node",
474
+ target: ["node22"],
475
+ sourcemap: false,
476
+ logLevel: "silent",
477
+ plugins: [plugin],
478
+ absWorkingDir: projectRoot,
479
+ // Use tsconfig if present for path aliases
480
+ ...existsSync2(tsconfigPath) ? { tsconfig: tsconfigPath } : {}
481
+ });
482
+ const mod = await import(`${pathToFileURL(outFile).href}?t=${Date.now()}`);
483
+ let agentExport = mod?.agent;
484
+ if (!agentExport && mod?.default) {
485
+ agentExport = mod.default.agent ?? mod.default;
486
+ }
487
+ try {
488
+ unlinkSync(outFile);
489
+ } catch {
490
+ }
491
+ if (agentExport) {
492
+ const isPrimitive = (v) => v == null || ["string", "number", "boolean"].includes(typeof v);
493
+ if (isPrimitive(agentExport)) {
494
+ if (!this.quiet) {
495
+ console.log(
496
+ `\u2139\uFE0F Ignoring primitive 'agent' export in ${filePath}; scanning module for factory...`
497
+ );
498
+ }
499
+ } else {
500
+ if (!this.quiet) {
501
+ console.log(`\u2705 TS agent imported via esbuild: ${filePath}`);
502
+ }
503
+ return { agent: agentExport };
504
+ }
505
+ }
506
+ return mod;
507
+ } catch (e) {
508
+ throw new Error(
509
+ `Failed to import TS agent via esbuild: ${e instanceof Error ? e.message : String(e)}`
510
+ );
511
+ }
512
+ }
513
+ loadEnvironmentVariables(agentFilePath) {
514
+ let projectRoot = dirname(agentFilePath);
515
+ while (projectRoot !== "/" && projectRoot !== dirname(projectRoot)) {
516
+ if (existsSync2(join2(projectRoot, "package.json")) || existsSync2(join2(projectRoot, ".env"))) {
517
+ break;
518
+ }
519
+ projectRoot = dirname(projectRoot);
520
+ }
521
+ const envPath = join2(projectRoot, ".env");
522
+ if (existsSync2(envPath)) {
523
+ try {
524
+ const envContent = readFileSync(envPath, "utf8");
525
+ const envLines = envContent.split("\n");
526
+ for (const line of envLines) {
527
+ const trimmedLine = line.trim();
528
+ if (trimmedLine && !trimmedLine.startsWith("#")) {
529
+ const [key, ...valueParts] = trimmedLine.split("=");
530
+ if (key && valueParts.length > 0) {
531
+ const value = valueParts.join("=").replace(/^"(.*)"$/, "$1");
532
+ process.env[key.trim()] = value.trim();
533
+ }
534
+ }
535
+ }
536
+ } catch (error) {
537
+ console.warn(
538
+ `\u26A0\uFE0F Warning: Could not load .env file: ${error instanceof Error ? error.message : String(error)}`
539
+ );
540
+ }
453
541
  }
454
542
  }
543
+ // Minimal resolution logic for agent exports: supports
544
+ // 1) export const agent = new LlmAgent(...)
545
+ // 2) export function agent() { return new LlmAgent(...) }
546
+ // 3) export async function agent() { return new LlmAgent(...) }
547
+ // 4) default export (object or function) returning or containing .agent
548
+ async resolveAgentExport(mod) {
549
+ let candidate = mod?.agent ?? mod?.default?.agent ?? mod?.default ?? mod;
550
+ const isLikelyAgentInstance = (obj) => obj && typeof obj === "object" && typeof obj.name === "string";
551
+ const isPrimitive = (v) => v == null || ["string", "number", "boolean"].includes(typeof v);
552
+ const invokeMaybe = async (fn) => {
553
+ let out = fn();
554
+ if (out && typeof out === "object" && "then" in out) {
555
+ out = await out;
556
+ }
557
+ return out;
558
+ };
559
+ if (!isLikelyAgentInstance(candidate) && isPrimitive(candidate) || !isLikelyAgentInstance(candidate) && candidate && candidate === mod) {
560
+ candidate = mod;
561
+ for (const [key, value] of Object.entries(mod)) {
562
+ if (key === "default") continue;
563
+ const keyLower = key.toLowerCase();
564
+ if (isPrimitive(value)) continue;
565
+ if (isLikelyAgentInstance(value)) {
566
+ candidate = value;
567
+ break;
568
+ }
569
+ if (value && typeof value === "object" && value.agent && isLikelyAgentInstance(value.agent)) {
570
+ candidate = value.agent;
571
+ break;
572
+ }
573
+ if (typeof value === "function" && (/(agent|build|create)/i.test(keyLower) || value.name && /(agent|build|create)/i.test(value.name.toLowerCase()))) {
574
+ try {
575
+ const maybe = await invokeMaybe(value);
576
+ if (isLikelyAgentInstance(maybe)) {
577
+ candidate = maybe;
578
+ break;
579
+ }
580
+ if (maybe && typeof maybe === "object" && maybe.agent && isLikelyAgentInstance(maybe.agent)) {
581
+ candidate = maybe.agent;
582
+ break;
583
+ }
584
+ } catch (e) {
585
+ }
586
+ }
587
+ }
588
+ }
589
+ if (typeof candidate === "function") {
590
+ try {
591
+ candidate = await invokeMaybe(candidate);
592
+ } catch (e) {
593
+ throw new Error(
594
+ `Failed executing exported agent function: ${e instanceof Error ? e.message : String(e)}`
595
+ );
596
+ }
597
+ }
598
+ if (candidate && typeof candidate === "object" && candidate.agent && isLikelyAgentInstance(candidate.agent)) {
599
+ candidate = candidate.agent;
600
+ }
601
+ if (candidate?.agent && isLikelyAgentInstance(candidate.agent)) {
602
+ candidate = candidate.agent;
603
+ }
604
+ if (!candidate || !isLikelyAgentInstance(candidate)) {
605
+ throw new Error(
606
+ "No agent export resolved (expected variable, function, or function returning an agent)"
607
+ );
608
+ }
609
+ return { agent: candidate };
610
+ }
611
+ };
612
+ var AgentManager = class {
613
+ constructor(sessionService, quiet = false) {
614
+ this.sessionService = sessionService;
615
+ this.quiet = quiet;
616
+ this.scanner = new AgentScanner(quiet);
617
+ this.loader = new AgentLoader(quiet);
618
+ }
619
+ agents = /* @__PURE__ */ new Map();
620
+ loadedAgents = /* @__PURE__ */ new Map();
621
+ scanner;
622
+ loader;
623
+ getAgents() {
624
+ return this.agents;
625
+ }
626
+ getLoadedAgents() {
627
+ return this.loadedAgents;
628
+ }
629
+ scanAgents(agentsDir) {
630
+ this.agents = this.scanner.scanAgents(agentsDir, this.loadedAgents);
631
+ }
455
632
  async startAgent(agentPath) {
456
633
  const agent = this.agents.get(agentPath);
457
634
  if (!agent) {
@@ -470,70 +647,31 @@ var ADKServer = class {
470
647
  `No agent.js or agent.ts file found in ${agent.absolutePath}`
471
648
  );
472
649
  }
473
- let projectRoot = dirname(agentFilePath);
474
- while (projectRoot !== "/" && projectRoot !== dirname(projectRoot)) {
475
- if (existsSync2(join2(projectRoot, "package.json")) || existsSync2(join2(projectRoot, ".env"))) {
476
- break;
477
- }
478
- projectRoot = dirname(projectRoot);
479
- }
480
- const envPath = join2(projectRoot, ".env");
481
- if (existsSync2(envPath)) {
482
- try {
483
- const envContent = readFileSync(envPath, "utf8");
484
- const envLines = envContent.split("\n");
485
- for (const line of envLines) {
486
- const trimmedLine = line.trim();
487
- if (trimmedLine && !trimmedLine.startsWith("#")) {
488
- const [key, ...valueParts] = trimmedLine.split("=");
489
- if (key && valueParts.length > 0) {
490
- const value = valueParts.join("=").replace(/^"(.*)"$/, "$1");
491
- process.env[key.trim()] = value.trim();
492
- }
493
- }
494
- }
495
- } catch (error) {
496
- console.warn(
497
- `\u26A0\uFE0F Warning: Could not load .env file: ${error instanceof Error ? error.message : String(error)}`
498
- );
499
- }
500
- }
650
+ this.loader.loadEnvironmentVariables(agentFilePath);
501
651
  const agentFileUrl = pathToFileURL(agentFilePath).href;
502
- const agentModule = agentFilePath.endsWith(".ts") ? await this.importTypeScriptFile(agentFilePath) : await import(agentFileUrl);
503
- if (!agentModule.agent) {
504
- throw new Error(`No 'agent' export found in ${agentFilePath}`);
505
- }
506
- if (!agentModule.agent || typeof agentModule.agent !== "object" || !agentModule.agent.name) {
652
+ const agentModule = agentFilePath.endsWith(".ts") ? await this.loader.importTypeScriptFile(agentFilePath) : await import(agentFileUrl);
653
+ const resolved = await this.loader.resolveAgentExport(agentModule);
654
+ const exportedAgent = resolved.agent;
655
+ if (!exportedAgent?.name) {
507
656
  throw new Error(
508
657
  `Invalid agent export in ${agentFilePath}. Expected an LlmAgent instance with a name property.`
509
658
  );
510
659
  }
511
- if (!agentModule.agent.model || !agentModule.agent.instruction) {
512
- }
513
- const agentBuilder = AgentBuilder.create(agentModule.agent.name).withModel(agentModule.agent.model).withDescription(agentModule.agent.description || "").withInstruction(agentModule.agent.instruction || "").withSessionService(this.sessionService, {
660
+ const agentBuilder = AgentBuilder.create(exportedAgent.name).withAgent(exportedAgent).withSessionService(this.sessionService, {
514
661
  userId: `user_${agentPath}`,
515
662
  appName: "adk-server"
516
663
  });
517
- if (agentModule.agent.tools && Array.isArray(agentModule.agent.tools) && agentModule.agent.tools.length > 0) {
518
- agentBuilder.withTools(...agentModule.agent.tools);
519
- if (!this.quiet) {
520
- const toolNames = agentModule.agent.tools.map((t) => t?.name || "<unnamed>").join(", ");
521
- console.log(
522
- `\u{1F9E9} Registered tools for agent "${agentModule.agent.name}": [${toolNames}]`
523
- );
524
- }
525
- }
526
664
  const { runner, session } = await agentBuilder.build();
527
665
  const loadedAgent = {
528
- agent: agentModule.agent,
666
+ agent: exportedAgent,
529
667
  runner,
530
668
  sessionId: session.id,
531
669
  userId: `user_${agentPath}`,
532
670
  appName: "adk-server"
533
671
  };
534
672
  this.loadedAgents.set(agentPath, loadedAgent);
535
- agent.instance = agentModule.agent;
536
- agent.name = agentModule.agent.name;
673
+ agent.instance = exportedAgent;
674
+ agent.name = exportedAgent.name;
537
675
  } catch (error) {
538
676
  console.error(`\u274C Failed to load agent "${agent.name}":`, error);
539
677
  throw new Error(
@@ -568,78 +706,65 @@ var ADKServer = class {
568
706
  throw new Error(`Failed to send message to agent: ${errorMessage}`);
569
707
  }
570
708
  }
571
- /**
572
- * Import a TypeScript file by compiling it on-demand
573
- */
574
- async importTypeScriptFile(filePath) {
575
- let projectRoot = dirname(filePath);
576
- while (projectRoot !== "/" && projectRoot !== dirname(projectRoot)) {
577
- if (existsSync2(join2(projectRoot, "package.json")) || existsSync2(join2(projectRoot, ".env"))) {
578
- break;
579
- }
580
- projectRoot = dirname(projectRoot);
709
+ stopAllAgents() {
710
+ for (const [agentPath] of this.loadedAgents.entries()) {
711
+ this.stopAgent(agentPath);
581
712
  }
713
+ }
714
+ };
715
+ var SessionManager = class {
716
+ constructor(sessionService) {
717
+ this.sessionService = sessionService;
718
+ }
719
+ async getSessionMessages(loadedAgent) {
582
720
  try {
583
- const { build } = await import("esbuild");
584
- const cacheDir = join2(projectRoot, ".adk-cache");
585
- if (!existsSync2(cacheDir)) {
586
- mkdirSync(cacheDir, { recursive: true });
587
- }
588
- const outFile = join2(cacheDir, `agent-${Date.now()}.mjs`);
589
- const plugin = {
590
- name: "externalize-bare-imports",
591
- setup(build2) {
592
- build2.onResolve({ filter: /.*/ }, (args) => {
593
- if (args.path.startsWith(".") || args.path.startsWith("/") || args.path.startsWith("..")) {
594
- return;
595
- }
596
- return { path: args.path, external: true };
597
- });
598
- }
599
- };
600
- const tsconfigPath = join2(projectRoot, "tsconfig.json");
601
- await build({
602
- entryPoints: [filePath],
603
- outfile: outFile,
604
- bundle: true,
605
- format: "esm",
606
- platform: "node",
607
- target: ["node22"],
608
- sourcemap: false,
609
- logLevel: "silent",
610
- plugins: [plugin],
611
- absWorkingDir: projectRoot,
612
- // Use tsconfig if present for path aliases
613
- ...existsSync2(tsconfigPath) ? { tsconfig: tsconfigPath } : {}
614
- });
615
- const mod = await import(`${pathToFileURL(outFile).href}?t=${Date.now()}`);
616
- let agentExport = mod?.agent;
617
- if (!agentExport && mod?.default) {
618
- agentExport = mod.default.agent ?? mod.default;
619
- }
620
- try {
621
- unlinkSync(outFile);
622
- } catch {
623
- }
624
- if (agentExport) {
625
- if (!this.quiet) {
626
- console.log(`\u2705 TS agent imported via esbuild: ${filePath}`);
627
- }
628
- return { agent: agentExport };
629
- }
630
- } catch (e) {
631
- throw new Error(
632
- `Failed to import TS agent via esbuild: ${e instanceof Error ? e.message : String(e)}`
721
+ const session = await this.sessionService.getSession(
722
+ loadedAgent.appName,
723
+ loadedAgent.userId,
724
+ loadedAgent.sessionId
633
725
  );
726
+ if (!session || !session.events) {
727
+ return [];
728
+ }
729
+ const messages = session.events.map((event, index) => ({
730
+ id: index + 1,
731
+ type: event.author === "user" ? "user" : "assistant",
732
+ content: event.content?.parts?.map(
733
+ (part) => typeof part === "object" && "text" in part ? part.text : ""
734
+ ).join("") || "",
735
+ timestamp: new Date(event.timestamp || Date.now()).toISOString()
736
+ }));
737
+ return messages;
738
+ } catch (error) {
739
+ console.error("Error fetching messages:", error);
740
+ return [];
634
741
  }
635
- throw new Error("No 'agent' export found in TypeScript module");
742
+ }
743
+ };
744
+
745
+ // src/server/index.ts
746
+ var ADKServer = class {
747
+ agentManager;
748
+ sessionManager;
749
+ sessionService;
750
+ app;
751
+ server;
752
+ config;
753
+ constructor(agentsDir, port = 8042, host = "localhost", quiet = false) {
754
+ this.config = { agentsDir, port, host, quiet };
755
+ this.sessionService = new InMemorySessionService();
756
+ this.agentManager = new AgentManager(this.sessionService, quiet);
757
+ this.sessionManager = new SessionManager(this.sessionService);
758
+ this.app = new Hono();
759
+ setupRoutes(this.app, this.agentManager, this.sessionManager, agentsDir);
760
+ this.agentManager.scanAgents(agentsDir);
636
761
  }
637
762
  async start() {
638
- return new Promise((resolve2, reject) => {
763
+ return new Promise((resolve2) => {
639
764
  this.server = serve({
640
765
  fetch: this.app.fetch,
641
- port: this.port,
642
- hostname: this.host
766
+ port: this.config.port,
767
+ hostname: this.config.host
643
768
  });
644
769
  setTimeout(() => {
645
770
  resolve2();
@@ -648,9 +773,7 @@ var ADKServer = class {
648
773
  }
649
774
  async stop() {
650
775
  return new Promise((resolve2) => {
651
- for (const [agentPath] of this.loadedAgents) {
652
- this.stopAgent(agentPath);
653
- }
776
+ this.agentManager.stopAllAgents();
654
777
  if (this.server) {
655
778
  this.server.close();
656
779
  }
@@ -658,19 +781,7 @@ var ADKServer = class {
658
781
  });
659
782
  }
660
783
  getPort() {
661
- return this.port;
662
- }
663
- extractAgentNameFromFile(filePath) {
664
- try {
665
- const content = readFileSync(filePath, "utf-8");
666
- const nameMatch = content.match(/name\s*:\s*["']([^"']+)["']/);
667
- if (nameMatch?.[1]) {
668
- return nameMatch[1];
669
- }
670
- return null;
671
- } catch {
672
- return null;
673
- }
784
+ return this.config.port;
674
785
  }
675
786
  };
676
787
 
@@ -963,8 +1074,7 @@ async function webCommand(options = {}) {
963
1074
  program.name("adk").description(package_default.description).version(package_default.version);
964
1075
  program.command("new").description("Create a new ADK project").argument("[project-name]", "Name of the project to create").option(
965
1076
  "-t, --template <template>",
966
- "Template to use (simple-agent, discord-bot, telegram-bot, hono-server, mcp-starter)",
967
- "simple-agent"
1077
+ "Template to use (simple-agent, discord-bot, telegram-bot, hono-server, mcp-starter)"
968
1078
  ).action(async (projectName, options) => {
969
1079
  try {
970
1080
  await createProject(projectName, options);