Blog
What's new in Dcision: shadow mode, engines side by side and GPT-Live
4 min read
Last week Dcision started running three decision engines: Jev, Laya and OpenAI Decisions. It also started accepting images, voice and documents as input. The next question came quickly: which engine should this decision use, and how do I know switching won't make things worse?
This release answers that, and closes a few loose ends.
At a glance
| What's new | What it solves | Where |
|---|---|---|
| Compare engines | See the same input answered by all three engines, side by side | Playground |
| Shadow mode | Measure in production how often a second engine agrees with the main one, without changing the answer | Decision settings and Overview |
| GPT-Live | Use the decision's questions and policies in an OpenAI voice session | Public API |
| Refusal as its own reason | Know when the engine declined to answer, and take the fallback | action_reason |
| File cost | See what transcribing audio and reading documents cost | Response metrics |
| Webhook with files | Send forms with attachments straight to the webhook trigger | /v1/hooks |
| Four new templates | Invoices, voice notes, images and an LLM guardrail, ready to use | Templates |
Compare engines in the Playground
The Playground has a new Compare engines button. It runs the same state, on the same draft, on Jev, Laya and OpenAI Decisions at once. The result is a table: each question's answer with its confidence, the final action, and each engine's latency and estimated cost. Rows where the engines disagree are highlighted.
Each engine counts as one Playground run, and destinations are not delivered. If an engine isn't set up in the workspace, its column shows the error code and the rest of the comparison still works.
Shadow mode in production
A handful of Playground examples helps, but real traffic is different. In shadow mode you pick a shadow engine and a share of production runs (1% to 100%, default 10%). Those runs also go to the shadow engine, in the background, with exactly the input the main engine received.
What stays the same:
- The answer always comes from the main engine. The shadow engine never changes the caller's action, destinations or latency.
- Shadow runs don't use Dcision credits. With the workspace's own key, the provider bills your account.
- The Playground never shadows. Only deployed versions called through the API, the webhook or the MCP do.
On the Overview tab, a card shows overall and per-question agreement, how many shadow runs ran, how many failed, and the shadow engine's p50 latency. Agreeing means picking the same option, giving the same score level, or landing on the same side of 50% for a yes/no question. Switching engines becomes a call you make with data.
GPT-Live: the decision's questions in a voice session
OpenAI built Decisions into GPT-Live: the voice session delegates questions to Decisions while the user is still speaking. Until now, doing that meant writing the questions again in the session code, and policies, logs and actions were left out.
There are now two endpoints:
GET /v1/decisions/{slug}/openai-livereturns the decision's deployed version as the session'sdelegationobject (type: "decisions"), with the questions already in OpenAI's format.POST /v1/decisions/{slug}/openai-live/answerstakes theanswersof eachdecision.completedevent. Dcision applies the policies, handles refusals, delivers to destinations and logs the execution, just like a regular API call.
The engine isn't called again and the engine cost is zero, because OpenAI already billed the Live session. The execution counts as one decision on your plan.
Refusals get their own reason
OpenAI Decisions can decline to answer a question. That used to surface as an engine error. Now the run answers 200, the refused question is left out of result, and the decision takes its fallback action with action_reason.type = "refusal" and the question's name. The evaluation order is: policies, refusal, the other option, minimum confidence and, finally, continue.
What reading the files cost
When the state carries files, the response now reports metrics.input_files, metrics.input_processing_ms and metrics.input_cost_usd. Documents read locally (PDF, Office, spreadsheets) cost nothing. Transcribed audio, images described for text-only engines and files read by OpenAI are priced, and estimated_cost_usd already adds it all up.
Webhook with files
The webhook trigger now accepts multipart/form-data. Text fields become state strings, files become inputs for image, audio or file fields, and an optional state field holding JSON is the base. The body can now be up to 32 MB, and the HMAC signature still covers the raw bytes. A form with an attachment reaches the decision directly, with no server in between.
Four new templates
- Invoice triage: reads the document and decides between pay, review or reject, escalating when the due date is close.
- Voice note routing: transcribes the voice message and decides intent, urgency and sentiment.
- Image moderation: checks whether a listing photo is safe and matches its caption.
- LLM output guardrail: checks an LLM's or agent's answer before it reaches the user. It has its own article.
Getting started
Open a decision, go to the Playground and click Compare engines. If agreement looks good, turn on shadow mode in Settings and watch the Overview for a few days before switching the main engine. The docs at docs.dcision.io walk through each feature, in five languages.