ensureAgentPackage — System-Provided Agent Startup Pattern
System-provided agent templates (shipped as ZIP files) are managed by ensureAgentPackage from /agents. It replaces the old per-package patch function pattern (deleted in Phase 54).
How it works
Section titled “How it works”- Version-skip guard — reads the existing template by
packageName. IfpackageVersionalready matches, returns{ skipped: true }without touching the DB. - ZIP injection — reads the ZIP from
data/downloads/, parses the OAS Flow descriptor (oas.jsoncanonical,agent.jsonfor legacy ZIPs), injectspackageNameandpackageVersion, then rebuilds the ZIP. - Upsert — delegates to
importAgentTemplate(..., { redirect: false }), which callsupdateAgentTemplateif a template with thatpackageNamealready exists, orcreateAgentTemplateif not. - Identity lock — calls
setAgentTemplatePackageNameafter upsert. The setter guards withWHERE package_name IS NULL, so it is a no-op on subsequent restarts. - Diagnostic logging — logs
[ensureAgentPackage] <packageName> v<version> upsertedorskipped — already up to dateviaconsole.info.
Calls live in src/instrumentation.node.ts, which runs once at server startup:
const { ensureAgentPackage } = await import("/agents");
await ensureAgentPackage({ zipFileName: "email-outreach-template.zip", // file in data/downloads/ packageName: "email-outreach-template", // stable identity — never changes packageVersion: "1.0.0", // bump to force a re-upsert on next start name: "Email Outreach", // display name override (optional)});Adding a new system-provided agent
Section titled “Adding a new system-provided agent”- Export the agent template as a ZIP via the agent builder UI.
- Place the ZIP in
data/downloads/. - Add an
ensureAgentPackagecall insrc/instrumentation.node.ts. - Set
packageVersionto"1.0.0"(or the initial version).
Forcing a re-upsert
Section titled “Forcing a re-upsert”Bump packageVersion in the instrumentation.node.ts call. On the next server start, ensureAgentPackage will see the version mismatch, re-read the ZIP, and run the upsert.
packageName identity rules
Section titled “packageName identity rules”packageNameis assigned once.setAgentTemplatePackageNameguards withWHERE package_name IS NULL— it cannot overwrite an established identity.updateAgentTemplatedoes not acceptpackageName— the general update path cannot rename a package identity.- The
agent_templates_package_name_idxunique index enforces one template per package name at the DB level. If a conflict occurs,importAgentTemplatemaps the Postgres error to a user-friendly message:"Package name [X] is already registered.".
Key files
Section titled “Key files”| File | Role |
|---|---|
packages/agents/src/ensure-agent-package.ts | Startup engine |
packages/agents/src/zip-helpers.ts | Pure Node ZIP read/write utilities |
packages/agents/src/import-export-actions.ts | importAgentTemplate with upsert-by-packageName |
packages/agents/src/store.ts | readAgentTemplateByPackageName, setAgentTemplatePackageName |
src/instrumentation.node.ts | Startup wiring — add new calls here |
data/downloads/ | System-provided agent ZIPs |