Integration Patterns
Patterns for integrating generated agents with other systems.
Generated agents can be integrated into various environments beyond the default CLI. This reference covers common integration patterns.
Interface Types
Agent Workshop supports multiple interface types:
| Interface | Status | Description |
|---|---|---|
| CLI | Full Support | Interactive command-line interface |
| Web | Scaffolding | Web-based chat interface |
| API | Scaffolding | REST API endpoint |
| Discord | Scaffolding | Discord bot |
| Slack | Scaffolding | Slack bot |
Scaffolding interfaces provide a starting structure but require additional configuration and deployment setup.
Programmatic Usage
Import and use the agent directly in your code:
1import { MyAgent } from './src/agent';
2
3// Create agent instance
4const agent = new MyAgent({
5 apiKey: process.env.ANTHROPIC_API_KEY,
6 model: 'claude-sonnet-4-5-20250929'
7});
8
9// Send a query
10const response = await agent.query('Analyze the codebase structure');
11
12// Handle streaming response
13for await (const chunk of agent.stream('Explain this file')) {
14 process.stdout.write(chunk);
15}Express API Integration
Wrap your agent in an Express API:
src/api.ts
1import express from 'express';
2import { MyAgent } from './agent';
3
4const app = express();
5app.use(express.json());
6
7const agent = new MyAgent({
8 apiKey: process.env.ANTHROPIC_API_KEY
9});
10
11app.post('/api/chat', async (req, res) => {
12 const { message, sessionId } = req.body;
13
14 try {
15 const response = await agent.query(message, { sessionId });
16 res.json({ response });
17 } catch (error) {
18 res.status(500).json({ error: error.message });
19 }
20});
21
22app.post('/api/chat/stream', async (req, res) => {
23 const { message, sessionId } = req.body;
24
25 res.setHeader('Content-Type', 'text/event-stream');
26 res.setHeader('Cache-Control', 'no-cache');
27 res.setHeader('Connection', 'keep-alive');
28
29 for await (const chunk of agent.stream(message, { sessionId })) {
30 res.write(`data: ${JSON.stringify({ chunk })}\n\n`);
31 }
32
33 res.write('data: [DONE]\n\n');
34 res.end();
35});
36
37app.listen(3000);Discord Bot Integration
Create a Discord bot with your agent:
src/discord-bot.ts
1import { Client, GatewayIntentBits } from 'discord.js';
2import { MyAgent } from './agent';
3
4const client = new Client({
5 intents: [
6 GatewayIntentBits.Guilds,
7 GatewayIntentBits.GuildMessages,
8 GatewayIntentBits.MessageContent
9 ]
10});
11
12const agent = new MyAgent({
13 apiKey: process.env.ANTHROPIC_API_KEY
14});
15
16// Store sessions per channel
17const sessions = new Map<string, string>();
18
19client.on('messageCreate', async (message) => {
20 if (message.author.bot) return;
21 if (!message.content.startsWith('!agent')) return;
22
23 const query = message.content.slice(7).trim();
24 const sessionId = sessions.get(message.channelId) || message.channelId;
25
26 try {
27 await message.channel.sendTyping();
28
29 const response = await agent.query(query, { sessionId });
30
31 // Discord has a 2000 character limit
32 if (response.length > 2000) {
33 const chunks = response.match(/.{1,2000}/g) || [];
34 for (const chunk of chunks) {
35 await message.reply(chunk);
36 }
37 } else {
38 await message.reply(response);
39 }
40 } catch (error) {
41 await message.reply('Sorry, I encountered an error.');
42 }
43});
44
45client.login(process.env.DISCORD_TOKEN);Slack Bot Integration
Create a Slack bot using Bolt:
src/slack-bot.ts
1import { App } from '@slack/bolt';
2import { MyAgent } from './agent';
3
4const app = new App({
5 token: process.env.SLACK_BOT_TOKEN,
6 signingSecret: process.env.SLACK_SIGNING_SECRET
7});
8
9const agent = new MyAgent({
10 apiKey: process.env.ANTHROPIC_API_KEY
11});
12
13// Respond to mentions
14app.event('app_mention', async ({ event, say }) => {
15 const query = event.text.replace(/<@[^>]+>/g, '').trim();
16
17 try {
18 const response = await agent.query(query, {
19 sessionId: event.channel
20 });
21
22 await say({
23 text: response,
24 thread_ts: event.thread_ts || event.ts
25 });
26 } catch (error) {
27 await say('Sorry, I encountered an error.');
28 }
29});
30
31// Respond to slash commands
32app.command('/agent', async ({ command, ack, respond }) => {
33 await ack();
34
35 const response = await agent.query(command.text, {
36 sessionId: command.channel_id
37 });
38
39 await respond(response);
40});
41
42app.start(process.env.PORT || 3000);Webhook Integration
Trigger agent actions via webhooks:
1import express from 'express';
2import { MyAgent } from './agent';
3
4const app = express();
5app.use(express.json());
6
7const agent = new MyAgent({
8 apiKey: process.env.ANTHROPIC_API_KEY
9});
10
11// GitHub webhook handler
12app.post('/webhook/github', async (req, res) => {
13 const event = req.headers['x-github-event'];
14 const payload = req.body;
15
16 if (event === 'pull_request' && payload.action === 'opened') {
17 const prNumber = payload.number;
18 const prTitle = payload.pull_request.title;
19
20 const response = await agent.query(
21 `Review PR #${prNumber}: ${prTitle}`
22 );
23
24 // Post review as comment (implement as needed)
25 console.log('Review:', response);
26 }
27
28 res.status(200).send('OK');
29});CI/CD Integration
Run agent as part of CI/CD pipeline:
.github/workflows/agent-review.yml
1name: Agent Review
2
3on:
4 pull_request:
5 types: [opened, synchronize]
6
7jobs:
8 review:
9 runs-on: ubuntu-latest
10 steps:
11 - uses: actions/checkout@v4
12 with:
13 fetch-depth: 0
14
15 - uses: actions/setup-node@v4
16 with:
17 node-version: '20'
18
19 - name: Install agent
20 run: |
21 cd my-agent
22 npm install
23 npm run build
24
25 - name: Run review
26 env:
27 ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
28 run: |
29 cd my-agent
30 node dist/cli.js --query "Review the changes in this PR"Best Practices
Session Management
Use session IDs to maintain conversation context:
- Generate unique session IDs per user/channel
- Store session state for continuity
- Clean up old sessions periodically
Error Handling
Always handle errors gracefully:
- Catch and log exceptions
- Return user-friendly error messages
- Implement retry logic for transient failures
Rate Limiting
Protect against abuse:
- Implement per-user rate limits
- Queue requests during high load
- Monitor API usage and costs