@botpress/adk 1.17.0 → 1.18.0-beta.2

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 (94) 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/generators/tests.d.ts.map +1 -1
  26. package/dist/index.d.ts +4 -3
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +704 -468
  29. package/dist/index.js.map +21 -21
  30. package/dist/integrations/checker.d.ts.map +1 -1
  31. package/dist/integrations/config-utils.d.ts +1 -0
  32. package/dist/integrations/config-utils.d.ts.map +1 -1
  33. package/dist/integrations/operations.d.ts +19 -6
  34. package/dist/integrations/operations.d.ts.map +1 -1
  35. package/dist/knowledge/manager.d.ts.map +1 -1
  36. package/dist/preflight/checker.d.ts.map +1 -1
  37. package/dist/templates/README.md +101 -0
  38. package/dist/templates/blank/README.md +36 -0
  39. package/dist/templates/blank/agent.config.ts +49 -0
  40. package/dist/templates/blank/package.json +17 -0
  41. package/dist/templates/blank/src/actions/index.ts +19 -0
  42. package/dist/templates/blank/src/conversations/index.ts +16 -0
  43. package/dist/templates/blank/src/knowledge/index.ts +17 -0
  44. package/dist/templates/blank/src/tables/index.ts +19 -0
  45. package/dist/templates/blank/src/triggers/index.ts +20 -0
  46. package/dist/templates/blank/src/workflows/index.ts +23 -0
  47. package/dist/templates/blank/tsconfig.json +22 -0
  48. package/dist/templates/crm-enrichment/README.md +85 -0
  49. package/dist/templates/crm-enrichment/agent.config.ts +33 -0
  50. package/dist/templates/crm-enrichment/package.json +17 -0
  51. package/dist/templates/crm-enrichment/src/actions/enrich-contact.ts +81 -0
  52. package/dist/templates/crm-enrichment/src/conversations/index.ts +14 -0
  53. package/dist/templates/crm-enrichment/src/knowledge/index.ts +17 -0
  54. package/dist/templates/crm-enrichment/src/tables/contacts.ts +43 -0
  55. package/dist/templates/crm-enrichment/src/triggers/daily-enrichment.ts +30 -0
  56. package/dist/templates/crm-enrichment/src/workflows/enrichment-pipeline.ts +171 -0
  57. package/dist/templates/crm-enrichment/tsconfig.json +22 -0
  58. package/dist/templates/hello-world/README.md +46 -0
  59. package/dist/templates/hello-world/agent.config.ts +48 -0
  60. package/dist/templates/hello-world/package.json +17 -0
  61. package/dist/templates/hello-world/src/actions/index.ts +19 -0
  62. package/dist/templates/hello-world/src/conversations/index.ts +10 -0
  63. package/dist/templates/hello-world/src/knowledge/index.ts +17 -0
  64. package/dist/templates/hello-world/src/tables/index.ts +19 -0
  65. package/dist/templates/hello-world/src/triggers/index.ts +20 -0
  66. package/dist/templates/hello-world/src/workflows/index.ts +23 -0
  67. package/dist/templates/hello-world/tsconfig.json +22 -0
  68. package/dist/templates/knowledge-assistant/README.md +66 -0
  69. package/dist/templates/knowledge-assistant/agent.config.ts +26 -0
  70. package/dist/templates/knowledge-assistant/package.json +17 -0
  71. package/dist/templates/knowledge-assistant/src/actions/index.ts +19 -0
  72. package/dist/templates/knowledge-assistant/src/actions/search-docs.ts +50 -0
  73. package/dist/templates/knowledge-assistant/src/conversations/index.ts +33 -0
  74. package/dist/templates/knowledge-assistant/src/knowledge/docs.ts +23 -0
  75. package/dist/templates/knowledge-assistant/src/knowledge/getting-started.md +49 -0
  76. package/dist/templates/knowledge-assistant/src/tables/index.ts +21 -0
  77. package/dist/templates/knowledge-assistant/src/triggers/index.ts +17 -0
  78. package/dist/templates/knowledge-assistant/src/workflows/index.ts +28 -0
  79. package/dist/templates/knowledge-assistant/tsconfig.json +22 -0
  80. package/dist/templates/slack-triage/README.md +74 -0
  81. package/dist/templates/slack-triage/agent.config.ts +35 -0
  82. package/dist/templates/slack-triage/evals/triage-basic.eval.ts +55 -0
  83. package/dist/templates/slack-triage/package.json +17 -0
  84. package/dist/templates/slack-triage/src/actions/classify-request.ts +65 -0
  85. package/dist/templates/slack-triage/src/conversations/slack-dm.ts +72 -0
  86. package/dist/templates/slack-triage/src/knowledge/team-directory.md +33 -0
  87. package/dist/templates/slack-triage/src/tables/routing-rules.ts +38 -0
  88. package/dist/templates/slack-triage/src/triggers/new-message.ts +44 -0
  89. package/dist/templates/slack-triage/src/workflows/triage-flow.ts +104 -0
  90. package/dist/templates/slack-triage/tsconfig.json +22 -0
  91. package/dist/templates/template.config.json +47 -0
  92. package/dist/utils/json-ordering.d.ts +1 -1
  93. package/dist/utils/json-ordering.d.ts.map +1 -1
  94. package/package.json +7 -15
