Definitions and instances
A definition describes a kind of agent. An instance is one durable agent assembled from that definition plus persisted data. Keeping them separate is what makes dynamic provisioning possible without turning configuration into code generation.
Definitions live in code
agents/release-planner/agent.ts is discovered as therelease-planner route. You do not repeat that identity insidedefineAgent. The generated route map gives clients a closed, type-safe set of definitions.
import { defineAgent } from "glove-foundry";
export default defineAgent({
description: "Turns an objective into a verified release plan",
systemPrompt: (_agent, ctx) => promptFor(ctx.message, ctx.history),
tools: (_agent, ctx) => toolsFor(ctx.agentInstance, ctx.message),
});Colocated primitives follow the same rule. A tool, app, memory adapter, subscriber, or schedule receives its runtime identity from its file during discovery. In static code, import the value itself: install(releaseNotes), not install("release-notes").
Instances live in data
An instance records what a particular agent has been given: its runtime ID, definition route, workspace, application installations, playbooks, schedules, and arbitrary context. Foundry can load that record after a restart and reconstruct the agent from the current code definition.
import { defineAgentInstance, install } from "glove-foundry";
import releasePlanner from "./agent.js";
import releaseNotes from "./apps/release-notes.app.js";
export const coordinator = defineAgentInstance(releasePlanner, {
// Instance identity is data. It may instead be assigned by your adapter.
id: "release-coordinator-01",
workspaceId: "launch-q4",
context: { role: "release-coordinator" },
installations: [install(releaseNotes, { channel: "launch" })],
playbooks: [],
});Where strings are correct
| Situation | Reference | Why |
|---|---|---|
| Definition imports another static primitive | Imported object | Renames fail at compile time and editors follow the reference. |
| Generated client selects an agent route | Generated string union | The HTTP route is serialized, but still checked against discovered files. |
| Persisted instance points to a definition | Serialized route | Data must survive processes and deployments. |
| Run points to an instance or conversation | Runtime ID | These identities are created and updated dynamically. |
Instances can change
Install or uninstall applications, replace playbooks, update instance context, add schedules, or move workspace bindings through the data adapter. The next run reconstructs from the latest persisted record and resolves every lazy definition again against the new message.
Instances can be provisioned by events
A playbook subscription can target an existing singleton, one agent per external thread, one per event, or a fixed fan-out. When an inbound transmission matches and no target instance exists, the provisioning adapter atomically creates the instance and conversation before dispatch. Duplicate delivery is claimed idempotently.