@botpress/adk 1.17.0 → 1.18.0-beta.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.
Files changed (93) hide show
  1. package/dist/agent-init/agent-project-generator.d.ts +32 -8
  2. package/dist/agent-init/agent-project-generator.d.ts.map +1 -1
  3. package/dist/agent-init/index.d.ts +1 -0
  4. package/dist/agent-init/index.d.ts.map +1 -1
  5. package/dist/agent-project/agent-project.d.ts +5 -1
  6. package/dist/agent-project/agent-project.d.ts.map +1 -1
  7. package/dist/agent-project/agent-resolver.d.ts +4 -3
  8. package/dist/agent-project/agent-resolver.d.ts.map +1 -1
  9. package/dist/agent-project/config-writer.d.ts +33 -0
  10. package/dist/agent-project/config-writer.d.ts.map +1 -1
  11. package/dist/agent-project/dependencies-parser.d.ts.map +1 -1
  12. package/dist/agent-project/index.d.ts +1 -1
  13. package/dist/agent-project/index.d.ts.map +1 -1
  14. package/dist/agent-project/types.d.ts +22 -4
  15. package/dist/agent-project/types.d.ts.map +1 -1
  16. package/dist/auth/credentials.d.ts.map +1 -1
  17. package/dist/bot-generator/dev-id-manager.d.ts.map +1 -1
  18. package/dist/bot-generator/generator.d.ts.map +1 -1
  19. package/dist/eval/index.d.ts +1 -1
  20. package/dist/eval/index.d.ts.map +1 -1
  21. package/dist/eval/loader.d.ts +2 -1
  22. package/dist/eval/loader.d.ts.map +1 -1
  23. package/dist/eval/types.d.ts +15 -2
  24. package/dist/eval/types.d.ts.map +1 -1
  25. package/dist/index.d.ts +4 -3
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +698 -462
  28. package/dist/index.js.map +21 -21
  29. package/dist/integrations/checker.d.ts.map +1 -1
  30. package/dist/integrations/config-utils.d.ts +1 -0
  31. package/dist/integrations/config-utils.d.ts.map +1 -1
  32. package/dist/integrations/operations.d.ts +19 -6
  33. package/dist/integrations/operations.d.ts.map +1 -1
  34. package/dist/knowledge/manager.d.ts.map +1 -1
  35. package/dist/preflight/checker.d.ts.map +1 -1
  36. package/dist/templates/README.md +101 -0
  37. package/dist/templates/blank/README.md +36 -0
  38. package/dist/templates/blank/agent.config.ts +49 -0
  39. package/dist/templates/blank/package.json +17 -0
  40. package/dist/templates/blank/src/actions/index.ts +19 -0
  41. package/dist/templates/blank/src/conversations/index.ts +16 -0
  42. package/dist/templates/blank/src/knowledge/index.ts +17 -0
  43. package/dist/templates/blank/src/tables/index.ts +19 -0
  44. package/dist/templates/blank/src/triggers/index.ts +20 -0
  45. package/dist/templates/blank/src/workflows/index.ts +23 -0
  46. package/dist/templates/blank/tsconfig.json +22 -0
  47. package/dist/templates/crm-enrichment/README.md +85 -0
  48. package/dist/templates/crm-enrichment/agent.config.ts +33 -0
  49. package/dist/templates/crm-enrichment/package.json +17 -0
  50. package/dist/templates/crm-enrichment/src/actions/enrich-contact.ts +81 -0
  51. package/dist/templates/crm-enrichment/src/conversations/index.ts +14 -0
  52. package/dist/templates/crm-enrichment/src/knowledge/index.ts +17 -0
  53. package/dist/templates/crm-enrichment/src/tables/contacts.ts +43 -0
  54. package/dist/templates/crm-enrichment/src/triggers/daily-enrichment.ts +30 -0
  55. package/dist/templates/crm-enrichment/src/workflows/enrichment-pipeline.ts +171 -0
  56. package/dist/templates/crm-enrichment/tsconfig.json +22 -0
  57. package/dist/templates/hello-world/README.md +46 -0
  58. package/dist/templates/hello-world/agent.config.ts +48 -0
  59. package/dist/templates/hello-world/package.json +17 -0
  60. package/dist/templates/hello-world/src/actions/index.ts +19 -0
  61. package/dist/templates/hello-world/src/conversations/index.ts +10 -0
  62. package/dist/templates/hello-world/src/knowledge/index.ts +17 -0
  63. package/dist/templates/hello-world/src/tables/index.ts +19 -0
  64. package/dist/templates/hello-world/src/triggers/index.ts +20 -0
  65. package/dist/templates/hello-world/src/workflows/index.ts +23 -0
  66. package/dist/templates/hello-world/tsconfig.json +22 -0
  67. package/dist/templates/knowledge-assistant/README.md +66 -0
  68. package/dist/templates/knowledge-assistant/agent.config.ts +26 -0
  69. package/dist/templates/knowledge-assistant/package.json +17 -0
  70. package/dist/templates/knowledge-assistant/src/actions/index.ts +19 -0
  71. package/dist/templates/knowledge-assistant/src/actions/search-docs.ts +50 -0
  72. package/dist/templates/knowledge-assistant/src/conversations/index.ts +33 -0
  73. package/dist/templates/knowledge-assistant/src/knowledge/docs.ts +23 -0
  74. package/dist/templates/knowledge-assistant/src/knowledge/getting-started.md +49 -0
  75. package/dist/templates/knowledge-assistant/src/tables/index.ts +21 -0
  76. package/dist/templates/knowledge-assistant/src/triggers/index.ts +17 -0
  77. package/dist/templates/knowledge-assistant/src/workflows/index.ts +28 -0
  78. package/dist/templates/knowledge-assistant/tsconfig.json +22 -0
  79. package/dist/templates/slack-triage/README.md +74 -0
  80. package/dist/templates/slack-triage/agent.config.ts +35 -0
  81. package/dist/templates/slack-triage/evals/triage-basic.eval.ts +55 -0
  82. package/dist/templates/slack-triage/package.json +17 -0
  83. package/dist/templates/slack-triage/src/actions/classify-request.ts +65 -0
  84. package/dist/templates/slack-triage/src/conversations/slack-dm.ts +72 -0
  85. package/dist/templates/slack-triage/src/knowledge/team-directory.md +33 -0
  86. package/dist/templates/slack-triage/src/tables/routing-rules.ts +38 -0
  87. package/dist/templates/slack-triage/src/triggers/new-message.ts +44 -0
  88. package/dist/templates/slack-triage/src/workflows/triage-flow.ts +104 -0
  89. package/dist/templates/slack-triage/tsconfig.json +22 -0
  90. package/dist/templates/template.config.json +47 -0
  91. package/dist/utils/json-ordering.d.ts +1 -1
  92. package/dist/utils/json-ordering.d.ts.map +1 -1
  93. package/package.json +2 -10
package/dist/index.js CHANGED
@@ -22,12 +22,15 @@ var init_types = __esm(() => {
22
22
  integrationInterfaceAlias: z.string().optional()
23
23
  });
