Skip to main content

Building Agents

Create custom agents to handle domain-specific background work, integrations, and automation.

Agent Definition

Every agent starts with a YAML definition that declares its triggers, capabilities, and configuration:

agents/cleanup-agent.yaml
name: cleanup-agent
version: 1.0.0
description: Removes expired records and orphaned files

triggers:
  - schedule: "0 3 * * *"    # daily at 3 AM

capabilities:
  - database:read
  - database:write
  - storage:delete

config:
  retention_days: 30
  dry_run: false
  batch_size: 500

Definition Fields

FieldRequiredDescription
nameYesUnique agent identifier
versionYesSemantic version
triggersYesWhat starts the agent — events, schedules, or API calls
capabilitiesYesExplicit resource grants (database, storage, network, realtime)
configNoAgent-specific configuration values

Trigger Types

TriggerFormatDescription
eventnamespace.actionFires when a matching event is emitted (e.g. client.sync.push)
scheduleCron expressionFires on a time schedule (e.g. "*/5 * * * *")
apiHTTP endpointFires when the agent's API endpoint is called

Implementation (Go)

The Go reference implementation requires a struct that implements the agent.Runner interface:

cleanup.go
// agents/cleanup/cleanup.go
package cleanup

import (
  "context"
  "github.com/avaropoint/weblisk-server/agent"
)

type CleanupAgent struct {
  RetentionDays int
  BatchSize     int
}

func (a *CleanupAgent) Run(ctx context.Context, env agent.Env) error {
  db := env.Database()
  // Delete records older than retention period
  deleted, err := db.DeleteExpired(ctx, a.RetentionDays, a.BatchSize)
  if err != nil {
    return err
  }
  env.Log("Cleaned up %d records", deleted)
  return nil
}

Capabilities

Agents are sandboxed — they can only access explicitly granted resources:

Test agents locally with weblisk-server dev — it watches for YAML changes and restarts agents automatically.