Skip to content

feat: add agent blueprints — instance-scoped reusable agent config presets#4451

Open
chewieglass-labs wants to merge 8 commits intopaperclipai:masterfrom
chewieglass-labs:feat/agent-blueprints
Open

feat: add agent blueprints — instance-scoped reusable agent config presets#4451
chewieglass-labs wants to merge 8 commits intopaperclipai:masterfrom
chewieglass-labs:feat/agent-blueprints

Conversation

@chewieglass-labs
Copy link
Copy Markdown

@chewieglass-labs chewieglass-labs commented Apr 25, 2026

Thinking Path

  • Paperclip orchestrates AI agents for zero-human companies — every agent in an org has a role, adapter config, capabilities, and runtime config that takes time to craft well
  • Instance-level config reuse: once an org has a well-tuned engineer or researcher agent, there is no way to share that configuration as a starting point for other orgs on the same instance
  • Gap: boards must redraft adapter configs, instruction sets, and capability descriptions from scratch for every agent hire, even for common roles
  • The org export/import feature covers whole-org snapshots; there is no per-agent template primitive
  • This pull request adds Agent Blueprints: instance-scoped, reusable agent configuration presets that boards can browse, hire from, and save existing agents into
  • The benefit is a shorter time-to-hire for common roles, a growing library of field-tested configs, and a traceable lineage from blueprint → agent → new blueprint

What Changed

Database

  • New table agent_blueprints (migration 0071_agent_blueprints.sql) — stores name, description, role, title, icon, capabilities, tags, adapter config, runtime config, budget, permissions, instructions, and metadata as an instance-scoped record with no company_id
  • Migration 0072_blueprint_lineage.sql — adds nullable source_agent_id and source_blueprint_id to agent_blueprints, and source_blueprint_id (FK → agent_blueprints.id ON DELETE SET NULL) to agents; also adds tags: text[] to agents; both migrations are additive and safe to run against production data
  • packages/db/src/schema/agent_blueprints.ts — new Drizzle schema file for the agent_blueprints table; exported from packages/db/src/schema/index.ts
  • packages/db/src/schema/agents.ts — extended Agent schema with tags: text[] and sourceBlueprintId FK referencing agent_blueprints

Backend

  • server/src/services/agent-blueprints.ts — CRUD service with ilike search across name, description, and capabilities
  • server/src/routes/agent-blueprints.ts — REST routes under /api/blueprints; read endpoints require assertAuthenticated (agents can discover blueprints), write endpoints require assertBoard
  • packages/shared/src/validators/agent-blueprint.ts — Zod validators for create and partial-update shapes, including lineage fields
  • packages/shared/src/validators/index.ts — re-exports createAgentBlueprintSchema, updateAgentBlueprintSchema, CreateAgentBlueprint, UpdateAgentBlueprint
  • packages/shared/src/index.ts — added explicit named exports for all four blueprint validator symbols so they are available as @paperclipai/shared top-level imports
  • packages/shared/src/types/agent.tsAgent interface extended with tags: string[] and sourceBlueprintId: string | null

Frontend

  • ui/src/api/blueprints.ts — typed API client with list, get, create, update, delete; list accepts optional search and role query params
  • ui/src/lib/queryKeys.ts — added blueprints.all, blueprints.list(search?, role?), blueprints.detail(id)
  • ui/src/components/TagsInput.tsx — shared tag chip input (Enter/comma to add, Backspace to remove last, deduplication); used by BlueprintFormDialog and SaveAsBlueprintDialog
  • ui/src/components/SkillsMultiSelect.tsx — shared searchable skills multi-select with All/Clear bulk actions and footer count; used by BlueprintFormDialog, SaveAsBlueprintDialog, and NewAgent
7
  • ui/src/pages/Blueprints.tsx — new /instance/blueprints page:

    • Responsive card grid (1–4 columns) with search bar, role dropdown, and clickable tag chips for filtering
    1
    • BlueprintCard: icon slot shows the agent's icon when the blueprint was derived from an agent, falls back to the Layers glyph for manually created ones; name, role badge, and Derived badge (when sourceAgentId is set); capabilities text expandable inline via a more/less toggle; skills chips with +N more collapse
    4
    • BlueprintFormDialog: create/edit form with description, adapter config via AgentConfigForm, tags via TagsInput, desired skills via SkillsMultiSelect, and monthly budget
    5
