Skip to content

Agent Configuration

The createAgent(options) function accepts an AgentOptions object. All fields are optional.

import { createAgent } from 'zupdev';
import { httpMonitor } from 'zupdev/plugins/http-monitor';
import { historianPlugin } from 'zupdev/plugins/historian';
const agent = await createAgent({
// Identity
id: 'sre-agent-prod',
name: 'Production SRE',
systemPrompt: 'You are an SRE agent monitoring production infrastructure.',
// LLM
llm: {
provider: 'anthropic',
apiKey: process.env.ANTHROPIC_API_KEY!,
model: 'claude-sonnet-4-6',
},
// Loop
mode: 'continuous',
loopInterval: 30000,
// SQLite
sqlite: {
path: './zup.db',
enableWAL: true,
enableVec: true,
},
// State persistence
statePersistence: {
enabled: true,
type: 'database',
config: {
tableName: 'agent_state',
},
},
// API
api: {
port: 3000,
host: 'localhost',
auth: {
apiKeys: [
{ key: 'sk-prod-abc123', name: 'production' },
],
allowUnauthenticated: false,
},
},
// Approvals
approvals: {
autoExpire: true,
ttlMs: 3600000,
},
// Plugins
plugins: [
httpMonitor({
endpoints: [
{ id: 'api', name: 'API', url: 'https://api.example.com/health' },
],
}),
historianPlugin({ minConfidence: 0.75 }),
],
});
FieldTypeDefaultDescription
idstringRandom UUIDUnique agent identifier.
namestring'Zup'Human-readable agent name.
systemPromptstringDefault SRE promptSystem prompt passed to the LLM.
loggerLoggerconsoleLogger instance. Must implement debug, info, warn, error.

The llm field configures the language model. It is optional — many plugins work without an LLM. Zup supports 16+ providers via the Vercel AI SDK.

// Anthropic
llm: {
provider: 'anthropic',
apiKey: string,
model: string,
baseURL?: string,
}
// OpenAI
llm: {
provider: 'openai',
apiKey: string,
model: string,
baseURL?: string,
organization?: string,
}
// Google Gemini
llm: {
provider: 'google',
apiKey: string,
model: string,
}
// Simple API-key providers (mistral, groq, xai, cohere, perplexity,
// togetherai, deepinfra, cerebras, openrouter)
llm: {
provider: 'groq', // or any of the above
apiKey: string,
model: string,
baseURL?: string,
}
// Azure OpenAI
llm: {
provider: 'azure',
apiKey: string,
model: string,
resourceName: string,
apiVersion?: string,
}
// Amazon Bedrock
llm: {
provider: 'amazon-bedrock',
model: string,
region: string,
accessKeyId: string,
secretAccessKey: string,
}
// Google Vertex AI
llm: {
provider: 'google-vertex',
model: string,
project: string,
location: string,
}
// OpenAI-compatible (Ollama, vLLM, LiteLLM, etc.)
llm: {
provider: 'openai-compatible',
baseURL: string,
apiKey: string,
model: string,
}

See LLM Providers for detailed configuration for each provider.

FieldTypeDefaultDescription
mode'manual' | 'continuous' | 'event-driven''manual'Agent operating mode.
loopIntervalnumber60000Milliseconds between loops in continuous mode.

Modes:

  • manual — Call agent.runLoop() yourself. start() just logs readiness.
  • continuousstart() runs the loop on a timer at loopInterval intervals.
  • event-drivenstart() logs readiness. Loops are triggered by external events (e.g., incoming runs via the API).
FieldTypeDefaultDescription
sqlite.pathstring':memory:'Path to the SQLite database file.
sqlite.enableWALbooleantrueEnable Write-Ahead Logging for better concurrent read performance.
sqlite.enableVecbooleantrueLoad the sqlite-vec extension for vector search.
sqlite.vecExtensionPathstringAuto-detectedPath to the sqlite-vec shared library.
FieldTypeDefaultDescription
statePersistence.enabledbooleanfalseEnable state persistence.
statePersistence.type'memory' | 'file' | 'database''memory'Storage backend.
statePersistence.config.pathstringFile path when type is 'file'.
statePersistence.config.flushIntervalMsnumber1000Debounce interval for file flushes.
statePersistence.config.tableNamestringTable name when type is 'database'.
FieldTypeDefaultDescription
api.portnumber3000Server port.
api.hoststring'localhost'Bind address.
api.auth.apiKeysArray<{ key, name, permissions? }>[]API keys for Bearer token auth.
api.auth.allowUnauthenticatedbooleanfalseAllow requests without an API key.

The API server is started separately via agent.startApi(). You can pass overrides:

const server = agent.startApi({
port: 8080,
hostname: '0.0.0.0',
apiKeys: ['override-key'],
allowUnauthenticated: false,
});
FieldTypeDefaultDescription
approvals.autoExpirebooleantrueAutomatically expire stale pending approvals.
approvals.ttlMsnumber3600000 (1 hour)Time-to-live for pending approvals in milliseconds.
FieldTypeDefaultDescription
playbooksDirstringDirectory path to load playbook .md files from.
playbooksPlaybook[]Inline playbook definitions.

Playbooks are markdown files that get fed into the LLM during orient/decide phases. See Playbooks for details.

const agent = await createAgent({
playbooksDir: './playbooks',
plugins: [
investigationOrienter({ tools: [...] }),
],
});
plugins: ZupPlugin[]

An array of initialized plugin objects. Plugins are loaded sequentially — earlier plugins can modify context that later plugins see.

plugins: [
httpMonitor({ endpoints: [...] }),
historianPlugin({ minConfidence: 0.75 }),
myCustomPlugin(),
]