@agentforge/cli 0.1.0
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/README.md +225 -0
- package/bin/agentforge.js +9 -0
- package/dist/index.cjs +1114 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +1103 -0
- package/dist/index.js.map +1 -0
- package/package.json +81 -0
- package/templates/README.md +163 -0
- package/templates/api/.env.example +13 -0
- package/templates/api/README.md +153 -0
- package/templates/api/package.json +41 -0
- package/templates/api/src/routes/agent.ts +54 -0
- package/templates/api/src/routes/health.ts +15 -0
- package/templates/api/src/server.ts +41 -0
- package/templates/api/tsconfig.json +10 -0
- package/templates/cli/.env.example +13 -0
- package/templates/cli/README.md +164 -0
- package/templates/cli/package.json +44 -0
- package/templates/cli/src/cli.ts +31 -0
- package/templates/cli/src/commands/analyze.ts +65 -0
- package/templates/cli/src/commands/chat.ts +65 -0
- package/templates/cli/tsconfig.json +10 -0
- package/templates/full/.env.example +13 -0
- package/templates/full/README.md +151 -0
- package/templates/full/package.json +40 -0
- package/templates/full/src/index.ts +53 -0
- package/templates/full/src/tools/example.ts +20 -0
- package/templates/full/tests/example.test.ts +17 -0
- package/templates/full/tsconfig.json +10 -0
- package/templates/minimal/README.md +64 -0
- package/templates/minimal/package.json +35 -0
- package/templates/minimal/src/index.ts +40 -0
- package/templates/minimal/tsconfig.json +10 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import { ChatOpenAI } from '@langchain/openai';
|
|
3
|
+
import { createReActAgent } from '@agentforge/patterns';
|
|
4
|
+
import { createLogger } from '@agentforge/core';
|
|
5
|
+
|
|
6
|
+
const router = Router();
|
|
7
|
+
const logger = createLogger({ level: 'info' });
|
|
8
|
+
|
|
9
|
+
// Initialize the agent
|
|
10
|
+
const model = new ChatOpenAI({
|
|
11
|
+
modelName: process.env.OPENAI_MODEL || 'gpt-4',
|
|
12
|
+
temperature: 0,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const agent = createReActAgent({
|
|
16
|
+
model,
|
|
17
|
+
tools: [],
|
|
18
|
+
systemPrompt: 'You are a helpful AI assistant API.',
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const compiledAgent = agent.compile();
|
|
22
|
+
|
|
23
|
+
// POST /api/agent/chat
|
|
24
|
+
router.post('/chat', async (req, res) => {
|
|
25
|
+
try {
|
|
26
|
+
const { message } = req.body;
|
|
27
|
+
|
|
28
|
+
if (!message) {
|
|
29
|
+
return res.status(400).json({ error: 'Message is required' });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
logger.info('Processing chat request');
|
|
33
|
+
|
|
34
|
+
const result = await compiledAgent.invoke({
|
|
35
|
+
messages: [{ role: 'user', content: message }],
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const response = result.messages[result.messages.length - 1].content;
|
|
39
|
+
|
|
40
|
+
res.json({
|
|
41
|
+
success: true,
|
|
42
|
+
response,
|
|
43
|
+
});
|
|
44
|
+
} catch (error: any) {
|
|
45
|
+
logger.error('Chat error:', error);
|
|
46
|
+
res.status(500).json({
|
|
47
|
+
success: false,
|
|
48
|
+
error: error.message,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
export { router as agentRouter };
|
|
54
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
|
|
3
|
+
const router = Router();
|
|
4
|
+
|
|
5
|
+
// GET /health
|
|
6
|
+
router.get('/', (req, res) => {
|
|
7
|
+
res.json({
|
|
8
|
+
status: 'healthy',
|
|
9
|
+
timestamp: new Date().toISOString(),
|
|
10
|
+
uptime: process.uptime(),
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export { router as healthRouter };
|
|
15
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
import express from 'express';
|
|
3
|
+
import cors from 'cors';
|
|
4
|
+
import { createLogger } from '@agentforge/core';
|
|
5
|
+
import { agentRouter } from './routes/agent.js';
|
|
6
|
+
import { healthRouter } from './routes/health.js';
|
|
7
|
+
|
|
8
|
+
const logger = createLogger({ level: 'info' });
|
|
9
|
+
const app = express();
|
|
10
|
+
const port = process.env.PORT || 3000;
|
|
11
|
+
|
|
12
|
+
// Middleware
|
|
13
|
+
app.use(cors());
|
|
14
|
+
app.use(express.json());
|
|
15
|
+
|
|
16
|
+
// Request logging
|
|
17
|
+
app.use((req, res, next) => {
|
|
18
|
+
logger.info(`${req.method} ${req.path}`);
|
|
19
|
+
next();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// Routes
|
|
23
|
+
app.use('/health', healthRouter);
|
|
24
|
+
app.use('/api/agent', agentRouter);
|
|
25
|
+
|
|
26
|
+
// Error handling
|
|
27
|
+
app.use((err: Error, req: express.Request, res: express.Response, next: express.NextFunction) => {
|
|
28
|
+
logger.error('Error:', err);
|
|
29
|
+
res.status(500).json({
|
|
30
|
+
error: 'Internal server error',
|
|
31
|
+
message: err.message,
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// Start server
|
|
36
|
+
app.listen(port, () => {
|
|
37
|
+
logger.info(`🚀 Server running on http://localhost:${port}`);
|
|
38
|
+
logger.info(`📊 Health check: http://localhost:${port}/health`);
|
|
39
|
+
logger.info(`🤖 Agent API: http://localhost:${port}/api/agent`);
|
|
40
|
+
});
|
|
41
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# OpenAI Configuration
|
|
2
|
+
OPENAI_API_KEY=your-api-key-here
|
|
3
|
+
OPENAI_MODEL=gpt-4
|
|
4
|
+
|
|
5
|
+
# LangSmith Configuration (optional)
|
|
6
|
+
LANGCHAIN_TRACING_V2=false
|
|
7
|
+
LANGCHAIN_API_KEY=your-langsmith-api-key
|
|
8
|
+
LANGCHAIN_PROJECT={{PROJECT_NAME}}
|
|
9
|
+
|
|
10
|
+
# Application Configuration
|
|
11
|
+
NODE_ENV=development
|
|
12
|
+
LOG_LEVEL=info
|
|
13
|
+
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# {{PROJECT_NAME}}
|
|
2
|
+
|
|
3
|
+
{{PROJECT_DESCRIPTION}}
|
|
4
|
+
|
|
5
|
+
A command-line interface powered by AgentForge agents.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- ✅ Interactive chat command
|
|
10
|
+
- ✅ File analysis command
|
|
11
|
+
- ✅ Commander.js CLI framework
|
|
12
|
+
- ✅ Colored output (chalk)
|
|
13
|
+
- ✅ Spinners and progress (ora)
|
|
14
|
+
- ✅ Interactive prompts (inquirer)
|
|
15
|
+
- ✅ ReAct agent integration
|
|
16
|
+
|
|
17
|
+
## Getting Started
|
|
18
|
+
|
|
19
|
+
### Prerequisites
|
|
20
|
+
|
|
21
|
+
- Node.js 18+
|
|
22
|
+
- pnpm (recommended) or npm
|
|
23
|
+
- OpenAI API key
|
|
24
|
+
|
|
25
|
+
### Installation
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pnpm install
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Configuration
|
|
32
|
+
|
|
33
|
+
1. Copy `.env.example` to `.env`:
|
|
34
|
+
```bash
|
|
35
|
+
cp .env.example .env
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
2. Add your OpenAI API key to `.env`:
|
|
39
|
+
```
|
|
40
|
+
OPENAI_API_KEY=your-api-key-here
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Development
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# Run in development mode
|
|
47
|
+
pnpm dev chat
|
|
48
|
+
|
|
49
|
+
# Build for production
|
|
50
|
+
pnpm build
|
|
51
|
+
|
|
52
|
+
# Run built CLI
|
|
53
|
+
pnpm start chat
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Commands
|
|
57
|
+
|
|
58
|
+
### Chat
|
|
59
|
+
Start an interactive chat session with the AI:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
{{PROJECT_NAME}} chat
|
|
63
|
+
|
|
64
|
+
# Use a different model
|
|
65
|
+
{{PROJECT_NAME}} chat --model gpt-3.5-turbo
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Analyze
|
|
69
|
+
Analyze a file using AI:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
{{PROJECT_NAME}} analyze myfile.txt
|
|
73
|
+
|
|
74
|
+
# Save results to a file
|
|
75
|
+
{{PROJECT_NAME}} analyze myfile.txt --output analysis.txt
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Project Structure
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
{{PROJECT_NAME}}/
|
|
82
|
+
├── src/
|
|
83
|
+
│ ├── cli.ts # CLI entry point
|
|
84
|
+
│ └── commands/
|
|
85
|
+
│ ├── chat.ts # Chat command
|
|
86
|
+
│ └── analyze.ts # Analyze command
|
|
87
|
+
├── .env.example # Environment variables template
|
|
88
|
+
├── package.json
|
|
89
|
+
├── tsconfig.json
|
|
90
|
+
└── README.md
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Adding Commands
|
|
94
|
+
|
|
95
|
+
Create a new command file in `src/commands/`:
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
import chalk from 'chalk';
|
|
99
|
+
import ora from 'ora';
|
|
100
|
+
|
|
101
|
+
interface MyCommandOptions {
|
|
102
|
+
option?: string;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export async function myCommand(options: MyCommandOptions) {
|
|
106
|
+
console.log(chalk.cyan('Running my command...'));
|
|
107
|
+
|
|
108
|
+
const spinner = ora('Processing...').start();
|
|
109
|
+
|
|
110
|
+
try {
|
|
111
|
+
// Command logic here
|
|
112
|
+
spinner.succeed('Done!');
|
|
113
|
+
} catch (error: any) {
|
|
114
|
+
spinner.fail('Failed');
|
|
115
|
+
console.error(chalk.red('Error:'), error.message);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Then register it in `src/cli.ts`:
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
import { myCommand } from './commands/my-command.js';
|
|
124
|
+
|
|
125
|
+
program
|
|
126
|
+
.command('my-command')
|
|
127
|
+
.description('Description of my command')
|
|
128
|
+
.option('-o, --option <value>', 'Option description')
|
|
129
|
+
.action(myCommand);
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Building for Distribution
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
# Build
|
|
136
|
+
pnpm build
|
|
137
|
+
|
|
138
|
+
# Link globally for testing
|
|
139
|
+
npm link
|
|
140
|
+
|
|
141
|
+
# Now you can run from anywhere
|
|
142
|
+
{{PROJECT_NAME}} chat
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Publishing
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
# Update version in package.json
|
|
149
|
+
npm version patch
|
|
150
|
+
|
|
151
|
+
# Publish to npm
|
|
152
|
+
npm publish
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Learn More
|
|
156
|
+
|
|
157
|
+
- [AgentForge Documentation](../../docs/)
|
|
158
|
+
- [Commander.js Documentation](https://github.com/tj/commander.js)
|
|
159
|
+
- [CLI Best Practices](../../docs/guides/cli-best-practices.md)
|
|
160
|
+
|
|
161
|
+
## License
|
|
162
|
+
|
|
163
|
+
MIT
|
|
164
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{PROJECT_NAME}}",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "{{PROJECT_DESCRIPTION}}",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"{{PROJECT_NAME}}": "./dist/cli.js"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"dev": "tsx watch src/cli.ts",
|
|
13
|
+
"build": "tsup",
|
|
14
|
+
"start": "node dist/cli.js",
|
|
15
|
+
"test": "vitest",
|
|
16
|
+
"test:watch": "vitest --watch",
|
|
17
|
+
"typecheck": "tsc --noEmit",
|
|
18
|
+
"lint": "eslint .",
|
|
19
|
+
"lint:fix": "eslint . --fix",
|
|
20
|
+
"format": "prettier --write ."
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@agentforge/core": "workspace:*",
|
|
24
|
+
"@agentforge/patterns": "workspace:*",
|
|
25
|
+
"@langchain/openai": "^0.3.14",
|
|
26
|
+
"langchain": "^0.3.7",
|
|
27
|
+
"zod": "^3.24.1",
|
|
28
|
+
"dotenv": "^16.4.7",
|
|
29
|
+
"commander": "^12.1.0",
|
|
30
|
+
"chalk": "^5.3.0",
|
|
31
|
+
"ora": "^8.1.1",
|
|
32
|
+
"inquirer": "^12.3.0"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/node": "^22.10.2",
|
|
36
|
+
"eslint": "^9.17.0",
|
|
37
|
+
"prettier": "^3.4.2",
|
|
38
|
+
"tsup": "^8.3.5",
|
|
39
|
+
"tsx": "^4.21.0",
|
|
40
|
+
"typescript": "^5.7.2",
|
|
41
|
+
"vitest": "^2.1.8"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import 'dotenv/config';
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { chatCommand } from './commands/chat.js';
|
|
6
|
+
import { analyzeCommand } from './commands/analyze.js';
|
|
7
|
+
|
|
8
|
+
const program = new Command();
|
|
9
|
+
|
|
10
|
+
program
|
|
11
|
+
.name('{{PROJECT_NAME}}')
|
|
12
|
+
.description('{{PROJECT_DESCRIPTION}}')
|
|
13
|
+
.version('0.1.0');
|
|
14
|
+
|
|
15
|
+
// Chat command
|
|
16
|
+
program
|
|
17
|
+
.command('chat')
|
|
18
|
+
.description('Start an interactive chat session')
|
|
19
|
+
.option('-m, --model <model>', 'LLM model to use', 'gpt-4')
|
|
20
|
+
.action(chatCommand);
|
|
21
|
+
|
|
22
|
+
// Analyze command
|
|
23
|
+
program
|
|
24
|
+
.command('analyze <file>')
|
|
25
|
+
.description('Analyze a file using AI')
|
|
26
|
+
.option('-o, --output <file>', 'Output file for results')
|
|
27
|
+
.action(analyzeCommand);
|
|
28
|
+
|
|
29
|
+
// Parse arguments
|
|
30
|
+
program.parse();
|
|
31
|
+
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
import { ChatOpenAI } from '@langchain/openai';
|
|
5
|
+
import { createReActAgent } from '@agentforge/patterns';
|
|
6
|
+
|
|
7
|
+
interface AnalyzeOptions {
|
|
8
|
+
output?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export async function analyzeCommand(file: string, options: AnalyzeOptions) {
|
|
12
|
+
console.log(chalk.bold.cyan('\n📊 File Analysis\n'));
|
|
13
|
+
|
|
14
|
+
const spinner = ora('Reading file...').start();
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
// Read the file
|
|
18
|
+
const content = await fs.readFile(file, 'utf-8');
|
|
19
|
+
spinner.text = 'Analyzing with AI...';
|
|
20
|
+
|
|
21
|
+
// Create agent
|
|
22
|
+
const model = new ChatOpenAI({
|
|
23
|
+
modelName: 'gpt-4',
|
|
24
|
+
temperature: 0,
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const agent = createReActAgent({
|
|
28
|
+
model,
|
|
29
|
+
tools: [],
|
|
30
|
+
systemPrompt: 'You are a code analysis expert. Analyze the provided file and give insights.',
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const compiledAgent = agent.compile();
|
|
34
|
+
|
|
35
|
+
// Analyze
|
|
36
|
+
const result = await compiledAgent.invoke({
|
|
37
|
+
messages: [
|
|
38
|
+
{
|
|
39
|
+
role: 'user',
|
|
40
|
+
content: `Analyze this file:\n\n${content}`,
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const analysis = result.messages[result.messages.length - 1].content;
|
|
46
|
+
|
|
47
|
+
spinner.succeed('Analysis complete');
|
|
48
|
+
|
|
49
|
+
console.log(chalk.bold('\nAnalysis Results:\n'));
|
|
50
|
+
console.log(analysis);
|
|
51
|
+
|
|
52
|
+
// Save to file if output specified
|
|
53
|
+
if (options.output) {
|
|
54
|
+
await fs.writeFile(options.output, analysis);
|
|
55
|
+
console.log(chalk.green(`\n✅ Results saved to ${options.output}`));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
console.log();
|
|
59
|
+
} catch (error: any) {
|
|
60
|
+
spinner.fail('Analysis failed');
|
|
61
|
+
console.error(chalk.red('Error:'), error.message);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import inquirer from 'inquirer';
|
|
4
|
+
import { ChatOpenAI } from '@langchain/openai';
|
|
5
|
+
import { createReActAgent } from '@agentforge/patterns';
|
|
6
|
+
|
|
7
|
+
interface ChatOptions {
|
|
8
|
+
model?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export async function chatCommand(options: ChatOptions) {
|
|
12
|
+
console.log(chalk.bold.cyan('\n🤖 AI Chat Session\n'));
|
|
13
|
+
console.log(chalk.gray('Type "exit" or "quit" to end the session\n'));
|
|
14
|
+
|
|
15
|
+
const model = new ChatOpenAI({
|
|
16
|
+
modelName: options.model || 'gpt-4',
|
|
17
|
+
temperature: 0.7,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const agent = createReActAgent({
|
|
21
|
+
model,
|
|
22
|
+
tools: [],
|
|
23
|
+
systemPrompt: 'You are a helpful AI assistant in a CLI chat session.',
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const compiledAgent = agent.compile();
|
|
27
|
+
const messages: any[] = [];
|
|
28
|
+
|
|
29
|
+
while (true) {
|
|
30
|
+
const { message } = await inquirer.prompt([
|
|
31
|
+
{
|
|
32
|
+
type: 'input',
|
|
33
|
+
name: 'message',
|
|
34
|
+
message: chalk.green('You:'),
|
|
35
|
+
},
|
|
36
|
+
]);
|
|
37
|
+
|
|
38
|
+
if (message.toLowerCase() === 'exit' || message.toLowerCase() === 'quit') {
|
|
39
|
+
console.log(chalk.yellow('\n👋 Goodbye!\n'));
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (!message.trim()) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const spinner = ora('Thinking...').start();
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
messages.push({ role: 'user', content: message });
|
|
51
|
+
|
|
52
|
+
const result = await compiledAgent.invoke({ messages });
|
|
53
|
+
const response = result.messages[result.messages.length - 1].content;
|
|
54
|
+
|
|
55
|
+
messages.push({ role: 'assistant', content: response });
|
|
56
|
+
|
|
57
|
+
spinner.stop();
|
|
58
|
+
console.log(chalk.blue('AI:'), response, '\n');
|
|
59
|
+
} catch (error: any) {
|
|
60
|
+
spinner.fail('Error');
|
|
61
|
+
console.error(chalk.red('Error:'), error.message, '\n');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# OpenAI Configuration
|
|
2
|
+
OPENAI_API_KEY=your-api-key-here
|
|
3
|
+
OPENAI_MODEL=gpt-4
|
|
4
|
+
|
|
5
|
+
# LangSmith Configuration (optional)
|
|
6
|
+
LANGCHAIN_TRACING_V2=false
|
|
7
|
+
LANGCHAIN_API_KEY=your-langsmith-api-key
|
|
8
|
+
LANGCHAIN_PROJECT={{PROJECT_NAME}}
|
|
9
|
+
|
|
10
|
+
# Application Configuration
|
|
11
|
+
NODE_ENV=development
|
|
12
|
+
LOG_LEVEL=info
|
|
13
|
+
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# {{PROJECT_NAME}}
|
|
2
|
+
|
|
3
|
+
{{PROJECT_DESCRIPTION}}
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ✅ ReAct agent pattern with tool support
|
|
8
|
+
- ✅ Example tool implementation
|
|
9
|
+
- ✅ Logging and error handling
|
|
10
|
+
- ✅ Environment configuration
|
|
11
|
+
- ✅ Test suite with Vitest
|
|
12
|
+
- ✅ TypeScript support
|
|
13
|
+
- ✅ Hot reload development
|
|
14
|
+
|
|
15
|
+
## Getting Started
|
|
16
|
+
|
|
17
|
+
### Prerequisites
|
|
18
|
+
|
|
19
|
+
- Node.js 18+
|
|
20
|
+
- pnpm (recommended) or npm
|
|
21
|
+
- OpenAI API key
|
|
22
|
+
|
|
23
|
+
### Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pnpm install
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Configuration
|
|
30
|
+
|
|
31
|
+
1. Copy `.env.example` to `.env`:
|
|
32
|
+
```bash
|
|
33
|
+
cp .env.example .env
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
2. Add your OpenAI API key to `.env`:
|
|
37
|
+
```
|
|
38
|
+
OPENAI_API_KEY=your-api-key-here
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Development
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# Run in development mode with hot reload
|
|
45
|
+
pnpm dev
|
|
46
|
+
|
|
47
|
+
# Build for production
|
|
48
|
+
pnpm build
|
|
49
|
+
|
|
50
|
+
# Run tests
|
|
51
|
+
pnpm test
|
|
52
|
+
|
|
53
|
+
# Run tests with UI
|
|
54
|
+
pnpm test:ui
|
|
55
|
+
|
|
56
|
+
# Run tests with coverage
|
|
57
|
+
pnpm test:coverage
|
|
58
|
+
|
|
59
|
+
# Type check
|
|
60
|
+
pnpm typecheck
|
|
61
|
+
|
|
62
|
+
# Lint code
|
|
63
|
+
pnpm lint
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Project Structure
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
{{PROJECT_NAME}}/
|
|
70
|
+
├── src/
|
|
71
|
+
│ ├── index.ts # Main entry point
|
|
72
|
+
│ └── tools/
|
|
73
|
+
│ └── example.ts # Example tool
|
|
74
|
+
├── tests/
|
|
75
|
+
│ └── example.test.ts # Example tests
|
|
76
|
+
├── .env.example # Environment variables template
|
|
77
|
+
├── package.json
|
|
78
|
+
├── tsconfig.json
|
|
79
|
+
└── README.md
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Adding Tools
|
|
83
|
+
|
|
84
|
+
Create a new tool in `src/tools/`:
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
import { z } from 'zod';
|
|
88
|
+
import { createTool } from '@agentforge/core';
|
|
89
|
+
|
|
90
|
+
export const myTool = createTool()
|
|
91
|
+
.name('my_tool')
|
|
92
|
+
.description('Description of what the tool does')
|
|
93
|
+
.category('utility')
|
|
94
|
+
.schema(
|
|
95
|
+
z.object({
|
|
96
|
+
input: z.string().describe('Input parameter'),
|
|
97
|
+
})
|
|
98
|
+
)
|
|
99
|
+
.implement(async ({ input }) => {
|
|
100
|
+
// Tool implementation
|
|
101
|
+
return `Result: ${input}`;
|
|
102
|
+
})
|
|
103
|
+
.build();
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Then register it in `src/index.ts`:
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
import { myTool } from './tools/my-tool.js';
|
|
110
|
+
|
|
111
|
+
const agent = createReActAgent({
|
|
112
|
+
model,
|
|
113
|
+
tools: [exampleTool, myTool],
|
|
114
|
+
// ...
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Testing
|
|
119
|
+
|
|
120
|
+
Write tests in the `tests/` directory:
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
import { describe, it, expect } from 'vitest';
|
|
124
|
+
import { myTool } from '../src/tools/my-tool.js';
|
|
125
|
+
|
|
126
|
+
describe('My Tool', () => {
|
|
127
|
+
it('should work correctly', async () => {
|
|
128
|
+
const result = await myTool.invoke({ input: 'test' });
|
|
129
|
+
expect(result).toBeDefined();
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Deployment
|
|
135
|
+
|
|
136
|
+
See the [deployment guides](../../templates/deployment/) for deploying to:
|
|
137
|
+
- AWS (Lambda, ECS, EKS)
|
|
138
|
+
- Google Cloud (Cloud Run, GKE)
|
|
139
|
+
- Azure (Container Apps, AKS)
|
|
140
|
+
|
|
141
|
+
## Learn More
|
|
142
|
+
|
|
143
|
+
- [AgentForge Documentation](../../docs/)
|
|
144
|
+
- [Agent Patterns Guide](../../docs/guides/patterns/)
|
|
145
|
+
- [Tool Development Guide](../../docs/guides/tools/)
|
|
146
|
+
- [Middleware Guide](../../docs/guides/middleware-guide.md)
|
|
147
|
+
|
|
148
|
+
## License
|
|
149
|
+
|
|
150
|
+
MIT
|
|
151
|
+
|