Voz e execução de conversas
Orbz permanece silencioso ao conectar. Em @neongate-ai/orbz@1.0.3, o pacote não fornece saudação, persona nem conversa: talk é um objeto vazio congelado e DEFAULT_TALK_FLOW é um array vazio congelado. O host fornece speech para uma frase ou um talkFlow tipado para uma conversa, configura o mecanismo e só inicia após ação explícita do usuário.
speech tem precedência sobre talkFlow. Sem ambos, startTalking() não faz nada. Iniciar um fluxo não vazio limpa seu contexto; uma etapa ask captura a entrada na chave capture quando o host chama receive(). Etapas posteriores podem interpolar a chave. Esse contexto não é persistido em cookies, local storage, IndexedDB ou backend.
Dados de conversa integrados
import { DEFAULT_TALK_FLOW, talk } from "@neongate-ai/orbz";
console.log(talk); // {}
console.log(DEFAULT_TALK_FLOW); // []Continue o fluxo
Depois que o fluxo personalizado abaixo chegar à etapa ask, passe a entrada enviada pelo usuário a receive(). A chave fullName existe porque o exemplo declara capture: "fullName"; não é um dado de conversa integrado.
import "@neongate-ai/orbz/browser";
import type { OrbzElement } from "@neongate-ai/orbz";
const orb = document.querySelector<OrbzElement>("orb-z");
await orb?.receive("Jonatas");
console.log(orb?.talkContext.fullName);Fala em inglês no navegador
WebSpeechAdapter usa pt-BR por padrão no pacote instalado. O exemplo seleciona en-US explicitamente porque a frase é em inglês. Para outros idiomas, configure o texto do host e o idioma do adaptador. Ele aguarda a lista assíncrona e prioriza vozes compatíveis com o idioma solicitado; a disponibilidade depende do ambiente do visitante.
import '@neongate-ai/orbz/browser'
import {
WebSpeechAdapter,
type OrbzElement
} from "@neongate-ai/orbz";
const orb = document.createElement("orb-z") as OrbzElement;
orb.speech = "Hello. This is an explicit speech example.";
orb.voiceEngine = new WebSpeechAdapter({
language: "en-US",
preferredVoices: ["Google US English", "Microsoft Aria Online"]
});
document.body.append(orb);
const startVoiceButton = document.querySelector<HTMLButtonElement>("[data-start-voice]");
startVoiceButton?.addEventListener("click", async () => {
await orb.startTalking();
});As vozes realmente instaladas continuam dependendo do navegador e do sistema operacional da pessoa visitante. WebSpeechAdapter melhora a seleção; ele não transforma uma voz do sistema em uma voz da OpenAI.
Fala com qualidade OpenAI
Na versão 1.0.3, OpenAISpeechAdapter usa gpt-4o-mini-tts, marin, MP3 e instruções em português brasileiro por padrão. Este exemplo em inglês substitui instructions para corresponder ao texto do host. A aplicação deve implementar e proteger o endpoint do exemplo.
import '@neongate-ai/orbz/browser'
import {
OpenAISpeechAdapter,
type OrbzElement
} from "@neongate-ai/orbz";
const orb = document.createElement("orb-z") as OrbzElement;
orb.speech = "Hello. This is an explicit speech example.";
orb.voiceEngine = new OpenAISpeechAdapter({
endpoint: "/api/orbz/speech",
instructions: "Speak in natural American English. Do not change the supplied text."
});
document.body.append(orb);
const startVoiceButton = document.querySelector<HTMLButtonElement>("[data-start-voice]");
startVoiceButton?.addEventListener("click", async () => {
await orb.startTalking();
});O endpoint pertence à aplicação que implementa a integração. Ele recebe um corpo JSON compatível com a OpenAI, contendo input, instructions, model, response_format e voice, e retorna a resposta de áudio gerada. Mantenha a chave de API da OpenAI nesse endpoint do servidor; nunca a coloque no código do navegador nem no pacote npm.
Aplicações que usam fala gerada devem informar claramente que a voz é gerada por IA.
Ativação explícita e política do navegador
Renderize um <button> nativo com um rótulo claro, como Iniciar voz, e chame startTalking() no manipulador de clique. Conectar o orb, atribuir um mecanismo de voz ou navegar para uma página nunca inicia o áudio.
Se o navegador ainda rejeitar o áudio solicitado com NotAllowedError, Orbz emite orbz-talk-error com o erro original e tenta novamente o fluxo solicitado após a próxima interação de ponteiro, teclado ou toque. Os controles de reinicialização não devem remontar o elemento apenas para liberar a fala.
Forneça um fluxo personalizado
import "@neongate-ai/orbz/browser";
import { WebSpeechAdapter, type OrbzElement, type OrbzTalkStep } from "@neongate-ai/orbz";
const flow = [
{ id: "welcome", kind: "say", needsAuth: false, text: "Hello." },
{ id: "name", kind: "ask", needsAuth: false, text: "What is your name?", capture: "fullName" },
{ id: "help", kind: "say", needsAuth: false, text: "How can I help, {{fullName}}?" },
{ id: "answer", kind: "respond", needsAuth: false, strategy: "openai", fallback: "I cannot answer that right now." }
] as const satisfies readonly OrbzTalkStep[];
const orb = document.createElement("orb-z") as OrbzElement;
orb.talkFlow = flow;
orb.voiceEngine = new WebSpeechAdapter({ language: "en-US" });
document.body.append(orb);
const startVoiceButton = document.querySelector<HTMLButtonElement>("[data-start-voice]");
startVoiceButton?.addEventListener("click", async () => {
await orb.startTalking();
});Atribua voiceEngine, talkFlow e intelligence antes de chamar startTalking(), para que a execução explícita os utilize.
Inteligência opcional
import type {
OrbzElement,
OrbzIntelligencePort
} from "@neongate-ai/orbz";
const intelligence: OrbzIntelligencePort = {
async respond(input, context) {
return productAgent.respond({ context, input });
}
};
orb.intelligence = intelligence;Eventos e estado visual
Enquanto o áudio é reproduzido, Orbz usa temporariamente o estado visual speaking e depois restaura o estado anterior.
| Evento | Detalhe |
|---|---|
orbz-speaking-change | { speaking: boolean } |
orbz-talk-error | { error: unknown } |
Os fluxos de texto para fala acima não capturam microfone. O host controla entrada, permissões, transcrições, lógica e receive(). Orbz também expõe uma API separada de conversa Realtime; estes exemplos de startTalking() não a iniciam.