AI & Agents

Agent Presets

Two distinct things called "preset" — compile-time preset templates surfaced as connector actions, and tenant-owned versioned agent presets referenced by chat sessions and workflow steps.

"Agent preset" means two different things in Ductor, and conflating them causes confusion. This page keeps them apart.

Two different presets

Preset templates are compile-time, built-in agents surfaced as one-click connector actions in the workflow editor. Tenant agent presets are runtime, tenant-owned, versioned agent configurations managed through an API. The first ships with the binary; the second is data your tenants create.

1. Preset templates (connector actions)

A preset template is a compile-time agent baked into the binary and registered as a connector action under the agent provider (displayed as "AI Agents") so it appears one-click in the workflow editor palette alongside every other action. The provider is registered AuthNone and read-only — preset agents consume no per-tenant credentials; the inference proxy handles upstream LLM authentication.

Each template is a thin authoring wrapper: a model, a baked-in system prompt, and sensible generation defaults. The built-ins:

SlugModelProviderDoes
support_triagegpt-4o-miniopenaiClassifies and routes inbound support cases by severity and topic.
deal_summarizergpt-4oopenaiSummarizes deal context, owners, history, and risk into a brief.
reply_drafterclaude-3-5-sonnetanthropicDrafts an empathetic customer reply for human review.

The action key is the provider key plus the slug — e.g. agent.support_triage.

Overriding a template per step

A step author supplies the input and can override the baked defaults:

ArgRequiredEffect
user_promptyesThe input passed to the agent. CEL expressions over prior step output are allowed.
instructionsnoExtra system-prompt text, appended to the preset's baked instructions.
modelnoOverride the default model.
temperaturenoOverride sampling temperature (0.0–2.0).
max_tokensnoCap completion tokens.

The action output is a structured object:

ai agent preset output
{
  "preset": "support_triage",
  "model": "gpt-4o-mini",
  "provider": "openai",
  "content": "…the model's answer…",
  "latency_ms": 812,
  "usage": { "prompt_tokens": 0, "completion_tokens": 0, "total_tokens": 0 }
}

Because a preset template is just a connector action, it runs anywhere a connector action runs — most commonly as a step in a workflow run. See workflow AI steps for how it slots into a DAG.

2. Tenant agent presets (versioned config)

A tenant agent preset is a reusable, tenant-owned agent configuration stored per tenant and versioned. It captures the full agent runtime configuration — model, provider, instructions, the tool set, per-tool approval requirements, output type, and generation parameters (max tokens, temperature, top-p, and the loop bounds max_tool_calls / max_requests) — so that a session or a workflow step can reference a preset by id instead of inlining all of that. A chat session records the preset it runs against via agent_preset_id; an ai_agent workflow step resolves a preset (optionally pinned to a version) at execution.

Every save mints a new version, so a PresetRef can pin an exact version — or use version 0 to mean "resolve the latest."

When the deployment defines a governed typed-decision policy, chat and workflow hosts apply it only while constructing a new immutable definition. It fills absent model-routing and completion policy; an already persisted definition wins, and active sessions never change when operator config changes.

The presets are managed through the AgentPresetService:

OperationPurpose
CreateAgentPreset / UpdateAgentPresetAuthor a preset; each write creates a new version.
GetAgentPreset / ListAgentPresetsRead presets (latest version).
DeleteAgentPresetSoft-delete a preset.
ListAgentPresetVersions / GetAgentPresetVersionWalk the version history and fetch a specific version.

A tenant preset requires a name and a model. Its tool set may be empty for a model-only worker that produces text or structured output without calling tools. Every declared tool still requires a name and action, and names must be unique within the preset.

Tool and request bounds

Preset bounds are resolved after the workflow host merges the selected preset with step arguments and normalizes the effective definition:

BoundStored preset value 0Explicit workflow argument
max_tool_callsDefaults to 0 when the effective definition has no callable tools, otherwise 50.0 forbids tool calls; a positive value sets the ceiling.
max_requestsDefaults to 25 model requests.Must be positive; an omitted argument inherits the preset's positive bound before applying the default.

Skills and declared specialists add callable broker tools, so an empty inline tool array alone does not establish a model-only definition. A workflow's explicit max_tool_calls: 0 survives preset resolution and JSON round trips. Negative bounds and an explicit max_requests: 0 are refused.

Model-only execution still persists a governed session, an empty tool manifest, policy evidence, and journaled model turns. An unsolicited tool proposal cannot execute. The worker registers against the same immutable preset version and definition hash as a worker with tools; final acceptance and receipt issuance use the same clearing contract.