Skip to main content

Discussions

Reusable deliberation configs whose invocations are runs — a panel of participants thinks over a topic and returns a synthesized outcome.

Overview

A Discussion is the home of deep thinking in SOAT. It is a reusable configuration (who deliberates and how); each invocation is a DiscussionRun (what was deliberated and what came out) — the same split as an Agent and its generations. Author a discussion once, then invoke it many times: standalone (brainstorming, red-teaming, expert review) or, more commonly, from an agent mid-loop via a discussion-type tool.

Deep thinking lives entirely in Discussions rather than in a per-agent reasoning config. If you are porting a reasoning recipe, see Migrating from agent reasoning.

See the Permissions Reference for the IAM action strings for this module.

Data Model

Discussion

FieldTypeDescription
idstringUnique identifier (disc_ prefix)
project_idstringProject the discussion belongs to
namestringDisplay name
descriptionstringOptional description
ai_provider_idstringDefault AI provider participants and synthesis fall back to (required)
modelstringDefault model (falls back to the provider's default_model)
max_roundsnumberRounds of deliberation (1–3, default 1)
synthesisobjectOptional override for the final synthesis pass — see Synthesis
participantsarrayThe deliberation participants — see Participant
tagsobjectArbitrary string tags
created_atstringISO 8601 creation timestamp
updated_atstringISO 8601 last-updated timestamp

Participant

Each participant is one voice in the deliberation. A discussion allows 1–5 participants.

FieldTypeDescription
idstringUnique identifier (dpt_ prefix)
namestringDisplay label used for transcript attribution
promptstringPersona prompt for this participant
positionnumberTurn order (defaults to array index)
actor_idstringDurable Actor identity to attribute this voice's turns to
ai_provider_idstringProvider override for this participant (falls back to the discussion)
modelstringModel override
temperaturenumberSampling temperature
effortstringlow | medium | high — provider-native reasoning effort for this participant's turns

DiscussionRun

A run is a single invocation of a discussion.

FieldTypeDescription
idstringUnique identifier (drn_ prefix)
discussion_idstringDiscussion that was invoked
project_idstringProject the run belongs to
topicstringThe subject the participants deliberated on (the invocation argument)
statusstringpending | running | completed | failed
outcomestring/nullThe synthesized outcome text (the tool-result contract)
conversation_idstring/nullThe persisted transcript as a Conversation
outcome_document_idstring/nullThe stored outcome as a Document
started_byobject/nullIdentity that triggered the run
initiator_generation_idstring/nullGeneration that invoked this run (when triggered by an agent tool)
trace_idstring/nullAssociated trace ID
completed_atstring/nullISO 8601 completion timestamp
created_atstringISO 8601 creation timestamp

Key Concepts

Deliberation and synthesis

A run maps each participant to a voice in a single deliberation step that runs for max_rounds rounds; every voice sees the running transcript. When there is more than one participant, more than one round, or an explicit synthesis config, a final synthesis pass weighs the deliberation into a single outcome. A single-participant, single-round discussion with no synthesis skips the extra pass — its lone turn is the outcome.

Each turn is a side-effect-free completion (no tools). Deep thinking never fails a run: a failed turn is dropped and the run continues; if synthesis fails, the last successful turn becomes the outcome.

Synthesis

The optional synthesis object overrides the final pass:

FieldTypeDescription
ai_provider_idstringProvider for the synthesis completion
modelstringModel for the synthesis completion
promptstringSynthesis prompt template (supports {steps.deliberation} and {topic})
effortstringlow | medium | high provider-native effort

Invoking a discussion from an agent

An agent thinks by attaching a discussion-type tool that references a discussion config ({ "type": "discussion", "discussion": { "discussion_id": "disc_..." } }). The model calls it mid-loop with a topic; the server runs the discussion synchronously and returns { outcome, run_id } as the tool result. Use tool_choice: required or a step rule to force "discuss before acting". See discussion tools.

The full transcript and outcome persist on the run (Conversation + Document); the tool result carries only the synthesized outcome plus the run_id, so it never floods the caller's context.

Migrating from agent reasoning

Migration note. Earlier versions exposed a reasoning config on the agent (provider-native effort and a reasoning-step pipeline). Discussions replace it.

The agent schema has no reasoning field: agent create/update and per-generation overrides that include it are rejected with a 400 (unknown field). Map each reasoning recipe to a discussion:

Former agent reasoningDiscussion equivalent
reflect (draft → critique → revise)A single-participant discussion with a synthesis prompt that critiques and revises
debate (multi-perspective + synthesis)Multiple participants (one per perspective) + a synthesis pass; set max_rounds for rebuttal rounds
best-of-N (independent samples + judge)Multiple participants with varied temperature + a synthesis pass that picks/merges
reasoning.efforteffort on a participant and/or the synthesis override

Invoke the discussion from the agent via a discussion-type tool, or call POST /discussions/{id}/runs before/after a generation. No data migration is required — the old reasoning config simply stops being read.

Examples

Create a discussion

soat create-discussion \
--project-id proj_ABC \
--name "Design review panel" \
--ai-provider-id aip_01 \
--max-rounds 2 \
--participants '[{"name":"Advocate","prompt":"Steelman the proposal."},{"name":"Skeptic","prompt":"Attack the strongest claim."}]'

Run a discussion

soat create-discussion-run \
--discussion-id disc_01 \
--topic "Should we migrate the queue to Kafka?"