300 lines
9.1 KiB
Markdown
300 lines
9.1 KiB
Markdown
|
|
# @push.rocks/smartagent
|
||
|
|
A dual-agent agentic framework with Driver and Guardian agents for safe, policy-controlled AI task execution.
|
||
|
|
|
||
|
|
## Install
|
||
|
|
```bash
|
||
|
|
npm install @push.rocks/smartagent
|
||
|
|
# or
|
||
|
|
pnpm install @push.rocks/smartagent
|
||
|
|
```
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
SmartAgent implements a dual-agent architecture:
|
||
|
|
|
||
|
|
- **Driver Agent**: Executes tasks, reasons about goals, and proposes tool calls
|
||
|
|
- **Guardian Agent**: Evaluates tool call proposals against a policy prompt, approving or rejecting with feedback
|
||
|
|
|
||
|
|
This design ensures safe tool use through AI-based policy evaluation rather than rigid programmatic rules.
|
||
|
|
|
||
|
|
## Architecture
|
||
|
|
|
||
|
|
```
|
||
|
|
User Task + Guardian Policy Prompt
|
||
|
|
|
|
||
|
|
+---------------------------------------+
|
||
|
|
| DualAgentOrchestrator |
|
||
|
|
| |
|
||
|
|
| +--------+ +------------+ |
|
||
|
|
| | Driver |-------> | Guardian | |
|
||
|
|
| | Agent | tool | Agent | |
|
||
|
|
| | | call | | |
|
||
|
|
| | Reason |<--------| Evaluate | |
|
||
|
|
| | + Plan | approve | against | |
|
||
|
|
| +--------+ /reject | policy | |
|
||
|
|
| | +feedback+-----------+ |
|
||
|
|
| v (if approved) |
|
||
|
|
| +-----------------------------------+|
|
||
|
|
| | Standard Tools ||
|
||
|
|
| | Filesystem | HTTP | Shell | Browser|
|
||
|
|
| +-----------------------------------+|
|
||
|
|
+---------------------------------------+
|
||
|
|
```
|
||
|
|
|
||
|
|
## Quick Start
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
import { DualAgentOrchestrator } from '@push.rocks/smartagent';
|
||
|
|
|
||
|
|
// Create orchestrator with Guardian policy
|
||
|
|
const orchestrator = new DualAgentOrchestrator({
|
||
|
|
openaiToken: 'sk-...',
|
||
|
|
defaultProvider: 'openai',
|
||
|
|
guardianPolicyPrompt: `
|
||
|
|
FILE SYSTEM POLICY:
|
||
|
|
- ONLY allow reading/writing within /tmp or the current working directory
|
||
|
|
- REJECT operations on system directories or sensitive files
|
||
|
|
|
||
|
|
SHELL POLICY:
|
||
|
|
- Allow read-only commands (ls, cat, grep, echo)
|
||
|
|
- REJECT destructive commands (rm, mv, chmod) without explicit justification
|
||
|
|
|
||
|
|
FLAG any attempt to expose secrets or credentials.
|
||
|
|
`,
|
||
|
|
});
|
||
|
|
|
||
|
|
// Register standard tools
|
||
|
|
orchestrator.registerStandardTools();
|
||
|
|
|
||
|
|
// Start the orchestrator (initializes all tools)
|
||
|
|
await orchestrator.start();
|
||
|
|
|
||
|
|
// Run a task
|
||
|
|
const result = await orchestrator.run('List all TypeScript files in the current directory');
|
||
|
|
|
||
|
|
console.log('Success:', result.success);
|
||
|
|
console.log('Result:', result.result);
|
||
|
|
console.log('Iterations:', result.iterations);
|
||
|
|
|
||
|
|
// Cleanup
|
||
|
|
await orchestrator.stop();
|
||
|
|
```
|
||
|
|
|
||
|
|
## Standard Tools
|
||
|
|
|
||
|
|
### FilesystemTool
|
||
|
|
File and directory operations using `@push.rocks/smartfs`.
|
||
|
|
|
||
|
|
**Actions**: `read`, `write`, `append`, `list`, `delete`, `exists`, `stat`, `copy`, `move`, `mkdir`
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
// Example tool call by Driver
|
||
|
|
<tool_call>
|
||
|
|
<tool>filesystem</tool>
|
||
|
|
<action>read</action>
|
||
|
|
<params>{"path": "/tmp/config.json"}</params>
|
||
|
|
<reasoning>Need to read the configuration file to understand the settings</reasoning>
|
||
|
|
</tool_call>
|
||
|
|
```
|
||
|
|
|
||
|
|
### HttpTool
|
||
|
|
HTTP requests using `@push.rocks/smartrequest`.
|
||
|
|
|
||
|
|
**Actions**: `get`, `post`, `put`, `patch`, `delete`
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
<tool_call>
|
||
|
|
<tool>http</tool>
|
||
|
|
<action>get</action>
|
||
|
|
<params>{"url": "https://api.example.com/data"}</params>
|
||
|
|
<reasoning>Fetching data from the API endpoint</reasoning>
|
||
|
|
</tool_call>
|
||
|
|
```
|
||
|
|
|
||
|
|
### ShellTool
|
||
|
|
Secure shell command execution using `@push.rocks/smartshell` with `execSpawn` (no shell injection).
|
||
|
|
|
||
|
|
**Actions**: `execute`, `which`
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
<tool_call>
|
||
|
|
<tool>shell</tool>
|
||
|
|
<action>execute</action>
|
||
|
|
<params>{"command": "ls", "args": ["-la", "/tmp"]}</params>
|
||
|
|
<reasoning>Listing directory contents to find relevant files</reasoning>
|
||
|
|
</tool_call>
|
||
|
|
```
|
||
|
|
|
||
|
|
### BrowserTool
|
||
|
|
Web page interaction using `@push.rocks/smartbrowser` (Puppeteer-based).
|
||
|
|
|
||
|
|
**Actions**: `screenshot`, `pdf`, `evaluate`, `getPageContent`
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
<tool_call>
|
||
|
|
<tool>browser</tool>
|
||
|
|
<action>getPageContent</action>
|
||
|
|
<params>{"url": "https://example.com"}</params>
|
||
|
|
<reasoning>Extracting text content from the webpage</reasoning>
|
||
|
|
</tool_call>
|
||
|
|
```
|
||
|
|
|
||
|
|
## Guardian Policy Examples
|
||
|
|
|
||
|
|
### Strict Security Policy
|
||
|
|
```typescript
|
||
|
|
const securityPolicy = `
|
||
|
|
SECURITY POLICY:
|
||
|
|
1. REJECT any file operations outside /home/user/workspace
|
||
|
|
2. REJECT any shell commands that could modify system state
|
||
|
|
3. REJECT any HTTP requests to internal/private IP ranges
|
||
|
|
4. REJECT any attempts to read environment variables or credentials
|
||
|
|
5. FLAG and REJECT obfuscated code execution
|
||
|
|
|
||
|
|
When rejecting, always explain:
|
||
|
|
- What policy was violated
|
||
|
|
- What would be a safer alternative
|
||
|
|
`;
|
||
|
|
```
|
||
|
|
|
||
|
|
### Development Environment Policy
|
||
|
|
```typescript
|
||
|
|
const devPolicy = `
|
||
|
|
DEVELOPMENT POLICY:
|
||
|
|
- Allow file operations only within the project directory
|
||
|
|
- Allow npm/pnpm commands for package management
|
||
|
|
- Allow git commands for version control
|
||
|
|
- Allow HTTP requests to public APIs only
|
||
|
|
- REJECT direct database modifications
|
||
|
|
- REJECT commands that could affect other users
|
||
|
|
|
||
|
|
Always verify:
|
||
|
|
- File paths are relative or within project bounds
|
||
|
|
- Commands don't have dangerous flags (--force, -rf)
|
||
|
|
`;
|
||
|
|
```
|
||
|
|
|
||
|
|
## Configuration Options
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
interface IDualAgentOptions {
|
||
|
|
// Provider tokens (from @push.rocks/smartai)
|
||
|
|
openaiToken?: string;
|
||
|
|
anthropicToken?: string;
|
||
|
|
perplexityToken?: string;
|
||
|
|
groqToken?: string;
|
||
|
|
xaiToken?: string;
|
||
|
|
|
||
|
|
// Provider selection
|
||
|
|
defaultProvider?: TProvider; // For both Driver and Guardian
|
||
|
|
guardianProvider?: TProvider; // Optional: separate provider for Guardian
|
||
|
|
|
||
|
|
// Agent configuration
|
||
|
|
driverSystemMessage?: string; // Custom system message for Driver
|
||
|
|
guardianPolicyPrompt: string; // REQUIRED: Policy for Guardian to enforce
|
||
|
|
|
||
|
|
// Limits
|
||
|
|
maxIterations?: number; // Max task iterations (default: 20)
|
||
|
|
maxConsecutiveRejections?: number; // Abort after N rejections (default: 3)
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Result Interface
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
interface IDualAgentRunResult {
|
||
|
|
success: boolean; // Whether task completed successfully
|
||
|
|
completed: boolean; // Task completion status
|
||
|
|
result: string; // Final result or response
|
||
|
|
iterations: number; // Number of iterations taken
|
||
|
|
history: IAgentMessage[]; // Full conversation history
|
||
|
|
status: TDualAgentRunStatus; // 'completed' | 'max_iterations_reached' | etc.
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Custom Tools
|
||
|
|
|
||
|
|
Create custom tools by extending `BaseToolWrapper`:
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
import { BaseToolWrapper, IToolAction, IToolExecutionResult } from '@push.rocks/smartagent';
|
||
|
|
|
||
|
|
class MyCustomTool extends BaseToolWrapper {
|
||
|
|
public name = 'custom';
|
||
|
|
public description = 'My custom tool for specific operations';
|
||
|
|
|
||
|
|
public actions: IToolAction[] = [
|
||
|
|
{
|
||
|
|
name: 'myAction',
|
||
|
|
description: 'Performs a custom action',
|
||
|
|
parameters: {
|
||
|
|
type: 'object',
|
||
|
|
properties: {
|
||
|
|
input: { type: 'string', description: 'Input for the action' },
|
||
|
|
},
|
||
|
|
required: ['input'],
|
||
|
|
},
|
||
|
|
},
|
||
|
|
];
|
||
|
|
|
||
|
|
public async initialize(): Promise<void> {
|
||
|
|
this.isInitialized = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
public async cleanup(): Promise<void> {
|
||
|
|
this.isInitialized = false;
|
||
|
|
}
|
||
|
|
|
||
|
|
public async execute(action: string, params: Record<string, unknown>): Promise<IToolExecutionResult> {
|
||
|
|
this.validateAction(action);
|
||
|
|
this.ensureInitialized();
|
||
|
|
|
||
|
|
if (action === 'myAction') {
|
||
|
|
return {
|
||
|
|
success: true,
|
||
|
|
result: { processed: params.input },
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
return { success: false, error: 'Unknown action' };
|
||
|
|
}
|
||
|
|
|
||
|
|
public getCallSummary(action: string, params: Record<string, unknown>): string {
|
||
|
|
return `Custom action "${action}" with input "${params.input}"`;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Register custom tool
|
||
|
|
orchestrator.registerTool(new MyCustomTool());
|
||
|
|
```
|
||
|
|
|
||
|
|
## Supported Providers
|
||
|
|
|
||
|
|
| Provider | Driver | Guardian |
|
||
|
|
|----------|:------:|:--------:|
|
||
|
|
| OpenAI | Yes | Yes |
|
||
|
|
| Anthropic | Yes | Yes |
|
||
|
|
| Perplexity | Yes | Yes |
|
||
|
|
| Groq | Yes | Yes |
|
||
|
|
| Ollama | Yes | Yes |
|
||
|
|
| XAI | Yes | Yes |
|
||
|
|
|
||
|
|
## License and Legal Information
|
||
|
|
|
||
|
|
This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
|
||
|
|
|
||
|
|
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
|
||
|
|
|
||
|
|
### Trademarks
|
||
|
|
|
||
|
|
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.
|
||
|
|
|
||
|
|
### Company Information
|
||
|
|
|
||
|
|
Task Venture Capital GmbH
|
||
|
|
Registered at District court Bremen HRB 35230 HB, Germany
|
||
|
|
|
||
|
|
For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.
|
||
|
|
|
||
|
|
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
|