@scom/agent
v0.1.16
Published
A powerful TypeScript-based agent runner framework for building and executing autonomous agents with built-in plugins, security features, and isolated execution environments.
Downloads
42
Readme
@scom/agent
A powerful TypeScript-based agent runner framework for building and executing autonomous agents with built-in plugins, security features, and isolated execution environments.
Overview
@scom/agent (agent) provides a secure runtime environment for executing autonomous agents with TypeScript/JavaScript. It offers isolated VM execution, built-in plugins for common tasks, HTTP server capabilities, and secure request signing with Nostr integration.
Features
- 🔒 Isolated Execution: Run agents in isolated VMs with configurable memory and time limits
- 🔌 Plugin System: Built-in plugins for cache, database, fetch, scraper, and more
- 🌐 HTTP Server: Built-in HTTP server with HTTPS support and CORS configuration
- 🔐 Secure Authentication: Nostr-based request signing and whitelist support
- 📦 Package Management: Dynamic package installation and bundling
- ⚡ TypeScript Support: Write agents in TypeScript with automatic compilation
- 🚀 Easy Deployment: Simple CLI for scaffolding new agent projects
- 🔄 Queue System: Built-in job queue for managing agent tasks
- 📊 Rate Limiting: Configurable rate limiting for agent requests
Installation
npm install @scom/agentQuick Start
CLI Commands
The @scom/agent package provides a CLI for managing agent projects:
# Initialize a new agent project
npx @scom/agent init <agent-name>
# Start an agent server
npx @scom/agent serve [options]
# Get help
npx @scom/agent --help
npx @scom/agent serve --helpInitialize a New Agent Project
Create a new agent project using the CLI:
npx @scom/agent init my-agent
cd my-agent
npm installThis will create a new agent project with the following structure:
my-agent/
├── src/
│ └── agent.ts # Your agent implementation
├── tests/
│ └── agent.test.ts # Test files
├── package.json
├── tsconfig.json
├── scconfig.json # Agent configuration
└── README.mdBasic Agent Implementation
Edit src/agent.ts to implement your agent:
import { IWorkerPlugin, ISession } from '@scom/agent';
export default class Agent implements IWorkerPlugin {
async process(session: ISession, data?: any): Promise<any> {
// Access configuration parameters
const params = session.params;
// Use built-in plugins
const fetch = session.plugins.fetch;
const response = await fetch('https://api.example.com/data');
// Process data and return results
return {
status: 'success',
data: response
};
}
}Configure Your Agent
Edit scconfig.json to configure plugins and parameters:
{
"type": "agent",
"name": "my-agent",
"module": "agent.ts",
"description": "My autonomous agent",
"params": {
"apiKey": "your-api-key",
"model": "gpt-4"
},
"plugins": {
"cache": true,
"db": false,
"fetch": true,
"wallet": false
}
}Build and Test
# Build the agent
npm run build
# Run tests
npm testStart the Agent Server
Run your agent as an HTTP service:
# Start the agent server (default port 8080)
npx @scom/agent serve
# Specify a custom port
npx @scom/agent serve --port 8080
# Specify a custom package path
npx @scom/agent serve --path ./my-agent --port 8080
# Enable CORS
npx @scom/agent serve --cors
# Disable script caching
npx @scom/agent serve --no-cache
# Get help
npx @scom/agent serve --helpOnce the server is running, you can send POST requests to http://localhost:8080/agent:
# Example request using curl
curl -X POST http://localhost:8080/agent \
-H "Content-Type: application/json" \
-d '{
"params": {
"location": "New York",
"units": "celsius"
}
}'The server will route requests to your agent's process method with the provided parameters.
Programmatic Usage
Running an Agent from a Package
import { AgentRunner } from '@scom/agent';
const runner = new AgentRunner();
// Run from a package directory
const result = await runner.runPackage({
packagePath: './my-agent',
params: {
apiKey: 'your-api-key'
},
plugins: {
fetch: true,
cache: true
}
});
console.log(result);Running an Agent from Script
import { AgentRunner } from '@scom/agent';
const runner = new AgentRunner();
// Run TypeScript code directly
const result = await runner.runScript({
ts: `
export default class Agent {
async process(session: ISession, data?: any) {
return { message: 'Hello from agent!' };
}
}
`,
params: { greeting: 'Hello' },
plugins: { fetch: true }
});
console.log(result);Bundling an Agent
import { AgentRunner } from '@scom/agent';
const runner = new AgentRunner();
// Bundle agent for distribution
const bundle = await runner.bundle({
packagePath: './my-agent',
mainFile: 'agent.ts',
outputPath: './dist/bundle.js'
});
console.log('Bundle created:', bundle.script);HTTP Server
Start an HTTP server to handle agent requests:
import { AgentRunner } from '@scom/agent';
const runner = new AgentRunner({
port: 3000,
securePort: 3443,
certPath: './certs',
cors: true,
cacheCompiledScript: true,
whitelistNpubs: ['npub1...'], // Optional Nostr public key whitelist
signerPrivateKey: 'nsec1...' // Optional private key for signing responses
});
await runner.startServer();
console.log('Agent runner server started on port 8080');The HTTP server provides endpoints for:
- Running agents from packages
- Executing scripts
- Bundling agents
- Uploading packages to IPFS
Available Plugins
Agent Runner supports plugins at both the global level and per-endpoint level. Endpoint-level configuration is recommended as it enables web frontends to query required plugin parameters and generate appropriate UI.
Plugin Configuration
Endpoint-Level (Recommended):
{
"endpoints": [
{
"name": "weather",
"path": "/weather",
"method": "POST",
"plugins": {
"fetch": {
"enabled": true,
"credentials": {
"api_key": {
"type": "api-key",
"description": "Weather API key",
"required": true
}
}
}
}
}
]
}Default Credentials (.env.json):
{
"plugins": {
"fetch": {
"credentials": {
"api_key": "your-actual-api-key-here"
}
}
}
}Create .env.json to provide default credential values (never commit this file).
Global (Legacy):
{
"plugins": {
"fetch": true,
"cache": true
}
}Fetch Plugin
Make HTTP requests with fetch API:
const response = await session.plugins.fetch('https://api.example.com');
const data = await response.json();Cache Plugin
Store and retrieve cached data:
const cache = session.plugins.cache;
await cache.set('key', { data: 'value' }, 3600); // TTL in seconds
const value = await cache.get('key');Database Plugin
Execute database queries:
const db = session.plugins.db;
const results = await db.query('SELECT * FROM users WHERE id = ?', [userId]);Scraper Plugin
Extract data from web pages:
const scraper = session.plugins.scraper;
const data = await scraper.scrape('https://example.com', {
selector: '.article-title'
});Wallet Plugin
Interact with blockchain wallets:
const wallet = session.plugins.wallet;
const balance = await wallet.getBalance();Configuration Options
Agent Runner Config
interface IAgentRunnerConfig {
cors?: boolean; // Enable CORS
certPath?: string; // Path to SSL certificates
port?: number; // HTTP port
securePort?: number; // HTTPS port
cacheCompiledScript?: boolean; // Cache compiled scripts
whitelistNpubs?: string[]; // Nostr public key whitelist
signerPrivateKey?: string; // Private key for signing
}Worker Config
interface IWorkerConfig {
plugins?: IRequiredPlugins; // Enabled plugins
memoryLimit?: number; // Memory limit in MB
script?: string; // Compiled script
timeLimit?: number; // Execution time limit in ms
params?: any; // Custom parameters
}Security
- Isolated Execution: Agents run in isolated VMs with limited access to system resources
- Memory Limits: Configurable memory limits per agent
- Time Limits: Configurable execution time limits
- Nostr Authentication: Optional whitelist-based authentication using Nostr public keys
- Request Signing: Sign responses with private keys for verification
Testing
The framework includes a testing utility for writing agent tests:
import { AgentRunner } from '@scom/agent';
describe('My Agent', function () {
let runner: AgentRunner;
beforeAll(async function () {
runner = new AgentRunner();
});
it('should process data correctly', async function () {
const result = await runner.runPackage({
packagePath: './my-agent',
params: { test: true }
});
expect(result.status).toBe('success');
});
afterAll(async function () {
// Cleanup
});
});CLI Commands
The package includes a CLI tool accessible via npx @scom/agent or the agent command if installed globally:
# Initialize a new agent project
npx @scom/agent init <agent-name>
# Examples
npx @scom/agent init my-agent
npx @scom/agent init @myorg/my-agentExamples
Check the samples/ directory for example agent implementations:
samples/demoAgent/- Basic agent example
API Reference
AgentRunner
Main class for running agents:
runPackage(config: IWorkerPackageConfig): Promise<any>- Run agent from packagerunScript(config: IWorkerScriptConfig): Promise<any>- Run agent from scriptbundle(options: IBundleOptions): Promise<IBundleResult>- Bundle agentstartServer(): Promise<void>- Start HTTP server
ISession
Session object passed to agents:
params: any- Configuration parametersplugins: IPlugins- Enabled pluginsdata?: any- Request data
IWorkerPlugin
Interface for agent implementations:
interface IWorkerPlugin {
process(session: ISession, data?: any): Promise<any>;
}Requirements
- Node.js >= 18.0.0
- TypeScript 5.8.2
License
Released under dual BSL 1.1/commercial license
Links
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Support
For issues and questions, please open an issue on the GitHub repository.
