Front door builder chat
Conversational authoring for organization-specific Agent and Workflow definitions, entered through the normal Front Door and backed by the existing DefinitionService.
Front door builder chat
Users should be able to say:
"Create an agent that qualifies UK fintech companies for SEO outreach."
or:
"Make a custom workflow based on Signals Search, but add a human review before outreach."
The experience starts in the normal AgencyCore chat. Architecturally, however, the Front Door does not become a definition editor. It delegates authoring intent to one platform-authored Definition Builder Agent.
User
│
▼
Channel Gateway
│
▼
Front Door
│ authoring intent
▼
Definition Builder Agent
│
├── search templates / capabilities
├── create or patch draft
├── validate draft
└── publish after explicit user intent + policy
│
▼
DefinitionService
│
▼
Agent / Workflow definition
│
publish
▼
normal Front Door -> RunManager execution path
From the user's point of view this is one chat experience. From the platform's point of view the boundaries remain unchanged.
What the feature owns
The Builder Chat owns the conversational authoring experience:
- understand what the admin wants to build or customize;
- decide whether the target is an Agent or a Workflow;
- find relevant platform templates, Agents, Skills and Tools;
- ask only for missing high-impact requirements;
- create and iteratively update one durable definition draft;
- explain validation failures in product language;
- summarize the effective design before publish;
- publish only after explicit user intent and normal policy checks.
It does not own runtime execution, policy, tool implementation, trigger scheduling, definition storage or validation rules.
Why this is not more Front Door logic
The platform Front Door stays responsible for intent and capability selection. It must not absorb definition authoring because that would give it another open-ended responsibility and turn it into a second runtime.
The Definition Builder is therefore a normal platform-authored Agent Definition that the Front Door can select like any other capability.
Front Door
answer / clarify / delegate / control_run
│
└── delegate(definition_builder, authoring brief)
No new Front Door outcome is required.
Definition Builder Agent
The Builder Agent has one responsibility: turn conversational requirements into a valid definition draft.
Its tool set is intentionally narrow.
| Tool | Purpose |
|---|---|
search_definition_templates | Find platform Agent/Workflow templates that are good starting points. |
search_capabilities | Find published Agents, Skills and Tools that may be referenced. |
get_definition_draft | Load one draft by ID when continuing authoring. |
create_definition_draft | Create one organization-owned draft. |
update_definition_draft | Apply a bounded patch to draft_config. |
validate_definition_draft | Run the shared deterministic DefinitionValidator. |
publish_definition | Publish through DefinitionService after explicit user intent and policy. |
These are normal internal Tools over the existing Definition APIs/services. The Agent never writes definition rows directly.
A refused write must never come back as a success. DefinitionService answers a stale expected_updated_at by returning None rather than raising, because its caller always reloads. A tool that maps that None onto an ordinary result tells the model the patch landed. The model then summarises a design it did not write, and offers to publish it, and the config that publishes is the other admin's. That is worse than the silent overwrite this page already forbids, because nothing anywhere disagrees.
So every write tool returns the refusal as a value the model must read:
| Tool | Refusals it must surface |
|---|---|
update_definition_draft | stale_draft |
publish_definition | stale_draft, validation_failed, too_many_referrers, definition_in_use |
The model never carries expected_updated_at. Asking a language model to hold an opaque timestamp across turns and echo it back correctly is asking it to be an optimistic concurrency client, and it will eventually send a stale one or invent one. update_definition_draft instead reads the draft, applies the patch and writes conditionally on the updated_at it just read. The window shrinks to one round trip and the compare-and-swap still catches the other admin, so the guarantee is unchanged and the model holds no state. On stale_draft the agent reloads and applies the patch again.
Draft writes are product authoring effects, not execution. Publishing is the safety boundary and may be gated by Policy.
Durable authoring state
There is no authoring-session table in V1.
The conversation carries the draft ID. An authoring conversation outlives its Run: the Front Door starts a fresh Run for every turn, so the second turn's Builder Agent has no memory of what the first one created. "The current draft" is not a thing the platform can resolve, because an organization may hold many.
So the draft ID lives on the conversation, in the one place that already spans turns.
create_definition_draft returns the ID
-> the Run result carries it as a ResourceRef
-> the conversation records it as an entity in scope
-> the next turn's ContextBrief carries it
-> get_definition_draft(id) loads it
Nothing new is built. agent.conversation_entities already feeds ContextRequest.entities, and a ResourceRef is already how a Run points at a row it produced. An admin who wants a different draft names it, and the agent searches.
The definition row is the durable state:
definition
id
organization_id
kind: agent | workflow
origin: platform | custom
source_definition_id
state: draft | active | disabled
draft_config
published_config
The conversation may remember the active definition_id as lightweight thread/session metadata so follow-ups such as "add CRM read access" resolve naturally.
If that conversational pointer is lost, the draft is still safe and can be reopened by ID/name from the Builder or direct Agent Builder UI.
Agent authoring flow
"I need an agent that qualifies inbound companies."
│
▼
identify responsibility + expected output
│
▼
search available Tools / Skills / templates
│
▼
ask only for required missing constraints
│
▼
create Agent draft
│
▼
validate
┌────┴─────┐
invalid valid
│ │
explain summarize
+ patch effective design
│
explicit publish
│
▼
DefinitionService.publish()
A custom Agent draft may configure:
responsibility / instructions
model
context_policy
tool_ids[]
skill_ids[]
budget_defaults
The Builder does not invent permissions. The Agent may reference only Tools/Scopes available to the organization and compatible with the authoring principal.
Workflow authoring flow
The Builder composes the existing V1 Workflow Definition language:
sequence parallel containers
agent tool subworkflow work
branch wait approval control
It may reference existing published Agents, Tools and subworkflows. Validation remains deterministic and enforces node IDs, references, types, cycles, nesting depth, wait node shape and declared scopes.
The approval node is how an author says "stop here for a person", which is the request in the example below. It is one of the three sources that write an agent.approvals row. See human review.
"Create a workflow that researches a prospect,
gets human review, then starts outreach."
│
▼
Builder finds published capabilities
│
▼
sequence
-> agent/signals research
-> approval node
-> subworkflow/email sequence
│
▼
validate -> summarize -> publish
Schedules and event conditions do not belong inside the Workflow Definition. If the user asks "run this every Monday" or "run when a CRM signal changes", that is Trigger configuration and remains a separate platform concept.
Template customization
Platform templates are read-only. Customization forks them.
platform template
│ customize
▼
organization draft
origin = custom
source_definition_id = template.id
│
▼
edit -> validate -> publish
This allows product capabilities such as Signals Search or the email sequence workflow to become starting points for organization-specific workflows without mutating the platform definition.
Later changes to the platform template do not silently change the organization's fork.
Publish and test
V1 keeps the boundary simple:
Drafts are not executable.
The flow is:
draft
-> deterministic validation
-> user sees summary
-> explicit publish intent
-> Policy / DefinitionService.publish()
-> current published_config
-> normal Front Door / RunManager Run
There is no separate draft runtime or preview execution engine.
After publish, "test it with Acme" is simply a normal request to the Front Door. The newly published capability is found through CapabilityIndex and runs through the standard RunManager path with a frozen Run snapshot.
Example: custom Agent
User:
Create an agent that reviews a company and tells me whether it fits
our UK fintech SEO ICP.
Builder:
- finds CRM read + intelligence search Tools
- proposes an Agent responsibility and output shape
- asks whether it may write qualification back to CRM
User:
Read only for now.
Builder:
- creates/patches draft with read-only Tools
- validates successfully
- summarizes model, context, Tools and budget
- asks whether to publish
User:
Publish it.
publish_definition
-> Policy
-> DefinitionService.publish()
-> capability becomes discoverable by Front Door
Example: customize a product workflow
User:
Make our Signals Search workflow require a person to review the
prospect before Email Sequence can start.
Front Door
-> Definition Builder Agent
Builder
-> finds Signals Search template
-> forks organization draft
-> adds the supported wait/approval boundary
-> validates references and types
-> summarizes the changed workflow
-> publishes after explicit confirmation
The new Workflow uses the same shared Tools, Policy, Context, Runs, spans and Idempotency Service as the platform workflow. Customization creates data, not infrastructure.
Roles and policy
V1 keeps the existing rule:
Admins author. Authorized users run.
Rules:
- Only organization admins may create, patch or publish custom definitions.
- The Builder Agent runs with the user's
Principal; it cannot widen the user's authority. - A custom Agent cannot grant itself Tool scopes the organization/principal cannot authorize.
publish_definitionpasses through normal Policy and deterministic validation.- The Builder cannot bypass an approval by editing the definition around it; runtime action policy is evaluated live at execution.
- Tenant isolation remains database/RLS enforced through the underlying service path.
Failure handling
| Failure | Product behavior |
|---|---|
| Requirement is genuinely ambiguous | Ask one focused question. |
| No suitable Tool/capability exists | Explain the missing capability; do not fabricate one. |
| Draft validation fails | Explain the deterministic validation errors and propose a patch. |
| Concurrent admin edit | Reload after optimistic concurrency failure; never overwrite silently, and never report a refused write as done. |
| Referenced capability is disabled | Validation blocks publish until replaced. |
| Publish policy denies | Keep the draft and explain the policy decision. |
| Conversation loses active draft pointer | Search/reopen the durable draft; no work is lost. |
V1 rules
- Front Door routes authoring; it does not author definitions itself.
- Definition Builder is one normal platform Agent, not a new runtime.
- One durable definition draft is the source of truth; no authoring-session database.
- All draft lifecycle operations go through
DefinitionService. - Deterministic
DefinitionValidatoris authoritative; the model cannot waive an error. - Drafts never execute in V1.
- Publishing is explicit and policy-controlled.
- Workflow schedules/events stay in Triggers, not in workflow config.
- Organization customization forks platform templates; it never mutates them.
- After publish, the capability uses the exact same Front Door ->
RunManagerexecution path as every other Agent/Workflow.
Minimum scenarios
- Non-admin cannot create or patch a custom definition through chat.
- Front Door routes authoring intent to Definition Builder without adding a new Front Door outcome.
- Builder cannot reference a Tool/Skill outside the visible/allowed capability set.
- Invalid Agent/Workflow draft cannot publish even if the model says it is valid.
- Concurrent draft update produces optimistic-concurrency failure rather than silent overwrite.
- A stale draft write reaches the model as
stale_draft, and the agent reloads instead of reporting success. - A publish refused for referrers or for a definition in use is rendered to the person, never swallowed.
- No tool call carries
expected_updated_atfrom the model. - Platform template customization creates a separate organization-owned definition with
source_definition_id. - Draft cannot be started as a Run.
- Published custom capability is discoverable through
CapabilityIndexand starts throughRunManager. - Trigger/schedule request is not serialized into Workflow config.