Interface AgencyOptions

Configuration for the agency() factory function. Extends BaseAgentConfig with a required agents roster and optional multi-agent orchestration settings.

Example

import { agency, hitl } from '@framers/agentos';

const myAgency = agency({
provider: 'openai',
model: 'gpt-4o',
strategy: 'sequential',
agents: {
researcher: { instructions: 'Find relevant papers.' },
writer: { instructions: 'Write a clear summary.' },
},
controls: { maxTotalTokens: 50_000, onLimitReached: 'warn' },
hitl: {
approvals: { beforeTool: ['delete-file'], beforeReturn: true },
handler: hitl.autoApprove(),
timeoutMs: 30_000,
onTimeout: 'reject',
},
on: {
agentStart: (e) => console.log(`[${e.agent}] started`),
agentEnd: (e) => console.log(`[${e.agent}] done in ${e.durationMs}ms`),
},
});

See

agency -- the factory function that consumes this configuration. See BaseAgentConfig for the shared config surface inherited by this interface.

interface AgencyOptions {
    model?: string;
    provider?: string;
    instructions?: string;
    name?: string;
    apiKey?: string;
    baseUrl?: string;
    personality?: Partial<{
        honesty: number;
        emotionality: number;
        extraversion: number;
        agreeableness: number;
        conscientiousness: number;
        openness: number;
        honestyHumility: number;
        honesty_humility: number;
        opennessToExperience: number;
    }>;
    tools?: AdaptableToolInput;
    maxSteps?: number;
    maxTokens?: number;
    thinking?: false | {
        budgetTokens: number;
    };
    effort?: string;
    customModelParams?: Record<string, unknown>;
    memory?: boolean | MemoryConfig;
    rag?: RagConfig;
    discovery?: DiscoveryConfig;
    guardrails?: string[] | GuardrailsConfig;
    security?: {
        tier: SecurityTier;
    };
    permissions?: PermissionsConfig;
    hitl?: HitlConfig;
    emergent?: EmergentConfig;
    voice?: VoiceConfig;
    avatar?: AvatarConfig;
    channels?: Record<string, Record<string, unknown>>;
    output?: unknown;
    provenance?: AgencyProvenanceConfig;
    observability?: ObservabilityConfig;
    on?: AgencyCallbacks;
    controls?: ResourceControls;
    dependsOn?: string[];
    cognitiveMechanisms?: CognitiveMechanismsConfig;
    verifyCitations?: VerifyCitationsConfig;
    agents: Record<string, Agent | AgencySeatConfig>;
    modelPool?: Record<string, ModelPoolEntry>;
    seating?: SeatingConfig;
    chair?: false | AgencySeatConfig;
    panel?: PanelOptions;
    quorum?: AgencyQuorumConfig;
    strategy?: AgencyStrategy;
    adaptive?: boolean;
    maxRounds?: number;
    runtime?: "legacy" | "gmi";
}

Hierarchy

  • BaseAgentConfig
    • AgencyOptions

Properties

model?: string

Model identifier. Accepted in two formats:

  • Plain model name (e.g. "gpt-4o") when provider is also set. Preferred.
  • "provider:model" combined string (e.g. "openai:gpt-4o").
provider?: string

Provider name (e.g. "openai", "anthropic", "ollama"). Auto-detected from environment API keys when omitted.

instructions?: string

Free-form system instructions prepended to the system prompt.

name?: string

Display name for the agent, injected into the system prompt.

apiKey?: string

Override the provider API key instead of reading from environment variables.

baseUrl?: string

Override the provider base URL (useful for local proxies or Ollama). An empty or whitespace-only value is unset: a same-provider setDefaultProvider() URL, then the provider's URL variable, apply as with none. A seat of an agency with a blank value takes the agency-level baseUrl as a seat with none does.

personality?: Partial<{
    honesty: number;
    emotionality: number;
    extraversion: number;
    agreeableness: number;
    conscientiousness: number;
    openness: number;
    honestyHumility: number;
    honesty_humility: number;
    opennessToExperience: number;
}>

HEXACO-inspired personality trait overrides (0–1 scale). Encoded as a human-readable trait string appended to the system prompt. The SOUL.md spellings honestyHumility / honesty_humility and opennessToExperience are accepted for honesty and openness; when both spellings are given, the canonical key wins.

Type declaration

  • honesty: number
  • emotionality: number
  • extraversion: number
  • agreeableness: number
  • conscientiousness: number
  • openness: number
  • honestyHumility: number
  • honesty_humility: number
  • opennessToExperience: number

Tools available to the agent on every call.

Accepts:

  • a named high-level tool map
  • an ExternalToolRegistry (Record, Map, or iterable)
  • a prompt-only ToolDefinitionForLLM[]
maxSteps?: number

Maximum number of agentic steps (LLM calls) per invocation. Defaults to 5.

maxTokens?: number

Upper bound on completion tokens for each LLM call the agent makes. Forwarded to the underlying generateText / streamText call on every generate(), stream(), and session.send() invocation.

Caps tail spend when a model misbehaves and yaps past the intended output size. Omit to use the provider default — AnthropicProvider defaults to 16000 (set 2026-05-17; was 4096), OpenAIProvider defaults to 4096, GeminiProvider defaults to 8192. Set to ~2× the agent's typical response size so normal calls finish naturally and only runaway generations hit the cap.

Example

// Cap a roleplay agent at 1024 — short turns, fast feedback.
const companion = agent({
provider: 'anthropic',
model: 'claude-sonnet-4-6',
instructions: 'Reply in character. 2-3 sentences.',
maxTokens: 1024,
});

// Tool-use agent emitting verbose JSON — go big so structured
// output doesn't truncate mid-token. Opus 4.7 supports 32000.
const codegen = agent({
provider: 'anthropic',
model: 'claude-opus-4-7',
tools: { GenerateCode, RunTests, JudgeOutput },
maxTokens: 16000,
});
thinking?: false | {
    budgetTokens: number;
}

Extended-thinking switch forwarded to Claude models on every generate() / stream() / session call this agent makes. Any positive budgetTokens turns adaptive thinking on (the number itself is not sent). false turns thinking off with the model's own off shape; Opus 5.5, Fable and Mythos always think. Omitted keeps the model's default: thinking on for Opus 5 and later, Sonnet 5 and later, Fable and Mythos, off for older models. Other providers ignore it.

Type declaration

  • budgetTokens: number

Example

const codegen = agent({
provider: 'anthropic',
model: 'claude-opus-5',
tools: { GenerateCode, RunTests, JudgeOutput },
maxTokens: 24000,
thinking: { budgetTokens: 8000 },
});
effort?: string

Reasoning-effort control forwarded to every generate/stream/session call. On effort-capable Claude models (Opus 4.5+, Sonnet 4.6, Fable/Mythos 5) the provider sends output_config.effort (low|medium|high|xhigh|max). On OpenAI reasoning models (o-series, GPT-5.x) the provider sends reasoning_effort (chat) / reasoning.effort (Responses), with max clamping to xhigh — OpenAI's ceiling — and a model-aware guard capping xhigh → high on ids not probe-verified for xhigh (gpt-5.5/5.6 families are verified). Independent of thinking; ignored on unsupported models/values. Works per-agent in agency() rosters — each sub-agent may pin its own depth.

customModelParams?: Record<string, unknown>

Provider-specific TOP-LEVEL request-payload parameters forwarded verbatim on every generate/stream/session call via ModelCompletionOptions.customModelParams. Providers spread these onto the outgoing request body — the escape hatch for params the typed options don't model, e.g. OpenRouter provider-routing preferences:

customModelParams: { provider: { sort: 'throughput' } }
memory?: boolean | MemoryConfig

Memory configuration. agent() reads it only with runtime: 'gmi', where true or a MemoryConfig turns on cognitive memory for the agent's sessions (its embedding and consolidation fields are read) and false keeps it off, also under cognition: 'full'. A session's message history is set by history, not by this field.

rag?: RagConfig

Retrieval-Augmented Generation configuration.

discovery?: DiscoveryConfig

Runtime capability discovery configuration.

guardrails?: string[] | GuardrailsConfig

Guardrail policy identifiers or structured config. agency() evaluates none of them (see GuardrailsConfig), and agent() does not apply them.

  • string[] — shorthand; agency() reads it as the output list.
  • GuardrailsConfig — separate input and output lists.
security?: {
    tier: SecurityTier;
}

Security tier. Accepted and not enforced (see SecurityTier).

Type declaration

  • tier: SecurityTier
permissions?: PermissionsConfig

Tool and resource permission fields. Accepted and not enforced (see PermissionsConfig).

hitl?: HitlConfig

Human-in-the-loop approval configuration.

emergent?: EmergentConfig

Emergent agent synthesis configuration.

voice?: VoiceConfig

Voice interface configuration.

avatar?: AvatarConfig

Avatar visual presentation configuration.

channels?: Record<string, Record<string, unknown>>

Channel adapter configurations keyed by channel name. Values are channel-specific option objects passed through opaquely.

output?: unknown

Output schema for structured generation. Accepts a Zod schema at runtime; typed as unknown here to avoid a hard dependency on the zod package in the types layer.

provenance?: AgencyProvenanceConfig

Provenance and audit-trail configuration.

observability?: ObservabilityConfig

Observability and telemetry configuration.

Event callbacks fired at various lifecycle points during the run. agency() fires them for its run. A gmi() agent fires them only for the teams it launches with launch_agency (agencies.launch), each named launch:<agencyId>, and for those launches' failures; its own turns fire none, and neither does agent() without runtime: 'gmi'.

controls?: ResourceControls

Resource limits (tokens, cost, time). agency() and the full runtime enforce every field against the entire run. The lightweight agent() helper forwards two of them per call: maxTotalTokens caps each LLM call's completion output (mapped to maxTokens when no explicit maxTokens is set, NOT the prompt+completion run total) and maxDurationMs bounds each LLM request (mapped to requestTimeout). The remaining fields stay agency()-only.

dependsOn?: string[]

Names of other agents in the agency that must complete before this agent runs. Used with strategy: 'graph' to build an explicit dependency DAG. Agents with no dependsOn, or an empty one, are roots and run first. agency() throws AgencyConfigError, naming the agent, for a value that is not an array of names.

Example

`dependsOn: ['researcher']` — this agent waits for `researcher` to finish.
cognitiveMechanisms?: CognitiveMechanismsConfig

Cognitive mechanisms config: the eight memory mechanisms of CognitiveMemoryManager (reconsolidation, retrieval-induced forgetting, involuntary recall, feeling of knowing, temporal gist, schema encoding, source-confidence decay and emotion regulation). Pass {} for the defaults, or override fields per mechanism.

The mechanisms run inside a CognitiveMemoryManager initialized with this config (CognitiveMemoryConfig.cognitiveMechanisms). agent() without runtime: 'gmi' and agency() construct no memory manager, so they log a warning and leave this field unused; agent({ runtime: 'gmi' }) with memory on passes it to the agent's memory manager. On the full runtime, a gmiManagerConfig.cognitiveMemoryFactory builds the manager for each GMI.

verifyCitations?: VerifyCitationsConfig

Verify citations after generate() and default-runtime session calls.

When set, generate() produces the answer, then fetches sources for the user's input with the configured retriever and scores each atomic claim of the answer against them via CitationVerifier. The resulting VerifiedResponse is attached to the result's grounding field — no separate verifier.verify(text, sources) call needed. On the default runtime, session.send() also checks its reply and session.stream() exposes a grounding promise that runs after its text completes. Direct stream() and GMI session calls do not verify. When the retriever returns no sources, or retrieval or the verifier fails, grounding stays unset and the answer is returned as generated.

Pass a config object with the embedding function and the source retriever the verifier should use:

Example

const docsAgent = agent({
provider: 'openai',
model: 'gpt-4o',
verifyCitations: {
embedFn: async (texts) => (await embeddingManager.generateEmbeddings({ texts })).embeddings,
retrieve: (query) => retriever.search(query),
},
});

const result = await docsAgent.generate('How do I configure a guardrail?');
console.log(result.text);
console.log(result.grounding?.overallGrounded);
for (const claim of result.grounding?.claims ?? []) {
if (claim.verdict !== 'supported') console.warn(claim.text);
}
agents: Record<string, Agent | AgencySeatConfig>

Named roster of sub-agents. Each value is either a seat config (the agency builds it with agent(); see AgencySeatConfig) or a pre-built Agent instance.

modelPool?: Record<string, ModelPoolEntry>

Every model a seat may sit on, named. A config seat that names neither provider nor model is then filled from the pool per call (see SeatingConfig). Declaration order is the preference order.

seating?: SeatingConfig

How pooled seats are filled. Requires modelPool.

chair?: false | AgencySeatConfig

panel only: the agent that synthesizes the seats' outputs (from picks its model from the pool), or false for no synthesis.

panel?: PanelOptions

panel only: deadlines, a concurrency cap and the minimum text that counts as an answer.

The floor the fan-out must reach. Under parallel: successful seats and distinct provider ids, checked after the fan-out (a seat with empty text counts, minAgents defaults to 0, 'proceed' is honoured with zero survivors). Under panel: healthy seats (those that returned text), distinct providers and distinct known vendors; minAgents defaults to 2 for a roster of two or more, and zero healthy seats always throws. Ignored by the other strategies.

strategy?: AgencyStrategy

Orchestration strategy for coordinating sub-agents. Defaults to "sequential" when omitted.

adaptive?: boolean

Whether the orchestrator may override strategy at runtime based on task complexity signals.

maxRounds?: number

Maximum number of orchestration rounds before the run is terminated. Applies to iterative strategies like "debate" and "review-loop".

runtime?: "legacy" | "gmi"

The engine of every config seat that names none (a roster config, the panel's chair, a specialist the hierarchical manager spawns): 'legacy' (the default) calls the model through generateText and streamText, 'gmi' serves each of the seat's calls with a Generalized Mind Instance (docs/GMI.md, "GMIs from agent()"). A seat's own runtime wins. Pre-built seats keep the engine they were built with, and the hierarchical manager and the parallel and debate synthesizers stay on the legacy engine. Any other value throws AgencyConfigError, here and on a seat; null is unset at both levels. The agency itself takes no cognition: a strategy runs a config seat through its generate() or stream(), which run the 'light' profile; seat a persistent GMI with sessionSeat() to run its own profile.