@agentforge/cli 0.5.0 → 0.5.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.
- package/README.md +51 -0
- package/dist/index.cjs +174 -86
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +172 -84
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/api/package.json +2 -2
- package/templates/cli/package.json +2 -2
- package/templates/full/package.json +2 -2
- package/templates/minimal/package.json +2 -2
- package/templates/reusable-agent/README.md +148 -0
- package/templates/reusable-agent/index.test.ts +155 -0
- package/templates/reusable-agent/index.ts +147 -0
- package/templates/reusable-agent/package.json +35 -0
- package/templates/reusable-agent/prompt-loader.ts +43 -0
- package/templates/reusable-agent/prompts/system.md +28 -0
- package/templates/reusable-agent/tsconfig.json +10 -0
- package/templates/reusable-agent/vitest.config.ts +14 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# {{AGENT_NAME_PASCAL}} Agent
|
|
2
|
+
|
|
3
|
+
{{AGENT_DESCRIPTION}}
|
|
4
|
+
|
|
5
|
+
A configurable, reusable AI agent built with AgentForge.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- ✅ **Factory Function Pattern** - Easy to instantiate with different configurations
|
|
10
|
+
- ✅ **External Prompt Templates** - Prompts stored in `.md` files for easy editing
|
|
11
|
+
- ✅ **Tool Injection** - Add custom tools via ToolRegistry or direct injection
|
|
12
|
+
- ✅ **Feature Flags** - Enable/disable capabilities as needed
|
|
13
|
+
- ✅ **Configuration Validation** - Type-safe configuration with Zod schemas
|
|
14
|
+
- ✅ **Comprehensive Tests** - Full test coverage demonstrating all features
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @agentforge/core @agentforge/patterns @agentforge/tools @langchain/openai zod
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { create{{AGENT_NAME_PASCAL}}Agent } from './{{AGENT_NAME_KEBAB}}';
|
|
26
|
+
|
|
27
|
+
// Create with default configuration
|
|
28
|
+
const agent = create{{AGENT_NAME_PASCAL}}Agent();
|
|
29
|
+
|
|
30
|
+
// Invoke the agent
|
|
31
|
+
const result = await agent.invoke({
|
|
32
|
+
input: 'Your query here',
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
console.log(result);
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Configuration
|
|
39
|
+
|
|
40
|
+
### Basic Configuration
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
const agent = create{{AGENT_NAME_PASCAL}}Agent({
|
|
44
|
+
organizationName: 'Acme Corp',
|
|
45
|
+
temperature: 0.7,
|
|
46
|
+
maxIterations: 10,
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### With Custom Tools
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import { toolBuilder, ToolCategory } from '@agentforge/core';
|
|
54
|
+
|
|
55
|
+
const customTool = toolBuilder()
|
|
56
|
+
.name('my-custom-tool')
|
|
57
|
+
.description('Does something specific')
|
|
58
|
+
.category(ToolCategory.UTILITY)
|
|
59
|
+
.schema(z.object({
|
|
60
|
+
input: z.string().describe('Input parameter'),
|
|
61
|
+
}))
|
|
62
|
+
.implement(async ({ input }) => {
|
|
63
|
+
return { result: `Processed: ${input}` };
|
|
64
|
+
})
|
|
65
|
+
.build();
|
|
66
|
+
|
|
67
|
+
const agent = create{{AGENT_NAME_PASCAL}}Agent({
|
|
68
|
+
customTools: [customTool],
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### With Tool Registry
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import { ToolRegistry, ToolCategory } from '@agentforge/core';
|
|
76
|
+
|
|
77
|
+
const registry = new ToolRegistry();
|
|
78
|
+
// ... register tools
|
|
79
|
+
|
|
80
|
+
const agent = create{{AGENT_NAME_PASCAL}}Agent({
|
|
81
|
+
toolRegistry: registry,
|
|
82
|
+
enabledCategories: [ToolCategory.UTILITY],
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Feature Flags
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
const agent = create{{AGENT_NAME_PASCAL}}Agent({
|
|
90
|
+
enableExampleFeature: true, // Enable example feature
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Configuration Reference
|
|
95
|
+
|
|
96
|
+
| Option | Type | Default | Description |
|
|
97
|
+
|--------|------|---------|-------------|
|
|
98
|
+
| `model` | `BaseLanguageModel` | `ChatOpenAI(gpt-4)` | LLM model to use |
|
|
99
|
+
| `temperature` | `number` | `0.7` | Model temperature (0-2) |
|
|
100
|
+
| `customTools` | `Tool[]` | `[]` | Custom tools to inject |
|
|
101
|
+
| `toolRegistry` | `ToolRegistry` | `undefined` | Tool registry for tool management |
|
|
102
|
+
| `enabledCategories` | `ToolCategory[]` | `undefined` | Filter tools by category |
|
|
103
|
+
| `enableExampleFeature` | `boolean` | `true` | Enable example feature |
|
|
104
|
+
| `maxIterations` | `number` | `10` | Maximum agent iterations |
|
|
105
|
+
| `systemPrompt` | `string` | (from file) | Custom system prompt |
|
|
106
|
+
| `organizationName` | `string` | `undefined` | Organization name for context |
|
|
107
|
+
| `description` | `string` | (default) | Agent description |
|
|
108
|
+
|
|
109
|
+
## Built-in Tools
|
|
110
|
+
|
|
111
|
+
### example-action
|
|
112
|
+
Perform an example action.
|
|
113
|
+
|
|
114
|
+
**Parameters:**
|
|
115
|
+
- `input` (string) - Input for the action
|
|
116
|
+
|
|
117
|
+
**Returns:**
|
|
118
|
+
- `result` (string) - Processed result
|
|
119
|
+
- `success` (boolean) - Success status
|
|
120
|
+
|
|
121
|
+
## Prompt Management
|
|
122
|
+
|
|
123
|
+
Prompts are stored in `prompts/system.md` and support variable substitution:
|
|
124
|
+
|
|
125
|
+
```markdown
|
|
126
|
+
# {{AGENT_NAME_PASCAL}} Agent
|
|
127
|
+
|
|
128
|
+
You are working for {{organizationName}}.
|
|
129
|
+
|
|
130
|
+
{{#if enableExampleFeature}}
|
|
131
|
+
You have access to example features.
|
|
132
|
+
{{/if}}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Template Syntax:**
|
|
136
|
+
- Simple variables: `{{variableName}}`
|
|
137
|
+
- Conditional blocks: `{{#if variableName}}...{{/if}}`
|
|
138
|
+
|
|
139
|
+
## Testing
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
npm test
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## License
|
|
146
|
+
|
|
147
|
+
MIT
|
|
148
|
+
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { create{{AGENT_NAME_PASCAL}}Agent, {{AGENT_NAME_PASCAL}}ConfigSchema } from './index.js';
|
|
4
|
+
import { toolBuilder, ToolCategory, ToolRegistry } from '@agentforge/core';
|
|
5
|
+
import { ChatOpenAI } from '@langchain/openai';
|
|
6
|
+
|
|
7
|
+
describe('{{AGENT_NAME_PASCAL}}Agent', () => {
|
|
8
|
+
describe('Configuration Validation', () => {
|
|
9
|
+
it('should accept valid configuration', () => {
|
|
10
|
+
const config = {
|
|
11
|
+
temperature: 0.7,
|
|
12
|
+
organizationName: 'Test Org',
|
|
13
|
+
enableExampleFeature: true,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
expect(() => {{AGENT_NAME_PASCAL}}ConfigSchema.parse(config)).not.toThrow();
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('should reject invalid temperature', () => {
|
|
20
|
+
const config = {
|
|
21
|
+
temperature: 3.0, // Invalid: > 2
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
expect(() => {{AGENT_NAME_PASCAL}}ConfigSchema.parse(config)).toThrow();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('should accept empty configuration', () => {
|
|
28
|
+
expect(() => {{AGENT_NAME_PASCAL}}ConfigSchema.parse({})).not.toThrow();
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
describe('Agent Creation', () => {
|
|
33
|
+
it('should create agent with default configuration', () => {
|
|
34
|
+
const agent = create{{AGENT_NAME_PASCAL}}Agent();
|
|
35
|
+
expect(agent).toBeDefined();
|
|
36
|
+
expect(typeof agent.invoke).toBe('function');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('should create agent with custom model', () => {
|
|
40
|
+
const customModel = new ChatOpenAI({
|
|
41
|
+
modelName: 'gpt-3.5-turbo',
|
|
42
|
+
temperature: 0.3,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const agent = create{{AGENT_NAME_PASCAL}}Agent({
|
|
46
|
+
model: customModel,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
expect(agent).toBeDefined();
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('should create agent with custom temperature', () => {
|
|
53
|
+
const agent = create{{AGENT_NAME_PASCAL}}Agent({
|
|
54
|
+
temperature: 0.2,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
expect(agent).toBeDefined();
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe('Tool Injection', () => {
|
|
62
|
+
it('should accept custom tools', () => {
|
|
63
|
+
const customTool = toolBuilder()
|
|
64
|
+
.name('custom-tool')
|
|
65
|
+
.description('A custom tool for testing')
|
|
66
|
+
.category(ToolCategory.UTILITY)
|
|
67
|
+
.schema(z.object({
|
|
68
|
+
input: z.string().describe('Test input'),
|
|
69
|
+
}))
|
|
70
|
+
.implement(async ({ input }) => ({ result: input }))
|
|
71
|
+
.build();
|
|
72
|
+
|
|
73
|
+
const agent = create{{AGENT_NAME_PASCAL}}Agent({
|
|
74
|
+
customTools: [customTool],
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
expect(agent).toBeDefined();
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('should accept tool registry', () => {
|
|
81
|
+
const registry = new ToolRegistry();
|
|
82
|
+
|
|
83
|
+
const tool = toolBuilder()
|
|
84
|
+
.name('registry-tool')
|
|
85
|
+
.description('A tool from registry')
|
|
86
|
+
.category(ToolCategory.UTILITY)
|
|
87
|
+
.schema(z.object({
|
|
88
|
+
input: z.string().describe('Test input'),
|
|
89
|
+
}))
|
|
90
|
+
.implement(async ({ input }) => ({ result: input }))
|
|
91
|
+
.build();
|
|
92
|
+
|
|
93
|
+
registry.register(tool);
|
|
94
|
+
|
|
95
|
+
const agent = create{{AGENT_NAME_PASCAL}}Agent({
|
|
96
|
+
toolRegistry: registry,
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
expect(agent).toBeDefined();
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('should filter tools by category', () => {
|
|
103
|
+
const registry = new ToolRegistry();
|
|
104
|
+
|
|
105
|
+
const utilityTool = toolBuilder()
|
|
106
|
+
.name('utility-tool')
|
|
107
|
+
.description('A utility tool')
|
|
108
|
+
.category(ToolCategory.UTILITY)
|
|
109
|
+
.schema(z.object({}))
|
|
110
|
+
.implement(async () => ({ result: 'utility' }))
|
|
111
|
+
.build();
|
|
112
|
+
|
|
113
|
+
registry.register(utilityTool);
|
|
114
|
+
|
|
115
|
+
const agent = create{{AGENT_NAME_PASCAL}}Agent({
|
|
116
|
+
toolRegistry: registry,
|
|
117
|
+
enabledCategories: [ToolCategory.UTILITY],
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
expect(agent).toBeDefined();
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
describe('Feature Flags', () => {
|
|
125
|
+
it('should enable example feature by default', () => {
|
|
126
|
+
const agent = create{{AGENT_NAME_PASCAL}}Agent();
|
|
127
|
+
expect(agent).toBeDefined();
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it('should disable example feature when configured', () => {
|
|
131
|
+
const agent = create{{AGENT_NAME_PASCAL}}Agent({
|
|
132
|
+
enableExampleFeature: false,
|
|
133
|
+
});
|
|
134
|
+
expect(agent).toBeDefined();
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
describe('System Prompt Customization', () => {
|
|
139
|
+
it('should use default system prompt', () => {
|
|
140
|
+
const agent = create{{AGENT_NAME_PASCAL}}Agent({
|
|
141
|
+
organizationName: 'Test Org',
|
|
142
|
+
});
|
|
143
|
+
expect(agent).toBeDefined();
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it('should accept custom system prompt', () => {
|
|
147
|
+
const customPrompt = 'You are a custom agent with specific instructions.';
|
|
148
|
+
const agent = create{{AGENT_NAME_PASCAL}}Agent({
|
|
149
|
+
systemPrompt: customPrompt,
|
|
150
|
+
});
|
|
151
|
+
expect(agent).toBeDefined();
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { createReActAgent } from '@agentforge/patterns';
|
|
3
|
+
import { toolBuilder, ToolCategory, ToolRegistry } from '@agentforge/core';
|
|
4
|
+
import type { BaseLanguageModel } from '@langchain/core/language_models/base';
|
|
5
|
+
import { ChatOpenAI } from '@langchain/openai';
|
|
6
|
+
import { loadPrompt } from './prompt-loader.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Configuration schema for {{AGENT_NAME_PASCAL}}Agent
|
|
10
|
+
*/
|
|
11
|
+
export const {{AGENT_NAME_PASCAL}}ConfigSchema = z.object({
|
|
12
|
+
// Model configuration
|
|
13
|
+
model: z.custom<BaseLanguageModel>().optional(),
|
|
14
|
+
temperature: z.number().min(0).max(2).optional(),
|
|
15
|
+
|
|
16
|
+
// Tool configuration
|
|
17
|
+
customTools: z.array(z.any()).optional(),
|
|
18
|
+
toolRegistry: z.custom<ToolRegistry>().optional(),
|
|
19
|
+
enabledCategories: z.array(z.nativeEnum(ToolCategory)).optional(),
|
|
20
|
+
|
|
21
|
+
// Feature flags
|
|
22
|
+
enableExampleFeature: z.boolean().optional(),
|
|
23
|
+
|
|
24
|
+
// Behavior configuration
|
|
25
|
+
maxIterations: z.number().min(1).max(50).optional(),
|
|
26
|
+
systemPrompt: z.string().optional(),
|
|
27
|
+
|
|
28
|
+
// Domain-specific configuration
|
|
29
|
+
organizationName: z.string().optional(),
|
|
30
|
+
description: z.string().optional(),
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
export type {{AGENT_NAME_PASCAL}}Config = z.infer<typeof {{AGENT_NAME_PASCAL}}ConfigSchema>;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Default configuration for {{AGENT_NAME_PASCAL}}Agent
|
|
37
|
+
*/
|
|
38
|
+
const DEFAULT_CONFIG: Partial<{{AGENT_NAME_PASCAL}}Config> = {
|
|
39
|
+
temperature: 0.7,
|
|
40
|
+
maxIterations: 10,
|
|
41
|
+
enableExampleFeature: true,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Build tools for the {{AGENT_NAME_CAMEL}} agent
|
|
46
|
+
*/
|
|
47
|
+
function buildTools(config: {{AGENT_NAME_PASCAL}}Config) {
|
|
48
|
+
const tools = [];
|
|
49
|
+
|
|
50
|
+
// Example built-in tool
|
|
51
|
+
if (config.enableExampleFeature) {
|
|
52
|
+
const exampleTool = toolBuilder()
|
|
53
|
+
.name('example-action')
|
|
54
|
+
.description('Perform an example action')
|
|
55
|
+
.category(ToolCategory.UTILITY)
|
|
56
|
+
.schema(z.object({
|
|
57
|
+
input: z.string().describe('Input for the action'),
|
|
58
|
+
}))
|
|
59
|
+
.implement(async ({ input }) => {
|
|
60
|
+
return {
|
|
61
|
+
result: `Processed: ${input}`,
|
|
62
|
+
success: true,
|
|
63
|
+
};
|
|
64
|
+
})
|
|
65
|
+
.build();
|
|
66
|
+
|
|
67
|
+
tools.push(exampleTool);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Add custom tools from registry
|
|
71
|
+
if (config.toolRegistry) {
|
|
72
|
+
const registryTools = config.enabledCategories
|
|
73
|
+
? config.toolRegistry.getByCategory(config.enabledCategories)
|
|
74
|
+
: config.toolRegistry.getAll();
|
|
75
|
+
tools.push(...registryTools);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Add custom tools
|
|
79
|
+
if (config.customTools) {
|
|
80
|
+
tools.push(...config.customTools);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return tools;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Build system prompt for the {{AGENT_NAME_CAMEL}} agent
|
|
88
|
+
*/
|
|
89
|
+
function buildSystemPrompt(config: {{AGENT_NAME_PASCAL}}Config): string {
|
|
90
|
+
if (config.systemPrompt) {
|
|
91
|
+
return config.systemPrompt;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Load prompt from external file with variable substitution
|
|
95
|
+
return loadPrompt('system', {
|
|
96
|
+
organizationName: config.organizationName || 'your organization',
|
|
97
|
+
description: config.description || '{{AGENT_DESCRIPTION}}',
|
|
98
|
+
enableExampleFeature: config.enableExampleFeature,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Create a {{AGENT_NAME_CAMEL}} agent
|
|
104
|
+
*
|
|
105
|
+
* @param config - Configuration options for the agent
|
|
106
|
+
* @returns A configured ReAct agent
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```typescript
|
|
110
|
+
* const agent = create{{AGENT_NAME_PASCAL}}Agent({
|
|
111
|
+
* organizationName: 'Acme Corp',
|
|
112
|
+
* enableExampleFeature: true,
|
|
113
|
+
* });
|
|
114
|
+
*
|
|
115
|
+
* const result = await agent.invoke({
|
|
116
|
+
* input: 'Your query here',
|
|
117
|
+
* });
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
export function create{{AGENT_NAME_PASCAL}}Agent(config: {{AGENT_NAME_PASCAL}}Config = {}) {
|
|
121
|
+
// Validate and merge with defaults
|
|
122
|
+
const validatedConfig = {{AGENT_NAME_PASCAL}}ConfigSchema.parse({
|
|
123
|
+
...DEFAULT_CONFIG,
|
|
124
|
+
...config,
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// Create model
|
|
128
|
+
const model = validatedConfig.model || new ChatOpenAI({
|
|
129
|
+
modelName: 'gpt-4',
|
|
130
|
+
temperature: validatedConfig.temperature,
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// Build tools
|
|
134
|
+
const tools = buildTools(validatedConfig);
|
|
135
|
+
|
|
136
|
+
// Build system prompt
|
|
137
|
+
const systemPrompt = buildSystemPrompt(validatedConfig);
|
|
138
|
+
|
|
139
|
+
// Create agent
|
|
140
|
+
return createReActAgent({
|
|
141
|
+
model,
|
|
142
|
+
tools,
|
|
143
|
+
systemPrompt,
|
|
144
|
+
maxIterations: validatedConfig.maxIterations,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{PACKAGE_NAME}}",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "{{AGENT_DESCRIPTION}}",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "tsc",
|
|
10
|
+
"test": "vitest run",
|
|
11
|
+
"test:watch": "vitest",
|
|
12
|
+
"typecheck": "tsc --noEmit"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"agentforge",
|
|
16
|
+
"ai-agent",
|
|
17
|
+
"llm",
|
|
18
|
+
"reusable-agent"
|
|
19
|
+
],
|
|
20
|
+
"author": "{{AUTHOR}}",
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@agentforge/core": "workspace:*",
|
|
24
|
+
"@agentforge/patterns": "workspace:*",
|
|
25
|
+
"@langchain/core": "^1.1.8",
|
|
26
|
+
"@langchain/openai": "^0.3.14",
|
|
27
|
+
"zod": "^3.24.1"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/node": "^22.10.5",
|
|
31
|
+
"typescript": "^5.7.3",
|
|
32
|
+
"vitest": "^3.0.5"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { readFileSync } from 'fs';
|
|
2
|
+
import { join, dirname } from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = dirname(__filename);
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Simple template variable substitution
|
|
10
|
+
* Supports: {{variable}} and {{#if variable}}...{{/if}}
|
|
11
|
+
*/
|
|
12
|
+
export function renderTemplate(template: string, variables: Record<string, any>): string {
|
|
13
|
+
let result = template;
|
|
14
|
+
|
|
15
|
+
// Replace simple variables: {{variableName}}
|
|
16
|
+
result = result.replace(/\{\{(\w+)\}\}/g, (match, varName) => {
|
|
17
|
+
return variables[varName] !== undefined ? String(variables[varName]) : match;
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// Handle conditional blocks: {{#if variableName}}...{{/if}}
|
|
21
|
+
result = result.replace(/\{\{#if (\w+)\}\}([\s\S]*?)\{\{\/if\}\}/g, (match, varName, content) => {
|
|
22
|
+
return variables[varName] ? content : '';
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
return result;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Load a prompt template from the prompts directory
|
|
30
|
+
*/
|
|
31
|
+
export function loadPromptTemplate(name: string): string {
|
|
32
|
+
const promptPath = join(__dirname, '..', 'prompts', `${name}.md`);
|
|
33
|
+
return readFileSync(promptPath, 'utf-8');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Load and render a prompt with variables
|
|
38
|
+
*/
|
|
39
|
+
export function loadPrompt(name: string, variables: Record<string, any> = {}): string {
|
|
40
|
+
const template = loadPromptTemplate(name);
|
|
41
|
+
return renderTemplate(template, variables);
|
|
42
|
+
}
|
|
43
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# {{AGENT_NAME_PASCAL}} Agent
|
|
2
|
+
|
|
3
|
+
You are a professional AI agent{{#if organizationName}} working for {{organizationName}}{{/if}}.
|
|
4
|
+
|
|
5
|
+
## Your Role
|
|
6
|
+
|
|
7
|
+
{{description}}
|
|
8
|
+
|
|
9
|
+
## Guidelines
|
|
10
|
+
|
|
11
|
+
- Be helpful, accurate, and professional
|
|
12
|
+
- Use the available tools to accomplish tasks
|
|
13
|
+
- Ask clarifying questions when needed
|
|
14
|
+
- Provide clear explanations of your actions
|
|
15
|
+
|
|
16
|
+
{{#if enableExampleFeature}}
|
|
17
|
+
## Example Feature
|
|
18
|
+
|
|
19
|
+
You have access to example actions that can help you accomplish tasks more effectively.
|
|
20
|
+
|
|
21
|
+
{{/if}}
|
|
22
|
+
|
|
23
|
+
## Important Notes
|
|
24
|
+
|
|
25
|
+
- Always verify information before providing it
|
|
26
|
+
- If you're unsure about something, say so
|
|
27
|
+
- Use tools appropriately and explain your reasoning
|
|
28
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { defineConfig } from 'vitest/config';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
test: {
|
|
5
|
+
globals: true,
|
|
6
|
+
environment: 'node',
|
|
7
|
+
coverage: {
|
|
8
|
+
provider: 'v8',
|
|
9
|
+
reporter: ['text', 'json', 'html'],
|
|
10
|
+
exclude: ['dist/**', '**/*.test.ts', '**/*.config.ts'],
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
|