Front door general chat
The default conversational answer path for AgencyCore. It answers from supplied context, cites what it used, asks when context is insufficient, and delegates real work through the normal Front Door.
Front door general chat
AgencyCore chat is the user's front door. A person may ask:
"What can AgencyCore do with this company?"
or:
"Why did the prospect search stop?"
or:
"What is lifecycle stage?"
Those are not all task requests. Some are product questions, some are questions about live or past Runs, some are follow-ups on scoped business entities, and some are requests to start work. The Front Door must handle that breadth without becoming a second runtime.
The rule is:
General chat answers from supplied context, or it asks, delegates, or controls a Run.
User message
|
v
Front Door
+-- conversation context
+-- entities in scope
+-- run history
+-- platform and organization knowledge
+-- capability shortlist
|
v
answer / clarify / delegate / control_run
No new Front Door outcome is required. General chat is the product contract for the answer and clarify paths, plus the routing discipline that keeps work in delegated Agents and Workflows.
What the feature owns
General chat owns the everyday conversational experience before a specialized capability takes over:
- build the right bounded context for the user's question;
- answer product and platform questions from retrieved knowledge;
- answer questions about scoped business entities from application context;
- summarize live and recent Runs from run history;
- resolve conversational follow-ups such as "this company" through entity scope;
- cite the records, documents or Runs that support a factual answer;
- ask one focused question when the user intent or reference is ambiguous;
- explain when the platform lacks enough context or capability;
- delegate work requests to one published Agent or Workflow;
- control a live Run when the user clearly asks to stop it.
It does not own deep research, CRM exploration, email search, web browsing, tool execution, workflow steps, policy, approval rules, memory writes, trigger scheduling or definition authoring.
The front door builder chat is still a delegated specialized Agent. General chat may route authoring intent to it, but it does not create or patch definitions itself.
Phase 6 focus
Phase 6 is not the final chat product. It is the slice that makes chat dependable as the default entry point.
The focus is:
- high-quality context assembly for general chat;
- evaluation against real question scenarios;
- missing knowledge and read capabilities for CRM, workflows and agents;
- broad question generation for test coverage;
- stress testing the chat flow for stability and latency;
- useful progress messages while the user waits.
The UI should follow the existing chat experience. Phase 6 should not redesign chat chrome, message layout, navigation or source rendering. Any source affordance should fit the current message model and can be replaced later with the full chat redesign.
Why this is not more task logic
The Front Door already has the correct closed set:
answer(text)
clarify(question)
delegate(capability_id, input)
control_run(run_id, action)
General chat makes answer useful. It does not widen what the Front Door may do.
"What does lifecycle mean?"
|
v
answer from platform knowledge
"Find fintech companies hiring a head of growth."
|
v
delegate(Signals Search, original message)
"Add a human review step to the workflow."
|
v
delegate(Definition Builder, authoring brief)
A general answer is a conversational product result. A delegated Run is execution. The distinction stays visible in both state and UI.
Context sources
Phase 5 enables the web chat surface and the thin Front Door. Phase 6 should make that Front Door useful as the actual front door by adding the missing context sources and entity scope.
| Source | Answers | Boundary |
|---|---|---|
conversation | What did we just discuss? | Recent messages and summary only. |
entity_scope | What does "this company", "that run" or "the draft" refer to? | Conversation-scoped ResourceRefs. |
application | What is true about an already-scoped CRM/product entity? | Scoped projections only, no search. |
dossier | What does the organization sell, and to whom? | The Company dossier from Settings. No user section. |
run_history | What happened with recent or active work? | Root/child Run summaries and refs, not span trees. |
knowledge | What do AgencyCore docs or organization docs say? | Bounded retrieval over ready chunks. |
memory | What preferences or observations should shape the answer? | User or agent memory, never authority for live facts. |
The ContextBuilder owns retrieval. The model receives a bounded ContextBrief; it does not call search tools from the Front Door. The draft turn of a form chat is the one exception, and Front Door § A draft turn researches specifies it.
The rolling summary
A conversation past the read window would drop its oldest turns, so each conversation carries a rolling summary and the conversation source reads it first. The summary takes one slot of the source item cap, so a summary and the messages never spend more than the policy allows.
The frontdoor.turn function writes it, in a step after the model decision. The step is where the turn already ends, so the summary needs no trigger of its own, and a retried turn writes one summary and one usage row. agent.conversations.summary_message_count records how many messages the stored summary covers: a pass reads the newer messages alone, and the model is asked on a threshold rather than on every turn.
The summary is context, and it is never evidence. It carries no row identifier and it supplies no ResourceRef, so an answer cannot cite it.
Fresh exploration remains delegated. If the user asks "which companies match this ICP?", the Front Door does not run a CRM or web search. It delegates to the appropriate capability.
Context evaluation
The success of general chat depends more on context quality than on prompt wording. Phase 6 should evaluate the context builder against use cases before tuning the model.
Question scenario
|
v
Expected context ingredients
|
v
ContextBuilder policy and source retrieval
|
v
Packed ContextBrief
|
v
Front Door outcome
|
v
Answer, clarify, delegate or control_run
Each scenario should record:
| Field | Purpose |
|---|---|
| User question | The exact phrasing to test. |
| Expected outcome | answer, clarify, delegate or control_run. |
| Required sources | Which context sources must appear. |
| Forbidden sources | Sources that would imply task work or over-retrieval. |
| Required citations | Refs the answer must cite when it makes factual claims. |
| Latency target | Whether this should feel instant or show progress. |
| Failure expectation | What the system should say when context is missing. |
Evaluation should include both positive and negative cases. A good result is not only "the answer is right"; it is also "the Front Door did not search, execute or guess."
Initial question set
Phase 6 should generate and test a large library of user questions. The first scope is CRM, workflows and agents.
CRM questions
What does lifecycle stage mean?
Why is this company marked as a prospect?
What changed on this company recently?
Who owns this deal?
Why is this prospect waiting for review?
What evidence supports this opportunity score?
Show me the last activity on this company.
Why did this company stop matching our ICP?
Can I promote this prospect to CRM?
Find more companies like this one.
Most CRM explanation questions should answer from scoped application context and knowledge. Discovery questions such as "find more companies" should delegate.
Workflow questions
What steps does Signals Search run?
Why is this workflow waiting?
What happens after the approval step?
Can I change this workflow to add human review?
Which workflow should I use for outreach?
Why did this workflow fail?
What data does this workflow write?
Run this workflow every Monday.
Stop that workflow run.
Definition and behaviour questions should answer from knowledge and definition summaries. Authoring questions should delegate to Builder Chat. Trigger questions should route to trigger configuration when that capability exists.
Agent questions
What agents can I use?
What does the Definition Builder do?
Which tools can this agent use?
Why did this agent ask for approval?
What memory does this agent keep?
Create an agent that qualifies inbound leads.
Can this agent send email?
Why did the agent stop?
Change the running agent's instructions.
Capability questions can answer from the capability index and platform knowledge, but the capability index is not evidence for factual product behaviour. Authoring requests delegate. Live steering still clarifies or explains cancel plus restart.
General platform questions
What can AgencyCore do?
How is chat different from running a workflow?
What does approval mean?
Where do citations come from?
Why can you not answer this from chat?
What should I upload so you can answer this?
These should answer from platform knowledge. If the relevant docs are not ingested, the answer should name the missing knowledge instead of guessing.
Entity scope
General chat needs a durable way to resolve follow-ups.
Run result returns ResourceRefs
|
v
conversation stores entities in scope
|
v
next Front Door turn carries those refs
|
v
ApplicationContextSource resolves only those refs
The conversation should store a small ordered set of scoped entities:
agent.conversation_entities
conversation_id
kind
resource_id
label
introduced_by_message_id
last_referenced_at
Rules:
- Entity scope is a pointer set, not a knowledge store.
- A Run result, an assistant answer or an explicit ref sent with a message may add a ref.
- An exact, unambiguous relevant ref resolves "this" or "that".
- If more than one ref fits, the Front Door returns
clarify. - The source still resolves every ref through the normal scoped reader.
- Losing the pointer loses convenience, not data.
What writes a ref
Three deterministic outputs write, and no model-chosen text does:
| Producer | Where it runs | What it writes |
|---|---|---|
| A Run result | frontdoor.scope, on agent/run.succeeded | result.refs of a Run that names a conversation |
| An assistant answer | frontdoor.turn, after the reply | the citations of that answer |
| An explicit ref | the send-message contract | the rows a product surface names with the message |
A citation is checked against the brief before the turn writes it, so this path stores a row the platform supplied and never a string the model invented.
⚠️ A platform ref is refused. A definition, a knowledge chunk and a memory each resolve through no product reader, so a stored one holds a slot no turn can read.
What evicts a ref
Two things evict a ref.
The bound is the first. The scope holds what one turn reads, and today that is
twenty refs. A write that carries the set past that bound deletes the least
recently referenced rows, in the order last_referenced_at DESC, id DESC that
the reader also uses. An answer's citations move last_referenced_at, so a row
the conversation returns to outlives a row it named once.
The introducing message is the second. introduced_by_message_id cascades, so
deleting that message deletes the ref. The upsert rewrites the column, so it
names the message that referenced the ref last, and not the first one. A Run
result writes no message, and a later citation of the same row then ties it to
that reply.
⚠️ The delete names the rows it removes, and never the rows it keeps. Two
producers write one conversation, so a delete phrased as "everything but these
twenty" would remove a row the other producer committed a moment earlier. That
row carries the newest last_referenced_at, which makes it the ref the next
turn resolves.
The share each kind takes
The write is cut to the bound before it reaches the table, and each kind takes a share of the bound. One Run writes its refs in node order. A node that answers many rows writes them last, so a flat cut to the last twenty kept that node alone.
One producer passes the bound today. The CRM Question Agent cites up to one hundred records of five kinds from one node. A flat cut kept the last twenty, and those twenty can be one kind. The share keeps four of each kind instead.
The second case is not live yet. intelligence.upsert_people_batch declares no
row_pointers, and a declaration there is the next step. It answers up to
seventy-five people, and Signals Search runs it after promote-prospects
answers ten prospects. A flat cut to twenty would keep no prospect. The share
keeps ten prospects and ten people.
A kind that holds less than its share releases the rest, and the kinds after it divide what is left. Inside one kind the tail still wins, because the last rows of a kind are the rows the final stage produced.
⚠️ The kind stands for the node, and it is not the same thing. A tool
declares one item_kind, so one node answers one kind in practice. An Agent
answers several kinds from one node. Two nodes that answer one kind divide that
kind's share, and the later of them wins inside it.
Builder Chat uses the same mechanism for active definition drafts. No authoring-session table is needed.
Knowledge-backed answers
Platform documentation is the main source for product questions:
docs page
-> extract text
-> chunk
-> embed
-> agent.knowledge_sources(scope = platform)
-> agent.knowledge_chunks
-> ContextBuilder knowledge source
-> Front Door answer
An organization document uses the same tables with organization_id set. The Front Door may read only sources visible to the actor's organization.
The ordinary resource upload writes the document to the organization scope. It stays hidden from chat while processing, becomes readable only in ready, and is removed from the knowledge index when the resource is deleted.
Knowledge retrieval is not live web search. It answers from documents AgencyCore has ingested and marked ready.
Every factual answer from knowledge should carry source refs:
Knowledge source: /engineering/system-design/agentic-platform/interfaces/front-door
Chunk: 12
Claim: The Front Door selects one Agent or Workflow and never executes work itself.
The UI may render those refs as source chips or footnotes. The storage requirement is simpler: the assistant message records the refs it used so an answer can be audited later.
Answer contract
answer remains one Front Door outcome, but Phase 6 should make its payload structured enough to audit.
class FrontDoorAnswer(BaseModel):
text: str
citations: list[ResourceRef] = []
unresolved: list[str] = []
The user-visible text is still plain chat. The extra fields are for rendering, audit and tests.
Rules:
- A factual claim about AgencyCore behaviour cites platform knowledge.
- A factual claim about the user's business cites an application or Run ref.
- A preference-shaped answer may use memory, but memory never overrides application state.
- If the needed source is missing or unavailable, say what is missing.
- If a request requires fresh work, delegate instead of answering from old context.
- If the user asks for external current facts and no research capability is available, say the platform cannot answer it from chat.
- Do not cite the capability shortlist. It is routing context, not evidence.
This is a prompt rule and a validation rule. The Front Door can reject an answer that carries unsupported citations or references outside the supplied brief.
Missing capabilities
General chat can answer only what its context sources can provide. Phase 6 should add the missing read capabilities needed for the first question set.
| Capability | Needed for |
|---|---|
| Platform knowledge ingestion | Product questions about chat, CRM, workflows, agents, approvals, runs and definitions. |
| Conversation entity scope | Pronouns and follow-ups such as "this company" or "that run". |
| CRM application projections | Scoped answers about companies, people, deals, activities and prospects. |
| Definition summary context | Questions about published Agents, Workflows, Skills and Tools. |
| Run summary context | Questions about active, failed, waiting and completed work. |
| Citation validation | Refuse unsupported citations and keep answers auditable. |
The first implementation should prefer read-only projections over new agent tools. A read capability is context; a tool is action.
A projection answers one scoped read. It cannot answer a question that joins several reads, because the turn must choose its filters after it sees the first result. "Which open deals have no activity in 30 days, and who owns them" reads deals, then activities for those deals, then the owner of each. The Front Door delegates that question to an Agent that holds bounded read-only Tools. The Agent reads; it does not act. A write still needs the proposed-action queue. See agentic CRM.
Routing matrix
| User intent | Correct outcome |
|---|---|
| Product definition or usage question | answer from knowledge, with citations. |
| Question about an active or recent Run | answer from run history, or clarify if multiple Runs fit. |
| Question about a scoped company, person, deal, activity or prospect | answer from application context, with refs. |
| Follow-up with an ambiguous pronoun | clarify. |
| Request to start work | delegate to one published Agent or Workflow. |
| Request to create or change an Agent/Workflow | delegate to Definition Builder. |
| Request to stop one clear live Run | control_run(cancel). |
| Request to change a live Run | clarify or explain cancel plus restart. Steering is still deferred. |
| Unsupported task with no capability | answer with the missing capability, not a guessed workaround. |
The model may be conversational in tone, but the outcome is not conversationally loose. One turn produces one of the four structured outcomes.
Examples
Product question
User:
What is the Front Door allowed to do?
General chat:
Answers from platform knowledge:
- decide answer / clarify / delegate / control_run
- never execute task work
- delegate Runs through RunManager
Includes citations to the Front Door design.
Scoped business question
User:
Why is this prospect marked review needed?
Context:
conversation entity scope contains prospect:123
application source returns review_state and reason
General chat:
Answers from the scoped prospect fields.
Does not search for more prospects.
Work request
User:
Find 20 UK fintech companies that just raised seed funding.
General chat:
Delegates to Signals Search if visible.
If no such capability is visible, explains that no published capability can do it.
Authoring request
User:
Make a workflow that researches a company, asks me to review it, then drafts outreach.
General chat:
Delegates to Definition Builder with the authoring brief.
Definition Builder owns the draft.
UI behaviour
The web chat should keep the existing chat UI and UX. Phase 6 should improve behaviour inside that experience, not replace the interface.
| State | UI behaviour |
|---|---|
| General answer | Render a normal assistant message. Store citations for audit; render only what the existing UI supports. |
| Clarification | Render one focused question. |
| Delegation | Show the handoff reply, then attach to Run progress. |
| Terminal Run report | After a delegated Run succeeds or fails, render one work report after the handoff and keep the link to the Run. |
| Run control | Show the result of the control action. |
| Missing capability | State the missing capability in product language. |
| Missing context | State what the user must name, upload or run first. |
Source rendering is not the Phase 6 product bet. The important contract is that answers record citations and never make unsupported factual claims. The future chat redesign can choose how to expose those citations.
The handoff and the report are two assistant messages that answer the same inbound message. Both carry the same run_id; kind = reply identifies the handoff and kind = report identifies the terminal report. The report uses the stored Run result to answer the person's original question. A retry updates the one report row instead of appending a duplicate.
A succeeded or failed Run always closes the chat loop when the Run came from a conversation and its handoff reply still exists. The normal path uses one bounded model call. A day-limit denial, vendor failure or empty model answer uses a deterministic fallback, so the conversation does not stop at "I started that." A cancelled Run writes no report because the control turn already told the person it stopped. A Run started outside a conversation writes no report.
Waiting states
The user should see useful messages while the system works. Progress is semantic state, not chain-of-thought.
message accepted
|
v
thinking
|
v
checking_context
|
v
finding_capability
|
+-- searching_web, opening_page, reading_page, searching_crm
| (a draft turn, while one of its read tools runs)
|
+-- answer or clarify
|
+-- preparing_task
|
v
Run progress stream
|
+-- cancelled (control turn reported)
|
v
succeeded or failed
|
v
work report in chat
The Front Door owns progress until a Run owns the work. After delegation, the runtime owns the stream.
Suggested message meanings:
| State | Meaning |
|---|---|
thinking | The turn started and budget admission passed. |
checking_context | The system is retrieving conversation, scoped entities, knowledge and run history. |
finding_capability | The system is checking which Agents and Workflows are available. |
searching_web | A draft turn runs a web search. |
opening_page | A draft turn fetches a page. |
reading_page | The fetch answered, and the model reads the page. |
searching_crm | A draft turn reads the CRM companies or people. |
preparing_task | A delegated Run is being started. |
Do not emit fake specificity such as "searching CRM" from the Front Door. If CRM search is happening, a delegated Run owns it. The one exception is the draft turn of a form chat, which may call four read tools before it decides. Each of its four research states names the tool that runs, and the turn reports one only while that tool runs, so it claims no work the turn did not do. Front Door specifies it.
Stress testing
Phase 6 should stress test the whole chat flow, not only model output.
| Area | What to test |
|---|---|
| Context packing | Large conversations, many scoped entities, long knowledge chunks, source failures and token-budget cuts. |
| Routing | Similar capability names, unsupported requests, ambiguous pronouns and authoring versus execution intent. |
| Idempotency | Worker retry, duplicate inbound messages and answer-write replay. |
| Latency | Cold knowledge retrieval, large capability catalogues and slow context sources. |
| Streaming | Ordered progress states, no duplicate progress on retry and clean handoff to Run progress. |
| Terminal reports | Handoff before report, one report on replay, no report for cancellation or a Run outside chat, and a safe fallback when the report call is denied or unavailable. |
| Tenancy | Foreign entity refs, foreign Run refs and organization knowledge isolation. |
| Cost gates | Day-limit denial before the model call and no usage row on denial. |
| Citation safety | Unsupported refs, stale refs and answer claims without evidence. |
The stress suite should include scenario tests, contract tests and load-style tests. A stable chat flow is one that remains bounded, idempotent and clear under failure.
Quality gate
Phase 6 should end with a system design and code quality review. General chat sits on the product front door, so the implementation must stay small, explicit and easy to maintain.
The review should check:
- the Front Door still has only four outcomes;
- no action tools or exploratory reads were added to the Front Door;
- context sources are read-only, scoped and bounded;
- prompt and answer contracts are validated by code, not only by instruction text;
- retries and duplicate messages remain idempotent;
- dead or stale Phase 6 code was removed;
- files follow the existing module boundaries and clean-code patterns;
- tests match the final design and obsolete tests are deleted.
Any deferred design risk should become an explicit follow-up with an owner.
Failure handling
| Failure | Product behaviour |
|---|---|
| Knowledge source unavailable | Answer only from remaining sources and name the gap. |
| Knowledge retrieval returns nothing | Say the docs do not contain enough information. |
| Entity reference is ambiguous | Ask which entity the user means. |
| Entity reference no longer resolves | Say the item is no longer available or visible. |
| Run reference is ambiguous | Ask which Run the user means. |
| Capability shortlist has no match | Explain that no published capability can do the task. |
| Model returns an unsupported citation | Reject the answer and fail the turn cleanly. |
| Accrual denies the turn | Return the day-limit message and make no model call. |
| Accrual denies the terminal report call | Write the deterministic terminal report and make no model call or usage row. |
| Terminal report model is unavailable | Write the deterministic terminal report and do not retry into another model call. |
V1 rules
- General chat does not add a fifth Front Door outcome.
- Phase 6 focuses on CRM, workflow and agent questions first.
- Phase 6 follows the existing chat UI and UX.
- The Front Door does not receive action tools.
- The model never performs exploratory reads in the Front Door.
- The ContextBuilder retrieves before the model reasons.
- Context quality is evaluated through scenario fixtures.
- The question library includes positive, negative and ambiguous cases.
- Knowledge answers cite knowledge refs.
- Business answers cite application or Run refs.
- Capability summaries are not evidence.
- Entity scope is durable conversation metadata, not a fact store.
- Ambiguous pronouns lead to one clarification.
- Work requests delegate through
RunManager. - Authoring requests delegate to the Definition Builder Agent.
- Live Run changes are limited to cancel. Steering remains V2.
- Progress messages are semantic state and stop when Run progress begins.
- A succeeded or failed delegated Run writes one terminal report back to chat; a cancelled Run writes none.
- Stress tests cover context, routing, idempotency, latency, streaming, tenancy, cost gates and citations.
- Phase 6 closes with a design and clean-code review.
Minimum scenarios
- "What can you do?" answers from platform knowledge when knowledge is available.
- "What is lifecycle stage?" cites the relevant product documentation.
- "What agents can I use?" answers from visible capability summaries and platform knowledge.
- "What steps does Signals Search run?" answers from workflow knowledge or definition summary context.
- "Why did that run stop?" asks which Run when more than one recent Run fits.
- "Why did that run stop?" answers from run history when one Run fits.
- "Tell me more about this company" resolves a scoped company ref.
- A stale or unauthorized entity ref does not leak data.
- "Find companies like this" delegates instead of searching inside the Front Door.
- "Create an agent that qualifies inbound leads" delegates to Definition Builder.
- "Stop that" cancels only when one active Run is clear.
- An answer cannot cite a ref outside the supplied
ContextBrief. - A retry writes one assistant message and no second model usage row.
- A succeeded delegated Run renders the handoff and then one work report linked to the same Run.
- A failed delegated Run renders one work report in product words, without an internal error.
- A cancelled Run or a Run without a conversation writes no work report.
- A slow context source emits useful progress but does not expose internal reasoning.