24
24
  dependenciesSchema = z.object({
25
- integrations: z.record(z.object({
26
- version: z.string(),
27
- enabled: z.boolean(),
28
- configurationType: z.string().optional(),
29
- config: z.record(z.any()).optional()
30
- })).optional(),
25
+ integrations: z.record(z.union([
26
+ z.string(),
27
+ z.object({
28
+ version: z.string(),
29
+ enabled: z.boolean(),
30
+ configurationType: z.string().optional(),
31
+ config: z.record(z.any()).optional()
32
+ })
33
+ ])).optional(),
31
34
  plugins: z.record(z.object({
32
35
  version: z.string(),
33
36
  config: z.record(z.any()).optional(),
@@ -41,6 +44,9 @@ var init_types = __esm(() => {
41
44
  devId: z.string().optional().describe("The development ID used during local development")
42
45
  });
43
46
  agentLocalInfoSchema = z.object({
47
+ botId: z.string().optional().describe("The bot ID (overrides agent.json for local development)"),
48
+ workspaceId: z.string().optional().describe("The workspace ID (overrides agent.json for local development)"),
49
+ apiUrl: z.string().optional().describe("The Botpress API URL (overrides agent.json for local development)"),
44
50
  devId: z.string().optional().describe("The development bot ID used during local development")
45
51
  });
46
52
  ((ValidationErrorCode2) => {
@@ -470,9 +476,46 @@ var init_constants = __esm(() => {
470
476
  // src/agent-project/agent-resolver.ts
471
477
  import fs from "fs/promises";
472
478
  import path from "path";
479
+ async function readLocalInfo(agentPath) {
480
+ const localPath = path.join(agentPath, "agent.local.json");
481
+ try {
482
+ const localContent = await fs.readFile(localPath, "utf-8");
483
+ const localData = JSON.parse(localContent);
484
+ const localResult = agentLocalInfoSchema.safeParse(localData);
485
+ if (!localResult.success) {
486
+ const issue = localResult.error.errors[0];
487
+ throw ValidationErrors.warning(`agent.local.json has an invalid field: ${issue?.path.join(".")} — ${issue?.message}`, "agent.local.json");
488
+ }
489
+ return localResult.data;
490
+ } catch (error) {
491
+ if (error.code === "ENOENT") {
492
+ return null;
493
+ }
494
+ if (ValidationErrors.isValidationError(error)) {
495
+ throw error;
496
+ }
497
+ throw ValidationErrors.warning(`Failed to read agent.local.json: ${error.message}`, "agent.local.json");
498
+ }
499
+ }
500
+ function applyLocalOverrides(agentInfo, localInfo) {
501
+ if (localInfo.botId) {
502
+ agentInfo.botId = localInfo.botId;
503
+ }
504
+ if (localInfo.workspaceId) {
505
+ agentInfo.workspaceId = localInfo.workspaceId;
506
+ }
507
+ if (localInfo.apiUrl) {
508
+ agentInfo.apiUrl = localInfo.apiUrl;
509
+ }
510
+ if (localInfo.devId) {
511
+ agentInfo.devId = localInfo.devId;
512
+ }
513
+ }
473
514
  async function resolveAgent(agentPath, options = {}) {
474
515
  const { required = false, requireWorkspace = false, requireBot = false } = options;
475
516
  const agentJsonPath = path.join(agentPath, "agent.json");
517
+ const localInfo = await readLocalInfo(agentPath);
518
+ let agentInfo = null;
476
519
  try {
477
520
  const agentJsonContent = await fs.readFile(agentJsonPath, "utf-8");
478
521
  let agentData;
@@ -486,38 +529,42 @@ async function resolveAgent(agentPath, options = {}) {
486
529
  const zodError = validationResult.error.errors[0];
487
530
  throw ValidationErrors.invalidConfigSchema("agent.json", zodError?.path.join(".") || "unknown", zodError?.message || "Invalid schema");
488
531
  }
489
- const agentInfo = validationResult.data;
490
- if (!agentInfo.apiUrl) {
491
- agentInfo.apiUrl = DEFAULT_API_URL;
492
- }
493
- const localPath = path.join(agentPath, "agent.local.json");
494
- try {
495
- const localContent = await fs.readFile(localPath, "utf-8");
496
- const localData = JSON.parse(localContent);
497
- const localResult = agentLocalInfoSchema.safeParse(localData);
498
- if (localResult.success && localResult.data.devId) {
499
- agentInfo.devId = localResult.data.devId;
500
- }
501
- } catch {}
502
- if (requireWorkspace && !agentInfo.workspaceId) {
503
- throw ValidationErrors.workspaceIdMissing();
504
- }
505
- if (requireBot && !agentInfo.botId) {
506
- throw ValidationErrors.botIdMissing();
507
- }
508
- return agentInfo;
532
+ agentInfo = validationResult.data;
509
533
  } catch (error) {
510
- if (error.code === "ENOENT") {
511
- if (required || requireWorkspace || requireBot) {
512
- throw ValidationErrors.requiredFileMissing("agent.json");
513
- }
534
+ if (error.code === "ENOENT") {} else if (ValidationErrors.isValidationError(error)) {
535
+ throw error;
536
+ } else {
537
+ throw ValidationErrors.warning(`Failed to read agent.json: ${error.message}`, "agent.json");
538
+ }
539
+ }
540
+ if (!agentInfo) {
541
+ if (localInfo?.botId && localInfo?.workspaceId) {
542
+ agentInfo = {
543
+ botId: localInfo.botId,
544
+ workspaceId: localInfo.workspaceId,
545
+ apiUrl: localInfo.apiUrl,
546
+ devId: localInfo.devId
547
+ };
548
+ } else if (required || requireWorkspace || requireBot) {
549
+ throw ValidationErrors.requiredFileMissing("agent.json or agent.local.json");
550
+ } else {
514
551
  return null;
515
552
  }
516
- if (ValidationErrors.isValidationError(error)) {
517
- throw error;
553
+ } else {
554
+ if (localInfo) {
555
+ applyLocalOverrides(agentInfo, localInfo);
518
556
  }
519
- throw ValidationErrors.warning(`Failed to read agent.json: ${error.message}`, "agent.json");
520
557
  }
558
+ if (!agentInfo.apiUrl) {
559
+ agentInfo.apiUrl = DEFAULT_API_URL;
560
+ }
561
+ if (requireWorkspace && !agentInfo.workspaceId) {
562
+ throw ValidationErrors.workspaceIdMissing();
563
+ }
564
+ if (requireBot && !agentInfo.botId) {
565
+ throw ValidationErrors.botIdMissing();
566
+ }
567
+ return agentInfo;
521
568
  }
522
569
  var init_agent_resolver = __esm(() => {
523
570
  init_types();
@@ -694,7 +741,6 @@ class CredentialsManager {
694
741
  const store = await this.readCredentials();
695
742
  const matchingCredentials = this.findProfileByApiUrl(store, agentApiUrl);
696
743
  if (matchingCredentials) {
697
- console.info(`Using profile matching agent.json API URL (${agentApiUrl})`);
698
744
  baseCredentials = matchingCredentials;
699
745
  } else {
700
746
  const profileName = store.currentProfile || "default";
@@ -776,7 +822,7 @@ var _format = null, _formatLoaded = false, formatCode = async (code, filepath) =
776
822
  `));
777
823
  return code;
778
824
  }
779
- }, ADK_VERSION = "1.17.0", relative2 = (from, to) => {
825
+ }, ADK_VERSION = "1.18.0-beta.1", relative2 = (from, to) => {
780
826
  const fromDir = path10.dirname(from);
781
827
  const relative3 = path10.relative(fromDir, to);
782
828
  return relative3.startsWith(".") ? relative3 : `./${relative3}`;
@@ -907,7 +953,7 @@ var init_integration_action_types = __esm(() => {
907
953
  var require_package = __commonJS((exports, module) => {
908
954
  module.exports = {
909
955
  name: "@botpress/adk",
910
- version: "1.17.0",
956
+ version: "1.18.0-beta.1",
911
957
  description: "Core ADK library for building AI agents on Botpress",
912
958
  keywords: [
913
959
  "adk",
@@ -956,7 +1002,7 @@ var require_package = __commonJS((exports, module) => {
956
1002
  "@botpress/cli": "6.2.2",
957
1003
  "@botpress/client": "1.38.1",
958
1004
  "@botpress/cognitive": "0.4.2",
959
- "@botpress/runtime": "^1.17.0",
1005
+ "@botpress/runtime": "^1.18.0-beta.1",
960
1006
  "@botpress/sdk": "6.3.1",
961
1007
  "@bpinternal/jex": "^1.2.4",
962
1008
  "@bpinternal/yargs-extra": "^0.0.21",
@@ -970,14 +1016,6 @@ var require_package = __commonJS((exports, module) => {
970
1016
  semver: "^7.7.2",
971
1017
  "ts-morph": "^27.0.2"
972
1018
  },
973
- devDependencies: {
974
- "@bpinternal/zui": "2.1.0",
975
- "@types/debug": "^4.1.12",
976
- "@types/glob": "^9.0.0",
977
- "@types/luxon": "^3.7.1",
978
- "@types/semver": "^7.7.1",
979
- dotenv: "^17.2.3"
980
- },
981
1019
  peerDependencies: {
982
1020
  typescript: ">=4.5.0"
983
1021
  },
@@ -2266,7 +2304,7 @@ function getChatClient(cwd = process.cwd()) {
2266
2304
  }
2267
2305
  // src/utils/json-ordering.ts
2268
2306
  var agentInfoKeyOrder = ["botId", "workspaceId", "apiUrl"];
2269
- var agentLocalInfoKeyOrder = ["devId"];
2307
+ var agentLocalInfoKeyOrder = ["botId", "workspaceId", "apiUrl", "devId"];
2270
2308
  var dependenciesKeyOrder = ["integrations"];
2271
2309
  var integrationKeyOrder = ["version", "enabled", "configurationType", "config"];
2272
2310
  function orderKeys(obj, keyOrder) {
@@ -2317,6 +2355,7 @@ function stringifyWithOrder(obj, keyOrder, space = 2) {
2317
2355
  }
2318
2356
  // src/agent-project/agent-project.ts
2319
2357
  import { BuiltInActions, BuiltInWorkflows, Errors as Errors2, Primitives as Primitives2, setAdkCommand } from "@botpress/runtime/internal";
2358
+ import { Autonomous } from "@botpress/runtime";
2320
2359
  import createDebug2 from "debug";
2321
2360
  import { createRequire as createRequire3 } from "module";
2322
2361
  import fs10 from "fs/promises";
@@ -2935,7 +2974,8 @@ class IntegrationParser {
2935
2974
  errors.push(ValidationErrors.invalidIntegrationAlias(alias));
2936
2975
  continue;
2937
2976
  }
2938
- const ref = this.parseIntegrationRef(value.version);
2977
+ const normalized = typeof value === "string" ? { version: value } : value;
2978
+ const ref = this.parseIntegrationRef(normalized.version);
2939
2979
  const versionResult = versionSchema.safeParse(ref.version);
2940
2980
  if (!versionResult.success) {
2941
2981
  errors.push(ValidationErrors.invalidVersionFormat(alias, ref.version));
@@ -2943,9 +2983,9 @@ class IntegrationParser {
2943
2983
  integrations.push({
2944
2984
  alias,
2945
2985
  ref,
2946
- enabled: value.enabled,
2947
- configurationType: value.configurationType,
2948
- config: value.config
2986
+ enabled: "enabled" in normalized ? normalized.enabled : undefined,
2987
+ configurationType: "configurationType" in normalized ? normalized.configurationType : undefined,
2988
+ config: "config" in normalized ? normalized.config : undefined
2949
2989
  });
2950
2990
  } catch (error) {
2951
2991
  errors.push(ValidationErrors.invalidDependenciesSyntax(`Invalid integration '${alias}': ${error instanceof Error ? error.message : String(error)}`));
@@ -3262,7 +3302,7 @@ class IntegrationManager {
3262
3302
  return { valid: false, errors, warnings };
3263
3303
  }
3264
3304
  const hasChannels = integration.definition.channels && Object.keys(integration.definition.channels).length > 0;
3265
- if (!integration.config) {
3305
+ if (!integration.config && integration.enabled !== undefined) {
3266
3306
  let requiresConfig = false;
3267
3307
  if (integration.definition.configurations) {
3268
3308
  requiresConfig = Object.values(integration.definition.configurations).some((config) => config.identifier?.required === true);
@@ -3532,6 +3572,7 @@ class HubCache {
3532
3572
  // src/agent-project/config-writer.ts
3533
3573
  init_utils();
3534
3574
  import { Project, SyntaxKind } from "ts-morph";
3575
+ import { readFileSync } from "fs";
3535
3576
  import * as path11 from "path";
3536
3577
 
3537
3578
  class ConfigWriter {
@@ -3541,7 +3582,9 @@ class ConfigWriter {
3541
3582
  }
3542
3583
  loadConfig() {
3543
3584
  const project = new Project;
3544
- const sourceFile = project.addSourceFileAtPath(this.configPath);
3585
+ const sourceFile = project.createSourceFile(this.configPath, readFileSync(this.configPath, "utf-8"), {
3586
+ overwrite: true
3587
+ });
3545
3588
  const defineConfigCall = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression).find((call) => {
3546
3589
  return call.getExpression().getText() === "defineConfig";
3547
3590
  });
@@ -3561,6 +3604,47 @@ class ConfigWriter {
3561
3604
  sourceFile.replaceWithText(formatted);
3562
3605
  await sourceFile.save();
3563
3606
  }
3607
+ serializeDefaultModelSelection(value) {
3608
+ if (Array.isArray(value)) {
3609
+ return `[${value.map((entry) => `'${entry.replace(/'/g, "\\'")}'`).join(", ")}]`;
3610
+ }
3611
+ return `'${value.replace(/'/g, "\\'")}'`;
3612
+ }
3613
+ getIntegrationConfigMigrationCandidates() {
3614
+ const { sourceFile, configObject } = this.loadConfig();
3615
+ const dependenciesProp = configObject.getProperty("dependencies");
3616
+ if (!dependenciesProp) {
3617
+ return { sourceFile, candidates: [] };
3618
+ }
3619
+ const depsInit = dependenciesProp.getInitializerIfKind(SyntaxKind.ObjectLiteralExpression);
3620
+ if (!depsInit) {
3621
+ return { sourceFile, candidates: [] };
3622
+ }
3623
+ const integrationsProp = depsInit.getProperty("integrations");
3624
+ if (!integrationsProp) {
3625
+ return { sourceFile, candidates: [] };
3626
+ }
3627
+ const integrationsInit = integrationsProp.getInitializerIfKind(SyntaxKind.ObjectLiteralExpression);
3628
+ if (!integrationsInit) {
3629
+ return { sourceFile, candidates: [] };
3630
+ }
3631
+ const candidates = integrationsInit.getProperties().flatMap((prop) => {
3632
+ if (!prop.isKind(SyntaxKind.PropertyAssignment)) {
3633
+ return [];
3634
+ }
3635
+ const assignment = prop;
3636
+ const initializer = assignment.getInitializerIfKind(SyntaxKind.ObjectLiteralExpression);
3637
+ if (!initializer) {
3638
+ return [];
3639
+ }
3640
+ const hasConfigProperty = initializer.getProperty("config") !== undefined;
3641
+ const versionProp = initializer.getProperty("version");
3642
+ const versionInitializer = versionProp?.getInitializer();
3643
+ const versionInitializerText = versionInitializer && (versionInitializer.isKind(SyntaxKind.StringLiteral) || versionInitializer.isKind(SyntaxKind.NoSubstitutionTemplateLiteral)) ? versionInitializer.getText() : undefined;
3644
+ return [{ alias: assignment.getName(), assignment, hasConfigProperty, versionInitializerText }];
3645
+ });
3646
+ return { sourceFile, candidates };
3647
+ }
3564
3648
  async updateDependencies(dependencies) {
3565
3649
  const { sourceFile, configObject } = this.loadConfig();
3566
3650
  let dependenciesProperty = configObject.getProperty("dependencies");
@@ -3582,6 +3666,67 @@ class ConfigWriter {
3582
3666
  }
3583
3667
  await this.saveConfig(sourceFile);
3584
3668
  }
3669
+ async updateDefaultModels(updates) {
3670
+ const requestedEntries = Object.entries(updates).filter(([, value]) => value !== undefined);
3671
+ if (requestedEntries.length === 0) {
3672
+ return;
3673
+ }
3674
+ const { sourceFile, configObject } = this.loadConfig();
3675
+ let defaultModelsProperty = configObject.getProperty("defaultModels");
3676
+ if (!defaultModelsProperty) {
3677
+ defaultModelsProperty = configObject.addPropertyAssignment({
3678
+ name: "defaultModels",
3679
+ initializer: "{}"
3680
+ });
3681
+ }
3682
+ const defaultModelsObject = defaultModelsProperty.getInitializerIfKind(SyntaxKind.ObjectLiteralExpression);
3683
+ if (!defaultModelsObject) {
3684
+ throw new Error("defaultModels must be an object literal in agent.config.ts");
3685
+ }
3686
+ for (const [key, value] of requestedEntries) {
3687
+ const existingProperty = defaultModelsObject.getProperty(key);
3688
+ const initializer = this.serializeDefaultModelSelection(value);
3689
+ if (existingProperty) {
3690
+ existingProperty.setInitializer(initializer);
3691
+ } else {
3692
+ defaultModelsObject.addPropertyAssignment({
3693
+ name: key,
3694
+ initializer
3695
+ });
3696
+ }
3697
+ }
3698
+ await this.saveConfig(sourceFile);
3699
+ }
3700
+ async migrateIntegrationsToStringFormat() {
3701
+ const { sourceFile, candidates } = this.getIntegrationConfigMigrationCandidates();
3702
+ const migrated = [];
3703
+ for (const candidate of candidates) {
3704
+ if (!candidate.versionInitializerText || candidate.hasConfigProperty) {
3705
+ continue;
3706
+ }
3707
+ candidate.assignment.setInitializer(candidate.versionInitializerText);
3708
+ migrated.push(candidate.alias);
3709
+ }
3710
+ if (migrated.length > 0) {
3711
+ await this.saveConfig(sourceFile);
3712
+ }
3713
+ return migrated;
3714
+ }
3715
+ getIntegrationConfigMigrationState() {
3716
+ try {
3717
+ const { candidates } = this.getIntegrationConfigMigrationCandidates();
3718
+ const deprecatedAliases = candidates.map((candidate) => candidate.alias);
3719
+ const migratableAliases = candidates.filter((candidate) => candidate.versionInitializerText && !candidate.hasConfigProperty).map((candidate) => candidate.alias);
3720
+ return { deprecatedAliases, migratableAliases };
3721
+ } catch (error) {
3722
+ const message = error instanceof Error ? error.message : String(error);
3723
+ console.error(`Configuration update failed with error: ${message} — please verify that there are no syntax errors in your agent.config.ts`);
3724
+ return { deprecatedAliases: [], migratableAliases: [] };
3725
+ }
3726
+ }
3727
+ getObjectFormatIntegrations() {
3728
+ return this.getIntegrationConfigMigrationState().deprecatedAliases;
3729
+ }
3585
3730
  async updateConfiguration(updates) {
3586
3731
  const { sourceFile, configObject } = this.loadConfig();
3587
3732
  const hasAdds = updates.some((u) => u.action === "add");
@@ -3693,6 +3838,66 @@ class IntegrationOperations {
3693
3838
  }
3694
3839
  return { name, version, fullName: name };
3695
3840
  }
3841
+ isIntegrationVersionId(input) {
3842
+ return input.startsWith("intver_");
3843
+ }
3844
+ isResourceNotFoundError(error) {
3845
+ return Boolean(error && typeof error === "object" && "type" in error && error.type === "ResourceNotFound");
3846
+ }
3847
+ getCanonicalIntegrationFullName(integration) {
3848
+ if (integration.public) {
3849
+ return integration.name;
3850
+ }
3851
+ const workspaceHandle = integration.ownerWorkspace?.handle;
3852
+ return workspaceHandle ? `${workspaceHandle}/${integration.name}` : integration.name;
3853
+ }
3854
+ async resolveIntegrationVersionId(id) {
3855
+ const client = await this.getClient();
3856
+ try {
3857
+ const response = await client.getIntegration({ id });
3858
+ return response.integration;
3859
+ } catch (error) {
3860
+ if (!this.isResourceNotFoundError(error)) {
3861
+ throw error;
3862
+ }
3863
+ }
3864
+ try {
3865
+ const response = await client.getPublicIntegrationById({ id });
3866
+ return response.integration;
3867
+ } catch (error) {
3868
+ if (this.isResourceNotFoundError(error)) {
3869
+ throw new Error(`Integration "${id}" not found`);
3870
+ }
3871
+ throw error;
3872
+ }
3873
+ }
3874
+ async resolveAddIntegrationInput(options) {
3875
+ const requestedVersion = options.version || "latest";
3876
+ if (!this.isIntegrationVersionId(options.name)) {
3877
+ const ref = this.parseIntegrationRef(`${options.name}@${requestedVersion}`);
3878
+ return {
3879
+ name: ref.name,
3880
+ fullName: ref.fullName,
3881
+ version: ref.version,
3882
+ alias: options.alias || ref.name,
3883
+ ref: `${ref.fullName}@${ref.version}`,
3884
+ isIntegrationId: false
3885
+ };
3886
+ }
3887
+ if (options.version && options.version !== "latest") {
3888
+ throw new Error("Integration version IDs are already version-pinned and do not accept an additional @version override");
3889
+ }
3890
+ const integration = await this.resolveIntegrationVersionId(options.name);
3891
+ const fullName = this.getCanonicalIntegrationFullName(integration);
3892
+ return {
3893
+ name: integration.name,
3894
+ fullName,
3895
+ version: integration.version,
3896
+ alias: options.alias || integration.name,
3897
+ ref: `${fullName}@${integration.version}`,
3898
+ isIntegrationId: true
3899
+ };
3900
+ }
3696
3901
  async getIntegrationVersions(name) {
3697
3902
  const client = await this.getClient();
3698
3903
  const ref = this.parseIntegrationRef(name);
@@ -3726,9 +3931,8 @@ class IntegrationOperations {
3726
3931
  }
3727
3932
  async addIntegration(options) {
3728
3933
  const project = await AgentProject.load(this.projectPath || process2.cwd());
3729
- const { name, version = "latest" } = options;
3730
- const ref = this.parseIntegrationRef(`${name}@${version}`);
3731
- const alias = options.alias || ref.name;
3934
+ const resolvedInput = await this.resolveAddIntegrationInput(options);
3935
+ const { alias } = resolvedInput;
3732
3936
  const dependencies = project.dependencies || { integrations: {} };
3733
3937
  if (!dependencies.integrations) {
3734
3938
  dependencies.integrations = {};
@@ -3745,11 +3949,17 @@ class IntegrationOperations {
3745
3949
  } else {
3746
3950
  existingVersion = "unknown";
3747
3951
  }
3748
- if (!version || version === "latest" || version === existingVersion) {
3952
+ const effectiveVersionSpecified = Boolean(options.version) || resolvedInput.isIntegrationId;
3953
+ if (!effectiveVersionSpecified || resolvedInput.version === "latest" || resolvedInput.version === existingVersion) {
3749
3954
  return {
3750
3955
  success: false,
3751
3956
  message: `Integration '${alias}' already exists with version ${existingVersion}. Use 'adk upgrade ${alias}' to upgrade to the latest version.`,
3752
- existingVersion
3957
+ existingVersion,
3958
+ name: resolvedInput.name,
3959
+ fullName: resolvedInput.fullName,
3960
+ alias: resolvedInput.alias,
3961
+ version: existingVersion,
3962
+ ref: `${resolvedInput.fullName}@${existingVersion}`
3753
3963
  };
3754
3964
  }
3755
3965
  }
@@ -3761,7 +3971,7 @@ class IntegrationOperations {
3761
3971
  const loadResult = await tempManager.loadIntegrations({
3762
3972
  integrations: {
3763
3973
  [alias]: {
3764
- version: `${ref.fullName}@${ref.version}`,
3974
+ version: resolvedInput.ref,
3765
3975
  enabled: true
3766
3976
  }
3767
3977
  }
@@ -3779,88 +3989,28 @@ class IntegrationOperations {
3779
3989
  throw new Error(`Failed to add integration: ${error instanceof Error ? error.message : String(error)}`);
3780
3990
  }
3781
3991
  const actualVersion = integrationDefinition.version;
3782
- const integrationVersion = `${ref.fullName}@${actualVersion}`;
3992
+ const integrationVersion = `${resolvedInput.fullName}@${actualVersion}`;
3783
3993
  const existingEntry = dependencies.integrations[alias];
3784
- const existingConfig = existingEntry && typeof existingEntry === "object" ? existingEntry.config : undefined;
3785
- const existingConfigurationType = existingEntry && typeof existingEntry === "object" ? existingEntry.configurationType : undefined;
3786
- const configurationType = existingConfigurationType || this.selectBestConfigurationType(integrationDefinition.configurations);
3787
- let requiresConfiguration = false;
3788
- const selectedConfigDef = configurationType && integrationDefinition.configurations?.[configurationType] || integrationDefinition.configurations?.["default"] || integrationDefinition.configuration;
3789
- if (selectedConfigDef) {
3790
- if (selectedConfigDef.identifier?.required === true) {
3791
- requiresConfiguration = true;
3792
- }
3793
- if (selectedConfigDef.schema?.required && selectedConfigDef.schema.required.length > 0) {
3794
- requiresConfiguration = true;
3795
- }
3796
- }
3797
- const config = requiresConfiguration && !existingConfig ? this.getPlaceholderConfig(integrationDefinition, configurationType) : existingConfig;
3798
3994
  if (existingEntry && typeof existingEntry === "object" && "version" in existingEntry) {
3799
- const resolvedConfigType = existingEntry.configurationType || configurationType;
3800
3995
  dependencies.integrations[alias] = {
3801
- version: integrationVersion,
3802
- enabled: existingEntry.enabled,
3803
- ...resolvedConfigType ? { configurationType: resolvedConfigType } : {},
3804
- config: existingEntry.config
3996
+ ...existingEntry,
3997
+ version: integrationVersion
3805
3998
  };
3806
3999
  } else {
3807
- dependencies.integrations[alias] = {
3808
- version: integrationVersion,
3809
- enabled: !requiresConfiguration,
3810
- ...configurationType ? { configurationType } : {},
3811
- config
3812
- };
4000
+ dependencies.integrations[alias] = integrationVersion;
3813
4001
  }
3814
4002
  const configWriter = new ConfigWriter(project.path);
3815
4003
  await configWriter.updateDependencies(dependencies);
3816
4004
  return {
3817
4005
  success: true,
3818
- requiresConfiguration,
3819
- newVersion: actualVersion
4006
+ newVersion: actualVersion,
4007
+ name: resolvedInput.name,
4008
+ fullName: resolvedInput.fullName,
4009
+ alias: resolvedInput.alias,
4010
+ version: actualVersion,
4011
+ ref: integrationVersion
3820
4012
  };
3821
4013
  }
3822
- selectBestConfigurationType(configurations) {
3823
- if (!configurations || Object.keys(configurations).length === 0) {
3824
- return;
3825
- }
3826
- const keys = Object.keys(configurations);
3827
- if (keys.length === 1) {
3828
- return keys[0];
3829
- }
3830
- const priority = ["apiKey", "api", "api_key", "token", "default", "refreshToken", "oauth", "oauth2"];
3831
- for (const preferred of priority) {
3832
- const match = keys.find((k) => k.toLowerCase() === preferred.toLowerCase());
3833
- if (match)
3834
- return match;
3835
- }
3836
- return keys[0];
3837
- }
3838
- getPlaceholderConfig(integrationDefinition, configurationType) {
3839
- const configPlaceholder = {};
3840
- const configDef = configurationType && integrationDefinition.configurations?.[configurationType] || integrationDefinition.configurations?.["default"] || integrationDefinition.configuration;
3841
- if (configDef) {
3842
- const schema = configDef.schema;
3843
- if (schema?.required && schema.required.length > 0) {
3844
- const properties = schema.properties || {};
3845
- for (const fieldName of schema.required) {
3846
- const fieldDef = properties[fieldName];
3847
- if (fieldDef?.type === "string") {
3848
- configPlaceholder[fieldName] = `YOUR_${fieldName.toUpperCase()}_HERE`;
3849
- } else if (fieldDef?.type === "number" || fieldDef?.type === "integer") {
3850
- configPlaceholder[fieldName] = 0;
3851
- } else if (fieldDef?.type === "boolean") {
3852
- configPlaceholder[fieldName] = false;
3853
- } else {
3854
- configPlaceholder[fieldName] = null;
3855
- }
3856
- }
3857
- if (Object.keys(configPlaceholder).length > 0) {
3858
- return configPlaceholder;
3859
- }
3860
- }
3861
- }
3862
- return;
3863
- }
3864
4014
  async removeIntegration(name) {
3865
4015
  const project = await AgentProject.load(this.projectPath || process2.cwd());
3866
4016
  const dependencies = project.dependencies;
@@ -3899,10 +4049,8 @@ class IntegrationOperations {
3899
4049
  }
3900
4050
  const versionInfo = await this.getIntegrationVersions(ref.fullName);
3901
4051
  if (versionInfo.latestVersion && versionInfo.latestVersion !== currentVersion) {
3902
- dependencies.integrations[alias] = {
3903
- ...value,
3904
- version: `${ref.fullName}@${versionInfo.latestVersion}`
3905
- };
4052
+ const newVersion = `${ref.fullName}@${versionInfo.latestVersion}`;
4053
+ dependencies.integrations[alias] = typeof value === "string" ? newVersion : { ...value, version: newVersion };
3906
4054
  upgraded.push(`${alias} (${currentVersion} → ${versionInfo.latestVersion})`);
3907
4055
  }
3908
4056
  } catch {
@@ -3991,7 +4139,7 @@ async function fetchServerIntegrationConfigs(project, targetBotId) {
3991
4139
  const { devId, botId } = project.agentInfo ?? {};
3992
4140
  const targetId = targetBotId || devId || botId;
3993
4141
  if (!targetId) {
3994
- return { configs: {}, fetched: false, skipped: true };
4142
+ return { configs: {}, enabledStates: {}, fetched: false, skipped: true };
3995
4143
  }
3996
4144
  try {
3997
4145
  const credentials = await auth.getActiveCredentials();
@@ -4014,18 +4162,26 @@ async function fetchServerIntegrationConfigs(project, targetBotId) {
4014
4162
  }
4015
4163
  } catch (err) {
4016
4164
  const message = err instanceof Error ? err.message : String(err);
4017
- return { configs: {}, fetched: false, skipped: false, error: message };
4165
+ return {
4166
+ configs: {},
4167
+ enabledStates: {},
4168
+ fetched: false,
4169
+ skipped: false,
4170
+ error: message
4171
+ };
4018
4172
  }
4019
4173
  }
4020
4174
  async function fetchBotConfigs(client, botId) {
4021
4175
  const { bot } = await client.getBot({ id: botId });
4022
4176
  const configs = {};
4177
+ const enabledStates = {};
4023
4178
  for (const [alias, integration] of Object.entries(bot.integrations || {})) {
4024
4179
  if (integration.configuration && Object.keys(integration.configuration).length > 0) {
4025
4180
  configs[alias] = integration.configuration;
4026
4181
  }
4182
+ enabledStates[alias] = integration.enabled;
4027
4183
  }
4028
- return { configs, fetched: true, skipped: false };
4184
+ return { configs, enabledStates, fetched: true, skipped: false };
4029
4185
  }
4030
4186
 
4031
4187
  // src/integrations/checker.ts
@@ -4139,7 +4295,7 @@ class IntegrationChecker {
4139
4295
  }
4140
4296
  }
4141
4297
  }
4142
- const desiredInstallStatus = enabled === false ? "disabled" : "enabled";
4298
+ const desiredInstallStatus = enabled === true ? "enabled" : enabled === false ? "disabled" : installedIntegration ? installedIntegration.enabled ? "enabled" : "disabled" : "disabled";
4143
4299
  const result = {
4144
4300
  alias,
4145
4301
  name: ref.fullName,
@@ -4167,7 +4323,7 @@ class IntegrationChecker {
4167
4323
  }
4168
4324
  }
4169
4325
  if (!installedIntegration) {
4170
- result.needsInstall = enabled !== false;
4326
+ result.needsInstall = true;
4171
4327
  if (result.needsInstall && config) {
4172
4328
  result.needsConfiguration = true;
4173
4329
  }
@@ -4187,11 +4343,7 @@ class IntegrationChecker {
4187
4343
  }
4188
4344
  }
4189
4345
  if (enabled !== undefined && enabled !== installedIntegration.enabled) {
4190
- if (enabled === false) {
4191
- result.needsRemoval = true;
4192
- } else if (enabled === true && result.installStatus === "disabled") {
4193
- result.needsConfiguration = true;
4194
- }
4346
+ result.needsUpdate = true;
4195
4347
  }
4196
4348
  }
4197
4349
  return result;
@@ -4728,6 +4880,21 @@ init_agent_resolver();
4728
4880
  init_types();
4729
4881
  init_validation_errors();
4730
4882
  var debug2 = createDebug2("adk:agent-project");
4883
+ function getToolDefinition(value) {
4884
+ if (typeof value !== "object" || value === null) {
4885
+ return;
4886
+ }
4887
+ const maybeTool = value;
4888
+ const isAutonomousToolInstance = value instanceof Autonomous.Tool;
4889
+ const looksLikeAutonomousTool = maybeTool.constructor?.name === Autonomous.Tool.name && typeof maybeTool.name === "string" && typeof maybeTool.execute === "function" && typeof maybeTool.toJSON === "function";
4890
+ if (!isAutonomousToolInstance && !looksLikeAutonomousTool) {
4891
+ return;
4892
+ }
4893
+ return {
4894
+ name: maybeTool.name,
4895
+ description: maybeTool.description
4896
+ };
4897
+ }
4731
4898
 
4732
4899
  class AgentProject {
4733
4900
  static _projectCache = new Map;
@@ -4751,6 +4918,7 @@ class AgentProject {
4751
4918
  _workflows = [];
4752
4919
  _actions = [];
4753
4920
  _tables = [];
4921
+ _tools = [];
4754
4922
  constructor(projectPath, options = {}) {
4755
4923
  this._options = options;
4756
4924
  this._path = path13.resolve(projectPath);
@@ -4807,6 +4975,9 @@ class AgentProject {
4807
4975
  get tables() {
4808
4976
  return this._tables;
4809
4977
  }
4978
+ get tools() {
4979
+ return this._tools;
4980
+ }
4810
4981
  get config() {
4811
4982
  return this._config;
4812
4983
  }
@@ -4845,6 +5016,7 @@ class AgentProject {
4845
5016
  this._workflows = [];
4846
5017
  this._actions = [];
4847
5018
  this._tables = [];
5019
+ this._tools = [];
4848
5020
  this._errors = [];
4849
5021
  this._warnings = [];
4850
5022
  const validation = await this.validate();
@@ -5018,7 +5190,21 @@ class AgentProject {
5018
5190
  const content = stringifyWithOrder(merged, agentLocalInfoKeyOrder);
5019
5191
  await fs10.writeFile(localPath, content);
5020
5192
  if (this._agentInfo) {
5021
- this._agentInfo.devId = merged.devId;
5193
+ if (merged.botId)
5194
+ this._agentInfo.botId = merged.botId;
5195
+ if (merged.workspaceId)
5196
+ this._agentInfo.workspaceId = merged.workspaceId;
5197
+ if (merged.apiUrl)
5198
+ this._agentInfo.apiUrl = merged.apiUrl;
5199
+ if (merged.devId)
5200
+ this._agentInfo.devId = merged.devId;
5201
+ } else if (merged.botId && merged.workspaceId) {
5202
+ this._agentInfo = {
5203
+ botId: merged.botId,
5204
+ workspaceId: merged.workspaceId,
5205
+ apiUrl: merged.apiUrl,
5206
+ devId: merged.devId
5207
+ };
5022
5208
  }
5023
5209
  }
5024
5210
  async updateAgentLocalInfo(updates) {
@@ -5037,7 +5223,15 @@ class AgentProject {
5037
5223
  const content = stringifyWithOrder(updated, agentLocalInfoKeyOrder);
5038
5224
  await fs10.writeFile(localPath, content);
5039
5225
  if (this._agentInfo) {
5040
- this._agentInfo.devId = updated.devId;
5226
+ const local = updated;
5227
+ if (local.botId)
5228
+ this._agentInfo.botId = local.botId;
5229
+ if (local.workspaceId)
5230
+ this._agentInfo.workspaceId = local.workspaceId;
5231
+ if (local.apiUrl)
5232
+ this._agentInfo.apiUrl = local.apiUrl;
5233
+ if (local.devId)
5234
+ this._agentInfo.devId = local.devId;
5041
5235
  }
5042
5236
  }
5043
5237
  requiresAgentInfo(operation) {
@@ -5242,6 +5436,19 @@ ${err.stack?.split(`
5242
5436
  }
5243
5437
  return true;
5244
5438
  }
5439
+ isToolBarrelReexport(existingPath, newPath) {
5440
+ const isNewBarrel = /^index\.[tj]s$/i.test(path13.basename(newPath));
5441
+ const isExistingBarrel = /^index\.[tj]s$/i.test(path13.basename(existingPath));
5442
+ if (!isNewBarrel && !isExistingBarrel) {
5443
+ return false;
5444
+ }
5445
+ return true;
5446
+ }
5447
+ shouldPreferToolDefinition(existingPath, newPath) {
5448
+ const isNewBarrel = /^index\.[tj]s$/i.test(path13.basename(newPath));
5449
+ const isExistingBarrel = /^index\.[tj]s$/i.test(path13.basename(existingPath));
5450
+ return isExistingBarrel && !isNewBarrel;
5451
+ }
5245
5452
  getChannelsList(channelSpec) {
5246
5453
  if (channelSpec === "*") {
5247
5454
  return ["*"];
@@ -5442,6 +5649,35 @@ ${err.stack?.split(`
5442
5649
  export: key,
5443
5650
  path: relPath
5444
5651
  });
5652
+ } else {
5653
+ const toolDefinition = getToolDefinition(expandedExports[key]);
5654
+ if (!toolDefinition) {
5655
+ continue;
5656
+ }
5657
+ const existing = this._tools.find((tool) => tool.definition.name === toolDefinition.name);
5658
+ if (existing) {
5659
+ if (this.isToolBarrelReexport(existing.path, relPath)) {
5660
+ if (this.shouldPreferToolDefinition(existing.path, relPath)) {
5661
+ existing.path = relPath;
5662
+ existing.export = key;
5663
+ existing.definition = toolDefinition;
5664
+ }
5665
+ continue;
5666
+ }
5667
+ this._warnings.push({
5668
+ $type: "ValidationError",
5669
+ code: "DUPLICATE_PRIMITIVE" /* DUPLICATE_PRIMITIVE */,
5670
+ severity: "warning" /* WARNING */,
5671
+ message: `Duplicate tool definition found: ${filename} -> ${key} (already defined in ${existing.path} -> ${existing.export})`,
5672
+ file: relPath
5673
+ });
5674
+ continue;
5675
+ }
5676
+ this._tools.push({
5677
+ definition: toolDefinition,
5678
+ export: key,
5679
+ path: relPath
5680
+ });
5445
5681
  }
5446
5682
  }
5447
5683
  } catch (error) {
@@ -5725,6 +5961,8 @@ class ConfigManager {
5725
5961
  init_utils();
5726
5962
  import * as fs11 from "fs";
5727
5963
  import * as path15 from "path";
5964
+ import { fileURLToPath } from "url";
5965
+ import { createRequire as createRequire4 } from "module";
5728
5966
 
5729
5967
  // src/agent-init/ai-assistant-instructions.template.md
5730
5968
  var ai_assistant_instructions_template_default = `# Botpress ADK Agent
@@ -5775,10 +6013,12 @@ Run \`adk mcp:init --all\` to generate configuration for your editor, or use the
5775
6013
 
5776
6014
  ### Workflows
5777
6015
 
5778
- | Tool | Use for |
5779
- | -------------------- | ------------------------------------------ |
5780
- | \`adk_list_workflows\` | List available workflows with descriptions |
5781
- | \`adk_start_workflow\` | Start a workflow or get its input schema |
6016
+ | Tool | Use for |
6017
+ | -------------------- | ---------------------------------------- |
6018
+ | \`adk_list_workflows\` | Deprecated compat workflow discovery |
6019
+ | \`adk_start_workflow\` | Start a workflow or get its input schema |
6020
+
6021
+ > **Tip:** Prefer \`adk workflows\` in the terminal to discover workflow names and metadata. Keep \`adk_list_workflows\` for MCP compatibility only.
5782
6022
 
5783
6023
  > **Tip:** The dev server must be running (\`adk dev\`) for debugging and testing tools to work.
5784
6024
 
@@ -5796,6 +6036,30 @@ Run \`adk mcp:init --all\` to generate configuration for your editor, or use the
5796
6036
  `;
5797
6037
 
5798
6038
  // src/agent-init/agent-project-generator.ts
6039
+ var TEXT_EXTENSIONS = new Set([
6040
+ ".ts",
6041
+ ".tsx",
6042
+ ".js",
6043
+ ".jsx",
6044
+ ".mjs",
6045
+ ".cjs",
6046
+ ".json",
6047
+ ".md",
6048
+ ".txt",
6049
+ ".yml",
6050
+ ".yaml",
6051
+ ".html",
6052
+ ".css",
6053
+ ".svg",
6054
+ ".gitignore"
6055
+ ]);
6056
+ function isTextFile(filename) {
6057
+ if (filename === ".gitignore")
6058
+ return true;
6059
+ const ext = path15.extname(filename).toLowerCase();
6060
+ return TEXT_EXTENSIONS.has(ext);
6061
+ }
6062
+
5799
6063
  class AgentProjectGenerator {
5800
6064
  projectPath;
5801
6065
  projectName;
@@ -5809,253 +6073,146 @@ class AgentProjectGenerator {
5809
6073
  }
5810
6074
  async generate() {
5811
6075
  this.ensureEmptyDirectory();
5812
- this.createPackageJson();
5813
- await this.createAgentConfig();
5814
- this.createTsConfig();
5815
- this.createAgentJson();
5816
- this.createGitIgnore();
5817
- await this.createReadme();
5818
- this.createAIAssistantInstructions();
5819
- await this.createSourceStructure();
5820
- }
5821
- ensureEmptyDirectory() {
5822
- if (!fs11.existsSync(this.projectPath)) {
5823
- fs11.mkdirSync(this.projectPath, { recursive: true });
6076
+ const templateDir = this.resolveTemplateDir();
6077
+ await this.copyTemplateFiles(templateDir);
6078
+ if (!fs11.existsSync(path15.join(this.projectPath, "agent.json"))) {
6079
+ this.createAgentJson();
5824
6080
  }
5825
- const files = fs11.readdirSync(this.projectPath);
5826
- if (files.length > 0) {
5827
- throw new Error(`Directory ${this.projectPath} is not empty. Please use an empty directory.`);
6081
+ if (!fs11.existsSync(path15.join(this.projectPath, "CLAUDE.md"))) {
6082
+ this.createAIAssistantInstructions();
5828
6083
  }
5829
6084
  }
5830
- createPackageJson() {
5831
- const packageJson = {
5832
- name: this.projectName,
5833
- version: "1.0.0",
5834
- description: `A Botpress Agent built with the ADK`,
5835
- type: "module",
5836
- packageManager: this.packageManager === "npm" ? undefined : `${this.packageManager}@latest`,
5837
- scripts: {
5838
- dev: "adk dev",
5839
- build: "adk build",
5840
- deploy: "adk deploy"
5841
- },
5842
- dependencies: {
5843
- "@botpress/runtime": `^${"1.17.0"}`
5844
- },
5845
- devDependencies: {
5846
- typescript: "^5.9.3"
6085
+ static getAvailableTemplates() {
6086
+ try {
6087
+ const templatesRoot = AgentProjectGenerator.getTemplatesRoot();
6088
+ const configPath = path15.join(templatesRoot, "template.config.json");
6089
+ if (!fs11.existsSync(configPath)) {
6090
+ return [];
5847
6091
  }
5848
- };
5849
- if (packageJson.packageManager === undefined) {
5850
- delete packageJson.packageManager;
6092
+ const raw = fs11.readFileSync(configPath, "utf-8");
6093
+ const registry = JSON.parse(raw);
6094
+ return registry.templates;
6095
+ } catch {
6096
+ return [];
5851
6097
  }
5852
- this.writeJsonFile("package.json", packageJson);
5853
6098
  }
5854
- getDefaultDependencies() {
5855
- const dependencies = {
5856
- integrations: {}
5857
- };
5858
- if (this.template === "hello-world") {
5859
- dependencies.integrations = {
5860
- chat: {
5861
- version: "chat@latest",
5862
- enabled: true
5863
- },
5864
- webchat: {
5865
- version: "webchat@latest",
5866
- enabled: true
5867
- }
5868
- };
5869
- }
5870
- return dependencies;
6099
+ getPostInitCommands() {
6100
+ const templates = AgentProjectGenerator.getAvailableTemplates();
6101
+ const config = templates.find((t) => t.name === this.template);
6102
+ return config?.postInit ?? [];
5871
6103
  }
5872
- async createAgentConfig() {
5873
- const dependencies = this.getDefaultDependencies();
5874
- const integrationsJson = JSON.stringify(dependencies.integrations, null, 4).replace(/\n/g, `
5875
- `);
5876
- const defaultModels = this.template === "hello-world" ? `
5877
- defaultModels: {
5878
- autonomous: "cerebras:gpt-oss-120b",
5879
- zai: "cerebras:gpt-oss-120b",
5880
- },
5881
- ` : "";
5882
- const agentConfig = `import { z, defineConfig } from '@botpress/runtime';
5883
-
5884
- export default defineConfig({
5885
- name: '${this.projectName}',
5886
- description: 'An AI agent built with Botpress ADK',
5887
- ${defaultModels}
5888
- bot: {
5889
- state: z.object({}),
5890
- },
6104
+ static _templatesRootOverride = null;
6105
+ static setTemplatesRoot(dir) {
6106
+ AgentProjectGenerator._templatesRootOverride = dir;
6107
+ }
6108
+ static getTemplatesRoot() {
6109
+ if (AgentProjectGenerator._templatesRootOverride) {
6110
+ return AgentProjectGenerator._templatesRootOverride;
6111
+ }
6112
+ const candidates = [];
6113
+ try {
6114
+ const esmRequire = createRequire4(import.meta.url);
6115
+ const adkPkgPath = esmRequire.resolve("@botpress/adk/package.json");
6116
+ const adkRoot = path15.dirname(adkPkgPath);
6117
+ candidates.push(path15.join(adkRoot, "dist", "templates"));
6118
+ candidates.push(path15.join(adkRoot, "templates"));
6119
+ } catch {}
6120
+ const thisDir = path15.dirname(fileURLToPath(import.meta.url));
6121
+ candidates.push(path15.resolve(thisDir, "templates"));
6122
+ candidates.push(path15.resolve(thisDir, "../../templates"));
6123
+ candidates.push(path15.join(path15.dirname(process.execPath), "templates"));
6124
+ for (const candidate of candidates) {
6125
+ if (fs11.existsSync(candidate) && fs11.existsSync(path15.join(candidate, "template.config.json"))) {
6126
+ return candidate;
6127
+ }
6128
+ }
6129
+ const tried = candidates.map((c) => ` - ${c}`).join(`
6130
+ `);
6131
+ throw new Error(`Could not find templates directory.
5891
6132
 
5892
- user: {
5893
- state: z.object({}),
5894
- },
6133
+ Searched:
6134
+ ${tried}
5895
6135
 
5896
- dependencies: {
5897
- integrations: ${integrationsJson},
5898
- },
5899
- });
5900
- `;
5901
- await this.writeFormattedFile("agent.config.ts", agentConfig);
6136
+ Ensure the ADK package is properly installed or run the CLI build.`);
5902
6137
  }
5903
- createTsConfig() {
5904
- const tsConfig = {
5905
- compilerOptions: {
5906
- target: "ES2022",
5907
- module: "ES2022",
5908
- moduleResolution: "Bundler",
5909
- lib: ["ES2022", "DOM"],
5910
- outDir: "./dist",
5911
- rootDir: ".",
5912
- strict: true,
5913
- esModuleInterop: true,
5914
- allowSyntheticDefaultImports: true,
5915
- skipLibCheck: true,
5916
- forceConsistentCasingInFileNames: true,
5917
- moduleDetection: "force",
5918
- resolveJsonModule: true,
5919
- paths: {
5920
- "@botpress/runtime/_types/*": ["./.adk/*-types"]
5921
- }
5922
- },
5923
- include: ["src/**/*", ".adk/**/*"],
5924
- exclude: ["node_modules", "dist"]
6138
+ resolveTemplateDir() {
6139
+ const templatesRoot = AgentProjectGenerator.getTemplatesRoot();
6140
+ const templateDir = path15.join(templatesRoot, this.template);
6141
+ if (!fs11.existsSync(templateDir)) {
6142
+ const available = AgentProjectGenerator.getAvailableTemplates();
6143
+ const names = available.map((t) => ` - ${t.name}: ${t.description}`).join(`
6144
+ `);
6145
+ throw new Error(`Unknown template: "${this.template}"
6146
+
6147
+ Available templates:
6148
+ ${names || " (none found)"}`);
6149
+ }
6150
+ const configFile = path15.join(templateDir, "agent.config.ts");
6151
+ if (!fs11.existsSync(configFile)) {
6152
+ throw new Error(`Template "${this.template}" is missing agent.config.ts`);
6153
+ }
6154
+ return templateDir;
6155
+ }
6156
+ async copyTemplateFiles(templateDir) {
6157
+ const substitutions = {
6158
+ "{{projectName}}": this.projectName,
6159
+ "{{runtimeVersion}}": "1.18.0-beta.1",
6160
+ "{{packageManager}}": this.packageManager
5925
6161
  };
5926
- this.writeJsonFile("tsconfig.json", tsConfig);
6162
+ await this.copyDirRecursive(templateDir, this.projectPath, substitutions);
6163
+ }
6164
+ async copyDirRecursive(src, dest, substitutions) {
6165
+ if (!fs11.existsSync(dest)) {
6166
+ fs11.mkdirSync(dest, { recursive: true });
6167
+ }
6168
+ const entries = fs11.readdirSync(src, { withFileTypes: true });
6169
+ for (const entry of entries) {
6170
+ const srcPath = path15.join(src, entry.name);
6171
+ const destPath = path15.join(dest, entry.name);
6172
+ if (entry.isDirectory()) {
6173
+ await this.copyDirRecursive(srcPath, destPath, substitutions);
6174
+ } else if (isTextFile(entry.name)) {
6175
+ let content = fs11.readFileSync(srcPath, "utf-8");
6176
+ for (const [placeholder, value] of Object.entries(substitutions)) {
6177
+ content = content.replaceAll(placeholder, value);
6178
+ }
6179
+ const remaining = content.match(/\{\{[a-zA-Z]+\}\}/g);
6180
+ if (remaining) {
6181
+ console.warn(`Warning: unresolved placeholders in ${entry.name}: ${remaining.join(", ")}`);
6182
+ }
6183
+ if (entry.name.endsWith(".ts") || entry.name.endsWith(".tsx")) {
6184
+ try {
6185
+ content = await formatCode(content, destPath);
6186
+ } catch {}
6187
+ }
6188
+ fs11.writeFileSync(destPath, content);
6189
+ } else {
6190
+ fs11.copyFileSync(srcPath, destPath);
6191
+ }
6192
+ }
6193
+ }
6194
+ ensureEmptyDirectory() {
6195
+ if (!fs11.existsSync(this.projectPath)) {
6196
+ fs11.mkdirSync(this.projectPath, { recursive: true });
6197
+ }
6198
+ const files = fs11.readdirSync(this.projectPath);
6199
+ if (files.length > 0) {
6200
+ throw new Error(`Directory ${this.projectPath} is not empty. Please use an empty directory.`);
6201
+ }
5927
6202
  }
5928
6203
  createAgentJson() {
5929
6204
  const agentJson = {};
5930
6205
  this.writeJsonFile("agent.json", agentJson);
5931
6206
  }
5932
- createGitIgnore() {
5933
- const gitIgnore = `# Dependencies
5934
- node_modules/
5935
- .pnpm-store/
5936
-
5937
- # Build outputs
5938
- dist/
5939
- .adk/
5940
-
5941
- # Environment files
5942
- .env
5943
- .env.local
5944
- .env.production
5945
-
5946
- # Local development
5947
- agent.local.json
5948
-
5949
- # MCP configuration (auto-generated by adk mcp:init)
5950
- .mcp.json
5951
-
5952
- # IDE files
5953
- .vscode/
5954
- .idea/
5955
- *.swp
5956
- *.swo
5957
-
5958
- # OS files
5959
- .DS_Store
5960
- Thumbs.db
5961
-
5962
- # Logs
5963
- *.log
5964
- logs/
5965
-
5966
- # Runtime files
5967
- *.pid
5968
- *.seed
5969
- *.pid.lock
5970
- `;
5971
- this.writeFile(".gitignore", gitIgnore);
5972
- }
5973
- async createReadme() {
5974
- const installCommand = this.packageManager === "npm" ? "npm install" : this.packageManager === "yarn" ? "yarn install" : `${this.packageManager} install`;
5975
- const readme = `# ${this.projectName}
5976
-
5977
- A Botpress Agent built with the ADK.
5978
-
5979
- ## Getting Started
5980
-
5981
- 1. Install dependencies:
5982
- \`\`\`bash
5983
- ${installCommand}
5984
- \`\`\`
5985
-
5986
- 2. Start development server:
5987
- \`\`\`bash
5988
- adk dev
5989
- \`\`\`
5990
-
5991
- 3. Deploy your agent:
5992
- \`\`\`bash
5993
- adk deploy
5994
- \`\`\`
5995
-
5996
- ## Project Structure
5997
-
5998
- - \`src/actions/\` - Define callable functions
5999
- - \`src/workflows/\` - Define long-running processes
6000
- - \`src/conversations/\` - Define conversation handlers
6001
- - \`src/tables/\` - Define data storage schemas
6002
- - \`src/triggers/\` - Define event subscriptions
6003
- - \`src/knowledge/\` - Add knowledge base files
6004
-
6005
- ## Learn More
6006
-
6007
- - [ADK Documentation](https://botpress.com/docs/adk)
6008
- - [Botpress Platform](https://botpress.com)
6009
- `;
6010
- await this.writeFormattedFile("README.md", readme);
6011
- }
6012
6207
  createAIAssistantInstructions() {
6013
6208
  const content = ai_assistant_instructions_template_default;
6014
6209
  this.writeFile("CLAUDE.md", content);
6015
6210
  this.writeFile("AGENTS.md", content);
6016
6211
  }
6017
- async createSourceStructure() {
6018
- const srcPath = path15.join(this.projectPath, "src");
6019
- fs11.mkdirSync(srcPath);
6020
- const subdirectories = ["actions", "conversations", "knowledge", "tables", "triggers", "workflows"];
6021
- for (const subdir of subdirectories) {
6022
- const subdirPath = path15.join(srcPath, subdir);
6023
- fs11.mkdirSync(subdirPath);
6024
- if (subdir === "conversations" && this.template === "hello-world") {
6025
- const conversationContent = `import { Conversation } from "@botpress/runtime";
6026
-
6027
- export default new Conversation({
6028
- channel: "*",
6029
- handler: async ({ execute }) => {
6030
- await execute({
6031
- instructions: \`You are a helpful AI assistant built with Botpress ADK. You can assist users with their questions and tasks.\`,
6032
- });
6033
- },
6034
- });
6035
- `;
6036
- await this.writeFormattedFile(path15.join("src", subdir, "index.ts"), conversationContent);
6037
- } else {
6038
- const placeholderContent = `/**
6039
- * TODO: Add your ${subdir} here
6040
- *
6041
- * This is a placeholder file to initialize the ${subdir} directory.
6042
- * You can delete this file once you add your own ${subdir}.
6043
- */
6044
-
6045
- export default {};
6046
- `;
6047
- await this.writeFormattedFile(path15.join("src", subdir, "index.ts"), placeholderContent);
6048
- }
6049
- }
6050
- }
6051
6212
  writeFile(relativePath, content) {
6052
6213
  const filePath = path15.join(this.projectPath, relativePath);
6053
6214
  fs11.writeFileSync(filePath, content);
6054
6215
  }
6055
- async writeFormattedFile(relativePath, content) {
6056
- const formatted = await formatCode(content, relativePath);
6057
- this.writeFile(relativePath, formatted);
6058
- }
6059
6216
  writeJsonFile(relativePath, data) {
6060
6217
  this.writeFile(relativePath, JSON.stringify(data, null, 2) + `
6061
6218
  `);
@@ -7077,7 +7234,7 @@ export function createAdkClient(client: Client): AdkClient {
7077
7234
  }
7078
7235
  // src/bot-generator/generator.ts
7079
7236
  import dedent from "dedent";
7080
- import { existsSync as existsSync8 } from "fs";
7237
+ import { existsSync as existsSync7 } from "fs";
7081
7238
  import fs18 from "fs/promises";
7082
7239
  import path38 from "path";
7083
7240
 
@@ -7962,8 +8119,10 @@ async function linkSdk(agentDir, botDir) {
7962
8119
  // src/bot-generator/dev-id-manager.ts
7963
8120
  import path32 from "path";
7964
8121
  import fs14 from "fs/promises";
7965
- import { existsSync as existsSync4 } from "fs";
8122
+ import createDebug3 from "debug";
7966
8123
  import { Client as Client14 } from "@botpress/client";
8124
+ var debug3 = createDebug3("adk:dev-id-manager");
8125
+
7967
8126
  class DevIdManager {
7968
8127
  projectPath;
7969
8128
  botProjectPath;
@@ -7998,11 +8157,26 @@ class DevIdManager {
7998
8157
  }
7999
8158
  async readProjectCache() {
8000
8159
  try {
8001
- if (existsSync4(this.projectCachePath)) {
8002
- const content = await fs14.readFile(this.projectCachePath, "utf-8");
8003
- return JSON.parse(content);
8160
+ const content = await fs14.readFile(this.projectCachePath, "utf-8");
8161
+ if (content.trim().length === 0) {
8162
+ debug3("project cache is empty, treating as bootstrap state: %s", this.projectCachePath);
8163
+ return {};
8004
8164
  }
8165
+ const parsed = JSON.parse(content);
8166
+ if (!isProjectCache(parsed)) {
8167
+ debug3("project cache contains unexpected JSON type, treating as bootstrap state: %s", this.projectCachePath);
8168
+ return {};
8169
+ }
8170
+ return parsed;
8005
8171
  } catch (error) {
8172
+ if (isMissingFileError(error)) {
8173
+ debug3("project cache missing, treating as bootstrap state: %s", this.projectCachePath);
8174
+ return {};
8175
+ }
8176
+ if (error instanceof SyntaxError) {
8177
+ debug3("project cache contains transient invalid JSON, treating as bootstrap state: %s (%O)", this.projectCachePath, error);
8178
+ return {};
8179
+ }
8006
8180
  console.error("Error reading project.cache.json:", error);
8007
8181
  }
8008
8182
  return {};
@@ -8056,11 +8230,17 @@ class DevIdManager {
8056
8230
  return false;
8057
8231
  }
8058
8232
  }
8233
+ function isMissingFileError(error) {
8234
+ return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
8235
+ }
8236
+ function isProjectCache(value) {
8237
+ return typeof value === "object" && value !== null && !Array.isArray(value);
8238
+ }
8059
8239
 
8060
8240
  // src/bot-generator/integration-sync.ts
8061
8241
  import path33 from "path";
8062
8242
  import fs15 from "fs/promises";
8063
- import { existsSync as existsSync5 } from "fs";
8243
+ import { existsSync as existsSync4 } from "fs";
8064
8244
  class IntegrationSync {
8065
8245
  projectPath;
8066
8246
  botProjectPath;
@@ -8100,12 +8280,12 @@ class IntegrationSync {
8100
8280
  }
8101
8281
  async isIntegrationSynced(integration) {
8102
8282
  const targetFolder = path33.join(this.bpModulesPath, `integration_${integration.alias}`);
8103
- if (!existsSync5(targetFolder)) {
8283
+ if (!existsSync4(targetFolder)) {
8104
8284
  return false;
8105
8285
  }
8106
8286
  try {
8107
8287
  const indexPath = path33.join(targetFolder, "index.ts");
8108
- if (!existsSync5(indexPath)) {
8288
+ if (!existsSync4(indexPath)) {
8109
8289
  return false;
8110
8290
  }
8111
8291
  const indexContent = await fs15.readFile(indexPath, "utf-8");
@@ -8138,17 +8318,17 @@ class IntegrationSync {
8138
8318
  async renameIntegrationFolder(integration) {
8139
8319
  const sourceFolder = path33.join(this.bpModulesPath, integration.name.replace("/", "-"));
8140
8320
  const targetFolder = path33.join(this.bpModulesPath, `integration_${integration.alias}`);
8141
- if (!existsSync5(sourceFolder)) {
8321
+ if (!existsSync4(sourceFolder)) {
8142
8322
  throw new Error(`Integration folder not found: ${sourceFolder}`);
8143
8323
  }
8144
- if (existsSync5(targetFolder)) {
8324
+ if (existsSync4(targetFolder)) {
8145
8325
  await fs15.rm(targetFolder, { recursive: true, force: true });
8146
8326
  }
8147
8327
  await fs15.rename(sourceFolder, targetFolder);
8148
8328
  }
8149
8329
  async removeIntegrationFolder(alias) {
8150
8330
  const targetFolder = path33.join(this.bpModulesPath, `integration_${alias}`);
8151
- if (existsSync5(targetFolder)) {
8331
+ if (existsSync4(targetFolder)) {
8152
8332
  await fs15.rm(targetFolder, { recursive: true, force: true });
8153
8333
  }
8154
8334
  }
@@ -8183,7 +8363,7 @@ class IntegrationSync {
8183
8363
  // src/bot-generator/interface-sync.ts
8184
8364
  import path34 from "path";
8185
8365
  import fs16 from "fs/promises";
8186
- import { existsSync as existsSync6 } from "fs";
8366
+ import { existsSync as existsSync5 } from "fs";
8187
8367
  init_constants();
8188
8368
  class InterfaceSync {
8189
8369
  projectPath;
@@ -8211,12 +8391,12 @@ class InterfaceSync {
8211
8391
  }
8212
8392
  async isInterfaceSynced(interfaceInfo) {
8213
8393
  const targetFolder = path34.join(this.bpModulesPath, `interface_${pascalCase(interfaceInfo.alias)}`);
8214
- if (!existsSync6(targetFolder)) {
8394
+ if (!existsSync5(targetFolder)) {
8215
8395
  return false;
8216
8396
  }
8217
8397
  try {
8218
8398
  const indexPath = path34.join(targetFolder, "index.ts");
8219
- if (!existsSync6(indexPath)) {
8399
+ if (!existsSync5(indexPath)) {
8220
8400
  return false;
8221
8401
  }
8222
8402
  const indexContent = await fs16.readFile(indexPath, "utf-8");
@@ -8263,17 +8443,17 @@ class InterfaceSync {
8263
8443
  async renameInterfaceFolder(interfaceInfo) {
8264
8444
  const sourceFolder = path34.join(this.bpModulesPath, interfaceInfo.name);
8265
8445
  const targetFolder = path34.join(this.bpModulesPath, `interface_${pascalCase(interfaceInfo.alias)}`);
8266
- if (!existsSync6(sourceFolder)) {
8446
+ if (!existsSync5(sourceFolder)) {
8267
8447
  throw new Error(`Interface folder not found: ${sourceFolder}`);
8268
8448
  }
8269
- if (existsSync6(targetFolder)) {
8449
+ if (existsSync5(targetFolder)) {
8270
8450
  await fs16.rm(targetFolder, { recursive: true, force: true });
8271
8451
  }
8272
8452
  await fs16.rename(sourceFolder, targetFolder);
8273
8453
  }
8274
8454
  async removeInterfaceFolder(alias) {
8275
8455
  const targetFolder = path34.join(this.bpModulesPath, `interface_${pascalCase(alias)}`);
8276
- if (existsSync6(targetFolder)) {
8456
+ if (existsSync5(targetFolder)) {
8277
8457
  await fs16.rm(targetFolder, { recursive: true, force: true });
8278
8458
  }
8279
8459
  }
@@ -8308,7 +8488,7 @@ class InterfaceSync {
8308
8488
  // src/bot-generator/plugin-sync.ts
8309
8489
  import path35 from "path";
8310
8490
  import fs17 from "fs/promises";
8311
- import { existsSync as existsSync7 } from "fs";
8491
+ import { existsSync as existsSync6 } from "fs";
8312
8492
  class PluginSync {
8313
8493
  projectPath;
8314
8494
  botProjectPath;
@@ -8340,12 +8520,12 @@ class PluginSync {
8340
8520
  }
8341
8521
  async isPluginSynced(plugin) {
8342
8522
  const targetFolder = path35.join(this.bpModulesPath, `plugin_${plugin.alias}`);
8343
- if (!existsSync7(targetFolder)) {
8523
+ if (!existsSync6(targetFolder)) {
8344
8524
  return false;
8345
8525
  }
8346
8526
  try {
8347
8527
  const indexPath = path35.join(targetFolder, "index.ts");
8348
- if (!existsSync7(indexPath)) {
8528
+ if (!existsSync6(indexPath)) {
8349
8529
  return false;
8350
8530
  }
8351
8531
  const indexContent = await fs17.readFile(indexPath, "utf-8");
@@ -8378,17 +8558,17 @@ class PluginSync {
8378
8558
  async renamePluginFolder(plugin) {
8379
8559
  const sourceFolder = path35.join(this.bpModulesPath, plugin.name.replace("/", "-"));
8380
8560
  const targetFolder = path35.join(this.bpModulesPath, `plugin_${plugin.alias}`);
8381
- if (!existsSync7(sourceFolder)) {
8561
+ if (!existsSync6(sourceFolder)) {
8382
8562
  throw new Error(`Plugin folder not found: ${sourceFolder}`);
8383
8563
  }
8384
- if (existsSync7(targetFolder)) {
8564
+ if (existsSync6(targetFolder)) {
8385
8565
  await fs17.rm(targetFolder, { recursive: true, force: true });
8386
8566
  }
8387
8567
  await fs17.rename(sourceFolder, targetFolder);
8388
8568
  }
8389
8569
  async removePluginFolder(alias) {
8390
8570
  const targetFolder = path35.join(this.bpModulesPath, `plugin_${alias}`);
8391
- if (existsSync7(targetFolder)) {
8571
+ if (existsSync6(targetFolder)) {
8392
8572
  await fs17.rm(targetFolder, { recursive: true, force: true });
8393
8573
  }
8394
8574
  }
@@ -8451,7 +8631,7 @@ class BotGenerator {
8451
8631
  }
8452
8632
  async listFilesRecursive(rootDir) {
8453
8633
  try {
8454
- if (!existsSync8(rootDir))
8634
+ if (!existsSync7(rootDir))
8455
8635
  return [];
8456
8636
  const result = [];
8457
8637
  const walk = async (dir, relativeBase) => {
@@ -8473,7 +8653,7 @@ class BotGenerator {
8473
8653
  }
8474
8654
  }
8475
8655
  async removeEmptyDirectories(rootDir) {
8476
- if (!existsSync8(rootDir))
8656
+ if (!existsSync7(rootDir))
8477
8657
  return;
8478
8658
  const removeIfEmpty = async (dir) => {
8479
8659
  const entries = await fs18.readdir(dir, { withFileTypes: true });
@@ -8679,7 +8859,7 @@ class BotGenerator {
8679
8859
  const integrations = await manager3.loadIntegrations(project.dependencies || {});
8680
8860
  const channels = [];
8681
8861
  for (const integration of integrations.integrations) {
8682
- if (integration.enabled && integration.definition) {
8862
+ if (integration.definition) {
8683
8863
  const alias = integration.alias;
8684
8864
  for (const channelName of Object.keys(integration.definition.channels || {})) {
8685
8865
  channels.push(`"${alias}.${channelName}"`);
@@ -8737,7 +8917,7 @@ declare module "@botpress/runtime/_types/state" {
8737
8917
  const interfacesDir = path38.join(this.projectPath, ".adk", "interfaces");
8738
8918
  const existingInterfaceFiles = await this.listFilesRecursive(interfacesDir);
8739
8919
  const interfaces = await manager3.loadInterfaces(project.dependencies || {}).then((result) => result.interfaces.filter((int) => int.definition).map((x) => x.definition));
8740
- const integrationsWithAlias = await integrationManager.loadIntegrations(project.dependencies || {}).then((result) => result.integrations.filter((int) => int.enabled && int.definition).map((x) => ({ alias: x.alias, definition: x.definition })));
8920
+ const integrationsWithAlias = await integrationManager.loadIntegrations(project.dependencies || {}).then((result) => result.integrations.filter((int) => int.definition).map((x) => ({ alias: x.alias, definition: x.definition })));
8741
8921
  let imports = new Set;
8742
8922
  let aliases = new Set;
8743
8923
  let files = new Set;
@@ -8802,10 +8982,7 @@ declare module "@botpress/runtime/_types/state" {
8802
8982
  const integrations = project.dependencies?.integrations || {};
8803
8983
  const imports = [];
8804
8984
  const integrationDefs = [];
8805
- for (const [alias, config] of Object.entries(integrations)) {
8806
- if (config.enabled === false) {
8807
- continue;
8808
- }
8985
+ for (const [alias] of Object.entries(integrations)) {
8809
8986
  const normalizedAlias = getIntegrationAlias(alias);
8810
8987
  imports.push(`import integration_${normalizedAlias} from "../bp_modules/integration_${normalizedAlias}";`);
8811
8988
  integrationDefs.push(`"${alias}": integration_${normalizedAlias}`);
@@ -8907,21 +9084,21 @@ declare module "@botpress/runtime/_types/state" {
8907
9084
  async generateBotDefinition() {
8908
9085
  const project = await AgentProject.load(this.projectPath);
8909
9086
  const integrations = project.integrations;
8910
- const enabledIntegrations = integrations.filter((i) => i.enabled);
8911
9087
  const isDeployOrBuild = this.adkCommand === "adk-deploy" || this.adkCommand === "adk-build";
8912
9088
  const configTargetBotId = isDeployOrBuild ? project.agentInfo?.botId : undefined;
8913
9089
  const serverConfigResult = await fetchServerIntegrationConfigs(project, configTargetBotId);
8914
- this.reportServerConfigSync(serverConfigResult, enabledIntegrations);
9090
+ this.reportServerConfigSync(serverConfigResult, integrations);
8915
9091
  const imports = [];
8916
9092
  const addIntegrations = [];
8917
- for (const integration of enabledIntegrations) {
9093
+ for (const integration of integrations) {
8918
9094
  const { alias, configurationType, config } = integration;
8919
9095
  const importName = `integration_${getIntegrationAlias(alias)}`;
8920
9096
  imports.push(`import ${importName} from "./bp_modules/${importName}";`);
8921
9097
  const configType = configurationType && configurationType !== "default" ? `, configurationType: "${configurationType}"` : "";
8922
9098
  const mergedConfig = mergeIntegrationConfig(serverConfigResult.configs[alias], config);
8923
9099
  const configData = Object.keys(mergedConfig).length > 0 ? `, configuration: ${JSON.stringify(mergedConfig)}` : "";
8924
- addIntegrations.push(`bot.addIntegration(${importName}, { alias: "${alias}", enabled: true${configType}${configData} });`);
9100
+ const enabled = integration.enabled ?? serverConfigResult.enabledStates[alias] ?? false;
9101
+ addIntegrations.push(`bot.addIntegration(${importName}, { alias: "${alias}", enabled: ${enabled}${configType}${configData} });`);
8925
9102
  }
8926
9103
  const depRefErrors = PluginParser.validateDependencyReferences(project.dependencies || {});
8927
9104
  if (depRefErrors.length > 0) {
@@ -9350,7 +9527,7 @@ export default bot;`;
9350
9527
  async copyAssets() {
9351
9528
  const assetsPath = path38.join(this.projectPath, "assets");
9352
9529
  const targetPath = path38.join(this.outputPath, "assets");
9353
- if (existsSync8(assetsPath)) {
9530
+ if (existsSync7(assetsPath)) {
9354
9531
  await fs18.mkdir(targetPath, { recursive: true });
9355
9532
  await this.copyDirectory(assetsPath, targetPath);
9356
9533
  }
@@ -9688,7 +9865,7 @@ export default bot;`;
9688
9865
  }
9689
9866
  async copyAssetsRuntime() {
9690
9867
  const assetsRuntimePath = path38.join(this.projectPath, ".adk", "assets-runtime.ts");
9691
- if (existsSync8(assetsRuntimePath)) {
9868
+ if (existsSync7(assetsRuntimePath)) {
9692
9869
  const content = await fs18.readFile(assetsRuntimePath, "utf-8");
9693
9870
  await createFile(path38.join(this.outputPath, "src", "assets-runtime.ts"), await formatCode(content));
9694
9871
  }
@@ -10752,6 +10929,7 @@ class KnowledgeManager {
10752
10929
  const sourcesToSync = options.force ? item.sources || [] : (item.sources || []).filter((s) => s.needsSync);
10753
10930
  const directorySourcesToSync = sourcesToSync.filter((s) => s.dsType === "document");
10754
10931
  const websiteSourcesToSync = sourcesToSync.filter((s) => s.dsType === "web-page");
10932
+ let currentTags = { ...remoteKb.tags ?? {} };
10755
10933
  for (const sourceStatus of directorySourcesToSync) {
10756
10934
  const source = kbRef.definition.sources?.find((s) => s.id === sourceStatus.dsId);
10757
10935
  if (!source || !DataSource.isDirectory(source))
@@ -10764,27 +10942,52 @@ class KnowledgeManager {
10764
10942
  syncOutput.deleted.push(...sourceOutput.deleted);
10765
10943
  syncOutput.errors.push(...sourceOutput.errors);
10766
10944
  const sourceHash = await this.computeDirectorySourceHash(source.directoryPath, source.filterFn);
10767
- await this.updateSourceHash(remoteKb.id, item.kb.name, source.id, sourceHash, remoteKb.tags);
10945
+ await this.updateSourceHash(remoteKb.id, item.kb.name, source.id, sourceHash, currentTags);
10946
+ currentTags = {
10947
+ ...currentTags,
10948
+ [sourceTag(source.id, "hash")]: sourceHash,
10949
+ [sourceTag(source.id, "lastupdatedat")]: new Date().toISOString()
10950
+ };
10768
10951
  }
10769
- if (websiteSourcesToSync.length > 0) {
10952
+ for (const sourceStatus of websiteSourcesToSync) {
10953
+ const source = kbRef.definition.sources?.find((s) => s.id === sourceStatus.dsId);
10954
+ if (!source || !DataSource.isWebsite(source))
10955
+ continue;
10956
+ const config = source.getConfig();
10957
+ if (config.mode === "website") {
10958
+ console.warn(` ⚠️ Skipping website source "${source.id}": website mode requires browser integration for URL discovery. Use WebsiteSource.fromSitemap() instead.`);
10959
+ continue;
10960
+ }
10961
+ if (config.fetchStrategy === "integration:browser") {
10962
+ console.warn(` ⚠️ Skipping website source "${source.id}": integration:browser fetch strategy requires browser integration. Use fetch: 'node:fetch' or a custom fetch function instead.`);
10963
+ continue;
10964
+ }
10965
+ await this.deleteLegacyWebsiteFiles(item.kb.name, sourceStatus.dsId);
10770
10966
  try {
10771
- for (const sourceStatus of websiteSourcesToSync) {
10772
- await this.deleteLegacyWebsiteFiles(item.kb.name, sourceStatus.dsId);
10773
- }
10774
- console.log(` Triggering website sync workflow for ${websiteSourcesToSync.length} source(s)...`);
10775
- const { workflowId } = await this.syncWebsiteSource(item.kb.name, remoteKb.id, options.force || false);
10776
- result.websiteSyncs.push({ kbName: item.kb.name, workflowId });
10777
- for (const sourceStatus of websiteSourcesToSync) {
10778
- const source = kbRef.definition.sources?.find((s) => s.id === sourceStatus.dsId);
10779
- if (!source || !DataSource.isWebsite(source))
10780
- continue;
10781
- const config = source.getConfig();
10782
- const configHash = this.computeConfigHash(config);
10783
- await this.updateSourceHash(remoteKb.id, item.kb.name, source.id, configHash, remoteKb.tags);
10784
- }
10967
+ this.assertBotId("sync website source");
10968
+ console.log(` Syncing website source "${source.id}" locally...`);
10969
+ const sourceOutput = await source.syncDirect(client, this.botId, {
10970
+ dsId: source.id,
10971
+ kbName: item.kb.name,
10972
+ kbId: remoteKb.id,
10973
+ force: options.force || false
10974
+ });
10975
+ syncOutput.processed += sourceOutput.processed;
10976
+ syncOutput.added.push(...sourceOutput.added);
10977
+ syncOutput.updated.push(...sourceOutput.updated);
10978
+ syncOutput.deleted.push(...sourceOutput.deleted);
10979
+ syncOutput.errors.push(...sourceOutput.errors.map((e) => typeof e === "string" ? { file: source.id, error: e } : e));
10980
+ const configHash = this.computeConfigHash(config);
10981
+ await this.updateSourceHash(remoteKb.id, item.kb.name, source.id, configHash, currentTags);
10982
+ currentTags = {
10983
+ ...currentTags,
10984
+ [sourceTag(source.id, "hash")]: configHash,
10985
+ [sourceTag(source.id, "lastupdatedat")]: new Date().toISOString()
10986
+ };
10785
10987
  } catch (error) {
10786
10988
  const errorMsg = error instanceof Error ? error.message : String(error);
10787
- console.warn(` Warning: Could not trigger website sync: ${errorMsg}`);
10989
+ console.error(` Failed to sync website source "${source.id}": ${errorMsg}`);
10990
+ syncOutput.errors.push({ file: source.id, error: errorMsg });
10788
10991
  }
10789
10992
  }
10790
10993
  result.synced.push({ name: item.kb.name, result: syncOutput });
@@ -10928,7 +11131,7 @@ class KnowledgeManager {
10928
11131
  }
10929
11132
  }
10930
11133
  // src/knowledge/sync-formatter.ts
10931
- import { readFileSync } from "fs";
11134
+ import { readFileSync as readFileSync3 } from "fs";
10932
11135
  import { join as join8 } from "path";
10933
11136
  var getAdkVersion = () => {
10934
11137
  try {
@@ -10937,7 +11140,7 @@ var getAdkVersion = () => {
10937
11140
  } catch {
10938
11141
  try {
10939
11142
  const adkPackagePath = join8(process.cwd(), "node_modules/@botpress/adk/package.json");
10940
- const pkg = JSON.parse(readFileSync(adkPackagePath, "utf-8"));
11143
+ const pkg = JSON.parse(readFileSync3(adkPackagePath, "utf-8"));
10941
11144
  return pkg.version;
10942
11145
  } catch {
10943
11146
  return "unknown";
@@ -11031,7 +11234,7 @@ class KBSyncFormatter {
11031
11234
  import { watch as watch2, readdirSync as readdirSync2, statSync } from "fs";
11032
11235
  import { EventEmitter as EventEmitter3 } from "events";
11033
11236
  import { join as join9, relative as relative3 } from "path";
11034
- import { existsSync as existsSync9 } from "fs";
11237
+ import { existsSync as existsSync8 } from "fs";
11035
11238
 
11036
11239
  class FileWatcher2 extends EventEmitter3 {
11037
11240
  projectPath;
@@ -11049,12 +11252,12 @@ class FileWatcher2 extends EventEmitter3 {
11049
11252
  const rootFiles = ["package.json", "agent.json", "agent.config.ts"];
11050
11253
  for (const file of rootFiles) {
11051
11254
  const filePath = join9(this.projectPath, file);
11052
- if (existsSync9(filePath)) {
11255
+ if (existsSync8(filePath)) {
11053
11256
  this.watchFile(filePath);
11054
11257
  }
11055
11258
  }
11056
11259
  const srcPath = join9(this.projectPath, "src");
11057
- if (existsSync9(srcPath)) {
11260
+ if (existsSync8(srcPath)) {
11058
11261
  this.initializeDirectoryState(srcPath);
11059
11262
  this.watchDirectory(srcPath);
11060
11263
  }
@@ -11104,12 +11307,12 @@ class FileWatcher2 extends EventEmitter3 {
11104
11307
  }
11105
11308
  handleFileChange(filePath) {
11106
11309
  try {
11107
- if (existsSync9(filePath) && statSync(filePath).isDirectory()) {
11310
+ if (existsSync8(filePath) && statSync(filePath).isDirectory()) {
11108
11311
  this.scanDirectoryForChanges(filePath);
11109
11312
  return;
11110
11313
  }
11111
11314
  } catch {}
11112
- const fileExists = existsSync9(filePath);
11315
+ const fileExists = existsSync8(filePath);
11113
11316
  const previousState = this.fileStates.get(filePath);
11114
11317
  let changeType;
11115
11318
  if (!fileExists && previousState !== undefined) {
@@ -11182,7 +11385,7 @@ class FileWatcher2 extends EventEmitter3 {
11182
11385
  }, this.debounceMs);
11183
11386
  }
11184
11387
  updateFileState(filePath) {
11185
- if (existsSync9(filePath)) {
11388
+ if (existsSync8(filePath)) {
11186
11389
  this.fileStates.set(filePath, Date.now());
11187
11390
  }
11188
11391
  }
@@ -11264,7 +11467,7 @@ class AgentConfigSyncManager {
11264
11467
  }
11265
11468
 
11266
11469
  // src/preflight/formatter.ts
11267
- import { readFileSync as readFileSync2 } from "fs";
11470
+ import { readFileSync as readFileSync4 } from "fs";
11268
11471
  import { join as join10 } from "path";
11269
11472
  var getAdkVersion2 = () => {
11270
11473
  try {
@@ -11273,7 +11476,7 @@ var getAdkVersion2 = () => {
11273
11476
  } catch {
11274
11477
  try {
11275
11478
  const adkPackagePath = join10(process.cwd(), "node_modules/@botpress/adk/package.json");
11276
- const pkg = JSON.parse(readFileSync2(adkPackagePath, "utf-8"));
11479
+ const pkg = JSON.parse(readFileSync4(adkPackagePath, "utf-8"));
11277
11480
  return pkg.version;
11278
11481
  } catch {
11279
11482
  return "unknown";
@@ -11455,9 +11658,6 @@ class PreflightChecker {
11455
11658
  const toRemove = [];
11456
11659
  const toUpdate = [];
11457
11660
  for (const result of results) {
11458
- if (result.desiredInstallStatus === "disabled" && !result.needsRemoval && !result.needsConfiguration) {
11459
- continue;
11460
- }
11461
11661
  if (result.needsInstall) {
11462
11662
  toInstall.push({
11463
11663
  alias: result.alias,
@@ -11577,7 +11777,7 @@ class PreflightChecker {
11577
11777
  }
11578
11778
  // src/runner/script-runner.ts
11579
11779
  import dedent2 from "dedent";
11580
- import { existsSync as existsSync10 } from "fs";
11780
+ import { existsSync as existsSync9 } from "fs";
11581
11781
  import fs20 from "fs/promises";
11582
11782
  import path41 from "path";
11583
11783
  import { spawn } from "child_process";
@@ -11615,7 +11815,7 @@ class ScriptRunner {
11615
11815
  const botPath = path41.join(this.projectPath, ".adk", "bot");
11616
11816
  const runnerPath = path41.join(botPath, "src", "script-runner.ts");
11617
11817
  const botpressTypesPath = path41.join(botPath, ".botpress", "implementation", "index.ts");
11618
- const needsRegenerate = this.forceRegenerate || !existsSync10(runnerPath) || !existsSync10(botpressTypesPath);
11818
+ const needsRegenerate = this.forceRegenerate || !existsSync9(runnerPath) || !existsSync9(botpressTypesPath);
11619
11819
  if (needsRegenerate) {
11620
11820
  try {
11621
11821
  await generateAssetsTypes(project.path);
@@ -11773,7 +11973,7 @@ class ScriptRunner {
11773
11973
  initialize: async () => {
11774
11974
  const botModule = await import(runtimePath);
11775
11975
  const runtimeModule = await import("@botpress/runtime/runtime");
11776
- const { Autonomous } = await import("@botpress/runtime");
11976
+ const { Autonomous: Autonomous2 } = await import("@botpress/runtime");
11777
11977
  const { context, agentRegistry } = runtimeModule;
11778
11978
  const { Client: Client18 } = await import("@botpress/client");
11779
11979
  const { BotSpecificClient, BotLogger } = await import("@botpress/sdk");
@@ -11795,7 +11995,7 @@ class ScriptRunner {
11795
11995
  botId,
11796
11996
  client,
11797
11997
  cognitive,
11798
- citations: new Autonomous.CitationsManager,
11998
+ citations: new Autonomous2.CitationsManager,
11799
11999
  logger,
11800
12000
  configuration: configuration ?? {},
11801
12001
  integrations: agentRegistry.integrations,
@@ -11811,7 +12011,7 @@ class ScriptRunner {
11811
12011
  async run(scriptPath, options = {}) {
11812
12012
  const { botPath, runnerPath, project } = await this.prepare();
11813
12013
  const absoluteScriptPath = path41.isAbsolute(scriptPath) ? scriptPath : path41.resolve(this.projectPath, scriptPath);
11814
- if (!existsSync10(absoluteScriptPath)) {
12014
+ if (!existsSync9(absoluteScriptPath)) {
11815
12015
  throw new Error(`Script not found: ${absoluteScriptPath}`);
11816
12016
  }
11817
12017
  const botId = this.prod ? project.agentInfo?.botId : project.agentInfo?.devId || project.agentInfo?.botId;
@@ -11900,42 +12100,78 @@ Either run from within an agent project directory, or provide projectPath explic
11900
12100
  return runner.setupTestRuntime({ env: options.env });
11901
12101
  }
11902
12102
  // src/eval/types.ts
11903
- function defineEval(def) {
11904
- return def;
12103
+ class Eval {
12104
+ name;
12105
+ description;
12106
+ tags;
12107
+ type;
12108
+ setup;
12109
+ conversation;
12110
+ outcome;
12111
+ options;
12112
+ constructor(def) {
12113
+ this.name = def.name;
12114
+ this.description = def.description;
12115
+ this.tags = def.tags;
12116
+ this.type = def.type;
12117
+ this.setup = def.setup;
12118
+ this.conversation = def.conversation;
12119
+ this.outcome = def.outcome;
12120
+ this.options = def.options;
12121
+ }
11905
12122
  }
11906
12123
  // src/eval/loader.ts
11907
- import { readdirSync as readdirSync3, existsSync as existsSync11 } from "fs";
12124
+ import { readdirSync as readdirSync3, existsSync as existsSync10 } from "fs";
11908
12125
  import { resolve as resolve3 } from "path";
12126
+ function isEvalDefinition(value) {
12127
+ return value !== null && typeof value === "object" && typeof value.name === "string" && value.name !== "" && Array.isArray(value.conversation);
12128
+ }
11909
12129
  async function loadEvalFile(filePath) {
11910
12130
  const absPath = resolve3(filePath);
11911
12131
  const mod = await import(absPath);
11912
- const def = mod.default;
11913
- if (!def || typeof def !== "object" || !def.name || !Array.isArray(def.conversation)) {
11914
- throw new Error(`Invalid eval file ${filePath}: must export default a defineEval({...}) object with name and conversation`);
12132
+ const results = [];
12133
+ for (const [key, value] of Object.entries(mod)) {
12134
+ if (key === "__esModule")
12135
+ continue;
12136
+ if (value instanceof Eval || isEvalDefinition(value)) {
12137
+ results.push(value);
12138
+ }
11915
12139
  }
11916
- return def;
12140
+ if (results.length === 0) {
12141
+ throw new Error(`Invalid eval file ${filePath}: no valid evals found. Export one or more \`new Eval({...})\` instances (as default or named exports).`);
12142
+ }
12143
+ return results;
11917
12144
  }
11918
12145
  async function loadEvalsFromDir(dirPath) {
11919
12146
  const absDir = resolve3(dirPath);
11920
- if (!existsSync11(absDir)) {
12147
+ if (!existsSync10(absDir)) {
11921
12148
  return [];
11922
12149
  }
11923
12150
  const files = readdirSync3(absDir).filter((f) => f.endsWith(".eval.ts"));
11924
12151
  const evals = [];
11925
12152
  for (const f of files) {
11926
- evals.push(await loadEvalFile(`${absDir}/${f}`));
12153
+ const defs = await loadEvalFile(`${absDir}/${f}`);
12154
+ evals.push(...defs);
12155
+ }
12156
+ const seen = new Set;
12157
+ for (const e of evals) {
12158
+ if (seen.has(e.name)) {
12159
+ throw new Error(`Duplicate eval name "${e.name}" found in ${dirPath}`);
12160
+ }
12161
+ seen.add(e.name);
11927
12162
  }
11928
12163
  return evals;
11929
12164
  }
11930
12165
  async function loadEvalByName(dirPath, name) {
11931
12166
  const absDir = resolve3(dirPath);
11932
- if (!existsSync11(absDir))
12167
+ if (!existsSync10(absDir))
11933
12168
  return null;
11934
12169
  const files = readdirSync3(absDir).filter((f) => f.endsWith(".eval.ts"));
11935
12170
  for (const f of files) {
11936
- const def = await loadEvalFile(`${absDir}/${f}`);
11937
- if (def.name === name)
11938
- return def;
12171
+ const defs = await loadEvalFile(`${absDir}/${f}`);
12172
+ const found = defs.find((d) => d.name === name);
12173
+ if (found)
12174
+ return found;
11939
12175
  }
11940
12176
  return null;
11941
12177
  }
@@ -13089,11 +13325,11 @@ async function runEvalSuite(config, filter) {
13089
13325
  return runReport;
13090
13326
  }
13091
13327
  // src/eval/store.ts
13092
- import { existsSync as existsSync12, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2, readFileSync as readFileSync3, readdirSync as readdirSync4 } from "fs";
13328
+ import { existsSync as existsSync11, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2, readFileSync as readFileSync5, readdirSync as readdirSync4 } from "fs";
13093
13329
  import { join as join11 } from "path";
13094
13330
  function getRunsDir(agentPath) {
13095
13331
  const dir = join11(agentPath, ".adk", "evals", "runs");
13096
- if (!existsSync12(dir)) {
13332
+ if (!existsSync11(dir)) {
13097
13333
  mkdirSync2(dir, { recursive: true });
13098
13334
  }
13099
13335
  return dir;
@@ -13111,19 +13347,19 @@ function loadRunResult(agentPath, runId) {
13111
13347
  for (const file of files) {
13112
13348
  if (file.includes(runId)) {
13113
13349
  const filepath = join11(dir, file);
13114
- return JSON.parse(readFileSync3(filepath, "utf-8"));
13350
+ return JSON.parse(readFileSync5(filepath, "utf-8"));
13115
13351
  }
13116
13352
  }
13117
13353
  return null;
13118
13354
  }
13119
13355
  function listRunResults(agentPath, limit = 50) {
13120
13356
  const dir = getRunsDir(agentPath);
13121
- if (!existsSync12(dir))
13357
+ if (!existsSync11(dir))
13122
13358
  return [];
13123
13359
  const files = readdirSync4(dir).filter((f) => f.endsWith(".json")).sort().reverse().slice(0, limit);
13124
13360
  return files.map((file) => {
13125
13361
  const filepath = join11(dir, file);
13126
- return JSON.parse(readFileSync3(filepath, "utf-8"));
13362
+ return JSON.parse(readFileSync5(filepath, "utf-8"));
13127
13363
  });
13128
13364
  }
13129
13365
  function getLatestRun(agentPath) {
@@ -13157,7 +13393,6 @@ export {
13157
13393
  generateAssetsRuntime,
13158
13394
  filterEvals,
13159
13395
  dependenciesKeyOrder,
13160
- defineEval,
13161
13396
  coerceConfigValue,
13162
13397
  buildOpenCodeConfig,
13163
13398
  bpCliImporter,
@@ -13189,6 +13424,7 @@ export {
13189
13424
  IntegrationCache,
13190
13425
  HubCache,
13191
13426
  FileWatcher2 as FileWatcher,
13427
+ Eval,
13192
13428
  EnhancedInterfaceCache,
13193
13429
  DevIdManager,
13194
13430
  CredentialsManager,
@@ -13209,4 +13445,4 @@ export {
13209
13445
  AgentProject
13210
13446
  };
13211
13447
 
13212
- //# debugId=984405F8F441F45F64756E2164756E21
13448
+ //# debugId=E3104143A79BCF1564756E2164756E21