npm package: @scom/agent
Description: A powerful TypeScript-based agent runner framework for building and executing autonomous agents with built-in plugins, security features, and isolated execution environments.
Latest version: 0.1.16

# @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

```bash
npm install @scom/agent
```

## Quick Start

### CLI Commands

The `@scom/agent` package provides a CLI for managing agent projects:

```bash
# 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 --help
```

### Initialize a New Agent Project

Create a new agent project using the CLI:

```bash
npx @scom/agent init my-agent
cd my-agent
npm install
```

This 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.md
```

### Basic Agent Implementation

Edit `src/agent.ts` to implement your agent:

```typescript
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:

```json
{
    "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

```bash
# Build the agent
npm run build

# Run tests
npm test
```

### Start the Agent Server

Run your agent as an HTTP service:

```bash
# 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 --help
```

Once the server is running, you can send POST requests to `http://localhost:8080/agent`:

```bash
# 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

```typescript
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

```typescript
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

```typescript
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:

```typescript
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):**
```json
{
  "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):**
```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):**
```json
{
  "plugins": {
    "fetch": true,
    "cache": true
  }
}
```

### Fetch Plugin
Make HTTP requests with fetch API:

```typescript
const response = await session.plugins.fetch('https://api.example.com');
const data = await response.json();
```

### Cache Plugin
Store and retrieve cached data:

```typescript
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:

```typescript
const db = session.plugins.db;
const results = await db.query('SELECT * FROM users WHERE id = ?', [userId]);
```

### Scraper Plugin
Extract data from web pages:

```typescript
const scraper = session.plugins.scraper;
const data = await scraper.scrape('https://example.com', {
    selector: '.article-title'
});
```

### Wallet Plugin
Interact with blockchain wallets:

```typescript
const wallet = session.plugins.wallet;
const balance = await wallet.getBalance();
```

## Configuration Options

### Agent Runner Config

```typescript
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

```typescript
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:

```typescript
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:

```bash
# Initialize a new agent project
npx @scom/agent init <agent-name>

# Examples
npx @scom/agent init my-agent
npx @scom/agent init @myorg/my-agent
```

## Examples

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 package
- `runScript(config: IWorkerScriptConfig): Promise<any>` - Run agent from script
- `bundle(options: IBundleOptions): Promise<IBundleResult>` - Bundle agent
- `startServer(): Promise<void>` - Start HTTP server

### ISession

Session object passed to agents:

- `params: any` - Configuration parameters
- `plugins: IPlugins` - Enabled plugins
- `data?: any` - Request data

### IWorkerPlugin

Interface for agent implementations:

```typescript
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

- [GitHub Repository](https://github.com/scom-repos/agent)
- [IJS Network](https://ijs.network)

## 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](https://github.com/scom-repos/agent/issues).