6
  • Export (.blueprint.json) and Import actions — strips id/createdAt/updatedAt on import

  • Create, edit, and delete mutations fire a pushToast success notification via useToastActions on completion

  • ui/src/pages/AgentDetail.tsx:

    • Three-dot menu gains Save as Blueprint — pre-filled dialog with name, role, title, capabilities, tags via TagsInput, adapter config via AgentConfigForm, desired skills via SkillsMultiSelect (non-required, filtered from agent's live AgentSkillSnapshot), and monthly budget; sets icon, sourceAgentId, and preserves sourceBlueprintId for full lineage; fires a success toast on save
    3
    • Blueprint lineage banner at top of the Overview tab when agent.sourceBlueprintId is set: Hired from blueprint: <linked name> — links to /instance/blueprints
    2
  • ui/src/pages/NewAgent.tsx — detects ?blueprintId= query param; pre-fills name, title, role, adapter config, and desired skill keys from the blueprint; passes sourceBlueprintId in the hire payload; tags removed (blueprint-only concept); skills section uses SkillsMultiSelect for consistency with blueprint forms

  • ui/src/components/NewAgentDialog.tsx — new 4-step onboarding flow replacing the previous single-step adapter picker:

    1. Main — three paths: ask CEO, start from blueprint, or configure manually
    8
    1. Blueprint pick — searchable list of all blueprints; select one to continue
    9
    1. Blueprint action — two options per blueprint: "Ask CEO to adapt" (creates an issue with full blueprint context and instructs CEO to use the paperclip-blueprints skill) or "Configure manually" (navigates to the hire form with ?blueprintId= pre-filled)
    10 11
    1. Adapter pick — original manual flow, retained for power users
  • ui/src/components/InstanceSidebar.tsx — added Blueprints nav item with Layers icon, positioned below Heartbeats in the instance settings nav

  • ui/src/App.tsx — registered instance/blueprints route

Tests & Fixtures

  • ui/src/components/CommentThread.test.tsx — added tags: [] and sourceBlueprintId: null to two inline Agent mock objects
  • ui/src/components/RoutineRunVariablesDialog.test.tsx — same fix to the agent fixture used by the dialog test
  • ui/src/fixtures/issueChatUxFixtures.ts — added missing fields to the shared agent fixture used across issue chat tests
  • ui/src/lib/agent-config-patch.test.ts — updated makeAgent() factory to include both new required fields
  • ui/src/lib/company-portability-sidebar.test.ts — updated makeAgent() helper to include both new required fields
  • ui/src/pages/IssueDetail.test.tsx — added fields to the createAgent() factory before the ...overrides spread to ensure the base object satisfies the updated Agent interface
  • ui/storybook/fixtures/paperclipData.ts — added tags: [] and sourceBlueprintId: null to all three agent entries in the shared storybook dataset
12

CEO Skill

  • skills/paperclip-blueprints/ — new CEO skill with six documented workflows: list, get, adapt, hire (passes sourceBlueprintId in the hire payload), reference in approval comment, and save-agent-as-blueprint; includes field-by-field adaptation guidelines and cleanup rules for stripping org-specific details before saving
  • skills/paperclip-blueprints/references/api-reference.md — full endpoint reference with payload shapes and query param docs
Screenshot from 2026-04-25 02-15-27 Screenshot from 2026-04-25 02-15-36

Verification

  • Build and run locally: BETTER_AUTH_SECRET=<secret> docker compose -f docker/docker-compose.quickstart.yml up --build — migrations run automatically on startup
  • Or against an existing DB: pnpm db:migrate — both migrations are additive, no data loss
  • Start the dev server and navigate to Instance → Blueprints in the sidebar
  • Create a blueprint manually via New Blueprint; verify it appears as a card
  • From the card, click Use — should navigate to the hire form pre-filled with the blueprint's adapter config and skills
  • Hire an agent from the blueprint; on the agent's Overview tab verify the Hired from blueprint banner shows with the correct name and a link back to the blueprints page
  • From the hired agent's three-dot menu, click Save as Blueprint — the dialog pre-fills name, role, title, capabilities, tags, adapter config, desired skills (non-required only), and monthly budget; save and verify a success toast appears, the blueprint card shows the Derived badge, and the agent's user-chosen skills are listed; adapter-required skills (always available) must not appear
  • Export a blueprint as .blueprint.json, then import it — verify the imported record has a new id and correct fields
  • From any org, open New Agent dialog and choose Start from a Blueprint — verify the search works and both "Ask CEO" and "Configure manually" paths function
  • CEO skill: curl "$PAPERCLIP_API_URL/api/blueprints" -H "Authorization: Bearer $PAPERCLIP_API_KEY" should return the blueprint list

Risks

  • Migration safety: both migrations are purely additive (new table, nullable columns with defaults). Existing agents and orgs are unaffected. ON DELETE SET NULL on agents.source_blueprint_id means deleting a blueprint does not cascade-delete agents.
  • No breaking API changes: all new routes are additive; existing agent hire payload is backward compatible (new sourceBlueprintId field is optional)
  • Instance-scoped blueprints: blueprints have no company_id — they are visible to all authenticated agents on the instance. This is intentional (templates are shared infrastructure) but means any board-role user can write blueprints. If multi-tenant isolation is a concern, a company_id or visibility flag can be added later without changing the schema's additive nature.
  • NewAgentDialog refactor: the existing adapter picker is preserved as the "Advanced" path; the new onboarding steps wrap it, so no existing hire flow is removed

Model Used

  • Claude Sonnet 4.6 (claude-sonnet-4-6) via Claude Code CLI
  • Tool use enabled; extended multi-file context across schema, service, routes, validators, frontend pages, and skill documentation

Checklist

  • I have included a thinking path that traces from project context to this change
  • I have specified the model used (with version and capability details)
  • I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work
  • I have run tests locally and they pass
  • I have added or updated tests where applicable
  • If this change affects the UI, I have included before/after screenshots
  • I have updated relevant documentation to reflect my changes
  • I have considered and documented any risks above
  • I will address all Greptile and reviewer comments before requesting merge

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 25, 2026

Greptile Summary

This PR adds instance-scoped Agent Blueprints — a well-structured feature covering DB migrations, a CRUD backend service, Zod validators, typed API client, and a full frontend (browse, create, edit, export/import, "Save as Blueprint", and a revamped NewAgentDialog). The backend is clean and the previously-flagged issues (silent lineage drop on update, redundant casts, instructionsContent missing on import, handleUse no-op) are all addressed. Two UI-level gaps remain: the export→import round-trip silently drops sourceAgentId/sourceBlueprintId (contrary to the stated "only strips id/createdAt/updatedAt"), and the instructionsContent blueprint field is never populated or applied through any UI path (neither BlueprintFormDialog, SaveAsBlueprintDialog, nor the NewAgent pre-fill effect), making it unreachable except via the raw API.

Confidence Score: 5/5

Safe to merge; both findings are P2 quality gaps, not blocking bugs

Only P2 findings — no P0/P1 issues remain after verifying the previously flagged fixes are in place. Migrations are additive, routes are correctly auth-gated, and the core hire/blueprint flows work end-to-end.

ui/src/pages/Blueprints.tsx (import drops lineage), ui/src/pages/AgentDetail.tsx and ui/src/pages/NewAgent.tsx (instructionsContent gap)

Important Files Changed

Filename Overview
packages/db/src/migrations/0071_agent_blueprints.sql Additive migration creating agent_blueprints table with appropriate indexes; no data loss risk
packages/db/src/migrations/0072_blueprint_lineage.sql Additive migration adding lineage columns; agent_blueprints.source_blueprint_id lacks a FK constraint (orphan refs possible if parent blueprint is deleted), while agents.source_blueprint_id correctly uses ON DELETE SET NULL
server/src/services/agent-blueprints.ts Clean CRUD service; ilike search correctly handles nullable columns via OR; update correctly uses undefined-guards so omitted fields are not overwritten
server/src/routes/agent-blueprints.ts REST routes correctly scope reads to assertAuthenticated and writes to assertBoard; validation middleware applied; no issues
packages/shared/src/validators/agent-blueprint.ts Zod validators correctly use .omit({ sourceAgentId, sourceBlueprintId }).partial() for update to enforce lineage immutability
ui/src/pages/Blueprints.tsx Main blueprint page; import silently drops sourceAgentId/sourceBlueprintId breaking the Derived badge after a round-trip; edit path correctly omits runtimeConfig/permissions from the PATCH body
ui/src/pages/AgentDetail.tsx SaveAsBlueprintDialog does not capture instructionsContent from the agent, leaving the blueprint's most important field empty for all UI-created blueprints
ui/src/components/NewAgentDialog.tsx New 4-step onboarding flow; useDeferredValue correctly debounces blueprint search; UnprefixedBoardRedirect preserves path and query params so blueprint-prefilled navigation works correctly
ui/src/pages/NewAgent.tsx Blueprint pre-fill effect handles name/title/role/adapterConfig/desiredSkills but does not apply blueprintData.instructionsContent or blueprintData.budgetMonthlyCents to the hired agent
packages/db/src/schema/agent_blueprints.ts Drizzle schema matches migration; sourceAgentId/sourceBlueprintId intentionally untyped as FKs, consistent with migration
Prompt To Fix All With AI
This is a comment left during a code review.
Path: ui/src/pages/Blueprints.tsx
Line: 560-575

Comment:
**Import silently drops `sourceAgentId` and `sourceBlueprintId`**

`handleImport` destructures only `id`, `createdAt`, and `updatedAt` before passing `payload` to `blueprintsApi.create`, but the explicit property list never includes `sourceAgentId` or `sourceBlueprintId`. The PR description says "strips `id`/`createdAt`/`updatedAt` on import", implying all other fields are preserved — but after an export → import round-trip the **Derived** badge will disappear and the lineage chain is permanently broken.

If dropping lineage on import is intentional (e.g. lineage UUIDs are meaningless on a different instance), document it explicitly; otherwise add the two fields to the `blueprintsApi.create` call:

```typescript
sourceAgentId: payload.sourceAgentId ?? null,
sourceBlueprintId: payload.sourceBlueprintId ?? null,
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: ui/src/pages/AgentDetail.tsx
Line: 1259-1278

Comment:
**`instructionsContent` not captured in "Save as Blueprint"**

`SaveAsBlueprintDialog.handleSave` omits `instructionsContent` from the `createMutation` payload, so the agent's prompt/instructions are never written to the blueprint. The `agent_blueprints` schema and the export output both carry this field, but it can never be populated through the UI: `BlueprintFormDialog` also exposes no instructions input, and `NewAgent.tsx` doesn't apply `blueprintData.instructionsContent` when pre-filling the hire form.

As a result `instructionsContent` is effectively write-only via the raw API — the most important part of an agent's configuration is silently absent from every blueprint created through the UI.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (5): Last reviewed commit: "fix: blueprint edit/search/import polish" | Re-trigger Greptile

Comment thread ui/src/pages/Blueprints.tsx
Comment thread server/src/services/agent-blueprints.ts
Comment thread server/src/routes/agent-blueprints.ts
@chewieglass-labs
Copy link
Copy Markdown
Author

chewieglass-labs commented Apr 25, 2026

  • added a pushToast({ tone: "warn", ... }) call in the else branch so clicking Use without a company selected now shows a warning toast.

  • removed sourceAgentId and sourceBlueprintId from updateAgentBlueprintSchema using .omit() before .partial(), so callers now get an explicit validation error rather than a silent no-op. Lineage is treated as immutable after creation.

  • removed the redundant as string casts.

@greptileai re-review

Comment thread ui/src/pages/Blueprints.tsx
Hash and others added 3 commits April 25, 2026 05:06
Export serializes the full blueprint including instructionsContent, but
the import payload passed to blueprintsApi.create was missing the field,
silently dropping agent instructions on every export→import round trip.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
handleSave was hardcoding runtimeConfig: {} and permissions: {} for
both create and edit paths. In edit mode this silently wiped any values
originally set when saving an agent as a blueprint. Now edit mode falls
back to the existing blueprint's values so they are preserved across
updates.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- preserve runtimeConfig and permissions on edit by omitting them from
  the PATCH payload (only sent on create where they default to {})
- debounce blueprint search via useDeferredValue to avoid a fetch on
  every keystroke
- add success toast after a successful blueprint import

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@chewieglass-labs
Copy link
Copy Markdown
Author

chewieglass-labs commented Apr 25, 2026

Fixed in d6dfbf7 — added instructionsContent: payload.instructionsContent ?? null to the blueprintsApi.create call inside handleImport. The field was present in payload after stripping id/createdAt/updatedAt, but was never forwarded, causing agent instructions to be silently dropped on every export → import round trip.

It's my first PR, so I'm hoping I did okay.
I've been enjoying Paperclip and this feature has been useful for my setup so I thought it could be useful for others too. Hope you like it!😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant