@botpress/adk 1.11.8 → 1.11.9

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.js CHANGED
@@ -654,7 +654,7 @@ var PRETTIER_CONFIG, formatCode = async (code, filepath) => {
654
654
  `));
655
655
  return code;
656
656
  }
657
- }, ADK_VERSION = "1.11.8", relative2 = (from, to) => {
657
+ }, ADK_VERSION = "1.11.9", relative2 = (from, to) => {
658
658
  const fromDir = path10.dirname(from);
659
659
  const relative3 = path10.relative(fromDir, to);
660
660
  return relative3.startsWith(".") ? relative3 : `./${relative3}`;
@@ -797,7 +797,7 @@ var init_integration_action_types = __esm(() => {
797
797
  var require_package = __commonJS((exports, module) => {
798
798
  module.exports = {
799
799
  name: "@botpress/adk",
800
- version: "1.11.8",
800
+ version: "1.11.9",
801
801
  description: "Core ADK library for building AI agents on Botpress",
802
802
  type: "module",
803
803
  main: "dist/index.js",
@@ -844,7 +844,7 @@ var require_package = __commonJS((exports, module) => {
844
844
  "@botpress/cli": "^4.27.3",
845
845
  "@botpress/client": "^1.27.2",
846
846
  "@botpress/cognitive": "^0.2.0",
847
- "@botpress/runtime": "^1.11.8",
847
+ "@botpress/runtime": "^1.11.9",
848
848
  "@botpress/sdk": "^4.18.1",
849
849
  "@bpinternal/jex": "^1.2.4",
850
850
  "@bpinternal/yargs-extra": "^0.0.21",
@@ -4827,10 +4827,1271 @@ class ConfigManager {
4827
4827
  init_utils();
4828
4828
  import * as fs11 from "fs";
4829
4829
  import * as path15 from "path";
4830
- import { fileURLToPath } from "url";
4831
- var __filename2 = fileURLToPath(import.meta.url);
4832
- var __dirname2 = path15.dirname(__filename2);
4833
4830
 
4831
+ // src/agent-init/CLAUDE.template.md
4832
+ var CLAUDE_template_default = `# Botpress ADK Project Context
4833
+
4834
+ This project is built with the **Botpress Agent Development Kit (ADK)** - a TypeScript-first framework for building AI agents.
4835
+
4836
+ ## Table of Contents
4837
+
4838
+ - [Quick Reference: Use the Botpress MCP Server](#quick-reference-use-the-botpress-mcp-server)
4839
+ - [What is the ADK?](#what-is-the-adk)
4840
+ - [ADK CLI](#adk-cli)
4841
+ - [Core Concepts](#core-concepts)
4842
+ - [1. Agent Configuration](#1-agent-configuration-agentconfigts)
4843
+ - [2. Conversations](#2-conversations-srcconversations)
4844
+ - [3. Workflows](#3-workflows-srcworkflows)
4845
+ - [4. Tools](#4-tools-srctools)
4846
+ - [5. Knowledge Bases](#5-knowledge-bases-srcknowledge)
4847
+ - [6. Actions](#6-actions-srcactions)
4848
+ - [7. Zai Library](#7-zai-library)
4849
+ - [Project Structure](#project-structure)
4850
+ - [Development Workflow](#development-workflow)
4851
+ - [Examples](#examples)
4852
+ - [Best Practices](#best-practices)
4853
+ - [Common APIs](#common-apis)
4854
+ - [Advanced Autonomous Execution](#advanced-autonomous-execution)
4855
+ - [State and Metadata Management](#state-and-metadata-management)
4856
+ - [Advanced Table Operations](#advanced-table-operations)
4857
+ - [Knowledge Base Operations](#knowledge-base-operations)
4858
+ - [Advanced Conversation Patterns](#advanced-conversation-patterns)
4859
+ - [Citations System](#citations-system)
4860
+ - [When Making Changes](#when-making-changes)
4861
+ - [Resources](#resources)
4862
+
4863
+ ## Quick Reference: Use the Botpress MCP Server
4864
+
4865
+ **IMPORTANT**: When working on this project, always search the Botpress documentation using the \`mcp__botpress-docs__SearchBotpress\` tool before making changes. The ADK has specific patterns and APIs that are well-documented.
4866
+
4867
+ ## What is the ADK?
4868
+
4869
+ The ADK allows developers to build Botpress agents using **code instead of the Studio interface**. It provides:
4870
+
4871
+ - Project scaffolding with TypeScript
4872
+ - Hot reloading development server (\`adk dev\`)
4873
+ - Type-safe APIs and auto-generated types
4874
+ - Build and deploy to Botpress Cloud
4875
+
4876
+ ## ADK CLI
4877
+
4878
+ The ADK CLI is installed globally. You can run it using \`adk <command>\`.
4879
+ Always use bash to run ADK. (\`Bash(adk)\`)
4880
+ To install an integration: \`adk install <integration>\`
4881
+ To generate types without running in dev mode: \`adk build\`
4882
+
4883
+ ## Core Concepts
4884
+
4885
+ ### 1. Agent Configuration (\`agent.config.ts\`)
4886
+
4887
+ The main configuration file defines:
4888
+
4889
+ - **Agent name and description**
4890
+ - **Default models** for autonomous and zai operations
4891
+ - **State schemas** (bot-level and user-level state using Zod)
4892
+ - **Configuration variables** (encrypted, secure storage for API keys)
4893
+ - **Integration dependencies** (webchat, chat, etc.)
4894
+
4895
+ \`\`\`typescript
4896
+ export default defineConfig({
4897
+ name: "my-agent",
4898
+ defaultModels: {
4899
+ autonomous: "cerebras:gpt-oss-120b",
4900
+ zai: "cerebras:gpt-oss-120b",
4901
+ },
4902
+ bot: { state: z.object({}) },
4903
+ user: { state: z.object({}) },
4904
+ dependencies: {
4905
+ integrations: {
4906
+ webchat: { version: "webchat@0.3.0", enabled: true },
4907
+ },
4908
+ },
4909
+ });
4910
+ \`\`\`
4911
+
4912
+ ### 2. Conversations (\`src/conversations/\`)
4913
+
4914
+ **Primary way agents handle user messages**. Each conversation handler:
4915
+
4916
+ - Responds to messages from specific channels
4917
+ - Uses \`execute()\` to run autonomous AI logic
4918
+ - Can access conversation state, send messages, and call tools
4919
+
4920
+ **Key Pattern**: The \`execute()\` function runs the agent's AI loop:
4921
+
4922
+ \`\`\`typescript
4923
+ export default new Conversation({
4924
+ channel: "webchat.channel",
4925
+ handler: async ({ execute, conversation, state }) => {
4926
+ await execute({
4927
+ instructions: "Your agent's instructions here",
4928
+ tools: [myTool1, myTool2],
4929
+ knowledge: [myKnowledgeBase],
4930
+ });
4931
+ },
4932
+ });
4933
+ \`\`\`
4934
+
4935
+ ### 3. Workflows (\`src/workflows/\`)
4936
+
4937
+ **Long-running processes** for complex, multi-step operations:
4938
+
4939
+ - Can run on schedules (cron syntax)
4940
+ - Run independently or triggered by events
4941
+ - NOT the same as Studio Workflows
4942
+ - Use \`step()\` for durable execution (survives restarts)
4943
+
4944
+ \`\`\`typescript
4945
+ export default new Workflow({
4946
+ name: "periodic-indexing",
4947
+ schedule: "0 */6 * * *",
4948
+ handler: async ({ step }) => {
4949
+ await step("task-name", async () => {
4950
+ // Your logic here
4951
+ });
4952
+ },
4953
+ });
4954
+ \`\`\`
4955
+
4956
+ #### Advanced Workflow Step Methods
4957
+
4958
+ Beyond basic \`step()\`, workflows have powerful methods for complex orchestration:
4959
+
4960
+ **Parallel Processing:**
4961
+
4962
+ - \`step.map()\` - Process array items in parallel with concurrency control
4963
+ - \`step.forEach()\` - Like map but for side effects (returns void)
4964
+ - \`step.batch()\` - Process in sequential batches
4965
+
4966
+ \`\`\`typescript
4967
+ // Process items in parallel
4968
+ const results = await step.map(
4969
+ 'process-items',
4970
+ items,
4971
+ async (item, { i }) => processItem(item),
4972
+ { concurrency: 5, maxAttempts: 3 }
4973
+ )
4974
+
4975
+ // Batch processing
4976
+ await step.batch(
4977
+ 'bulk-insert',
4978
+ records,
4979
+ async (batch) => database.bulkInsert(batch),
4980
+ { batchSize: 100 }
4981
+ )
4982
+ \`\`\`
4983
+
4984
+ **Workflow Coordination:**
4985
+
4986
+ - \`step.waitForWorkflow()\` - Wait for another workflow to complete
4987
+ - \`step.executeWorkflow()\` - Start and wait in one call
4988
+
4989
+ \`\`\`typescript
4990
+ const result = await step.executeWorkflow('run-child', ChildWorkflow, { input })
4991
+ \`\`\`
4992
+
4993
+ **Timing Control:**
4994
+
4995
+ - \`step.sleep()\` - Pause execution (< 10s in-memory, >= 10s uses listening mode)
4996
+ - \`step.sleepUntil()\` - Sleep until specific time
4997
+ - \`step.listen()\` - Pause and wait for external event
4998
+
4999
+ \`\`\`typescript
5000
+ await step.sleep('wait-5s', 5000)
5001
+ await step.sleepUntil('wait-until-noon', new Date('2025-01-15T12:00:00Z'))
5002
+ \`\`\`
5003
+
5004
+ **Request Data from Conversation:**
5005
+
5006
+ \`\`\`typescript
5007
+ // In workflow
5008
+ const { topic } = await step.request('topic', 'What topic should I research?')
5009
+
5010
+ // In conversation
5011
+ if (isWorkflowDataRequest(event)) {
5012
+ await workflow.provide(event, { topic: userInput })
5013
+ }
5014
+ \`\`\`
5015
+
5016
+ **Execution Control:**
5017
+
5018
+ - \`step.fail()\` - Mark workflow as failed
5019
+ - \`step.abort()\` - Abort without failing
5020
+ - \`step.progress()\` - Record progress checkpoint
5021
+
5022
+ ### 4. Tools (\`src/tools/\`)
5023
+
5024
+ **AI-callable functions** that enable agents to perform actions:
5025
+
5026
+ - Must have clear name and description
5027
+ - Use Zod schemas for input/output
5028
+ - Can be passed to \`execute()\`
5029
+
5030
+ \`\`\`typescript
5031
+ export default new Autonomous.Tool({
5032
+ name: "searchDatabase",
5033
+ description: "Search the database",
5034
+ input: z.object({ query: z.string() }),
5035
+ output: z.object({ results: z.array(z.any()) }),
5036
+ handler: async ({ query }) => {
5037
+ // Tool logic
5038
+ return { results: [] };
5039
+ },
5040
+ });
5041
+ \`\`\`
5042
+
5043
+ ### 5. Knowledge Bases (\`src/knowledge/\`)
5044
+
5045
+ **RAG (Retrieval-Augmented Generation)** for providing context:
5046
+
5047
+ - Website scraping
5048
+ - Document ingestion
5049
+ - Can be passed to \`execute()\` via \`knowledge\` parameter
5050
+
5051
+ ### 6. Actions (\`src/actions/\`)
5052
+
5053
+ **Reusable business logic** that can:
5054
+
5055
+ - Be called from anywhere (import \`actions\` from \`@botpress/runtime\`)
5056
+ - Be converted to tools with \`.asTool()\`
5057
+ - Encapsulate logic not tied to conversational flow
5058
+
5059
+ ### 7. Zai Library
5060
+
5061
+ **Zai** is an LLM utility library that provides a clean, type-safe API for common AI operations. It's designed to work seamlessly with the ADK and SDK to process LLM inputs and outputs programmatically.
5062
+
5063
+ #### Importing Zai in ADK
5064
+
5065
+ In the ADK, Zai is available from \`@botpress/runtime\`:
5066
+
5067
+ \`\`\`typescript
5068
+ import { adk } from '@botpress/runtime'
5069
+ // then adk.zai.<method_name>
5070
+ \`\`\`
5071
+
5072
+ The default model for Zai operations is configured in \`agent.config.ts\`:
5073
+
5074
+ \`\`\`typescript
5075
+ export default defineConfig({
5076
+ defaultModels: {
5077
+ autonomous: "cerebras:gpt-oss-120b",
5078
+ zai: "cerebras:gpt-oss-120b", // Model used for Zai operations
5079
+ },
5080
+ })
5081
+ \`\`\`
5082
+
5083
+ #### When to Use Zai
5084
+
5085
+ Use Zai when you need to:
5086
+ - Extract structured data from unstructured text
5087
+ - Answer questions from documents with source citations
5088
+ - Verify Boolean conditions in content
5089
+ - Summarize long text into concise summaries
5090
+ - Generate text programmatically based on prompts
5091
+
5092
+ **Use Zai instead of \`execute()\` when**: You need deterministic, structured outputs for specific AI tasks (extraction, validation, summarization) rather than conversational interactions.
5093
+
5094
+ #### Zai Methods
5095
+
5096
+ **1. \`answer()\` - Answer Questions with Citations**
5097
+
5098
+ Answers questions from documents with intelligent source citations.
5099
+
5100
+ \`\`\`typescript
5101
+ const documents = [
5102
+ 'Botpress was founded in 2016.',
5103
+ 'The company is based in Quebec, Canada.',
5104
+ ]
5105
+
5106
+ const result = await zai.answer(documents, 'When was Botpress founded?')
5107
+
5108
+ if (result.type === 'answer') {
5109
+ console.log(result.answer) // "Botpress was founded in 2016."
5110
+ console.log(result.citations) // Array of citations with source references
5111
+ }
5112
+ \`\`\`
5113
+
5114
+ **When to use**: When you need to answer questions from a set of documents with traceable sources (e.g., custom RAG implementations, document Q&A).
5115
+
5116
+ **2. \`extract()\` - Extract Structured Data**
5117
+
5118
+ Extracts structured data from unstructured input using Zod schemas.
5119
+
5120
+ \`\`\`typescript
5121
+ import { z, adk } from '@botpress/runtime'
5122
+
5123
+ const userSchema = z.object({
5124
+ name: z.string(),
5125
+ email: z.string().email(),
5126
+ age: z.number()
5127
+ })
5128
+
5129
+ const input = "My name is John Doe, I'm 30 years old and my email is john@example.com"
5130
+ // zai.extract returns the extracted data DIRECTLY (not wrapped in { output: ... })
5131
+ const result = await adk.zai.extract(input, userSchema)
5132
+
5133
+ console.log(result)
5134
+ // { name: "John Doe", email: "john@example.com", age: 30 }
5135
+ \`\`\`
5136
+
5137
+ **When to use**: When you need to parse unstructured user input into structured data (e.g., form extraction from natural language, parsing contact information).
5138
+
5139
+ **3. \`check()\` - Verify Boolean Conditions**
5140
+
5141
+ Verifies a condition against some input and returns a boolean with explanation.
5142
+
5143
+ \`\`\`typescript
5144
+ const email = "Get rich quick! Click here now!!!"
5145
+ const { output } = await zai.check(email, 'is spam').result()
5146
+
5147
+ console.log(output.value) // true
5148
+ console.log(output.explanation) // "This email contains typical spam indicators..."
5149
+ \`\`\`
5150
+
5151
+ **When to use**: When you need to validate content or make binary decisions (e.g., content moderation, intent verification, condition checking).
5152
+
5153
+ **4. \`summarize()\` - Summarize Text**
5154
+
5155
+ Creates concise summaries of lengthy text to a desired length.
5156
+
5157
+ \`\`\`typescript
5158
+ const longArticle = "..." // Long article content
5159
+
5160
+ const summary = await zai.summarize(longArticle, {
5161
+ length: 100, // tokens
5162
+ prompt: 'key findings and main conclusions'
5163
+ })
5164
+ \`\`\`
5165
+
5166
+ **When to use**: When you need to condense long content (e.g., article summaries, transcript summaries, document overviews).
5167
+
5168
+ **5. \`text()\` - Generate Text**
5169
+
5170
+ Generates text of the desired length according to a prompt.
5171
+
5172
+ \`\`\`typescript
5173
+ const generated = await zai.text('Write a welcome message for new users', {
5174
+ length: 50 // tokens
5175
+ })
5176
+ \`\`\`
5177
+
5178
+ **When to use**: When you need to generate specific text content programmatically (e.g., dynamic content generation, templated responses).
5179
+
5180
+ #### Response Methods
5181
+
5182
+ All Zai operations return a Response object with promise-like behavior and additional functionality:
5183
+
5184
+ \`\`\`typescript
5185
+ // Await the result directly
5186
+ const result = await zai.extract(input, schema)
5187
+
5188
+ // Or use .result() for explicit promise handling
5189
+ const { output } = await zai.check(content, 'is valid').result()
5190
+ \`\`\`
5191
+
5192
+ ## Project Structure
5193
+
5194
+ \`\`\`
5195
+ agent.config.ts # Main configuration
5196
+ src/
5197
+ conversations/ # Message handlers (primary user interaction)
5198
+ workflows/ # Long-running processes
5199
+ tools/ # AI-callable functions
5200
+ actions/ # Reusable business logic
5201
+ knowledge/ # Knowledge bases for RAG
5202
+ triggers/ # Event-based triggers
5203
+ tables/ # Database tables
5204
+ .botpress/ # Auto-generated types (DO NOT EDIT)
5205
+ \`\`\`
5206
+
5207
+ ## Development Workflow
5208
+
5209
+ 1. **Start dev server**: \`adk dev\` (http://localhost:3001 for console)
5210
+ 2. **Add integrations**: \`adk add webchat@latest\`
5211
+ 3. **Build**: \`adk build\`
5212
+ 4. **Deploy**: \`adk deploy\`
5213
+ 5. **Chat in CLI**: \`adk chat\`
5214
+
5215
+ ## Examples
5216
+
5217
+ Official examples: https://github.com/botpress/adk/tree/main/examples
5218
+
5219
+ ### subagents
5220
+
5221
+ **What you'll learn:** How to build a multi-agent system where an orchestrator delegates to specialists.
5222
+
5223
+ Shows the \`SubAgent\` pattern where each specialist (HR, IT, Sales, etc.) runs in its own context with \`mode: "worker"\`, returns structured results via custom exits, and reports progress through \`onTrace\` hooks.
5224
+
5225
+ ### webchat-rag
5226
+
5227
+ **What you'll learn:** How to build a RAG assistant with scheduled indexing, guardrails, and admin features.
5228
+
5229
+ Shows \`Autonomous.Object\` for dynamic tool grouping, \`onBeforeTool\` hooks to enforce knowledge search before answering, scheduled workflows for KB refresh, and \`ThinkSignal\` for interrupting execution.
5230
+
5231
+ ### deep-research
5232
+
5233
+ **What you'll learn:** How to build complex, long-running workflows with progress tracking.
5234
+
5235
+ Shows \`step()\` and \`step.map()\` for workflow phases, \`Reference.Workflow\` for conversation-workflow linking, Tables for activity tracking, and extensive Zai usage (\`extract\`, \`answer\`, \`filter\`, \`text\`).
5236
+
5237
+ ## Best Practices
5238
+
5239
+ 1. **Search Botpress docs first** - Use the MCP tool before implementing
5240
+ 2. **Keep tools focused** - Single responsibility per tool
5241
+ 3. **Use Zod schemas** with \`.describe()\` for clarity
5242
+ 4. **State management** - Minimize large variables in main workflow
5243
+ 5. **Type safety** - Run \`adk dev\` or \`adk build\` to regenerate types after config changes
5244
+ 6. **Conversations vs Workflows**:
5245
+ - Conversations: User interactions, real-time responses
5246
+ - Workflows: Background tasks, scheduled jobs, long-running processes
5247
+
5248
+ ## Common APIs
5249
+
5250
+ ### Conversation Handler
5251
+
5252
+ \`\`\`typescript
5253
+ handler: async ({
5254
+ execute, // Run autonomous AI loop
5255
+ conversation, // Send messages, manage conversation
5256
+ state, // Conversation state (persisted)
5257
+ message, // Incoming message
5258
+ client, // Botpress API client
5259
+ }) => {};
5260
+ \`\`\`
5261
+
5262
+ ### Execute Function
5263
+
5264
+ \`\`\`typescript
5265
+ await execute({
5266
+ instructions: "String or function returning instructions",
5267
+ tools: [tool1, tool2], // Optional tools
5268
+ knowledge: [kb1, kb2], // Optional knowledge bases
5269
+ exits: [customExit], // Optional custom exits
5270
+ hooks: { onTrace, onBeforeTool }, // Optional hooks
5271
+ mode: "worker", // Optional: autonomous until exit
5272
+ iterations: 10, // Max loops (default 10)
5273
+ });
5274
+ \`\`\`
5275
+
5276
+ ## Advanced Autonomous Execution
5277
+
5278
+ ### Autonomous Namespace
5279
+
5280
+ The \`Autonomous\` namespace provides powerful primitives for controlling LLM behavior:
5281
+
5282
+ #### Autonomous.Exit - Custom Exit Conditions
5283
+
5284
+ Define custom exits for autonomous execution loops:
5285
+
5286
+ \`\`\`typescript
5287
+ import { Autonomous, z } from '@botpress/runtime'
5288
+
5289
+ const AnswerExit = new Autonomous.Exit({
5290
+ name: 'answer',
5291
+ description: 'Return when you have the final answer',
5292
+ schema: z.object({
5293
+ answer: z.string(),
5294
+ confidence: z.number()
5295
+ })
5296
+ })
5297
+
5298
+ const NoAnswerExit = new Autonomous.Exit({
5299
+ name: 'no_answer',
5300
+ description: 'No answer could be found'
5301
+ })
5302
+
5303
+ const result = await execute({
5304
+ instructions: 'Research and answer the question',
5305
+ exits: [AnswerExit, NoAnswerExit],
5306
+ mode: 'worker' // Run until exit triggered
5307
+ })
5308
+
5309
+ // ✅ CORRECT - Use result.is() and result.output
5310
+ if (result.is(AnswerExit)) {
5311
+ console.log(result.output.answer) // Type-safe access
5312
+ console.log(result.output.confidence)
5313
+ } else if (result.is(NoAnswerExit)) {
5314
+ console.log('No answer found')
5315
+ }
5316
+
5317
+ // ❌ WRONG - Don't use result.exit.name or result.exit.value
5318
+ // if (result.exit?.name === 'answer') { ... }
5319
+ \`\`\`
5320
+
5321
+ #### Autonomous.ThinkSignal - Inject Context
5322
+
5323
+ Provide context to the LLM without continuing execution:
5324
+
5325
+ \`\`\`typescript
5326
+ const results = await fetchData()
5327
+
5328
+ if (!results.length) {
5329
+ throw new ThinkSignal('error', 'No results found')
5330
+ }
5331
+
5332
+ // Inject formatted results into LLM context
5333
+ throw new ThinkSignal('results ready', formatResults(results))
5334
+ \`\`\`
5335
+
5336
+ #### Autonomous.Object - Dynamic Tool Grouping
5337
+
5338
+ Group tools dynamically based on state:
5339
+
5340
+ \`\`\`typescript
5341
+ const adminTools = new Autonomous.Object({
5342
+ name: 'admin',
5343
+ description: user.isAdmin ? 'Admin tools available' : 'Login required',
5344
+ tools: user.isAdmin ? [refreshKB, manageBots] : [generateLoginCode]
5345
+ })
5346
+
5347
+ await execute({
5348
+ objects: [adminTools]
5349
+ })
5350
+ \`\`\`
5351
+
5352
+ ### Execution Hooks
5353
+
5354
+ Full control over the autonomous execution loop:
5355
+
5356
+ \`\`\`typescript
5357
+ await execute({
5358
+ instructions: '...',
5359
+ hooks: {
5360
+ // Before tool execution - can modify input
5361
+ onBeforeTool: async ({ iteration, tool, input, controller }) => {
5362
+ console.log(\`About to call \${tool.name}\`)
5363
+ return { input: modifiedInput } // Optional: transform input
5364
+ },
5365
+
5366
+ // After tool execution - can modify output
5367
+ onAfterTool: async ({ iteration, tool, input, output, controller }) => {
5368
+ console.log(\`\${tool.name} returned:\`, output)
5369
+ return { output: modifiedOutput } // Optional: transform output
5370
+ },
5371
+
5372
+ // Before code execution in iteration
5373
+ onBeforeExecution: async (iteration, controller) => {
5374
+ return { code: modifiedCode } // Optional: transform generated code
5375
+ },
5376
+
5377
+ // When exit is triggered
5378
+ onExit: async (result) => {
5379
+ console.log('Exited with:', result)
5380
+ },
5381
+
5382
+ // After each iteration completes
5383
+ onIterationEnd: async (iteration, controller) => {
5384
+ if (iteration > 5) {
5385
+ controller.abort() // Stop execution
5386
+ }
5387
+ },
5388
+
5389
+ // On trace events (synchronous, non-blocking)
5390
+ onTrace: ({ trace, iteration }) => {
5391
+ if (trace.type === 'comment') {
5392
+ console.log('LLM thinking:', trace.comment)
5393
+ }
5394
+ if (trace.type === 'tool_call') {
5395
+ console.log('Calling:', trace.tool_name)
5396
+ }
5397
+ }
5398
+ }
5399
+ })
5400
+ \`\`\`
5401
+
5402
+ **Hook use cases:**
5403
+ - Logging and debugging
5404
+ - Input/output validation and transformation
5405
+ - Rate limiting tool calls
5406
+ - Custom abort conditions
5407
+ - Injecting dynamic context
5408
+
5409
+ ## State and Metadata Management
5410
+
5411
+ ### Tags - Key-Value Metadata
5412
+
5413
+ Track metadata for any entity (bot, user, conversation, workflow):
5414
+
5415
+ \`\`\`typescript
5416
+ import { TrackedTags } from '@botpress/runtime'
5417
+
5418
+ // Create tags instance
5419
+ const tags = TrackedTags.create({
5420
+ type: 'bot', // or 'user' | 'conversation' | 'workflow'
5421
+ id: entityId,
5422
+ client: botClient,
5423
+ initialTags: { status: 'active' }
5424
+ })
5425
+
5426
+ // Load from server
5427
+ await tags.load()
5428
+
5429
+ // Modify tags
5430
+ tags.tags = {
5431
+ ...tags.tags,
5432
+ lastSync: new Date().toISOString()
5433
+ }
5434
+
5435
+ // Check if modified
5436
+ if (tags.isDirty()) {
5437
+ await tags.save()
5438
+ }
5439
+
5440
+ // Batch operations
5441
+ await TrackedTags.saveAllDirty()
5442
+ await TrackedTags.loadAll()
5443
+ \`\`\`
5444
+
5445
+ **Access via workflow instance:**
5446
+
5447
+ \`\`\`typescript
5448
+ workflow.tags = { status: 'processing' }
5449
+ await workflow.save()
5450
+ \`\`\`
5451
+
5452
+ ### Reference.Workflow - Typed Workflow References
5453
+
5454
+ Serialize workflow references in state that auto-hydrate on access:
5455
+
5456
+ \`\`\`typescript
5457
+ import { Reference, z } from '@botpress/runtime'
5458
+
5459
+ // In conversation state schema
5460
+ state: z.object({
5461
+ research: Reference.Workflow('deep_research').optional()
5462
+ // or untyped: Reference.Workflow().optional()
5463
+ })
5464
+
5465
+ // In handler - always a WorkflowInstance
5466
+ handler: async ({ state }) => {
5467
+ if (state.research) {
5468
+ // state.research is typed WorkflowInstance
5469
+ console.log(state.research.status) // 'running' | 'completed' | etc
5470
+ console.log(state.research.output) // Typed output
5471
+
5472
+ if (state.research.status === 'completed') {
5473
+ // Access completed workflow data
5474
+ }
5475
+ }
5476
+ }
5477
+ \`\`\`
5478
+
5479
+ ### Context Object - Runtime Access
5480
+
5481
+ Global context for accessing runtime information:
5482
+
5483
+ \`\`\`typescript
5484
+ import { context } from '@botpress/runtime'
5485
+
5486
+ // Get specific context
5487
+ const client = context.get('client')
5488
+ const citations = context.get('citations')
5489
+ const logger = context.get('logger')
5490
+
5491
+ // Get all context
5492
+ const { client, cognitive, logger, operation } = context.getAll()
5493
+ \`\`\`
5494
+
5495
+ **Available context properties:**
5496
+ - \`client\` - Botpress API client
5497
+ - \`cognitive\` - LLM access
5498
+ - \`logger\` - Logging
5499
+ - \`operation\` - Current operation info
5500
+ - \`citations\` - Citation tracking
5501
+ - \`chat\` - Chat interface
5502
+ - \`bot\` - Bot tags and metadata
5503
+ - \`user\` - User information
5504
+ - \`conversation\` - Current conversation
5505
+ - \`message\` - Incoming message
5506
+ - \`event\` - Current event
5507
+ - \`workflow\` - Current workflow
5508
+ - \`workflowControlContext\` - Workflow control (abort, fail, restart)
5509
+
5510
+ ### State Management
5511
+
5512
+ Access and modify tracked state:
5513
+
5514
+ \`\`\`typescript
5515
+ import { bot, user } from '@botpress/runtime'
5516
+
5517
+ // Bot state
5518
+ bot.state.lastIndexed = new Date().toISOString()
5519
+ bot.state.config = { theme: 'dark' }
5520
+
5521
+ // User state
5522
+ user.state.preferences = { notifications: true }
5523
+ user.state.lastActive = Date.now()
5524
+ \`\`\`
5525
+
5526
+ State persists automatically across executions.
5527
+
5528
+ ## Advanced Table Operations
5529
+
5530
+ ### Table Naming Rules
5531
+
5532
+ **IMPORTANT**: Tables have strict naming requirements:
5533
+
5534
+ \`\`\`typescript
5535
+ // ✅ CORRECT - Name must end with "Table"
5536
+ export const MyDataTable = new Table({
5537
+ name: "mydataTable", // Must end with "Table"
5538
+ columns: { ... }
5539
+ });
5540
+
5541
+ // ❌ WRONG - Missing "Table" suffix
5542
+ name: "mydata"
5543
+ name: "my_data"
5544
+ \`\`\`
5545
+
5546
+ **Reserved column names** - Cannot use these as column names:
5547
+ - \`id\` (auto-generated)
5548
+ - \`createdAt\` (auto-generated)
5549
+ - \`updatedAt\` (auto-generated)
5550
+ - \`computed\`
5551
+ - \`stale\`
5552
+
5553
+ \`\`\`typescript
5554
+ // ❌ WRONG - Using reserved column name
5555
+ columns: {
5556
+ createdAt: z.string() // Reserved!
5557
+ }
5558
+
5559
+ // ✅ CORRECT - Use alternative name
5560
+ columns: {
5561
+ savedAt: z.string()
5562
+ }
5563
+ \`\`\`
5564
+
5565
+ ### Auto-Registration
5566
+
5567
+ Files in \`src/tables/\` are **auto-registered** by the ADK. Do NOT re-export from index.ts:
5568
+
5569
+ \`\`\`typescript
5570
+ // src/tables/index.ts
5571
+ // ❌ WRONG - Causes duplicate registration errors
5572
+ export { MyTable } from "./myTable";
5573
+
5574
+ // ✅ CORRECT - Leave empty or add comment
5575
+ // Tables are auto-registered from src/tables/*.ts files
5576
+ \`\`\`
5577
+
5578
+ Same applies to \`src/conversations/\`, \`src/workflows/\`, \`src/triggers/\`, etc.
5579
+
5580
+ Beyond basic CRUD, Tables support powerful query and manipulation features:
5581
+
5582
+ ### Complex Filtering
5583
+
5584
+ Use logical operators and conditions:
5585
+
5586
+ \`\`\`typescript
5587
+ await MyTable.findRows({
5588
+ filter: {
5589
+ $and: [
5590
+ { status: 'open' },
5591
+ { priority: { $in: ['high', 'urgent'] } }
5592
+ ],
5593
+ $or: [
5594
+ { assignee: userId },
5595
+ { reporter: userId }
5596
+ ],
5597
+ title: { $regex: 'bug|error', $options: 'i' }
5598
+ }
5599
+ })
5600
+ \`\`\`
5601
+
5602
+ **Filter operators:**
5603
+ - \`$eq\`, \`$ne\` - Equal, not equal
5604
+ - \`$gt\`, \`$gte\`, \`$lt\`, \`$lte\` - Comparisons
5605
+ - \`$in\`, \`$nin\` - In array, not in array
5606
+ - \`$exists\` - Field exists
5607
+ - \`$regex\` - Regular expression match
5608
+ - \`$options\` - Regex options (e.g., 'i' for case-insensitive)
5609
+ - \`$and\`, \`$or\` - Logical operators
5610
+
5611
+ ### Full-Text Search
5612
+
5613
+ Search across searchable columns:
5614
+
5615
+ \`\`\`typescript
5616
+ await MyTable.findRows({
5617
+ search: 'query string',
5618
+ filter: { status: 'active' }
5619
+ })
5620
+ \`\`\`
5621
+
5622
+ Mark columns as searchable in schema:
5623
+
5624
+ \`\`\`typescript
5625
+ columns: {
5626
+ title: z.string().searchable(),
5627
+ description: z.string().searchable()
5628
+ }
5629
+ \`\`\`
5630
+
5631
+ ### Aggregation and Grouping
5632
+
5633
+ Group and aggregate data:
5634
+
5635
+ \`\`\`typescript
5636
+ await MyTable.findRows({
5637
+ group: {
5638
+ status: 'count',
5639
+ priority: ['sum', 'avg'],
5640
+ complexity: ['max', 'min']
5641
+ }
5642
+ })
5643
+ \`\`\`
5644
+
5645
+ **Aggregation operations:** \`key\`, \`count\`, \`sum\`, \`avg\`, \`max\`, \`min\`, \`unique\`
5646
+
5647
+ ### Computed Columns
5648
+
5649
+ Columns with values computed from row data:
5650
+
5651
+ \`\`\`typescript
5652
+ columns: {
5653
+ fullName: {
5654
+ computed: true,
5655
+ schema: z.string(),
5656
+ dependencies: ['firstName', 'lastName'],
5657
+ value: async (row) => \`\${row.firstName} \${row.lastName}\`
5658
+ },
5659
+ age: {
5660
+ computed: true,
5661
+ schema: z.number(),
5662
+ dependencies: ['birthDate'],
5663
+ value: async (row) => {
5664
+ const today = new Date()
5665
+ const birth = new Date(row.birthDate)
5666
+ return today.getFullYear() - birth.getFullYear()
5667
+ }
5668
+ }
5669
+ }
5670
+ \`\`\`
5671
+
5672
+ ### Upsert Operations
5673
+
5674
+ Insert or update based on key column:
5675
+
5676
+ \`\`\`typescript
5677
+ await MyTable.upsertRows({
5678
+ rows: [
5679
+ { externalId: '123', name: 'Item 1' },
5680
+ { externalId: '456', name: 'Item 2' }
5681
+ ],
5682
+ keyColumn: 'externalId', // Update if exists, insert if not
5683
+ waitComputed: true // Wait for computed columns to update
5684
+ })
5685
+ \`\`\`
5686
+
5687
+ ### Bulk Operations
5688
+
5689
+ Efficient batch operations:
5690
+
5691
+ \`\`\`typescript
5692
+ // Delete by filter
5693
+ await MyTable.deleteRows({
5694
+ filter: { status: 'archived', createdAt: { $lt: '2024-01-01' } }
5695
+ })
5696
+
5697
+ // Delete by IDs
5698
+ await MyTable.deleteRowIds([1, 2, 3])
5699
+
5700
+ // Delete all
5701
+ await MyTable.deleteAllRows()
5702
+
5703
+ // Update multiple
5704
+ await MyTable.updateRows({
5705
+ rows: [
5706
+ { id: 1, status: 'active' },
5707
+ { id: 2, status: 'inactive' }
5708
+ ],
5709
+ waitComputed: true
5710
+ })
5711
+ \`\`\`
5712
+
5713
+ ### Error Handling
5714
+
5715
+ Collect errors and warnings from bulk operations:
5716
+
5717
+ \`\`\`typescript
5718
+ const { errors, warnings } = await MyTable.createRows({
5719
+ rows: data,
5720
+ waitComputed: true
5721
+ })
5722
+
5723
+ if (errors?.length) {
5724
+ console.error('Failed rows:', errors)
5725
+ }
5726
+ if (warnings?.length) {
5727
+ console.warn('Warnings:', warnings)
5728
+ }
5729
+ \`\`\`
5730
+
5731
+ ## Knowledge Base Operations
5732
+
5733
+ ### Data Sources
5734
+
5735
+ Multiple source types for knowledge bases:
5736
+
5737
+ #### Directory Source
5738
+
5739
+ \`\`\`typescript
5740
+ import { DataSource } from '@botpress/runtime'
5741
+
5742
+ const docs = DataSource.Directory.fromPath('src/knowledge', {
5743
+ id: 'docs',
5744
+ filter: (path) => path.endsWith('.md') || path.endsWith('.txt')
5745
+ })
5746
+ \`\`\`
5747
+
5748
+ #### Website Source
5749
+
5750
+ \`\`\`typescript
5751
+ const siteDocs = DataSource.Website.fromSitemap('https://example.com/sitemap.xml', {
5752
+ id: 'website',
5753
+ maxPages: 500,
5754
+ fetch: 'node:fetch' // or custom fetch implementation
5755
+ })
5756
+ \`\`\`
5757
+
5758
+ ### Knowledge Base Definition
5759
+
5760
+ \`\`\`typescript
5761
+ import { Knowledge } from '@botpress/runtime'
5762
+
5763
+ export default new Knowledge({
5764
+ name: 'docs',
5765
+ description: 'Product documentation',
5766
+ sources: [docsDirectory, websiteSource]
5767
+ })
5768
+ \`\`\`
5769
+
5770
+ ### Refresh Operations
5771
+
5772
+ Manually refresh knowledge base content:
5773
+
5774
+ \`\`\`typescript
5775
+ // Refresh entire knowledge base
5776
+ await DocsKB.refresh({ force: true })
5777
+
5778
+ // Refresh specific source
5779
+ await DocsKB.refreshSource('website', { force: true })
5780
+ \`\`\`
5781
+
5782
+ **Options:**
5783
+ - \`force: true\` - Force refresh even if recently updated
5784
+ - Automatic refresh via scheduled workflows recommended
5785
+
5786
+ ### Using Knowledge in Execute
5787
+
5788
+ \`\`\`typescript
5789
+ await execute({
5790
+ instructions: 'Answer using the documentation',
5791
+ knowledge: [DocsKB, APIKB],
5792
+ tools: [searchTool]
5793
+ })
5794
+ \`\`\`
5795
+
5796
+ Knowledge bases are automatically searchable via the \`search_knowledge\` tool.
5797
+
5798
+ ## Advanced Conversation Patterns
5799
+
5800
+ ### Multiple Channel Support
5801
+
5802
+ Handle messages from multiple channels in one handler:
5803
+
5804
+ \`\`\`typescript
5805
+ export default new Conversation({
5806
+ channel: ['chat.channel', 'webchat.channel', 'slack.dm'],
5807
+ handler: async ({ channel, execute }) => {
5808
+ console.log(\`Message from: \${channel}\`)
5809
+ await execute({ instructions: '...' })
5810
+ }
5811
+ })
5812
+ \`\`\`
5813
+
5814
+ ### Event Handling
5815
+
5816
+ Subscribe to integration events:
5817
+
5818
+ \`\`\`typescript
5819
+ export default new Conversation({
5820
+ channel: 'webchat.channel',
5821
+ events: ['webchat:conversationStarted', 'webchat:conversationEnded'],
5822
+ handler: async ({ type, event, message }) => {
5823
+ if (type === 'event' && event.type === 'webchat:conversationStarted') {
5824
+ // Send welcome message
5825
+ await conversation.send({
5826
+ type: 'text',
5827
+ payload: { text: 'Welcome!' }
5828
+ })
5829
+ }
5830
+
5831
+ if (type === 'message' && message?.type === 'text') {
5832
+ // Handle regular messages
5833
+ await execute({ instructions: '...' })
5834
+ }
5835
+ }
5836
+ })
5837
+ \`\`\`
5838
+
5839
+ ### Workflow Request Handling
5840
+
5841
+ Handle data requests from workflows:
5842
+
5843
+ \`\`\`typescript
5844
+ import { isWorkflowDataRequest } from '@botpress/runtime'
5845
+
5846
+ handler: async ({ type, event, execute }) => {
5847
+ // Check if this is a workflow requesting data
5848
+ if (type === 'workflow_request' && isWorkflowDataRequest(event)) {
5849
+ const userInput = await promptUser(event.payload.message)
5850
+
5851
+ // Provide data back to workflow
5852
+ await workflow.provide(event, { topic: userInput })
5853
+ return
5854
+ }
5855
+
5856
+ // Regular message handling
5857
+ await execute({ instructions: '...' })
5858
+ }
5859
+ \`\`\`
5860
+
5861
+ ### Typed Workflow Interactions
5862
+
5863
+ Work with typed workflow instances:
5864
+
5865
+ \`\`\`typescript
5866
+ import { isWorkflow, ResearchWorkflow } from '@botpress/runtime'
5867
+
5868
+ handler: async ({ state }) => {
5869
+ if (state.research && isWorkflow(state.research, 'research')) {
5870
+ // state.research is now typed as ResearchWorkflow
5871
+ console.log(state.research.status)
5872
+ console.log(state.research.output) // Typed output
5873
+
5874
+ if (state.research.status === 'completed') {
5875
+ await conversation.send({
5876
+ type: 'text',
5877
+ payload: { text: state.research.output.result }
5878
+ })
5879
+ }
5880
+ }
5881
+ }
5882
+ \`\`\`
5883
+
5884
+ ### Dynamic Tools Based on State
5885
+
5886
+ Provide different tools based on conversation state:
5887
+
5888
+ \`\`\`typescript
5889
+ handler: async ({ state, execute }) => {
5890
+ const tools = () => {
5891
+ if (state.workflowRunning) {
5892
+ return [cancelWorkflowTool, checkStatusTool]
5893
+ } else {
5894
+ return [startWorkflowTool, browseTool, searchTool]
5895
+ }
5896
+ }
5897
+
5898
+ await execute({
5899
+ instructions: '...',
5900
+ tools: tools()
5901
+ })
5902
+ }
5903
+ \`\`\`
5904
+
5905
+ ### Message Sending
5906
+
5907
+ Send different message types:
5908
+
5909
+ \`\`\`typescript
5910
+ // Text message
5911
+ await conversation.send({
5912
+ type: 'text',
5913
+ payload: { text: 'Hello!' }
5914
+ })
5915
+
5916
+ // Custom message type (integration-specific)
5917
+ await conversation.send({
5918
+ type: 'custom:messageType',
5919
+ payload: { data: 'custom payload' }
5920
+ })
5921
+ \`\`\`
5922
+
5923
+ ## Citations System
5924
+
5925
+ Track and manage source citations for LLM responses:
5926
+
5927
+ ### CitationsManager
5928
+
5929
+ Access via context:
5930
+
5931
+ \`\`\`typescript
5932
+ import { context } from '@botpress/runtime'
5933
+
5934
+ const citations = context.get('citations')
5935
+ \`\`\`
5936
+
5937
+ ### Registering Sources
5938
+
5939
+ Register sources that can be cited:
5940
+
5941
+ \`\`\`typescript
5942
+ // Register with URL
5943
+ const { tag } = citations.registerSource({
5944
+ url: 'https://example.com/doc',
5945
+ title: 'Documentation Page'
5946
+ })
5947
+
5948
+ // Register with file reference
5949
+ const { tag } = citations.registerSource({
5950
+ file: fileKey,
5951
+ title: 'Internal Document'
5952
+ })
5953
+ \`\`\`
5954
+
5955
+ ### Using Citation Tags
5956
+
5957
+ Inject citation tags into LLM content:
5958
+
5959
+ \`\`\`typescript
5960
+ const results = await searchKnowledgeBase(query)
5961
+
5962
+ for (const result of results) {
5963
+ const { tag } = citations.registerSource({
5964
+ file: result.file.key,
5965
+ title: result.file.name
5966
+ })
5967
+
5968
+ content += \`\${result.content} \${tag}\\n\`
5969
+ }
5970
+
5971
+ // Return cited content
5972
+ throw new ThinkSignal('results', content)
5973
+ \`\`\`
5974
+
5975
+ ### Citation Format
5976
+
5977
+ Citations are automatically formatted with tags like \`[1]\`, \`[2]\`, etc., and tracked by the system for reference.
5978
+
5979
+ ### Example: Tool with Citations
5980
+
5981
+ \`\`\`typescript
5982
+ export default new Autonomous.Tool({
5983
+ name: 'search_docs',
5984
+ description: 'Search documentation',
5985
+ handler: async ({ query }) => {
5986
+ const citations = context.get('citations')
5987
+ const results = await searchDocs(query)
5988
+
5989
+ let response = ''
5990
+ for (const doc of results) {
5991
+ const { tag } = citations.registerSource({
5992
+ url: doc.url,
5993
+ title: doc.title
5994
+ })
5995
+ response += \`\${doc.content} \${tag}\\n\\n\`
5996
+ }
5997
+
5998
+ return response
5999
+ }
6000
+ })
6001
+ \`\`\`
6002
+
6003
+ ## Common Mistakes to Avoid
6004
+
6005
+ ### 1. Wrong Zai Import
6006
+ \`\`\`typescript
6007
+ // ❌ WRONG
6008
+ import { zai } from '@botpress/runtime'
6009
+ const result = await zai.extract(...)
6010
+
6011
+ // ✅ CORRECT
6012
+ import { adk } from '@botpress/runtime'
6013
+ const result = await adk.zai.extract(...)
6014
+ \`\`\`
6015
+
6016
+ ### 2. Expecting \`.output\` from zai.extract
6017
+ \`\`\`typescript
6018
+ // ❌ WRONG - zai.extract returns data directly
6019
+ const result = await adk.zai.extract(input, schema)
6020
+ console.log(result.output) // undefined!
6021
+
6022
+ // ✅ CORRECT
6023
+ const result = await adk.zai.extract(input, schema)
6024
+ console.log(result) // { name: "John", age: 30 }
6025
+ \`\`\`
6026
+
6027
+ ### 3. Wrong Exit Result Handling
6028
+ \`\`\`typescript
6029
+ // ❌ WRONG
6030
+ if (result.exit?.name === 'my_exit') {
6031
+ const data = result.exit.value
6032
+ }
6033
+
6034
+ // ✅ CORRECT
6035
+ if (result.is(MyExit)) {
6036
+ const data = result.output // Type-safe!
6037
+ }
6038
+ \`\`\`
6039
+
6040
+ ### 4. Reserved Table Column Names
6041
+ \`\`\`typescript
6042
+ // ❌ WRONG - These are reserved
6043
+ columns: {
6044
+ id: z.string(),
6045
+ createdAt: z.string(),
6046
+ updatedAt: z.string()
6047
+ }
6048
+
6049
+ // ✅ CORRECT - Use alternatives
6050
+ columns: {
6051
+ visibleId: z.string(),
6052
+ savedAt: z.string(),
6053
+ modifiedAt: z.string()
6054
+ }
6055
+ \`\`\`
6056
+
6057
+ ### 5. Re-exporting Auto-Registered Files
6058
+ \`\`\`typescript
6059
+ // ❌ WRONG - src/tables/index.ts
6060
+ export { MyTable } from "./myTable" // Causes duplicates!
6061
+
6062
+ // ✅ CORRECT - Leave index.ts empty
6063
+ // Files in src/tables/, src/conversations/, etc. are auto-registered
6064
+ \`\`\`
6065
+
6066
+ ### 6. Table Name Missing "Table" Suffix
6067
+ \`\`\`typescript
6068
+ // ❌ WRONG
6069
+ name: "users"
6070
+ name: "user_data"
6071
+
6072
+ // ✅ CORRECT
6073
+ name: "usersTable"
6074
+ name: "userdataTable"
6075
+ \`\`\`
6076
+
6077
+ ## When Making Changes
6078
+
6079
+ 1. **Always search Botpress docs** using \`mcp__botpress-docs__SearchBotpress\`
6080
+ 2. **Check examples** for patterns
6081
+ 3. **Regenerate types** after changing \`agent.config.ts\` (run \`adk dev\`)
6082
+ 4. **Test in dev mode** with hot reloading (\`adk dev\`)
6083
+ 5. **Follow TypeScript types** - They're auto-generated from integrations
6084
+
6085
+ ## Resources
6086
+
6087
+ - [ADK Overview](https://botpress.com/docs/for-developers/adk/overview)
6088
+ - [ADK Getting Started](https://botpress.com/docs/for-developers/adk/getting-started)
6089
+ - [Project Structure](https://botpress.com/docs/for-developers/adk/project-structure)
6090
+ - [Conversations](https://botpress.com/docs/for-developers/adk/concepts/conversations)
6091
+ - [Workflows](https://botpress.com/docs/for-developers/adk/concepts/workflows)
6092
+ `;
6093
+
6094
+ // src/agent-init/agent-project-generator.ts
4834
6095
  class AgentProjectGenerator {
4835
6096
  projectPath;
4836
6097
  projectName;
@@ -4875,7 +6136,7 @@ class AgentProjectGenerator {
4875
6136
  deploy: "adk deploy"
4876
6137
  },
4877
6138
  dependencies: {
4878
- "@botpress/runtime": `^${"1.11.8"}`
6139
+ "@botpress/runtime": `^${"1.11.9"}`
4879
6140
  },
4880
6141
  devDependencies: {
4881
6142
  typescript: "^5.9.3"
@@ -5039,9 +6300,7 @@ A Botpress Agent built with the ADK.
5039
6300
  await this.writeFormattedFile("README.md", readme);
5040
6301
  }
5041
6302
  createClaudeMd() {
5042
- const templatePath = path15.join(__dirname2, "CLAUDE.template.md");
5043
- const claudeMd = fs11.readFileSync(templatePath, "utf-8");
5044
- this.writeFile("CLAUDE.md", claudeMd);
6303
+ this.writeFile("CLAUDE.md", CLAUDE_template_default);
5045
6304
  }
5046
6305
  async createSourceStructure() {
5047
6306
  const srcPath = path15.join(this.projectPath, "src");
@@ -8840,7 +10099,7 @@ class KnowledgeManager {
8840
10099
  }
8841
10100
  }
8842
10101
  // src/knowledge/sync-formatter.ts
8843
- import { readFileSync as readFileSync2 } from "fs";
10102
+ import { readFileSync } from "fs";
8844
10103
  import { join as join7 } from "path";
8845
10104
  var getAdkVersion = () => {
8846
10105
  try {
@@ -8849,7 +10108,7 @@ var getAdkVersion = () => {
8849
10108
  } catch {
8850
10109
  try {
8851
10110
  const adkPackagePath = join7(process.cwd(), "node_modules/@botpress/adk/package.json");
8852
- const pkg = JSON.parse(readFileSync2(adkPackagePath, "utf-8"));
10111
+ const pkg = JSON.parse(readFileSync(adkPackagePath, "utf-8"));
8853
10112
  return pkg.version;
8854
10113
  } catch {
8855
10114
  return "unknown";
@@ -9137,7 +10396,7 @@ class AgentConfigSyncManager {
9137
10396
  }
9138
10397
 
9139
10398
  // src/preflight/formatter.ts
9140
- import { readFileSync as readFileSync3 } from "fs";
10399
+ import { readFileSync as readFileSync2 } from "fs";
9141
10400
  import { join as join9 } from "path";
9142
10401
  var getAdkVersion2 = () => {
9143
10402
  try {
@@ -9146,7 +10405,7 @@ var getAdkVersion2 = () => {
9146
10405
  } catch {
9147
10406
  try {
9148
10407
  const adkPackagePath = join9(process.cwd(), "node_modules/@botpress/adk/package.json");
9149
- const pkg = JSON.parse(readFileSync3(adkPackagePath, "utf-8"));
10408
+ const pkg = JSON.parse(readFileSync2(adkPackagePath, "utf-8"));
9150
10409
  return pkg.version;
9151
10410
  } catch {
9152
10411
  return "unknown";
@@ -9504,5 +10763,5 @@ export {
9504
10763
  AgentProject
9505
10764
  };
9506
10765
 
9507
- //# debugId=E3C3F451B27CF2ED64756E2164756E21
10766
+ //# debugId=4806E8ECDC510E9264756E2164756E21
9508
10767
  //# sourceMappingURL=index.js.map