Create user-defined TypeScript execution drivers for swamp — implement ExecutionDriver to control where and how model methods run. Use when users want custom execution environments (remote servers, cloud functions, custom containers). Triggers on "custom driver", "extension driver", "execution driver", "ExecutionDriver", "extensions/drivers", "create driver", "new driver type", "driver plugin", "remote execution", "driver implementation".
Create TypeScript execution drivers in extensions/drivers/ that swamp loads at
startup.
| Task | Command/Action |
|---|---|
| Search community | swamp extension search driver --json |
| Create driver file | Create extensions/drivers/my-driver/mod.ts |
| Verify registration | swamp model type search --json |
| Push extension | swamp extension push manifest.yaml --json |
| Dry-run push | swamp extension push manifest.yaml --dry-run |
// extensions/drivers/my-driver/mod.ts
import { z } from "npm:zod@4";
const ConfigSchema = z.object({
host: z.string(),
port: z.number().default(22),
});
export const driver = {
type: "@myorg/my-driver",
name: "My Custom Driver",
description: "Executes model methods on a remote host via SSH",
configSchema: ConfigSchema,
createDriver: (config: Record<string, unknown>) => {
const parsed = ConfigSchema.parse(config);
return {
type: "@myorg/my-driver",
execute: async (request: {
protocolVersion: number;
modelType: string;
modelId: string;
methodName: string;
globalArgs: Record<string, unknown>;
methodArgs: Record<string, unknown>;
definitionMeta: {
id: string;
name: string;
version: number;
tags: Record<string, string>;
};
bundle?: Uint8Array;
}, callbacks?: { onLog?: (line: string) => void }) => {
const start = performance.now();
const logs: string[] = [];
try {
callbacks?.onLog?.(
`Executing ${request.methodName} on ${parsed.host}:${parsed.port}`,
);
logs.push(`Connected to ${parsed.host}`);
// Your execution logic here
const output = new TextEncoder().encode(
JSON.stringify({ result: "ok" }),
);
return {
status: "success" as const,
outputs: [{
kind: "pending" as const,
specName: request.methodName,
name: request.methodName,
type: "resource" as const,
content: output,
}],
logs,
durationMs: performance.now() - start,
};
} catch (error) {
return {
status: "error" as const,
error: String(error),
outputs: [],
logs,
durationMs: performance.now() - start,
};
}
},
};
},
};
Verify it loaded: swamp model type search --json — your driver type should
appear in the output. If it doesn't, see Verify below.
Test with a model: create a definition with driver: "@myorg/my-driver" and
run a method to confirm end-to-end execution.
| Field | Required | Description |
|---|---|---|
type | Yes | Namespaced identifier (@collective/name) |
name | Yes | Human-readable display name |
description | Yes | What this driver does |
configSchema | No | Zod schema for validating driver config |
createDriver | Yes | Factory function (config) => ExecutionDriver |
The type must match the pattern @collective/name or collective/name.
Reserved collectives (swamp, si) cannot be used.
| Method | Required | Description |
|---|---|---|
type | Yes | The driver type identifier (readonly property) |
execute | Yes | Execute a model method and return results |
initialize | No | One-time setup (e.g., pull Docker image) |
shutdown | No | Cleanup (e.g., stop container, close connection) |
For full interface signatures (ExecutionRequest, ExecutionCallbacks,
ExecutionResult, DriverOutput), see references/api.md.
Set the driver field in YAML definitions, workflows, or steps:
# models/my-model.yaml