Connect by JBRH Open Connect

Telling the voice how to speak

Two blocks of text are assembled for every call. style_block turns the delivery settings — speed, energy, warmth, pauses, fillers, formality — into lines of instruction. behaviour_block turns the conduct settings — role, goal, tone, rules, what to ask and never ask, objections, escalation, opening and closing — into more of them. Both are directions the model follows, approximates, or occasionally ignores.

Status
Available What this means
Audience
both
Channels
phone
In the app
#/phone, #/behaviour-advanced
Last verified
Product version
6.3.2

Two blocks, and a third thing that is not a block#

The realtime engine is speech to speech. There is no synthesiser sitting between the model and the line with a pitch dial on it, so a setting can only reach the call in one of two ways: as a parameter the session is opened with, or as a sentence in the instructions.

KindAssembled byExamples
Session parametervoice_style.session_optionsModel, voice, pinned language code, temperature, reply length, end-of-speech silence, interruption thresholds, noise cancellation, the silence and hang-up timers
Style instructionvoice_style.style_blockSpeed, pitch, energy, warmth, emotion, pauses, fillers, formality, humanness, accent, pronunciation
Behaviour instructionvoice_style.behaviour_blockRole, goal, tone, style, knowledge, hard rules, what to ask and never ask, objection handling, escalation, opening, closing, proactiveness, language switching, memory use

The Lab shows which kind each control is, on the control itself. That is not decoration: a session parameter is applied by the runtime and will be there on every turn of the call, while an instruction is a request. Knowing which one you just changed tells you whether to expect a difference or to go and measure for one.

What a direction can actually influence#

The human voice profiles are the clearest statement of this, because their schema labels all 86 parameters by kind. engine is a session parameter. prompt is a direction the model follows fairly reliably — a filler rate, a politeness marker, a level of formality. coarse is a direction it approximates: you will get the general shape and not the specific value.

Anything the stack genuinely cannot set is in UNSUPPORTED and is shown as unsupported rather than as a slider that does nothing. That list covers pitch in hertz, level in decibels, jitter, formants, exact pause lengths and a deliberate delay before answering. A control that cannot move the thing it names is worse than no control, because somebody spends an afternoon moving it.

Which guide wins#

voice_style.resolve layers settings from the broadest to the narrowest, and the narrowest wins:

  1. The workspace's own settings.
  2. The default profile.
  3. A profile chosen by purpose — inbound, service, transactional or promotional. There is no campaign model here; per campaign means per purpose.
  4. A profile attached to a specific line number.
  5. A profile on the contact, held as contact.facts.voice_profile — one person who should always be spoken to a particular way.
  6. The Lab's draft, on a test call only. This is why a Lab call can sound unlike production without anything being wrong.

Whatever comes out of that resolution is snapshotted onto call.quality when the call ends, so the review judges the settings that actually ran. If somebody edits a profile an hour later, the old call still reports what it was given, not what the profile says now.

Budgets, because every character is time#

Instruction size is on the record as session.instructions_chars, and the relationship is not subtle: about 7,500 characters produced a 1.2–1.8 s first token, and about 9,600 produced 2.3–3.4 s. The budgets exist because of that measurement.

Knowledge
4 facts, 2,000 characters
Memory
700 characters
Contact block
600 characters
A human voice profile block
Under roughly 2,500 characters

A behaviour block written like a policy document will silently spend the whole latency budget of the line. Write the rules that change what the voice does and delete the ones that describe what it would have done anyway.

Where the language rule comes from#

One part of the brief is authored in neither block. voice_region.plan writes the language rule itself, from the evidence about the person on the other end, and it replaces the language line the behaviour block would otherwise carry. The behaviour block's switching setting still decides whether a pinned language is held or followed; everything else about which language is spoken is written from what is known, with a different bar in each of four tiers:

  • Pinned, with switching set to anything but follow — the call is held there, any language is understood, and no evidence moves the reply.
  • A remembered preferred_language — spoken from the first reply; a whole sentence in another language overrides it, never a switch mid-sentence, never mixed scripts unless the caller mixes them.
  • Likely, from the contact's city or state — the call opens in the line's language and does *not* assume the regional one, but two or three words of it, mixed with English or not, move the call into it and keep it there.
  • Nothing on file — the call opens in the line's language and moves only on a whole sentence.

Reconciled on 2026-09-10 against backend/app/voice_region.plan at f5ea518, read from the code rather than the docstring above it, which still describes an offer the code no longer makes. Nothing in the rule offers a language or quotes a phrase to try: on a production call an earlier brief's sample phrase was read out to the caller word for word, and a mid-call steer cannot reach a Gemini 3.1 session, so the opening line is the whole lever. Detecting the caller's language has the tiers in full.

Questions#

I set the speaking speed and nothing changed. Is it broken?

Speed is a style instruction, not a session parameter — the model is asked to speak at that pace and approximates it. If the pace matters more than anything else on the line, a chirp3-hd voice on the carrier path takes an actual speaking rate, because there the audio is synthesised rather than generated.

Why does my Voice Lab test sound different from a real call?

The Lab's draft sits at the narrowest layer of the resolution order, so it overrides everything, including a profile pinned to the line number or to the contact. A real call resolves without it. Save the draft as the profile if you want production to match what you just heard.

Can one customer always be spoken to formally?

Yes — a profile on the contact, held as contact.facts.voice_profile, wins over the line's and the workspace's. It resolves per call, so it applies whether they rang in or Connect rang them.