@@ -0,0 +1,66 @@
1
+ # {{projectName}}
2
+
3
+ A RAG-powered knowledge assistant built with Botpress ADK. This agent answers questions using your documents, with source citations for every response.
4
+
5
+ ## How It Works
6
+
7
+ 1. **Knowledge Base**: Documents in `src/knowledge/` are indexed for semantic search
8
+ 2. **Conversations**: When a user asks a question, the AI searches the knowledge base for relevant passages
9
+ 3. **Citations**: Responses include references to the source documents used
10
+
11
+ ## Getting Started
12
+
13
+ 1. Install dependencies:
14
+
15
+ ```bash
16
+ {{packageManager}} install
17
+ ```
18
+
19
+ 2. Add your documents to `src/knowledge/` (markdown, PDF, or text files)
20
+
21
+ 3. Start development server:
22
+
23
+ ```bash
24
+ adk dev
25
+ ```
26
+
27
+ 4. Deploy your agent:
28
+ ```bash
29
+ adk deploy
30
+ ```
31
+
32
+ ## Adding Documents
33
+
34
+ Place your documents in `src/knowledge/`. Supported formats:
35
+
36
+ - Markdown (`.md`)
37
+ - PDF (`.pdf`)
38
+ - Text (`.txt`)
39
+
40
+ The knowledge base automatically indexes all supported files. After adding new documents, run `adk kb sync` or restart `adk dev` to re-index.
41
+
42
+ ## Project Structure
43
+
44
+ - `src/knowledge/docs.ts` - Knowledge base definition
45
+ - `src/knowledge/*.md` - Your source documents
46
+ - `src/conversations/index.ts` - Conversation handler with RAG execution
47
+ - `src/actions/` - Add custom actions (e.g. programmatic KB search for API access)
48
+ - `src/tables/` - Data storage (extend as needed)
49
+ - `src/triggers/` - Event subscriptions (extend as needed)
50
+ - `src/workflows/` - Long-running processes (extend as needed)
51
+
52
+ ## How Citations Work
53
+
54
+ The conversation handler passes the knowledge base to `execute()`. The AI automatically searches relevant documents when answering questions and cites its sources. This is handled by the Botpress runtime -- no manual citation logic is required.
55
+
56
+ ## Customization
57
+
58
+ - **Model**: Change `defaultModels` in `agent.config.ts` to use a different LLM
59
+ - **Instructions**: Edit the `instructions` in `src/conversations/index.ts` to change the agent's personality
60
+ - **Knowledge sources**: Add website crawling or table-based sources in `src/knowledge/docs.ts`
61
+ - **Tools**: Convert the search action to a tool with `.asTool()` for more control
62
+
63
+ ## Learn More
64
+
65
+ - [ADK Documentation](https://botpress.com/docs/adk)
66
+ - [Botpress Platform](https://botpress.com)
@@ -0,0 +1,26 @@
1
+ import { z, defineConfig } from '@botpress/runtime'
2
+
3
+ export default defineConfig({
4
+ name: '{{projectName}}',
5
+ description: 'A RAG-powered knowledge assistant that answers questions using your documents',
6
+
7
+ defaultModels: {
8
+ autonomous: 'openai:gpt-4.1-mini-2025-04-14',
9
+ zai: 'openai:gpt-4.1-2025-04-14',
10
+ },
11
+
12
+ // Per-bot persistent state
13
+ bot: {
14
+ state: z.object({}),
15
+ },
16
+
17
+ // Per-user persistent state
18
+ user: {
19
+ state: z.object({}),
20
+ },
21
+
22
+ // Integrations extend your agent with actions, channels, and events.
23
+ dependencies: {
24
+ integrations: {},
25
+ },
26
+ })
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "{{projectName}}",
3
+ "version": "1.0.0",
4
+ "description": "A RAG-powered knowledge assistant built with Botpress ADK",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "adk dev",
8
+ "build": "adk build",
9
+ "deploy": "adk deploy"
10
+ },
11
+ "dependencies": {
12
+ "@botpress/runtime": "^{{runtimeVersion}}"
13
+ },
14
+ "devDependencies": {
15
+ "typescript": "^5.9.3"
16
+ }
17
+ }
@@ -0,0 +1,19 @@
1
+ // import { Action, z } from '@botpress/runtime'
2
+ //
3
+ // /**
4
+ // * A strongly-typed callable function — use `new Action(...)` (it's a class constructor).
5
+ // * Handler always receives `{ input, client }` as props, not the input fields directly.
6
+ // * Can be converted to an AI tool via `.asTool()` and passed to `execute()`.
7
+ // */
8
+ // export default new Action({
9
+ // name: 'myAction',
10
+ // input: z.object({
11
+ // message: z.string().describe('The message to process'),
12
+ // }),
13
+ // output: z.object({
14
+ // result: z.string().describe('The processed result'),
15
+ // }),
16
+ // handler: async ({ input }) => {
17
+ // return { result: `Processed: ${input.message}` }
18
+ // },
19
+ // })
@@ -0,0 +1,50 @@
1
+ import { Action, z, context } from '@botpress/runtime'
2
+ import { DocsKB } from '../knowledge/docs'
3
+
4
+ /**
5
+ * Search the knowledge base programmatically.
6
+ *
7
+ * This action provides API-level access to the documentation search,
8
+ * useful for integrations, workflows, or external systems that need
9
+ * to query the knowledge base outside of a conversation.
10
+ */
11
+ export const searchDocs = new Action({
12
+ name: 'searchDocs',
13
+ description: 'Search the documentation knowledge base',
14
+
15
+ input: z.object({
16
+ query: z.string().describe('The search query'),
17
+ limit: z.number().min(1).max(20).default(5).describe('Maximum number of results to return'),
18
+ }),
19
+
20
+ output: z.object({
21
+ results: z.array(
22
+ z.object({
23
+ content: z.string().describe('The matched passage content'),
24
+ source: z.string().describe('The source file path'),
25
+ score: z.number().describe('Relevance score'),
26
+ })
27
+ ),
28
+ }),
29
+
30
+ async handler({ input }) {
31
+ const client = context.get('client')
32
+
33
+ const { passages } = await client.searchFiles({
34
+ query: input.query,
35
+ tags: {
36
+ source: 'knowledge-base',
37
+ kbName: [DocsKB.name],
38
+ },
39
+ limit: input.limit,
40
+ })
41
+
42
+ return {
43
+ results: passages.map((p) => ({
44
+ content: p.content,
45
+ source: p.file.key,
46
+ score: p.score,
47
+ })),
48
+ }
49
+ },
50
+ })
@@ -0,0 +1,33 @@
1
+ import { Conversation } from '@botpress/runtime'
2
+ import { DocsKB } from '../knowledge/docs'
3
+
4
+ /**
5
+ * Main conversation handler for the knowledge assistant.
6
+ *
7
+ * Uses execute() with the DocsKB knowledge base. The AI automatically
8
+ * gets a search tool for the KB — no custom action needed.
9
+ *
10
+ * Handles all channels (chat, webchat, etc.) via the wildcard channel.
11
+ */
12
+ export default new Conversation({
13
+ channel: '*',
14
+
15
+ async handler({ execute }) {
16
+ await execute({
17
+ instructions: `You are a company knowledge assistant. You answer employee questions using the company documentation.
18
+
19
+ Lead with example questions, to assist the user in asking good questions. For example:
20
+ - "What is the company's remote work policy?"
21
+ - "How do I request time off?"
22
+ - "What are the steps to set up my email on a new device?"
23
+ Rules:
24
+ - Search the knowledge base for every question. Do not guess or use general knowledge.
25
+ - If the answer is in the docs, quote the relevant policy or section.
26
+ - If the docs don't cover it, say "I don't have information about that in our docs" and suggest who to ask (HR, manager, IT, etc).
27
+ - Be direct. Lead with the answer, then provide context.
28
+ - Use short paragraphs. Bullet points for lists.`,
29
+
30
+ knowledge: [DocsKB],
31
+ })
32
+ },
33
+ })
@@ -0,0 +1,23 @@
1
+ import { Knowledge, DataSource } from '@botpress/runtime'
2
+
3
+ /**
4
+ * Knowledge base that indexes all markdown files in the src/knowledge/ directory.
5
+ *
6
+ * Add your documents (markdown, PDF, text) to this folder and they will be
7
+ * automatically indexed for semantic search. The AI uses this knowledge base
8
+ * to answer questions with accurate, source-cited responses.
9
+ *
10
+ * Sync your knowledge base:
11
+ * adk kb sync (manual sync)
12
+ * adk dev (auto-syncs on startup and file changes)
13
+ */
14
+ const docsSource = DataSource.Directory.fromPath('src/knowledge', {
15
+ id: 'docs',
16
+ filter: (filePath) => filePath.endsWith('.md') || filePath.endsWith('.pdf') || filePath.endsWith('.txt'),
17
+ })
18
+
19
+ export const DocsKB = new Knowledge({
20
+ name: 'docsKB',
21
+ description: 'Documentation and reference materials for answering user questions',
22
+ sources: [docsSource],
23
+ })
@@ -0,0 +1,49 @@
1
+ # Company Handbook
2
+
3
+ Welcome to Acme Corp! This document covers our policies, benefits, and day-to-day operations.
4
+
5
+ > **Note:** This is sample content. Replace it with your actual company docs, product documentation, or any knowledge you want your assistant to answer questions about.
6
+
7
+ ## Working Hours
8
+
9
+ Our standard working hours are 9 AM to 5 PM in your local timezone. We offer flexible scheduling — as long as you're available for core hours (11 AM to 3 PM) and attend your team's standups, you can adjust your start and end times.
10
+
11
+ ## Time Off Policy
12
+
13
+ - **PTO:** 20 days per year, accruing monthly
14
+ - **Sick leave:** Unlimited, no questions asked for the first 3 days. Beyond that, a doctor's note is appreciated but not required.
15
+ - **Holidays:** We follow the US federal holiday calendar. If you're outside the US, you can swap US holidays for your local ones.
16
+ - **Parental leave:** 16 weeks paid for all parents, regardless of gender.
17
+
18
+ ## Expense Policy
19
+
20
+ - **Software and tools:** Pre-approved up to $100/month. Anything over needs manager approval.
21
+ - **Books and courses:** Fully covered, no cap. Submit receipts through Expensify.
22
+ - **Travel:** Book economy for flights under 5 hours, business class for longer. Hotels up to $250/night.
23
+ - **Meals:** $30/day when traveling. Team dinners covered fully with VP approval.
24
+
25
+ ## Engineering Practices
26
+
27
+ ### Code Review
28
+
29
+ Every PR needs at least one approval before merging. For changes touching auth, payments, or data deletion, two approvals are required. Reviewers should respond within 24 hours.
30
+
31
+ ### Incident Response
32
+
33
+ 1. **Severity 1 (service down):** Page the on-call engineer via PagerDuty. All hands until resolved.
34
+ 2. **Severity 2 (degraded):** Notify #incidents in Slack. On-call investigates, escalates if not resolved in 1 hour.
35
+ 3. **Severity 3 (minor bug):** File a ticket, fix in next sprint.
36
+
37
+ Post-incident reviews happen within 48 hours. No blame, just learnings.
38
+
39
+ ### Deployment
40
+
41
+ We deploy to production twice daily (11 AM and 4 PM UTC). Feature flags are required for anything user-facing. Rollbacks are one-click via the deploy dashboard.
42
+
43
+ ## Benefits
44
+
45
+ - **Health insurance:** 100% covered for employees, 80% for dependents
46
+ - **401k:** 4% match, vests immediately
47
+ - **Home office:** $1,500 one-time setup budget for new hires
48
+ - **Wellness:** $100/month for gym, therapy, or wellness apps
49
+ - **Learning:** Conference budget of $2,000/year plus 3 days off to attend
@@ -0,0 +1,21 @@
1
+ // import { Table, z } from '@botpress/runtime'
2
+ //
3
+ // /**
4
+ // * Example: Track search queries and feedback to improve the knowledge base over time.
5
+ // *
6
+ // * Table names must end with "Table" (e.g. QueriesTable, FeedbackTable).
7
+ // * Mark string columns as `{ searchable: true, schema: z.string() }` to enable semantic search.
8
+ // * @reserved id, createdAt, updatedAt — auto-managed by the system, do not define them.
9
+ // */
10
+ // export const QueriesTable = new Table({
11
+ // name: 'queriesTable',
12
+ // description: 'Tracks user search queries and their feedback',
13
+ // columns: {
14
+ // query: {
15
+ // searchable: true,
16
+ // schema: z.string().describe('The user search query'),
17
+ // },
18
+ // resultCount: z.number().describe('Number of results returned'),
19
+ // helpful: z.boolean().optional().describe('Whether the user found the answer helpful'),
20
+ // },
21
+ // })
@@ -0,0 +1,17 @@
1
+ // import { Trigger } from '@botpress/runtime'
2
+ //
3
+ // /**
4
+ // * Example: Track when users start conversations to monitor KB assistant usage.
5
+ // *
6
+ // * Bot events: 'register', 'message.created', 'conversation.started', 'conversation.ended',
7
+ // * 'user.created', 'workflow.started', 'workflow.completed', 'workflow.failed'
8
+ // * Run `adk info <integration>` to see all events for an integration.
9
+ // */
10
+ // export default new Trigger({
11
+ // name: 'onConversationStarted',
12
+ // description: 'Logs when a new knowledge assistant conversation begins',
13
+ // events: ['conversation.started'],
14
+ // handler: async ({ event }) => {
15
+ // console.log(`New conversation started: ${event.payload.conversationId}`)
16
+ // },
17
+ // })
@@ -0,0 +1,28 @@
1
+ // import { Workflow, z } from '@botpress/runtime'
2
+ // import { DocsKB } from '../knowledge/docs'
3
+ //
4
+ // /**
5
+ // * Example: A research workflow that searches the knowledge base and produces a summary.
6
+ // *
7
+ // * Each `step()` call is checkpointed — safe to retry on failure.
8
+ // * Start from a trigger or conversation via `ResearchWorkflow.start({ input })`.
9
+ // */
10
+ // export const ResearchWorkflow = new Workflow({
11
+ // name: 'research',
12
+ // input: z.object({
13
+ // topic: z.string().describe('The topic to research'),
14
+ // }),
15
+ // output: z.object({
16
+ // summary: z.string().describe('A summary of findings from the knowledge base'),
17
+ // }),
18
+ // handler: async ({ input, step, execute }) => {
19
+ // const summary = await step('research', async () => {
20
+ // const result = await execute({
21
+ // instructions: `Research the following topic using the knowledge base and provide a concise summary: ${input.topic}`,
22
+ // knowledge: [DocsKB],
23
+ // })
24
+ // return result
25
+ // })
26
+ // return { summary }
27
+ // },
28
+ // })
@@ -0,0 +1,22 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ES2022",
5
+ "moduleResolution": "Bundler",
6
+ "lib": ["ES2022", "DOM"],
7
+ "outDir": "./dist",
8
+ "rootDir": ".",
9
+ "strict": true,
10
+ "esModuleInterop": true,
11
+ "allowSyntheticDefaultImports": true,
12
+ "skipLibCheck": true,
13
+ "forceConsistentCasingInFileNames": true,
14
+ "moduleDetection": "force",
15
+ "resolveJsonModule": true,
16
+ "paths": {
17
+ "@botpress/runtime/_types/*": ["./.adk/*-types"]
18
+ }
19
+ },
20
+ "include": ["src/**/*", ".adk/**/*"],
21
+ "exclude": ["node_modules", "dist"]
22
+ }
@@ -0,0 +1,74 @@
1
+ # {{projectName}}
2
+
3
+ A Slack triage bot built with the Botpress ADK. It monitors channels for help requests, classifies them using AI, and routes them to the right person or channel based on configurable routing rules.
4
+
5
+ ## How It Works
6
+
7
+ 1. **Trigger**: A new message arrives in a monitored Slack channel
8
+ 2. **Classify**: The `classify-request` action uses Zai to categorize the request (bug, feature_request, question, ops_issue)
9
+ 3. **Route**: The `triage-flow` workflow looks up routing rules from the `RoutingRulesTable` and posts a summary to the appropriate channel or person
10
+ 4. **Respond**: The Slack DM conversation handler answers follow-up questions about triage status
11
+
12
+ ## Getting Started
13
+
14
+ 1. Install dependencies:
15
+
16
+ ```bash
17
+ {{packageManager}} install
18
+ ```
19
+
20
+ 2. Configure Slack:
21
+ - Create a Slack app at https://api.slack.com/apps
22
+ - Add the bot to your workspace
23
+ - Run `adk dev` and configure the Slack integration in the Botpress dashboard
24
+
25
+ 3. Seed routing rules:
26
+ After your first `adk dev`, add rows to the `RoutingRulesTable` via the Botpress dashboard or a script:
27
+
28
+ ```
29
+ | category | assignee | slackChannel | priority |
30
+ |-----------------|----------------|-------------------|----------|
31
+ | bug | @oncall-eng | #bugs | high |
32
+ | feature_request | @product-team | #feature_requests | medium |
33
+ | question | @support-team | #help-desk | low |
34
+ | ops_issue | @devops | #ops-alerts | high |
35
+ ```
36
+
37
+ 4. Start development server:
38
+
39
+ ```bash
40
+ adk dev
41
+ ```
42
+
43
+ 5. Deploy your agent:
44
+ ```bash
45
+ adk deploy
46
+ ```
47
+
48
+ ## Project Structure
49
+
50
+ - `src/actions/classify-request.ts` - AI-powered request classification
51
+ - `src/workflows/triage-flow.ts` - Multi-step triage workflow (classify, lookup, route)
52
+ - `src/conversations/slack-dm.ts` - Handles Slack channel messages with AI
53
+ - `src/tables/routing-rules.ts` - Configurable routing rules
54
+ - `src/triggers/new-message.ts` - Fires on new Slack messages
55
+ - `src/knowledge/team-directory.md` - Team directory for AI context
56
+
57
+ ## Customization
58
+
59
+ ### Adding Categories
60
+
61
+ Edit `src/actions/classify-request.ts` to add new categories to the `category` enum and update the Zai label definitions.
62
+
63
+ ### Changing Routing Logic
64
+
65
+ Edit `src/workflows/triage-flow.ts` to customize how requests are routed. You can add steps for priority escalation, duplicate detection, or SLA tracking.
66
+
67
+ ### Adding Channels
68
+
69
+ Create new conversation handlers in `src/conversations/` for other Slack channels or platforms (e.g., `slack-channel.ts` for public channel responses).
70
+
71
+ ## Learn More
72
+
73
+ - [ADK Documentation](https://botpress.com/docs/adk)
74
+ - [Botpress Platform](https://botpress.com)
@@ -0,0 +1,35 @@
1
+ import { z, defineConfig } from '@botpress/runtime'
2
+
3
+ export default defineConfig({
4
+ name: '{{projectName}}',
5
+ description: 'Slack triage bot - monitors channels, classifies help requests, and routes them to the right person',
6
+
7
+ defaultModels: {
8
+ autonomous: 'openai:gpt-4.1-mini-2025-04-14', // Model used by execute() in conversations/workflows
9
+ zai: 'openai:gpt-4.1-2025-04-14', // Model used by Zai (extract, check, label, etc.)
10
+ },
11
+
12
+ // Per-bot persistent state - tracks triage statistics across all conversations.
13
+ bot: {
14
+ state: z.object({
15
+ totalTriaged: z.number().default(0).describe('Total requests triaged'),
16
+ lastTriagedAt: z.string().optional().describe('ISO timestamp of last triage'),
17
+ }),
18
+ },
19
+
20
+ // Per-user persistent state - remembers routing preferences per user.
21
+ user: {
22
+ state: z.object({
23
+ preferredCategory: z.string().optional().describe('Category this user most often submits'),
24
+ requestCount: z.number().default(0).describe('Number of requests from this user'),
25
+ }),
26
+ },
27
+
28
+ // Integrations extend your agent with actions, channels, and events.
29
+ // Browse available integrations: adk search <name> | adk list --available
30
+ // Install one: adk add <integration> (e.g. adk add browser)
31
+ // See actions/events/channels: adk info <integration>
32
+ dependencies: {
33
+ integrations: {},
34
+ },
35
+ })
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Eval: triage-basic
3
+ *
4
+ * Verifies that the triage bot correctly classifies common request types.
5
+ *
6
+ * Evals use the Eval class from @botpress/adk. Each eval defines a simulated
7
+ * conversation with assertions on the bot's responses and tool usage.
8
+ *
9
+ * Run evals with: adk eval
10
+ * Run a specific eval: adk eval --name triage-basic
11
+ */
12
+ import { Eval } from '@botpress/adk'
13
+
14
+ export default new Eval({
15
+ name: 'triage-basic',
16
+ description: 'Verify the bot classifies bug reports, feature requests, and questions correctly',
17
+ tags: ['triage', 'classification'],
18
+ type: 'regression',
19
+
20
+ conversation: [
21
+ {
22
+ user: 'The login page is showing a 500 error whenever I try to sign in with Google SSO',
23
+ assert: {
24
+ response: [
25
+ {
26
+ llm_judge:
27
+ 'Response acknowledges this is a bug or error report and indicates it will be triaged or routed to the appropriate team',
28
+ },
29
+ ],
30
+ },
31
+ },
32
+ {
33
+ user: 'It would be great if we could export dashboard data to CSV',
34
+ assert: {
35
+ response: [
36
+ {
37
+ llm_judge:
38
+ 'Response recognizes this as a feature request and indicates it will be forwarded to the product team or logged appropriately',
39
+ },
40
+ ],
41
+ },
42
+ },
43
+ {
44
+ user: 'How do I reset my password?',
45
+ assert: {
46
+ response: [
47
+ {
48
+ llm_judge:
49
+ 'Response treats this as a general question and either answers it directly or indicates it will be routed to support',
50
+ },
51
+ ],
52
+ },
53
+ },
54
+ ],
55
+ })
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "{{projectName}}",
3
+ "version": "1.0.0",
4
+ "description": "A Slack triage bot built with the ADK - classifies help requests and routes them",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "adk dev",
8
+ "build": "adk build",
9
+ "deploy": "adk deploy"
10
+ },
11
+ "dependencies": {
12
+ "@botpress/runtime": "^{{runtimeVersion}}"
13
+ },
14
+ "devDependencies": {
15
+ "typescript": "^5.9.3"
16
+ }
17
+ }
@@ -0,0 +1,65 @@
1
+ import { Action, z, adk } from '@botpress/runtime'
2
+
3
+ /**
4
+ * Classifies an incoming help request into a category using Zai.
5
+ *
6
+ * Supported categories:
7
+ * - bug: Something is broken or not working as expected
8
+ * - feature_request: A request for new functionality
9
+ * - question: A general question or "how do I..." inquiry
10
+ * - ops_issue: Infrastructure, deployment, or operational problem
11
+ *
12
+ * Customize: Add new categories by extending the enum and the label definitions below.
13
+ */
14
+ export const classifyRequest = new Action({
15
+ name: 'classifyRequest',
16
+ description: 'Classify a help request into a category using AI',
17
+
18
+ input: z.object({
19
+ message: z.string().describe('The raw help request message text'),
20
+ }),
21
+
22
+ output: z.object({
23
+ category: z.enum(['bug', 'feature_request', 'question', 'ops_issue']).describe('The classified category'),
24
+ confidence: z.string().describe('How confident the classification is: high, medium, or low'),
25
+ summary: z.string().describe('A one-sentence summary of the request'),
26
+ }),
27
+
28
+ handler: async ({ input }) => {
29
+ // Use Zai label() with .result() to get confidence scores per category.
30
+ // Each label is evaluated independently with a 5-tier confidence scale.
31
+ const { output: labels } = await adk.zai
32
+ .label(input.message, {
33
+ bug: 'reports a bug, error, crash, or something not working as expected',
34
+ feature_request: 'requests a new feature, enhancement, or improvement to existing functionality',
35
+ question: 'asks a general question, seeks guidance, or wants to know how to do something',
36
+ ops_issue: 'reports an infrastructure, deployment, uptime, or operational problem',
37
+ })
38
+ .result()
39
+
40
+ // Pick the category with the highest confidence that matched (value: true).
41
+ type Category = 'bug' | 'feature_request' | 'question' | 'ops_issue'
42
+ const categories: Category[] = ['bug', 'feature_request', 'question', 'ops_issue']
43
+
44
+ const best = categories
45
+ .filter((c) => labels[c].value)
46
+ .sort((a, b) => labels[b].confidence - labels[a].confidence)[0]
47
+
48
+ const category: Category = best ?? 'question'
49
+ const confidence = best ? (labels[best].confidence >= 0.8 ? 'high' : 'medium') : 'low'
50
+
51
+ // Use Zai extract() to generate a concise summary of the request.
52
+ const extracted = await adk.zai.extract(
53
+ input.message,
54
+ z.object({
55
+ summary: z.string().describe('A single concise sentence summarizing the help request'),
56
+ })
57
+ )
58
+
59
+ return {
60
+ category,
61
+ confidence,
62
+ summary: extracted.summary,
63
+ }
64
+ },
65
+ })