Responder configuration reference
buzz.actor.set-responder decides who answers for one attached actor: its Staff configuration, DGI, or both. It is the only setting structured chat needs. Structured chat is part of DGI and is Alpha.
- Who may call it: an organization admin or owner, signed in as a person. Agents, API keys, the system and end users are refused.
- Where it is stored: on the space, per attachment.
data.buzz.attachment.listreturns it as each attachment'sresponder. Nothing in it is a secret. - When it takes effect: on the next message. No
buzz.bridge.syncis needed. - How to undo it: call it again with
responder: "staff". The DGI entry is removed and the actor answers with its Staff configuration. - Replacing, not merging: each call stores the whole entry. Send every field you want to keep.
Fields
| Field | Applies to | Values and default | What it does |
|---|---|---|---|
space_uuid | all | Required | The chat space |
attachment_uuid | all | Required. From data.buzz.attachment.list | The attached actor |
responder | all | Required. staff, dgi or hybrid | staff: the actor's Staff configuration (the default, no entry stored). dgi: DGI answers with cards. hybrid: DGI first, Staff for what DGI cannot decide |
allowed_workflow_types | dgi, hybrid | Required. 1 to 50 names, exact or prefix.* | The workflows DGI may start. Intersected with what the message author may run, so it never grants anything. An empty list is refused |
system_prompt | dgi, hybrid | Up to 8,000 characters | Instructions added to DGI's own: tone, language, what to show, what to avoid |
decision_engine | dgi, hybrid | auto (default), jev, llm | Who decides each turn. auto: Jev when it is confident, else the LLM. jev: Jev. llm: the LLM only. hybrid refuses llm |
jev_threshold | dgi, hybrid | 0.5 to 0.99, default 0.8 | Jev confidence needed to act without the LLM |
jev_connection_uuid | dgi, hybrid | An active TypeSafe connection of the organization | Which connection Jev decides with. Without it, DGI uses the organization's own |
ai_provider_config_uuid | dgi, hybrid | An AI provider configuration of the organization. Default: the organization's default | Which model answers when the LLM is used. Your organization pays its own tokens |
max_reasoning_turns | dgi, hybrid | 6 to 48, default 12 | Tool-loop budget per message on the LLM path |
renderers | dgi, hybrid | Subset of form, confirm, select, table, actionlist, logs, run, chart, kpi, link, composition, dag, schema, datagrid, query, diff, detail, timeline. Default: all | Which cards the chat may draw. A view whose renderer is left out is posted as text. See the card catalog |
default_inputs | dgi, hybrid | {workflow_type: {field: value}}. See below | Values DGI pre-fills for a workflow |
suggestions | dgi, hybrid | 1 to 8 {label, prompt} | Curated quick replies, offered instead of the ones DGI generates |
confirm_allowed_end_user_uuids | dgi, hybrid | Up to 50 end-user uuids | Only these people may press Confirm, on top of the card's own author check. For example, a founder-only approval |
compose | dgi, hybrid | Boolean, default false | Lets DGI show and edit compositions in chat. Honored only when replies run as an organization member, never in seat mode. Saving still goes through a confirm card |
hybrid_handoff_reasons | hybrid | 1 to 20 reason names. Default below | Which DGI fallback reasons hand the turn to the Staff configuration |
Suggestions
suggestions pins an actor's quick replies. Each entry has exactly two keys:
label: 1 to 48 characters, plain one-line text, distinct from the others (case-insensitive), not starting with a bullet or wrapped in quotes.prompt: 1 to 200 characters. It tells DGI what the label means.
A quick reply posts its label as the person's message, never its prompt. Pick labels that read well as a message, such as "Blocked tickets".
Seat mode or organization mode
The responder decides what answers. The attachment's reply principal, set with buzz.actor.set-reply-principal, decides as whom DGI runs:
| Reply principal | DGI runs as | Catalog DGI sees |
|---|---|---|
seat (default) | The end user who wrote the message | Workflows marked eligible for end users and compositions your app exposes, intersected with allowed_workflow_types. No compose, save, connection or run-inspection tools |
organization | The author's linked organization account; if there is none, the admin who turned internal mode on (re-checked as admin on every reply) | allowed_workflow_types, and nothing beyond it |
See Internal support actor for the gates of organization mode.
Hybrid: DGI first, Staff for the rest
With responder: "hybrid", every turn starts as a DGI turn. The turn is handed off to the actor's Staff configuration when DGI drew no card, did not refuse the request, and one of these holds:
- DGI stopped at a fallback whose reason is in
hybrid_handoff_reasons; - DGI produced no usable text and no card;
- the DGI run failed.
Default hybrid_handoff_reasons:
| Reason | DGI found |
|---|---|
workflow_none | No allowed workflow fits the message |
intent_unsupported | An intent it does not handle structurally |
needs_value_extraction | Values it would have to pull out of free text |
low_confidence | Jev was not confident enough |
no_candidates | No candidate workflows to choose from |
Reasons match by family. A listed name also covers every reason that starts with it: jev covers jev_timeout, and chitchat covers chitchat_needs_tools. A fallback reason that is not listed is answered by DGI's own LLM, so views that only the LLM path draws still reach a hybrid actor.
On a hand-off nothing of DGI's is posted: the Staff configuration answers the same message exactly as responder: "staff" would, as the actor's seat (so a hybrid actor in seat mode must declare that it acts as the app). An answer to a card always stays with DGI.
Default inputs
default_inputs pre-fills workflow inputs. For example, a support actor that should see only support tickets in active states:
{
"ticket.search": {
"labels": ["support"],
"status": ["open", "triaged", "in_progress", "blocked"]
}
}
- Limits. Every type must be allowed by
allowed_workflow_types(exactly, or under aprefix.*; a pattern itself is refused). Up to 20 types, 30 fields per type, field names like[A-Za-z_][A-Za-z0-9_]*up to 64 characters, values JSON scalars (strings up to 1,000 characters, numbers, booleans, null) or lists of up to 50 of them, and 8,192 bytes in total. Anything else isdefault_inputs_invalid. - The person's own values win. A default fills a field only when the message and the form leave it empty.
- Naming a value narrows the default. When a message names a value of a defaulted filter, DGI uses that value instead of the whole default list: "show me the blocked tickets" searches
status: [blocked], not the four defaults. The card's title says which filter it used. - They grant nothing. Defaults cannot widen the scope, skip the confirm, or reach another person's data.
- Superseded entry points. When an app entry point is republished under a new version, the defaults for the old type follow it, as
allowed_workflow_typesdo.
Troubleshooting
| You see | Why | Fix |
|---|---|---|
buzz_admin_role_required, buzz_admin_requires_human | The caller is not an admin or owner, or is not a person | An organization admin or owner starts the call, signed in as themselves |
dgi_responder_unavailable | The platform cannot store responder state for this space yet | Contact Orkestia support |
decision_engine_invalid | hybrid with decision_engine: "llm" | Use auto or jev for hybrid |
jev_connection_not_found, jev_connection_invalid, jev_connection_inactive | The connection is not an active TypeSafe connection of this organization | Pick one from connection.query filtered to typesafe, or leave the field out |
default_inputs_invalid, suggestions_invalid | A value breaks the limits above | Fix the entry the message names |
actor_act_as_not_declared | A hybrid actor in seat mode whose Staff definition does not act as the app | Declare act-as on the actor, or use dgi |
| The actor answers "I can't do that for you in this conversation" | DGI refused: the workflow is outside the scope or the person may not run it | Add the type to allowed_workflow_types, and in seat mode expose it to end users |
A configuration message ending in dgi_scope_required, author_not_linked or internal_principal_not_admin | The attachment has no scope, or organization mode cannot find who to run as | Set allowed_workflow_types; in organization mode, make sure the enabling admin is still an admin |
| Cards arrive as plain text | The renderer is not in renderers, the theme flag structured_ui is off, or the client is older than the card | Check the responder entry, the theme, and republish the chat page |
| "This form is no longer active" | The card was replaced by a newer one, or it is answered from another channel | Ask again, and answer where the card was posted |
| "This card expired" | Forms and confirms expire after 30 minutes | Ask again |
No / palette | The space predates the commands entry point, or the hosted page is old | Re-run buzz.space.enable, then buzz.space.publish-chat |
| A typed "yes" did nothing | Prose never confirms | Press Confirm on the card |
Ask your AI assistant
Read the responder of every actor in my chat space with data.buzz.attachment.list and explain each setting in plain words.
Draft a hybrid responder for my actor "<actor name>" that hands free-text questions to its Staff configuration but keeps low-confidence reads on DGI. Show me the hybrid_handoff_reasons you chose and why.
Add default_inputs to my support actor so ticket searches default to open support tickets, keeping every other responder field unchanged. Show me the full call first.
For AI agents
| Rule | Detail |
|---|---|
| Read before write | data.buzz.attachment.list shows the current entry. set-responder replaces the whole entry, so carry every field forward |
| Scope | Never propose an empty allowed_workflow_types. Verify each type with get_workflow_schema; in seat mode check end_user_eligible or that it is an exposed composition |
| Human callers | Prepare the call; an admin or owner starts it |
| Handoff reasons | Match by family prefix. Do not list llm_fallback itself as a reason |
| Defaults | default_inputs keys must be allowed types, not patterns |
Option C: custom client (wire contract)
Draw structured chat cards in your own chat client. The buzz-ui block and tag, every renderer and its fields, answers and card actions, server-side validation, in-place edits, quick replies, the status line and slash commands
Cards, live updates and proactive posts
Refresh a read card, keep it live, act on table rows, use the / command palette, run cards, and post cards from outside the chat with buzz.actor.post-view and buzz.message.post
