@opengeni/sdk 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -3
- package/dist/adapters/next.js +2 -2
- package/dist/artifacts.js +4 -4
- package/dist/azure-live-transport.d.ts +32 -0
- package/dist/browser.js +3 -3
- package/dist/chat/index.js +5 -5
- package/dist/{chunk-RSKO3CMZ.js → chunk-BVIIRSJY.js} +2 -2
- package/dist/{chunk-G5NZGPTB.js → chunk-CA2T7QT4.js} +2 -2
- package/dist/{chunk-ZBICMU4Z.js → chunk-D534PIXF.js} +2 -2
- package/dist/{chunk-CNSPJYF6.js → chunk-FYQAMXDW.js} +104 -5
- package/dist/chunk-FYQAMXDW.js.map +1 -0
- package/dist/{chunk-IB6SUE3R.js → chunk-GYM54GKM.js} +1 -1
- package/dist/chunk-GYM54GKM.js.map +1 -0
- package/dist/{chunk-VYCTL62C.js → chunk-GZQSWAKD.js} +1 -1
- package/dist/chunk-GZQSWAKD.js.map +1 -0
- package/dist/{chunk-CREM7YRK.js → chunk-LEBDXYMA.js} +2 -2
- package/dist/{chunk-YVH2PH4X.js → chunk-MXV5O25O.js} +2 -2
- package/dist/{chunk-2UXZUCEZ.js → chunk-ZNC44QEX.js} +77 -7
- package/dist/chunk-ZNC44QEX.js.map +1 -0
- package/dist/codex-realtime-controller.d.ts +13 -0
- package/dist/codex-realtime-controller.js +3 -1
- package/dist/codex-realtime-v3-wire.d.ts +3 -2
- package/dist/codex-realtime.d.ts +4 -0
- package/dist/core.js +4 -4
- package/dist/document-authority.js +3 -3
- package/dist/editable-artifacts.js +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +55 -18
- package/dist/index.js.map +1 -1
- package/dist/realtime.d.ts +1 -1
- package/dist/realtime.js +248 -2
- package/dist/realtime.js.map +1 -1
- package/dist/session-proxy-client.d.ts +7 -3
- package/dist/session-proxy.d.ts +9 -1
- package/dist/session-proxy.js +2 -2
- package/dist/site.js +3 -3
- package/dist/transcription.d.ts +1 -1
- package/dist/types.d.ts +30 -8
- package/package.json +3 -3
- package/src/azure-live-transport.ts +286 -0
- package/src/codex-realtime-controller.ts +95 -2
- package/src/codex-realtime-v3-wire.ts +4 -3
- package/src/codex-realtime-v3.ts +11 -2
- package/src/codex-realtime.ts +9 -1
- package/src/index.ts +3 -0
- package/src/realtime.ts +15 -6
- package/src/session-proxy-client.ts +7 -3
- package/src/session-proxy.ts +137 -4
- package/src/transcription.ts +3 -0
- package/src/types.ts +34 -5
- package/dist/chunk-2UXZUCEZ.js.map +0 -1
- package/dist/chunk-CNSPJYF6.js.map +0 -1
- package/dist/chunk-IB6SUE3R.js.map +0 -1
- package/dist/chunk-VYCTL62C.js.map +0 -1
- /package/dist/{chunk-RSKO3CMZ.js.map → chunk-BVIIRSJY.js.map} +0 -0
- /package/dist/{chunk-G5NZGPTB.js.map → chunk-CA2T7QT4.js.map} +0 -0
- /package/dist/{chunk-ZBICMU4Z.js.map → chunk-D534PIXF.js.map} +0 -0
- /package/dist/{chunk-CREM7YRK.js.map → chunk-LEBDXYMA.js.map} +0 -0
- /package/dist/{chunk-YVH2PH4X.js.map → chunk-MXV5O25O.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/transcription.ts"],"sourcesContent":["/**\n * Framework- and transport-agnostic speech-to-text capability contract.\n *\n * Audio transport, microphone access, credentials, and provider SDKs belong to\n * host-supplied adapters. This module deliberately contains no browser globals\n * and no provider implementation.\n */\n\nimport type { WorkspaceVoiceInputSettings } from \"./types\";\n\nexport type TranscriptionCredentialMode = \"managed\" | \"byok\";\n\nexport type WorkspaceTranscriptionTarget = {\n provider: string;\n model: string | null;\n credentialMode: TranscriptionCredentialMode;\n /** Workspace-scoped connection reference. This is never a secret. */\n credentialConnectionId: string | null;\n region: string | null;\n};\n\nexport type WorkspaceTranscriptionPolicy = {\n enabled: boolean;\n /** Exact admin-accepted policy identity; required whenever enabled. */\n acceptanceId: string | null;\n primary: WorkspaceTranscriptionTarget | null;\n /** Explicit language preference. Required when automatic detection is not accepted. */\n language: string | null;\n /** Whether the accepted adapter may automatically detect the spoken language. */\n autoDetectLanguage: boolean;\n /** Whether the accepted adapter may identify distinct speakers. */\n diarization: {\n enabled: boolean;\n maxSpeakers: number | null;\n };\n retention: {\n mode: \"none\" | \"provider-policy\";\n maxDays: number | null;\n };\n privacy: {\n allowProviderLogging: boolean;\n allowProviderTraining: boolean;\n };\n fallback: {\n mode: \"disabled\" | \"explicit\";\n targets: WorkspaceTranscriptionTarget[];\n };\n cost: {\n currency: \"USD\";\n maxPerHour: number | null;\n maxPerMonth: number | null;\n };\n};\n\nexport const DEFAULT_WORKSPACE_TRANSCRIPTION_POLICY: WorkspaceTranscriptionPolicy = {\n enabled: false,\n acceptanceId: null,\n primary: null,\n language: null,\n autoDetectLanguage: false,\n diarization: { enabled: false, maxSpeakers: null },\n retention: { mode: \"none\", maxDays: null },\n privacy: { allowProviderLogging: false, allowProviderTraining: false },\n fallback: { mode: \"disabled\", targets: [] },\n cost: { currency: \"USD\", maxPerHour: null, maxPerMonth: null },\n};\n\nexport type TranscriptionAdapterDescriptor = {\n provider: string;\n model: string | null;\n credentialMode: TranscriptionCredentialMode;\n region: string | null;\n};\n\nexport type TranscriptionTargetSelection =\n | { kind: \"primary\" }\n | { kind: \"fallback\"; index: number };\n\nexport type TranscriptionPolicyBlockReason =\n | \"disabled\"\n | \"unaccepted\"\n | \"target_missing\"\n | \"fallback_disabled\"\n | \"fallback_unaccepted\"\n | \"provider_mismatch\"\n | \"model_mismatch\"\n | \"credential_mode_mismatch\"\n | \"region_mismatch\";\n\nexport type TranscriptionAuthorization =\n | {\n authorized: true;\n acceptanceId: string;\n target: WorkspaceTranscriptionTarget;\n selection: TranscriptionTargetSelection;\n }\n | { authorized: false; reason: TranscriptionPolicyBlockReason };\n\nexport type TranscriptionLifecycleStatus =\n | \"idle\"\n | \"requesting-permission\"\n | \"listening\"\n | \"reconnecting\"\n | \"cancelling\"\n | \"closed\"\n | \"error\";\n\nexport type TranscriptionErrorCode =\n | \"insufficient_credits\"\n | \"allowance_exhausted\"\n | \"monthly_model_cost_limit\"\n | \"permission_denied\"\n | \"not_supported\"\n | \"network\"\n | \"provider\"\n | \"policy_blocked\"\n | \"timeout\"\n | \"cancelled\"\n | \"unavailable\"\n | \"too_large\"\n | \"invalid_audio\"\n | \"unknown\";\n\n/** Native browser voice input defaults to the configured deployment capability. */\nexport function resolveWorkspaceVoiceInputEnabled(settings: unknown): boolean | null {\n if (!isRecord(settings)) return null;\n const voiceInput = settings.voiceInput;\n if (isRecord(voiceInput) && typeof voiceInput.enabled === \"boolean\") {\n return (voiceInput as WorkspaceVoiceInputSettings).enabled;\n }\n const legacy = settings.transcription;\n return isRecord(legacy) && typeof legacy.enabled === \"boolean\" ? legacy.enabled : null;\n}\n\nexport type TranscriptionTimeSpan = {\n startMilliseconds: number;\n endMilliseconds: number;\n};\n\nexport type TranscriptionSpeaker = {\n /** Provider-neutral identity stable within the local transcription session. */\n id: string;\n label?: string | undefined;\n};\n\nexport type TranscriptionWord = {\n text: string;\n span: TranscriptionTimeSpan;\n confidence?: number | undefined;\n speaker?: TranscriptionSpeaker | undefined;\n};\n\n/** Optional result detail; adapters omit fields their provider cannot supply. */\nexport type TranscriptionResultMetadata = {\n detectedLanguage?: string | undefined;\n span?: TranscriptionTimeSpan | undefined;\n confidence?: number | undefined;\n speaker?: TranscriptionSpeaker | undefined;\n words?: TranscriptionWord[] | undefined;\n};\n\nexport type TranscriptionDiagnostic = {\n operation: \"start\" | \"session\" | \"cancel\" | \"close\";\n code: TranscriptionErrorCode;\n /** Exact diagnostic detail forwarded by React without content rewriting. */\n detail: string;\n};\n\ntype TranscriptionEventBase = {\n /** Stable across reconnects and explicitly accepted fallback attempts. */\n localSessionId: string;\n /** Adapter-monotonic across the entire local session, including replay. */\n sequence: number;\n occurredAt: string;\n};\n\nexport type TranscriptionEvent =\n | (TranscriptionEventBase & { type: \"permission.requested\" })\n | (TranscriptionEventBase & {\n type: \"session.opened\";\n providerSessionId: string;\n })\n | (TranscriptionEventBase & {\n type: \"transcript.partial\";\n segmentId: string;\n text: string;\n metadata?: TranscriptionResultMetadata | undefined;\n })\n | (TranscriptionEventBase & {\n type: \"transcript.final\";\n segmentId: string;\n text: string;\n /** Stable provider/coordinator acceptance identity used for dedupe. */\n providerAcceptanceId: string;\n metadata?: TranscriptionResultMetadata | undefined;\n })\n | (TranscriptionEventBase & {\n type: \"usage\";\n audioMilliseconds: number;\n costUsd: number | null;\n })\n | (TranscriptionEventBase & {\n type: \"session.reconnecting\";\n attempt: number;\n reason: string;\n })\n | (TranscriptionEventBase & {\n type: \"session.error\";\n code: TranscriptionErrorCode;\n recoverable: boolean;\n })\n | (TranscriptionEventBase & {\n type: \"session.closed\";\n reason: \"completed\" | \"cancelled\" | \"error\" | \"replaced\";\n });\n\nexport type TranscriptionSessionRequest = {\n localSessionId: string;\n policyAcceptanceId: string;\n selection: TranscriptionTargetSelection;\n target: WorkspaceTranscriptionTarget;\n language: string | null;\n autoDetectLanguage: boolean;\n diarization: WorkspaceTranscriptionPolicy[\"diarization\"];\n retention: WorkspaceTranscriptionPolicy[\"retention\"];\n privacy: WorkspaceTranscriptionPolicy[\"privacy\"];\n cost: WorkspaceTranscriptionPolicy[\"cost\"];\n /** A replacement/reconnect adapter must emit events above this floor. */\n sequenceFloor: number;\n};\n\nexport type TranscriptionEventListener = (event: TranscriptionEvent) => void;\n\nexport type TranscriptionAdapterStartContext = {\n /** Aborted on local cancellation, policy replacement, timeout, or unmount. */\n signal: AbortSignal;\n /** Non-UI observability seam; callers receive the exact provider detail. */\n reportDiagnostic: (diagnostic: TranscriptionDiagnostic) => void;\n};\n\nexport type TranscriptionSession = {\n readonly localSessionId: string;\n cancel(reason?: string): Promise<void>;\n close(): Promise<void>;\n};\n\nexport type TranscriptionAdapter = {\n readonly descriptor: TranscriptionAdapterDescriptor;\n start(\n request: TranscriptionSessionRequest,\n listener: TranscriptionEventListener,\n context: TranscriptionAdapterStartContext,\n ): Promise<TranscriptionSession>;\n};\n\n/** Invalid or absent settings always resolve to the fail-closed default. */\nexport function resolveWorkspaceTranscriptionPolicy(\n settings: unknown,\n): WorkspaceTranscriptionPolicy {\n if (!isRecord(settings)) return cloneDefaultPolicy();\n const candidate = settings.transcription;\n if (!isWorkspaceTranscriptionPolicy(candidate)) return cloneDefaultPolicy();\n return {\n ...candidate,\n primary: candidate.primary ? normalizeTarget(candidate.primary) : null,\n language: candidate.language?.trim() ?? null,\n diarization: { ...candidate.diarization },\n retention: { ...candidate.retention },\n privacy: { ...candidate.privacy },\n fallback: {\n mode: candidate.fallback.mode,\n targets: candidate.fallback.targets.map(normalizeTarget),\n },\n cost: { ...candidate.cost },\n };\n}\n\n/**\n * Speech authorization is intentionally independent from turn model policy.\n * Every selected adapter must match one exact admin-accepted target.\n */\nexport function authorizeTranscriptionAdapter(\n policy: WorkspaceTranscriptionPolicy,\n descriptor: TranscriptionAdapterDescriptor,\n selection: TranscriptionTargetSelection = { kind: \"primary\" },\n): TranscriptionAuthorization {\n if (!isWorkspaceTranscriptionPolicy(policy)) {\n return { authorized: false, reason: \"unaccepted\" };\n }\n if (!policy.enabled) return { authorized: false, reason: \"disabled\" };\n if (!policy.acceptanceId) return { authorized: false, reason: \"unaccepted\" };\n let target: WorkspaceTranscriptionTarget | null | undefined;\n if (selection.kind === \"primary\") {\n target = policy.primary;\n } else {\n if (policy.fallback.mode !== \"explicit\") {\n return { authorized: false, reason: \"fallback_disabled\" };\n }\n target = policy.fallback.targets[selection.index];\n if (!target) return { authorized: false, reason: \"fallback_unaccepted\" };\n }\n if (!target) return { authorized: false, reason: \"target_missing\" };\n const acceptedTarget = normalizeTarget(target);\n if (acceptedTarget.provider !== descriptor.provider) {\n return { authorized: false, reason: \"provider_mismatch\" };\n }\n if (acceptedTarget.model !== descriptor.model) {\n return { authorized: false, reason: \"model_mismatch\" };\n }\n if (acceptedTarget.credentialMode !== descriptor.credentialMode) {\n return { authorized: false, reason: \"credential_mode_mismatch\" };\n }\n if (acceptedTarget.region !== descriptor.region) {\n return { authorized: false, reason: \"region_mismatch\" };\n }\n return {\n authorized: true,\n acceptanceId: policy.acceptanceId,\n target: acceptedTarget,\n selection,\n };\n}\n\nexport function createTranscriptionSessionRequest(input: {\n policy: WorkspaceTranscriptionPolicy;\n adapter: TranscriptionAdapter;\n localSessionId: string;\n selection?: TranscriptionTargetSelection | undefined;\n sequenceFloor?: number | undefined;\n}): TranscriptionSessionRequest | null {\n const sequenceFloor = input.sequenceFloor ?? 0;\n if (!Number.isSafeInteger(sequenceFloor) || sequenceFloor < 0) return null;\n const authorization = authorizeTranscriptionAdapter(\n input.policy,\n input.adapter.descriptor,\n input.selection,\n );\n if (!authorization.authorized) return null;\n return {\n localSessionId: input.localSessionId,\n policyAcceptanceId: authorization.acceptanceId,\n selection: authorization.selection,\n target: { ...authorization.target },\n language: input.policy.language?.trim() ?? null,\n autoDetectLanguage: input.policy.autoDetectLanguage,\n diarization: { ...input.policy.diarization },\n retention: { ...input.policy.retention },\n privacy: { ...input.policy.privacy },\n cost: { ...input.policy.cost },\n sequenceFloor,\n };\n}\n\nfunction cloneDefaultPolicy(): WorkspaceTranscriptionPolicy {\n return {\n ...DEFAULT_WORKSPACE_TRANSCRIPTION_POLICY,\n diarization: { ...DEFAULT_WORKSPACE_TRANSCRIPTION_POLICY.diarization },\n retention: { ...DEFAULT_WORKSPACE_TRANSCRIPTION_POLICY.retention },\n privacy: { ...DEFAULT_WORKSPACE_TRANSCRIPTION_POLICY.privacy },\n fallback: { mode: \"disabled\", targets: [] },\n cost: { ...DEFAULT_WORKSPACE_TRANSCRIPTION_POLICY.cost },\n };\n}\n\nfunction isWorkspaceTranscriptionPolicy(value: unknown): value is WorkspaceTranscriptionPolicy {\n if (!isRecord(value) || typeof value.enabled !== \"boolean\") return false;\n if (\n !hasOnlyKeys(value, [\n \"enabled\",\n \"acceptanceId\",\n \"primary\",\n \"language\",\n \"autoDetectLanguage\",\n \"diarization\",\n \"retention\",\n \"privacy\",\n \"fallback\",\n \"cost\",\n ])\n ) {\n return false;\n }\n if (!(value.acceptanceId === null || isUuid(value.acceptanceId))) return false;\n if (!(value.primary === null || isTarget(value.primary))) return false;\n if (!(value.language === null || isBoundedString(value.language, 64))) return false;\n if (typeof value.autoDetectLanguage !== \"boolean\") return false;\n if (\n !isRecord(value.diarization) ||\n !hasOnlyKeys(value.diarization, [\"enabled\", \"maxSpeakers\"]) ||\n typeof value.diarization.enabled !== \"boolean\" ||\n !(\n value.diarization.maxSpeakers === null ||\n (isBoundedInteger(value.diarization.maxSpeakers, 100) && value.diarization.maxSpeakers >= 2)\n )\n ) {\n return false;\n }\n if (!value.diarization.enabled && value.diarization.maxSpeakers !== null) return false;\n if (!isRecord(value.retention) || !hasOnlyKeys(value.retention, [\"mode\", \"maxDays\"])) {\n return false;\n }\n if (value.retention.mode !== \"none\" && value.retention.mode !== \"provider-policy\") return false;\n if (!(value.retention.maxDays === null || isBoundedInteger(value.retention.maxDays, 3650))) {\n return false;\n }\n if (\n !isRecord(value.privacy) ||\n !hasOnlyKeys(value.privacy, [\"allowProviderLogging\", \"allowProviderTraining\"]) ||\n typeof value.privacy.allowProviderLogging !== \"boolean\" ||\n typeof value.privacy.allowProviderTraining !== \"boolean\"\n ) {\n return false;\n }\n if (!isRecord(value.fallback) || !hasOnlyKeys(value.fallback, [\"mode\", \"targets\"])) {\n return false;\n }\n if (value.fallback.mode !== \"disabled\" && value.fallback.mode !== \"explicit\") return false;\n if (\n !Array.isArray(value.fallback.targets) ||\n value.fallback.targets.length > 8 ||\n !value.fallback.targets.every(isTarget)\n ) {\n return false;\n }\n if (value.fallback.mode === \"disabled\" && value.fallback.targets.length !== 0) return false;\n if (value.fallback.mode === \"explicit\" && value.fallback.targets.length === 0) return false;\n if (\n !isRecord(value.cost) ||\n !hasOnlyKeys(value.cost, [\"currency\", \"maxPerHour\", \"maxPerMonth\"]) ||\n value.cost.currency !== \"USD\"\n ) {\n return false;\n }\n if (!isNullableBoundedNumber(value.cost.maxPerHour, 10_000)) return false;\n if (!isNullableBoundedNumber(value.cost.maxPerMonth, 1_000_000)) return false;\n if (value.enabled && (!value.acceptanceId || !value.primary)) return false;\n if (value.enabled && !value.autoDetectLanguage && value.language === null) return false;\n if (value.autoDetectLanguage && value.language !== null) return false;\n const targets = [value.primary, ...value.fallback.targets].filter(\n (target): target is WorkspaceTranscriptionTarget => target !== null,\n );\n if (new Set(targets.map(targetKey)).size !== targets.length) return false;\n return true;\n}\n\nfunction targetKey(target: WorkspaceTranscriptionTarget): string {\n return [\n target.provider.trim(),\n target.model?.trim() ?? \"\",\n target.credentialMode,\n target.credentialConnectionId ?? \"\",\n target.region?.trim() ?? \"\",\n ].join(\"\\u0000\");\n}\n\nfunction isTarget(value: unknown): value is WorkspaceTranscriptionTarget {\n if (!isRecord(value)) return false;\n if (\n !hasOnlyKeys(value, [\"provider\", \"model\", \"credentialMode\", \"credentialConnectionId\", \"region\"])\n ) {\n return false;\n }\n if (!isBoundedString(value.provider, 128)) return false;\n if (!(value.model === null || isBoundedString(value.model, 256))) return false;\n if (value.credentialMode !== \"managed\" && value.credentialMode !== \"byok\") return false;\n if (value.provider.trim() === \"azure-speech\" && value.credentialMode !== \"byok\") return false;\n if (!(value.credentialConnectionId === null || isUuid(value.credentialConnectionId))) {\n return false;\n }\n if (!(value.region === null || isBoundedString(value.region, 128))) return false;\n if (value.credentialMode === \"byok\" && value.credentialConnectionId === null) return false;\n if (value.credentialMode === \"managed\" && value.credentialConnectionId !== null) return false;\n return true;\n}\n\nfunction normalizeTarget(target: WorkspaceTranscriptionTarget): WorkspaceTranscriptionTarget {\n return {\n provider: target.provider.trim(),\n model: target.model?.trim() ?? null,\n credentialMode: target.credentialMode,\n credentialConnectionId: target.credentialConnectionId,\n region: target.region?.trim() ?? null,\n };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction hasOnlyKeys(value: Record<string, unknown>, keys: readonly string[]): boolean {\n const accepted = new Set(keys);\n return Object.keys(value).every((key) => accepted.has(key));\n}\n\nfunction isBoundedString(value: unknown, maximum: number): value is string {\n return typeof value === \"string\" && value.trim().length > 0 && value.length <= maximum;\n}\n\nfunction isUuid(value: unknown): value is string {\n return (\n typeof value === \"string\" &&\n /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value)\n );\n}\n\nfunction isBoundedInteger(value: unknown, maximum: number): value is number {\n return Number.isInteger(value) && (value as number) >= 0 && (value as number) <= maximum;\n}\n\nfunction isNullableBoundedNumber(value: unknown, maximum: number): boolean {\n return (\n value === null ||\n (typeof value === \"number\" && Number.isFinite(value) && value >= 0 && value <= maximum)\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-4SMEOV3P.js";
|
|
4
4
|
import {
|
|
5
5
|
OpenGeniClient
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-BVIIRSJY.js";
|
|
7
7
|
import {
|
|
8
8
|
OpenGeniApiError
|
|
9
9
|
} from "./chunk-V6GIY62B.js";
|
|
@@ -636,4 +636,4 @@ export {
|
|
|
636
636
|
isOpenGeniSiteBridgeCancelMessage,
|
|
637
637
|
sanitizeOpenGeniSiteToolCallRequest
|
|
638
638
|
};
|
|
639
|
-
//# sourceMappingURL=chunk-
|
|
639
|
+
//# sourceMappingURL=chunk-LEBDXYMA.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
OpenGeniDocumentAuthorityClient
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-CA2T7QT4.js";
|
|
4
4
|
|
|
5
5
|
// src/artifact-client.ts
|
|
6
6
|
var OpenGeniClient = class extends OpenGeniDocumentAuthorityClient {
|
|
@@ -121,4 +121,4 @@ var OpenGeniClient = class extends OpenGeniDocumentAuthorityClient {
|
|
|
121
121
|
export {
|
|
122
122
|
OpenGeniClient
|
|
123
123
|
};
|
|
124
|
-
//# sourceMappingURL=chunk-
|
|
124
|
+
//# sourceMappingURL=chunk-MXV5O25O.js.map
|
|
@@ -91,7 +91,7 @@ function parseCodexRealtimeV3Event(payload) {
|
|
|
91
91
|
}
|
|
92
92
|
};
|
|
93
93
|
}
|
|
94
|
-
if (type === "turn.done") {
|
|
94
|
+
if (type === "turn.done" || type === "transcript.segment") {
|
|
95
95
|
const turn = record(event.turn);
|
|
96
96
|
const turnIdField = boundedStringField(turn, "id", CODEX_REALTIME_V3_MAX_IDENTIFIER_BYTES);
|
|
97
97
|
const transcriptField = boundedStringField(
|
|
@@ -395,6 +395,10 @@ function createCodexRealtimeV3Bridge(options) {
|
|
|
395
395
|
clientAckThroughSequence = Math.max(clientAckThroughSequence ?? 0, entry.sequence);
|
|
396
396
|
}
|
|
397
397
|
}
|
|
398
|
+
if (options.events.readyState !== "open") {
|
|
399
|
+
publish();
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
398
402
|
for (let index = 0; index < result.outbound.length; ) {
|
|
399
403
|
const entry = result.outbound[index];
|
|
400
404
|
if (sentSequences.has(entry.sequence)) {
|
|
@@ -539,7 +543,7 @@ function createCodexRealtimeV3Bridge(options) {
|
|
|
539
543
|
}
|
|
540
544
|
} else if (event.type === "output_audio.delta") {
|
|
541
545
|
speaking = true;
|
|
542
|
-
} else if (event.type === "turn.done") {
|
|
546
|
+
} else if (event.type === "turn.done" || event.type === "transcript.segment") {
|
|
543
547
|
speaking = false;
|
|
544
548
|
if (event.transcript.length > 0 && !finalizedTurnIds.has(event.turnId)) {
|
|
545
549
|
const coveredByDelegationItemId = event.role === "user" && pendingDelegationUserTranscript !== null && normalizedTranscript(event.transcript) === normalizedTranscript(pendingDelegationUserTranscript.text) ? pendingDelegationUserTranscript.delegationItemId : null;
|
|
@@ -610,6 +614,7 @@ function finalTranscript(randomUUID, event, coveredByDelegationItemId, modelCont
|
|
|
610
614
|
text: event.transcript,
|
|
611
615
|
payload: {
|
|
612
616
|
turnId: event.turnId,
|
|
617
|
+
...event.type === "transcript.segment" ? { transcriptSource: "provider_fragments", grouping: "application_segment" } : {},
|
|
613
618
|
...coveredByDelegationItemId ? { coveredByDelegationItemId } : {}
|
|
614
619
|
},
|
|
615
620
|
...modelContext ? { modelContext } : {}
|
|
@@ -872,7 +877,7 @@ async function startCodexRealtimeWebrtc(options) {
|
|
|
872
877
|
{ signal: options.signal }
|
|
873
878
|
);
|
|
874
879
|
throwIfAborted(options.signal);
|
|
875
|
-
if (answer.version !== "v3" || answer.model !== "gpt-live-1-boulder-alpha" || !answer.sdp) {
|
|
880
|
+
if (answer.version !== "v3" || answer.model !== (options.expectedModel ?? "gpt-live-1-boulder-alpha") || !answer.sdp) {
|
|
876
881
|
throw new Error("Opengeni returned an incompatible Codex realtime answer");
|
|
877
882
|
}
|
|
878
883
|
await peerConnection.setRemoteDescription({
|
|
@@ -1093,7 +1098,30 @@ var SESSION_REALTIME_INBOUND_KINDS = /* @__PURE__ */ new Set([
|
|
|
1093
1098
|
"error"
|
|
1094
1099
|
]);
|
|
1095
1100
|
var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu;
|
|
1101
|
+
var REALTIME_REFUSAL_CODES = /* @__PURE__ */ new Set([
|
|
1102
|
+
"insufficient_credits",
|
|
1103
|
+
"allowance_exhausted",
|
|
1104
|
+
"monthly_model_cost_limit",
|
|
1105
|
+
"realtime_voice_unavailable"
|
|
1106
|
+
]);
|
|
1107
|
+
function codexRealtimeRefusal(error) {
|
|
1108
|
+
if (!(error instanceof OpenGeniApiError) || !error.code) return null;
|
|
1109
|
+
if (!REALTIME_REFUSAL_CODES.has(error.code)) return null;
|
|
1110
|
+
let message = null;
|
|
1111
|
+
try {
|
|
1112
|
+
const body = JSON.parse(error.body);
|
|
1113
|
+
const nested = body.error && typeof body.error === "object" ? body.error : body;
|
|
1114
|
+
message = typeof nested.message === "string" && nested.message ? nested.message : null;
|
|
1115
|
+
} catch {
|
|
1116
|
+
message = null;
|
|
1117
|
+
}
|
|
1118
|
+
return {
|
|
1119
|
+
code: error.code,
|
|
1120
|
+
message: message ?? (error.code === "insufficient_credits" ? "Live voice needs Opengeni credits. Add credits to continue." : "Live voice is unavailable right now.")
|
|
1121
|
+
};
|
|
1122
|
+
}
|
|
1096
1123
|
function sessionRealtimeOwnerStorageNamespace(model) {
|
|
1124
|
+
if (model === "opengeni-azure/gpt-live-1") return "azure-live-owner";
|
|
1097
1125
|
if (model === "gpt-live-1-boulder-alpha") return "codex-realtime-owner";
|
|
1098
1126
|
if (model === "supergrok/grok-voice-think-fast-2.0") return "xai-realtime-owner";
|
|
1099
1127
|
return "gateway-realtime-owner";
|
|
@@ -1151,7 +1179,8 @@ function createCodexRealtimeController(options) {
|
|
|
1151
1179
|
connectionGeneration: 0,
|
|
1152
1180
|
reconnectAttempt: 0,
|
|
1153
1181
|
diagnostic: null,
|
|
1154
|
-
error: null
|
|
1182
|
+
error: null,
|
|
1183
|
+
refusal: null
|
|
1155
1184
|
};
|
|
1156
1185
|
let active = null;
|
|
1157
1186
|
let pendingAbort = null;
|
|
@@ -1439,6 +1468,11 @@ function createCodexRealtimeController(options) {
|
|
|
1439
1468
|
transitionEnded("Realtime owner no longer exists");
|
|
1440
1469
|
return;
|
|
1441
1470
|
}
|
|
1471
|
+
const refusal = codexRealtimeRefusal(error);
|
|
1472
|
+
if (refusal) {
|
|
1473
|
+
await endForRefusal(refusal);
|
|
1474
|
+
return;
|
|
1475
|
+
}
|
|
1442
1476
|
if (error instanceof OpenGeniApiError && error.status === 409 && error.retryable && owner) {
|
|
1443
1477
|
try {
|
|
1444
1478
|
const reconciled = await begin(owner, true, false);
|
|
@@ -1574,6 +1608,13 @@ function createCodexRealtimeController(options) {
|
|
|
1574
1608
|
});
|
|
1575
1609
|
let connected;
|
|
1576
1610
|
try {
|
|
1611
|
+
if (active?.transport.drain) {
|
|
1612
|
+
await active.transport.drain();
|
|
1613
|
+
await active.bridge.flush();
|
|
1614
|
+
}
|
|
1615
|
+
if (closed || stopping || abort.signal.aborted || pendingGeneration !== targetGeneration) {
|
|
1616
|
+
throw abort.signal.reason ?? new DOMException("Aborted", "AbortError");
|
|
1617
|
+
}
|
|
1577
1618
|
const media = await ensureMicrophone(replaceMicrophone, abort.signal);
|
|
1578
1619
|
const operationId = randomUUID();
|
|
1579
1620
|
const commonTransportInput = {
|
|
@@ -1759,6 +1800,7 @@ function createCodexRealtimeController(options) {
|
|
|
1759
1800
|
return response.mode;
|
|
1760
1801
|
};
|
|
1761
1802
|
const heartbeat = async () => {
|
|
1803
|
+
let stopInstruction = null;
|
|
1762
1804
|
await exclusive(async () => {
|
|
1763
1805
|
const current = state.mode;
|
|
1764
1806
|
if (!owner || !current || current.state !== "active") {
|
|
@@ -1779,6 +1821,29 @@ function createCodexRealtimeController(options) {
|
|
|
1779
1821
|
return;
|
|
1780
1822
|
}
|
|
1781
1823
|
publish({ mode: result.mode, realtimeId: result.mode.id, error: null });
|
|
1824
|
+
stopInstruction = result.stop ?? null;
|
|
1825
|
+
});
|
|
1826
|
+
const instruction = stopInstruction;
|
|
1827
|
+
stopInstruction = null;
|
|
1828
|
+
if (instruction && !stopping && !closed) await endForRefusal(instruction);
|
|
1829
|
+
};
|
|
1830
|
+
const endForRefusal = async (refusal) => {
|
|
1831
|
+
try {
|
|
1832
|
+
await controller.stop();
|
|
1833
|
+
} catch {
|
|
1834
|
+
stopping = false;
|
|
1835
|
+
closeBrowserResources();
|
|
1836
|
+
clearOwner();
|
|
1837
|
+
}
|
|
1838
|
+
recoveryTerminal = false;
|
|
1839
|
+
publish({
|
|
1840
|
+
status: "error",
|
|
1841
|
+
realtimeId: null,
|
|
1842
|
+
mode: null,
|
|
1843
|
+
bridge: null,
|
|
1844
|
+
diagnostic: diagnostic("terminal_stop", refusal.message, false),
|
|
1845
|
+
error: refusal.message,
|
|
1846
|
+
refusal
|
|
1782
1847
|
});
|
|
1783
1848
|
};
|
|
1784
1849
|
const flush = async () => {
|
|
@@ -1838,11 +1903,12 @@ function createCodexRealtimeController(options) {
|
|
|
1838
1903
|
};
|
|
1839
1904
|
owner = record2;
|
|
1840
1905
|
storage?.setItem(storageKey, JSON.stringify(record2));
|
|
1841
|
-
publish({ status: "starting", error: null, diagnostic: null });
|
|
1906
|
+
publish({ status: "starting", error: null, diagnostic: null, refusal: null });
|
|
1842
1907
|
try {
|
|
1843
1908
|
await begin(record2, false);
|
|
1844
1909
|
} catch (error) {
|
|
1845
1910
|
closeBrowserResources(false);
|
|
1911
|
+
const refusal = codexRealtimeRefusal(error);
|
|
1846
1912
|
const failedMode = state.mode;
|
|
1847
1913
|
if (failedMode?.state === "active") {
|
|
1848
1914
|
await handleConnectionFailure(error, "reconnect", false);
|
|
@@ -1852,9 +1918,11 @@ function createCodexRealtimeController(options) {
|
|
|
1852
1918
|
status: "error",
|
|
1853
1919
|
realtimeId: null,
|
|
1854
1920
|
mode: null,
|
|
1855
|
-
error: safeError2(error)
|
|
1921
|
+
error: refusal?.message ?? safeError2(error),
|
|
1922
|
+
...refusal ? { refusal, diagnostic: diagnostic("terminal_stop", refusal.message, false) } : {}
|
|
1856
1923
|
});
|
|
1857
1924
|
}
|
|
1925
|
+
if (refusal) return;
|
|
1858
1926
|
throw error;
|
|
1859
1927
|
}
|
|
1860
1928
|
},
|
|
@@ -1979,6 +2047,7 @@ function createCodexRealtimeController(options) {
|
|
|
1979
2047
|
connectionTask = null;
|
|
1980
2048
|
void retiredTask?.catch(() => void 0);
|
|
1981
2049
|
try {
|
|
2050
|
+
await active?.transport.drain?.();
|
|
1982
2051
|
await active?.bridge.sealAndFlush();
|
|
1983
2052
|
closeBrowserResources();
|
|
1984
2053
|
let current = state.mode;
|
|
@@ -2273,9 +2342,10 @@ export {
|
|
|
2273
2342
|
createCodexRealtimeV3Bridge,
|
|
2274
2343
|
projectSessionRealtimeLifecycle,
|
|
2275
2344
|
CODEX_REALTIME_NEGOTIATION_TIMEOUT_MS,
|
|
2345
|
+
codexRealtimeRefusal,
|
|
2276
2346
|
sessionRealtimeOwnerStorageNamespace,
|
|
2277
2347
|
sessionRealtimeOwnerStorageKey,
|
|
2278
2348
|
hasStoredSessionRealtimeOwnerProof,
|
|
2279
2349
|
createCodexRealtimeController
|
|
2280
2350
|
};
|
|
2281
|
-
//# sourceMappingURL=chunk-
|
|
2351
|
+
//# sourceMappingURL=chunk-ZNC44QEX.js.map
|