Create user-defined TypeScript execution drivers for swamp — implement the ExecutionDriver interface to control where and how model methods run. Use ONLY when the user wants to author, build, or implement a new driver in extensions/drivers/. Do NOT use for running workflows on remote infrastructure (that is swamp-workflow), running existing models (that is swamp-model), or debugging driver issues (that is swamp-troubleshooting). Triggers on "custom driver", "extension driver", "execution driver", "ExecutionDriver", "extensions/drivers", "create driver", "new driver type", "driver plugin", "driver implementation", "implement ExecutionDriver".
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