@agimon-ai/po-voice 0.0.0-alpha.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/LICENSE +21 -0
- package/NOTICE +13 -0
- package/README.md +249 -0
- package/dist/apiContracts.cjs +809 -0
- package/dist/apiContracts.cjs.map +1 -0
- package/dist/apiContracts.d.mts +53 -0
- package/dist/apiContracts.d.mts.map +1 -0
- package/dist/apiContracts.mjs +805 -0
- package/dist/apiContracts.mjs.map +1 -0
- package/dist/assets/browserCaptureWorklet-Droj0fW0.js +13 -0
- package/dist/assets/silero_vad_v6.2.1-SjbCxFXk.onnx +0 -0
- package/dist/clientCaptureActivity-DN4xQtmw.d.mts +234 -0
- package/dist/clientCaptureActivity-DN4xQtmw.d.mts.map +1 -0
- package/dist/clientMedia-CfTfc9_4.mjs +49 -0
- package/dist/clientMedia-CfTfc9_4.mjs.map +1 -0
- package/dist/clientMedia-DuA4aYhD.cjs +156 -0
- package/dist/clientMedia-DuA4aYhD.cjs.map +1 -0
- package/dist/clientMedia.cjs +134 -0
- package/dist/clientMedia.cjs.map +1 -0
- package/dist/clientMedia.d.mts +2 -0
- package/dist/clientMedia.mjs +114 -0
- package/dist/clientMedia.mjs.map +1 -0
- package/dist/extensions/server.cjs +8975 -0
- package/dist/extensions/server.cjs.map +1 -0
- package/dist/extensions/server.d.mts +5 -0
- package/dist/extensions/server.d.mts.map +1 -0
- package/dist/extensions/server.mjs +8968 -0
- package/dist/extensions/server.mjs.map +1 -0
- package/dist/extensions/web.mjs +4530 -0
- package/dist/extensions/web.mjs.map +1 -0
- package/dist/index-C95HCjmT.d.mts +212 -0
- package/dist/index-C95HCjmT.d.mts.map +1 -0
- package/dist/index.cjs +637 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.mts +603 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +557 -0
- package/dist/index.mjs.map +1 -0
- package/dist/narrationBargeIn-C_Po8fgw.mjs +62 -0
- package/dist/narrationBargeIn-C_Po8fgw.mjs.map +1 -0
- package/dist/narrationBargeIn-Dje82XOm.cjs +73 -0
- package/dist/narrationBargeIn-Dje82XOm.cjs.map +1 -0
- package/dist/sileroVadWorker-D894njUe.mjs +110 -0
- package/dist/sileroVadWorker-D894njUe.mjs.map +1 -0
- package/dist/vad-DDe4RIdW.mjs +315 -0
- package/dist/vad-DDe4RIdW.mjs.map +1 -0
- package/dist/vad-n2RlruzB.cjs +332 -0
- package/dist/vad-n2RlruzB.cjs.map +1 -0
- package/dist/voiceReloadHandoff.cjs +9 -0
- package/dist/voiceReloadHandoff.d.mts +1 -0
- package/dist/voiceReloadHandoff.mjs +2 -0
- package/dist/voiceTools-CRQHK_Uc.cjs +616 -0
- package/dist/voiceTools-CRQHK_Uc.cjs.map +1 -0
- package/dist/voiceTools-aCCREMjS.mjs +611 -0
- package/dist/voiceTools-aCCREMjS.mjs.map +1 -0
- package/dist/voiceTools.cjs +12 -0
- package/dist/voiceTools.d.mts +7 -0
- package/dist/voiceTools.d.mts.map +1 -0
- package/dist/voiceTools.mjs +3 -0
- package/dist/voiceWorker.cjs +1929 -0
- package/dist/voiceWorker.cjs.map +1 -0
- package/dist/voiceWorker.d.mts +200 -0
- package/dist/voiceWorker.d.mts.map +1 -0
- package/dist/voiceWorker.mjs +1925 -0
- package/dist/voiceWorker.mjs.map +1 -0
- package/dist/voiceWorkerProtocol-0H3czPjt.cjs +2385 -0
- package/dist/voiceWorkerProtocol-0H3czPjt.cjs.map +1 -0
- package/dist/voiceWorkerProtocol-B_4B2_fR.mjs +2085 -0
- package/dist/voiceWorkerProtocol-B_4B2_fR.mjs.map +1 -0
- package/dist/voiceWorkerSessionController-DaYemiL3.cjs +1800 -0
- package/dist/voiceWorkerSessionController-DaYemiL3.cjs.map +1 -0
- package/dist/voiceWorkerSessionController-GB3SJ6YE.mjs +1734 -0
- package/dist/voiceWorkerSessionController-GB3SJ6YE.mjs.map +1 -0
- package/licenses/Codex-Apache-2.0.txt +201 -0
- package/llms.txt +9 -0
- package/package.json +153 -0
- package/src/extensions/workspaces/sessions/(frontend)/lifecycle/_lib/models/README.md +11 -0
- package/src/extensions/workspaces/sessions/(frontend)/lifecycle/_lib/models/SILERO-LICENSE +21 -0
- package/src/prompts/po-use-voice/SKILL.md +35 -0
- package/src/types/clientCaptureActivity.ts +155 -0
- package/src/types/clientMedia.ts +226 -0
- package/src/types/manualTranscription.ts +53 -0
- package/src/types/realtime.ts +107 -0
- package/src/types/voiceOwnership.ts +315 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiContracts.mjs","names":[],"sources":["../src/schemas/voiceControl.ts","../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineDoomPluginMethod } from '@agimon-ai/po-core/pluginProtocol';\nimport { Type } from 'typebox';\n\nexport const voiceControlMethod = defineDoomPluginMethod({\n service: 'voice',\n method: 'control',\n scope: 'session',\n direction: 'client-to-server',\n input: Type.Object(\n {\n action: Type.Union(\n ['status', 'manual', 'activate', 'deactivate', 'mute', 'unmute', 'interrupt', 'transfer'].map((value) =>\n Type.Literal(value),\n ),\n ),\n target: Type.Optional(Type.Integer({ minimum: 1 })),\n revision: Type.Optional(Type.String({ minLength: 1, maxLength: 128 })),\n },\n { additionalProperties: false },\n ),\n output: Type.Object(\n {\n state: Type.String(),\n mode: Type.String(),\n manual: Type.String(),\n muted: Type.Boolean(),\n error: Type.Optional(Type.String()),\n },\n { additionalProperties: false },\n ),\n});\n","import { defineApiContract, jsonApiResponses, type DoomHttpContract } from '@agimon-ai/po-core/apiContracts';\nimport { Type } from 'typebox';\n\nimport { voiceControlMethod } from './voiceControl';\n\nconst S = Type.String();\nconst N = Type.Number();\nconst B = Type.Boolean();\nconst O = Type.Optional;\nconst values = <T extends string>(items: T[]) => Type.Union(items.map((item) => Type.Literal(item)));\nconst Client = { clientId: S, connectionId: S };\nconst Configuration = Type.Object({\n mode: values(['manual', 'autonomous']),\n activityControl: values(['host', 'client']),\n endpointSilenceMs: O(Type.Integer({ minimum: 250 })),\n});\nconst Playback = { playbackId: S, outcome: values(['completed', 'stopped', 'aborted', 'failed']), error: O(S) };\nconst Sequence = { sequence: N };\nconst Control = values(['mute', 'unmute', 'interrupt']);\nconst Browser = Type.Object({\n connection: values(['connecting', 'connected', 'closed', 'failed']),\n listening: B,\n speaking: B,\n muted: B,\n error: O(S),\n});\nexport const VoiceMediaEventSchema = Type.Union([\n Type.Object({\n ...Sequence,\n type: Type.Literal('capture-start'),\n captureId: S,\n sampleRate: Type.Literal(16000),\n channels: Type.Literal(1),\n bitsPerSample: Type.Literal(16),\n configuration: Configuration,\n }),\n Type.Object({ ...Sequence, type: values(['capture-stop', 'capture-abort']), captureId: S }),\n Type.Object({\n ...Sequence,\n type: Type.Literal('playback-start'),\n playbackId: S,\n text: S,\n delivery: O(values(['client', 'streamed'])),\n voice: O(S),\n rate: O(N),\n }),\n Type.Object({ ...Sequence, type: values(['playback-stop', 'playback-abort']), playbackId: S }),\n Type.Object({ ...Sequence, type: values(['realtime-start', 'realtime-stop']), activationId: S }),\n Type.Object({ ...Sequence, type: Type.Literal('realtime-control'), activationId: S, action: Control }),\n Type.Object({ ...Sequence, type: Type.Literal('realtime-send'), activationId: S, messages: Type.Array(S) }),\n]);\nconst RealtimeEvent = Type.Union([\n Type.Object({ type: Type.Literal('ready') }),\n Type.Object({ type: Type.Literal('transcript'), role: values(['user', 'assistant']), text: S, complete: B }),\n Type.Object({ type: Type.Literal('request'), requestId: S, text: S }),\n Type.Object({ type: Type.Literal('error'), code: S }),\n]);\nconst RealtimeSnapshot = Type.Object({\n activationId: S,\n state: values(['connecting', 'active', 'closed', 'failed']),\n cursor: N,\n events: Type.Array(Type.Object({ sequence: N, event: RealtimeEvent })),\n browser: O(Browser),\n});\nconst Wake = Type.Object({ eventEpoch: S, sequence: N });\nconst GlobalLiveStatus = Type.Object({\n version: Type.Literal(1),\n state: values(['disabled', 'starting', 'active', 'draining', 'shuttingDown']),\n activeSessionId: Type.Union([S, Type.Null()]),\n muted: B,\n error: O(S),\n media: Type.Object({ client: B, realtime: B }),\n});\nconst Version = { version: Type.Literal(3) };\nconst Targets = Type.Array(Type.Object({ handle: S, label: S, order: N }), { maxItems: 32 });\nconst OwnershipAction = values(['catalog', 'prepare', 'activate', 'deactivate', 'readiness', 'fence']);\nconst Acknowledgement = Type.Object({\n ...Version,\n commandId: S,\n action: OwnershipAction,\n ok: B,\n active: B,\n error: O(S),\n});\nconst Command = Type.Object({\n ...Version,\n commandId: S,\n action: OwnershipAction,\n targets: O(Targets),\n catalogRevision: O(S),\n handoffId: O(S),\n controllerId: O(S),\n leaseId: O(S),\n revision: O(N),\n});\nconst Snapshot = Type.Object({\n registration: O(Type.Object({ ...Version, leaseId: S, revision: N, label: S, eligible: B, active: B })),\n targets: Targets,\n catalogRevision: O(S),\n activation: O(Type.Object({ ...Version, requestId: S })),\n handoff: O(Type.Object({ ...Version, requestId: S, handle: S, catalogRevision: S })),\n acknowledgement: O(Acknowledgement),\n});\nconst Errors = Object.fromEntries(\n [400, 404, 409, 410, 413, 415, 429, 500, 502, 503, 504].map((status) => [\n status,\n { description: 'Voice request failed.', schema: Type.Object({ error: S, code: O(S) }) },\n ]),\n);\nconst route = (\n path: string,\n method: 'GET' | 'POST',\n output?: object,\n input?: object,\n query: string[] = [],\n status = 200,\n): DoomHttpContract => ({\n id: `voice.${path.slice(1).replaceAll('/', '.')}`,\n scope: 'session',\n basePath: 'voice-media',\n path,\n method,\n authentication: 'owner',\n description: `Voice media ${path}.`,\n ...(path.startsWith('/host/') || path.startsWith('/hub/')\n ? { availability: 'Internal broker route; requires the host-issued bearer token for this route namespace.' }\n : {}),\n parameters: [\n ...query.map((name) => ({ name, in: 'query' as const, required: !['after', 'wait'].includes(name), schema: S })),\n ...(path.startsWith('/host/') || path.startsWith('/hub/')\n ? [\n {\n name: 'Authorization',\n in: 'header' as const,\n required: true,\n schema: Type.String({ pattern: '^Bearer .+' }),\n },\n ]\n : []),\n ],\n ...(input ? { body: { required: true, contentType: 'application/json', schema: input } } : {}),\n responses: {\n ...Errors,\n [output ? status : 204]: {\n description: output ? 'Voice response.' : 'Accepted with no response body.',\n ...(output ? { schema: output } : {}),\n },\n },\n});\nconst pcm = (path: string, method: 'GET' | 'POST', query: string[]): DoomHttpContract => {\n const result = route(path, method, undefined, undefined, query);\n result.description =\n 'PCM signed 16-bit little-endian, 16000 Hz, mono. Chunks contain complete samples. Activity headers carry state, level, elapsed time, epoch and speech duration. A 204 response carries x-po-capture-state or x-po-playback-state when applicable.';\n if (method === 'POST') result.body = { required: true, contentType: 'application/vnd.po.pcm-s16le', schema: S };\n else result.responses['200'] = { description: 'PCM bytes.', contentType: 'application/vnd.po.pcm-s16le', schema: S };\n return result;\n};\nexport const apiContracts = defineApiContract({\n version: 1,\n protocols: { 'voice-media': '6', 'voice-ownership': '3' },\n dynamic: ['Realtime event strings and SDP are provider-defined protocol documents passed through the media broker.'],\n http: [\n {\n id: 'voice.status',\n scope: 'session',\n basePath: 'voice',\n path: '/status',\n method: 'GET',\n authentication: 'owner',\n description: 'Voice session status and media readiness.',\n responses: jsonApiResponses(\n Type.Object({\n ...voiceControlMethod.output.properties,\n media: Type.Object({ closed: B, capture: B, playback: B, realtime: B }),\n readiness: Type.Object({\n configured: B,\n transcription: B,\n error: O(S),\n engine: O(S),\n mode: O(S),\n correctionModel: O(S),\n }),\n }),\n ),\n },\n {\n id: 'voice.control.http',\n scope: 'session',\n basePath: 'voice',\n path: '/control',\n method: 'POST',\n authentication: 'owner',\n description: 'Control the voice session.',\n body: { required: true, contentType: 'application/json', schema: voiceControlMethod.input },\n responses: jsonApiResponses(voiceControlMethod.output),\n },\n route(\n '/client/connect',\n 'POST',\n Type.Object({ version: Type.Literal(6), cursor: N, eventEpoch: O(S), heartbeatMs: O(N) }),\n Type.Object({\n version: Type.Literal(6),\n ...Client,\n clientKind: values(['browser', 'native']),\n controlLocation: values(['local', 'remote']),\n capabilities: Type.Object({\n capture: B,\n playback: B,\n captureActivity: B,\n autonomousOrchestration: B,\n playbackDucking: O(B),\n realtime: O(B),\n }),\n }),\n ),\n route('/client/disconnect', 'POST', undefined, Type.Object(Client)),\n route('/client/heartbeat', 'POST', Wake, Type.Object(Client)),\n {\n ...route('/client/events', 'GET', VoiceMediaEventSchema, undefined, [\n 'clientId',\n 'connectionId',\n 'after',\n 'wait',\n ]),\n responses: {\n ...Errors,\n '200': { description: 'Next event.', schema: VoiceMediaEventSchema },\n '204': { description: 'No pending event.' },\n },\n },\n pcm('/client/audio', 'POST', ['clientId', 'connectionId', 'captureId']),\n route('/client/capture-stopped', 'POST', undefined, Type.Object({ ...Client, captureId: S, error: O(S) })),\n pcm('/client/playback-audio', 'GET', ['clientId', 'connectionId', 'playbackId']),\n route('/client/playback-result', 'POST', undefined, Type.Object({ ...Client, ...Playback })),\n route(\n '/host/capture/start',\n 'POST',\n Type.Object({ configuration: Configuration }),\n Type.Object({ captureId: S, configuration: O(Configuration) }),\n [],\n 201,\n ),\n pcm('/host/capture/audio', 'GET', ['captureId']),\n ...['stop', 'abort'].map((action) =>\n route(`/host/capture/${action}`, 'POST', undefined, Type.Object({ captureId: S })),\n ),\n route(\n '/host/playback/start',\n 'POST',\n Type.Object({ delivery: values(['client', 'streamed']) }),\n Type.Object({ playbackId: S, text: S, voice: O(S), rate: O(N) }),\n [],\n 201,\n ),\n pcm('/host/playback/audio', 'POST', ['playbackId']),\n route('/host/playback/audio-end', 'POST', undefined, Type.Object({ playbackId: S, error: O(S) })),\n {\n ...route('/host/playback/result', 'GET', Type.Object(Playback), undefined, ['playbackId']),\n responses: {\n ...Errors,\n '200': { description: 'Playback outcome.', schema: Type.Object(Playback) },\n '204': { description: 'Playback is pending.' },\n },\n },\n ...['stop', 'abort'].map((action) =>\n route(`/host/playback/${action}`, 'POST', undefined, Type.Object({ playbackId: S })),\n ),\n route('/hub/ownership/state', 'GET', Snapshot),\n route('/hub/ownership/command', 'POST', Acknowledgement, Command),\n route('/host/ownership/sync', 'POST', Type.Object({ command: O(Command) }), Snapshot),\n route(\n '/host/realtime/start',\n 'POST',\n Type.Object({}),\n Type.Object({ activationId: S, instructions: Type.String({ maxLength: 16384 }) }),\n [],\n 201,\n ),\n route('/host/realtime/stop', 'POST', undefined, Type.Object({ activationId: S })),\n route('/host/realtime/poll', 'GET', RealtimeSnapshot, undefined, ['activationId', 'after']),\n route(\n '/host/realtime/send',\n 'POST',\n undefined,\n Type.Object({ activationId: S, messages: Type.Array(S, { maxItems: 64 }) }),\n ),\n route('/host/realtime/control', 'POST', undefined, Type.Object({ activationId: S, action: Control })),\n route(\n '/client/realtime/negotiate',\n 'POST',\n Type.Object({ sdp: S }),\n Type.Object({ ...Client, activationId: S, sdp: S }),\n ),\n route('/client/realtime/event', 'POST', undefined, Type.Object({ ...Client, activationId: S, event: S })),\n route('/client/realtime/state', 'POST', undefined, Type.Object({ ...Client, activationId: S, state: Browser })),\n {\n id: 'voice.manual',\n scope: 'session',\n basePath: 'voice-media',\n path: '/manual/transcribe',\n method: 'POST',\n authentication: 'owner',\n description: 'Transcribe at most 4 MiB of WebM/Opus or MP4/AAC audio, at most 300000 milliseconds.',\n parameters: [\n {\n name: 'x-doom-audio-duration-ms',\n in: 'header',\n required: true,\n schema: Type.Integer({ minimum: 0, maximum: 300000 }),\n },\n ],\n body: { required: true, contentType: 'audio/webm', contentTypes: ['audio/webm', 'audio/mp4'], schema: S },\n responses: { ...Errors, '200': { description: 'Transcript.', schema: Type.Object({ transcript: S }) } },\n },\n ...(\n [\n ['readiness', '/live/agent', 'GET'],\n ['prepare', '/live/agent/prepare', 'POST'],\n ['admit', '/live/agent/admit', 'POST'],\n ['results', '/live/agent/results', 'GET'],\n ['ack', '/live/agent/results/ack', 'POST'],\n ['fence', '/live/agent/fence', 'POST'],\n ['select', '/live/agent/select', 'POST'],\n ['revoke', '/live/agent/revoke', 'POST'],\n ] as const\n ).map(([name, path, method]): DoomHttpContract => ({\n id: `voice.agent.${name}`,\n scope: 'session',\n basePath: 'voice',\n path,\n method,\n authentication: 'owner',\n description: `Native Voice agent ${name}. Only the host-issued hub bearer can access this route.`,\n parameters: [\n { name: 'Authorization', in: 'header', required: true, schema: Type.String({ pattern: '^Bearer .+' }) },\n ...(name === 'results'\n ? ['activationId', 'routeGeneration', 'sessionIncarnation', 'after'].map((key) => ({\n name: key,\n in: 'query' as const,\n required: key !== 'after',\n schema: S,\n }))\n : []),\n ],\n ...(method === 'POST'\n ? {\n body: {\n required: true,\n contentType: 'application/json',\n schema:\n name === 'select'\n ? Type.Object({\n activationId: S,\n routeGeneration: Type.Integer({ minimum: 1 }),\n transactionId: S,\n sessionIncarnation: S,\n nativeTransferAllowed: B,\n catalog: Type.Object({\n revision: S,\n targets: Type.Array(Type.Object({ order: Type.Integer({ minimum: 1 }), label: S }), {\n maxItems: 256,\n }),\n }),\n })\n : name === 'revoke'\n ? Type.Object({\n activationId: S,\n routeGeneration: Type.Integer({ minimum: 1 }),\n transactionId: S,\n sessionIncarnation: S,\n })\n : Type.Unknown(),\n },\n }\n : {}),\n responses: {\n ...jsonApiResponses(Type.Unknown()),\n '204': { description: 'Agent result acknowledged or route fenced.' },\n },\n })),\n {\n id: 'voice.peer',\n scope: 'global',\n basePath: 'voice',\n path: '/peer',\n method: 'POST',\n authentication: 'none',\n description: 'Accept an HMAC-authenticated bounded Voice media relay request from a configured peer.',\n body: { required: true, contentType: 'application/json', schema: Type.Unknown() },\n responses: jsonApiResponses(Type.Unknown()),\n },\n {\n id: 'voice.peerOwnership',\n scope: 'global',\n basePath: 'voice',\n path: '/peer-ownership',\n method: 'POST',\n authentication: 'none',\n description: 'Discover and stage Voice ownership through an HMAC-authenticated paired host.',\n body: { required: true, contentType: 'application/json', schema: Type.Unknown() },\n responses: jsonApiResponses(Type.Unknown()),\n },\n {\n id: 'voice.peerAgent',\n scope: 'global',\n basePath: 'voice',\n path: '/peer-agent',\n method: 'POST',\n authentication: 'none',\n description: 'Accept a signed, replay-guarded, grant-scoped native Voice agent request from a configured peer.',\n body: { required: true, contentType: 'application/json', schema: Type.Unknown() },\n responses: jsonApiResponses(Type.Unknown()),\n },\n {\n id: 'voice.relayBinding',\n scope: 'global',\n basePath: 'voice',\n path: '/relay-binding',\n method: 'POST',\n authentication: 'owner',\n description: 'Issue an expiring controller-bound handle for a granted paired Voice session.',\n body: { required: true, contentType: 'application/json', schema: Type.Object({ target: S, connectionId: S }) },\n responses: jsonApiResponses(Type.Object({ binding: S, expiresAt: N })),\n },\n {\n id: 'voice.relay',\n scope: 'global',\n basePath: 'voice',\n path: '/relay',\n method: 'POST',\n authentication: 'owner',\n description: 'Relay a browser Voice media operation through an expiring controller-bound handle.',\n parameters: [{ name: 'binding', in: 'query', required: true, schema: S }],\n body: { required: true, contentType: 'application/json', schema: Type.Unknown() },\n responses: jsonApiResponses(Type.Unknown()),\n },\n {\n id: 'voice.nativeTransfer',\n scope: 'global',\n basePath: 'voice',\n path: '/live/native-transfer',\n method: 'POST',\n authentication: 'owner',\n description: 'Host-only revision-bound native Live transfer. Requires the host hub bearer.',\n parameters: [\n { name: 'Authorization', in: 'header', required: true, schema: Type.String({ pattern: '^Bearer .+' }) },\n ],\n body: {\n required: true,\n contentType: 'application/json',\n schema: Type.Object({\n sourceSessionId: S,\n activationId: S,\n routeGeneration: Type.Integer({ minimum: 0 }),\n sessionIncarnation: S,\n ordinal: Type.Integer({ minimum: 1 }),\n catalogRevision: S,\n }),\n },\n responses: {\n ...Errors,\n '202': {\n description: 'Transfer requested; source work drains before commit.',\n schema: Type.Object({ requested: Type.Literal(true) }),\n },\n },\n },\n {\n id: 'voice.liveStatus',\n scope: 'global',\n basePath: 'voice',\n path: '/live/status',\n method: 'GET',\n authentication: 'owner',\n description: 'Read the host-global live companion state without activating media.',\n responses: jsonApiResponses(GlobalLiveStatus),\n },\n {\n id: 'voice.liveControl',\n scope: 'global',\n basePath: 'voice',\n path: '/live/control',\n method: 'POST',\n authentication: 'owner',\n description: 'Explicitly activate, transfer, mute, interrupt or end the host-global live companion.',\n body: {\n required: true,\n contentType: 'application/json',\n schema: Type.Object({\n action: values(['activate', 'transfer', 'mute', 'unmute', 'interrupt', 'end']),\n sessionId: O(S),\n expectedSourceSessionId: O(S),\n }),\n },\n responses: jsonApiResponses(GlobalLiveStatus),\n },\n {\n id: 'voice.readiness',\n scope: 'global',\n basePath: 'voice',\n path: '/readiness',\n method: 'GET',\n authentication: 'owner',\n description: 'Read configured voice readiness.',\n responses: jsonApiResponses(\n Type.Object({\n configured: B,\n transcription: B,\n error: O(S),\n engine: O(S),\n mode: O(S),\n correctionModel: O(S),\n }),\n ),\n },\n ],\n sockets: [\n {\n id: 'voice.control',\n scope: 'session',\n service: voiceControlMethod.service,\n member: voiceControlMethod.method,\n kind: 'method',\n direction: 'client-to-server',\n description: 'Voice session control through the scoped plugin service.',\n input: voiceControlMethod.input,\n output: voiceControlMethod.output,\n },\n ...(['global', 'workspace'] as const).flatMap((scope) => [\n {\n id: 'voice.wake',\n scope,\n service: 'po.hub.v1',\n member: 'voice_media_wake',\n kind: 'channel' as const,\n direction: 'server-to-client' as const,\n description: 'Voice media wake channel payload.',\n input: Wake,\n },\n {\n id: 'voice.ownership',\n scope,\n service: 'po.hub.v1',\n member: 'voice_ownership',\n kind: 'channel' as const,\n direction: 'server-to-client' as const,\n description: 'Browser media ownership channel payload.',\n input: Type.Object({\n type: Type.Literal('browser-media-session'),\n ...Version,\n activeSessionId: Type.Union([S, Type.Null()]),\n }),\n },\n ]),\n ],\n});\nexport default apiContracts;\n"],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const PROCESSOR_NAME = 'po-voice-capture';
|
|
2
|
+
|
|
3
|
+
class PoVoiceCaptureProcessor extends AudioWorkletProcessor {
|
|
4
|
+
process(inputs, outputs) {
|
|
5
|
+
const input = inputs[0]?.[0];
|
|
6
|
+
if (input === undefined) return true;
|
|
7
|
+
outputs[0]?.[0]?.set(input);
|
|
8
|
+
this.port.postMessage({ samples: input.slice(), capturedAt: currentTime });
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
registerProcessor(PROCESSOR_NAME, PoVoiceCaptureProcessor);
|
|
Binary file
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
//#region src/types/realtime.d.ts
|
|
2
|
+
interface RealtimeBrowserState {
|
|
3
|
+
connection: 'connecting' | 'connected' | 'closed' | 'failed';
|
|
4
|
+
listening: boolean;
|
|
5
|
+
speaking: boolean;
|
|
6
|
+
muted: boolean;
|
|
7
|
+
error?: string;
|
|
8
|
+
}
|
|
9
|
+
type RealtimeControl = 'mute' | 'unmute' | 'interrupt';
|
|
10
|
+
type RealtimeMediaCommand = {
|
|
11
|
+
sequence: number;
|
|
12
|
+
type: 'realtime-start';
|
|
13
|
+
activationId: string;
|
|
14
|
+
} | {
|
|
15
|
+
sequence: number;
|
|
16
|
+
type: 'realtime-stop';
|
|
17
|
+
activationId: string;
|
|
18
|
+
} | {
|
|
19
|
+
sequence: number;
|
|
20
|
+
type: 'realtime-control';
|
|
21
|
+
activationId: string;
|
|
22
|
+
action: RealtimeControl;
|
|
23
|
+
} | {
|
|
24
|
+
sequence: number;
|
|
25
|
+
type: 'realtime-send';
|
|
26
|
+
activationId: string;
|
|
27
|
+
messages: string[];
|
|
28
|
+
};
|
|
29
|
+
/** All methods use the existing authenticated media transport and current connection lease. */
|
|
30
|
+
interface RealtimeMediaTransport {
|
|
31
|
+
realtimeNegotiate(clientId: string, connectionId: string, activationId: string, sdp: string, signal: AbortSignal): Promise<string>;
|
|
32
|
+
realtimeEvent(clientId: string, connectionId: string, activationId: string, event: string): Promise<void>;
|
|
33
|
+
realtimeState(clientId: string, connectionId: string, activationId: string, state: RealtimeBrowserState): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
//#region src/types/clientMedia.d.ts
|
|
37
|
+
declare const VOICE_MEDIA_API_BASE_PATH = "voice-media";
|
|
38
|
+
declare const VOICE_MEDIA_PROTOCOL_VERSION = 6;
|
|
39
|
+
declare const VOICE_MEDIA_SAMPLE_RATE = 16000;
|
|
40
|
+
declare const VOICE_MEDIA_CHANNELS = 1;
|
|
41
|
+
declare const VOICE_MEDIA_BITS_PER_SAMPLE = 16;
|
|
42
|
+
declare const VOICE_MEDIA_CONTENT_TYPE = "application/vnd.po.pcm-s16le";
|
|
43
|
+
declare const VOICE_MEDIA_ACTIVITY_STATE_HEADER = "x-po-voice-activity-state";
|
|
44
|
+
declare const VOICE_MEDIA_PLAYBACK_STATE_HEADER = "x-po-playback-state";
|
|
45
|
+
declare const VOICE_MEDIA_ACTIVITY_LEVEL_HEADER = "x-po-voice-activity-level";
|
|
46
|
+
declare const VOICE_MEDIA_ACTIVITY_ELAPSED_HEADER = "x-po-voice-activity-elapsed";
|
|
47
|
+
declare const VOICE_MEDIA_ACTIVITY_EPOCH_HEADER = "x-po-voice-activity-epoch";
|
|
48
|
+
declare const VOICE_MEDIA_ACTIVITY_SPEECH_MS_HEADER = "x-po-voice-activity-speech-ms";
|
|
49
|
+
declare const VOICE_MEDIA_ACTIVITY_ECHO_SPEECH_MS_HEADER = "x-po-voice-activity-echo-speech-ms";
|
|
50
|
+
declare const VOICE_MEDIA_WAKE_TYPE = "voice_media_wake";
|
|
51
|
+
declare const VOICE_MEDIA_HEARTBEAT_MS = 5000;
|
|
52
|
+
declare const VOICE_MEDIA_EVENT_WAIT_NONE = "0";
|
|
53
|
+
declare const VOICE_MEDIA_ROUTES: {
|
|
54
|
+
readonly clientConnect: '/client/connect';
|
|
55
|
+
readonly clientDisconnect: '/client/disconnect';
|
|
56
|
+
readonly clientEvents: '/client/events';
|
|
57
|
+
readonly clientHeartbeat: '/client/heartbeat';
|
|
58
|
+
readonly clientAudio: '/client/audio';
|
|
59
|
+
readonly clientCaptureStopped: '/client/capture-stopped';
|
|
60
|
+
readonly clientPlaybackAudio: '/client/playback-audio';
|
|
61
|
+
readonly clientPlaybackResult: '/client/playback-result';
|
|
62
|
+
readonly hostCaptureStart: '/host/capture/start';
|
|
63
|
+
readonly hostCaptureAudio: '/host/capture/audio';
|
|
64
|
+
readonly hostCaptureStop: '/host/capture/stop';
|
|
65
|
+
readonly hostCaptureAbort: '/host/capture/abort';
|
|
66
|
+
readonly hostPlaybackStart: '/host/playback/start';
|
|
67
|
+
readonly hostPlaybackAudio: '/host/playback/audio';
|
|
68
|
+
readonly hostPlaybackAudioEnd: '/host/playback/audio-end';
|
|
69
|
+
readonly hostPlaybackResult: '/host/playback/result';
|
|
70
|
+
readonly hostPlaybackStop: '/host/playback/stop';
|
|
71
|
+
readonly hostPlaybackAbort: '/host/playback/abort';
|
|
72
|
+
};
|
|
73
|
+
type VoiceClientKind = 'browser' | 'native';
|
|
74
|
+
type VoiceMediaControlLocation = 'local' | 'remote';
|
|
75
|
+
interface VoiceMediaCapabilities {
|
|
76
|
+
capture: boolean;
|
|
77
|
+
playback: boolean;
|
|
78
|
+
captureActivity: boolean;
|
|
79
|
+
autonomousOrchestration: boolean;
|
|
80
|
+
playbackDucking?: boolean;
|
|
81
|
+
realtime?: boolean;
|
|
82
|
+
}
|
|
83
|
+
type VoiceMediaCaptureMode = 'manual' | 'autonomous';
|
|
84
|
+
type VoiceMediaPlaybackDelivery = 'client' | 'streamed';
|
|
85
|
+
type VoiceMediaCaptureActivityState = 'listening' | 'speech' | 'endpoint';
|
|
86
|
+
interface VoiceMediaCaptureActivity {
|
|
87
|
+
state: VoiceMediaCaptureActivityState;
|
|
88
|
+
levelDbfs: number;
|
|
89
|
+
elapsedMs: number;
|
|
90
|
+
epoch?: number;
|
|
91
|
+
classifiedSpeechMs?: number;
|
|
92
|
+
echoDiscriminatedSpeechMs?: number;
|
|
93
|
+
}
|
|
94
|
+
interface VoiceMediaCaptureConfiguration {
|
|
95
|
+
mode: VoiceMediaCaptureMode;
|
|
96
|
+
activityControl: 'host' | 'client';
|
|
97
|
+
endpointSilenceMs?: number;
|
|
98
|
+
}
|
|
99
|
+
interface VoiceMediaConnectRequest {
|
|
100
|
+
version: typeof VOICE_MEDIA_PROTOCOL_VERSION;
|
|
101
|
+
clientId: string;
|
|
102
|
+
connectionId: string;
|
|
103
|
+
clientKind: VoiceClientKind;
|
|
104
|
+
controlLocation: VoiceMediaControlLocation;
|
|
105
|
+
capabilities: VoiceMediaCapabilities;
|
|
106
|
+
}
|
|
107
|
+
interface VoiceMediaWake {
|
|
108
|
+
eventEpoch: string;
|
|
109
|
+
sequence: number;
|
|
110
|
+
}
|
|
111
|
+
interface VoiceMediaConnectResult {
|
|
112
|
+
version: typeof VOICE_MEDIA_PROTOCOL_VERSION;
|
|
113
|
+
cursor: number;
|
|
114
|
+
eventEpoch?: string;
|
|
115
|
+
heartbeatMs?: number;
|
|
116
|
+
}
|
|
117
|
+
type VoiceMediaHeartbeatResult = VoiceMediaWake;
|
|
118
|
+
type VoiceMediaClientEvent = RealtimeMediaCommand | {
|
|
119
|
+
sequence: number;
|
|
120
|
+
type: 'capture-start';
|
|
121
|
+
captureId: string;
|
|
122
|
+
sampleRate: typeof VOICE_MEDIA_SAMPLE_RATE;
|
|
123
|
+
channels: typeof VOICE_MEDIA_CHANNELS;
|
|
124
|
+
bitsPerSample: typeof VOICE_MEDIA_BITS_PER_SAMPLE;
|
|
125
|
+
configuration: VoiceMediaCaptureConfiguration;
|
|
126
|
+
} | {
|
|
127
|
+
sequence: number;
|
|
128
|
+
type: 'capture-stop';
|
|
129
|
+
captureId: string;
|
|
130
|
+
} | {
|
|
131
|
+
sequence: number;
|
|
132
|
+
type: 'capture-abort';
|
|
133
|
+
captureId: string;
|
|
134
|
+
} | {
|
|
135
|
+
sequence: number;
|
|
136
|
+
type: 'playback-start';
|
|
137
|
+
playbackId: string;
|
|
138
|
+
text: string;
|
|
139
|
+
delivery?: VoiceMediaPlaybackDelivery;
|
|
140
|
+
voice?: string;
|
|
141
|
+
rate?: number;
|
|
142
|
+
} | {
|
|
143
|
+
sequence: number;
|
|
144
|
+
type: 'playback-stop';
|
|
145
|
+
playbackId: string;
|
|
146
|
+
} | {
|
|
147
|
+
sequence: number;
|
|
148
|
+
type: 'playback-abort';
|
|
149
|
+
playbackId: string;
|
|
150
|
+
};
|
|
151
|
+
type VoiceMediaPlaybackOutcome = 'completed' | 'stopped' | 'aborted' | 'failed';
|
|
152
|
+
interface VoiceMediaPlaybackResult {
|
|
153
|
+
playbackId: string;
|
|
154
|
+
outcome: VoiceMediaPlaybackOutcome;
|
|
155
|
+
error?: string;
|
|
156
|
+
}
|
|
157
|
+
interface VoiceMediaTransport extends Partial<RealtimeMediaTransport> {
|
|
158
|
+
connect(clientId: string, connectionId: string, capabilities: VoiceMediaCapabilities): Promise<VoiceMediaConnectResult>;
|
|
159
|
+
/** Refreshes optional capabilities without changing active work or event position. */
|
|
160
|
+
refreshCapabilities?(clientId: string, connectionId: string, capabilities: VoiceMediaCapabilities): Promise<void>;
|
|
161
|
+
disconnect(clientId: string, connectionId: string): Promise<void>;
|
|
162
|
+
nextEvent(clientId: string, connectionId: string, after: number, signal: AbortSignal): Promise<VoiceMediaClientEvent | undefined>;
|
|
163
|
+
sendAudio(clientId: string, connectionId: string, captureId: string, pcm: Uint8Array, activity?: VoiceMediaCaptureActivity): Promise<void>;
|
|
164
|
+
captureStopped(clientId: string, connectionId: string, captureId: string, error?: string): Promise<void>;
|
|
165
|
+
receivePlaybackAudio?(clientId: string, connectionId: string, playbackId: string, signal: AbortSignal): Promise<Uint8Array>;
|
|
166
|
+
playbackFinished(clientId: string, connectionId: string, result: VoiceMediaPlaybackResult): Promise<void>;
|
|
167
|
+
}
|
|
168
|
+
interface VoiceMediaCapture {
|
|
169
|
+
completion?: Promise<void>;
|
|
170
|
+
stop(): Promise<void>;
|
|
171
|
+
}
|
|
172
|
+
/** Optional browser-local speech input. The original capture PCM remains authoritative for transport. */
|
|
173
|
+
interface VoiceMediaCaptureSpeechAnalysis {
|
|
174
|
+
speechPcm: Uint8Array;
|
|
175
|
+
echoReferenceActive: boolean;
|
|
176
|
+
echoDiscriminated: boolean;
|
|
177
|
+
}
|
|
178
|
+
interface VoiceMediaPlayback {
|
|
179
|
+
readonly completion: Promise<VoiceMediaPlaybackResult>;
|
|
180
|
+
stop(outcome: Extract<VoiceMediaPlaybackOutcome, 'stopped' | 'aborted'>): void;
|
|
181
|
+
duck?(targetGain: number, fadeMs: number, holdMs: number): void;
|
|
182
|
+
}
|
|
183
|
+
/** Client hardware boundary. Browser and future native clients implement the same contract. */
|
|
184
|
+
interface VoiceMediaDevice {
|
|
185
|
+
readonly capabilities: VoiceMediaCapabilities;
|
|
186
|
+
/** Initializes optional authoritative media processors after baseline capabilities are available. */
|
|
187
|
+
prepare?(): Promise<void>;
|
|
188
|
+
createSpeechPresenceDetector?(): SpeechPresenceDetector | undefined;
|
|
189
|
+
startCapture(onPcm: (pcm: Uint8Array, speechAnalysis?: VoiceMediaCaptureSpeechAnalysis) => void): Promise<VoiceMediaCapture>;
|
|
190
|
+
speak(request: Extract<VoiceMediaClientEvent, {
|
|
191
|
+
type: 'playback-start';
|
|
192
|
+
}>, audio?: Promise<Uint8Array>): VoiceMediaPlayback;
|
|
193
|
+
close(): Promise<void>;
|
|
194
|
+
}
|
|
195
|
+
declare function voiceMediaClientUrl(sessionId: string, route: string, params?: Record<string, string>): string;
|
|
196
|
+
//#endregion
|
|
197
|
+
//#region src/types/clientCaptureActivity.d.ts
|
|
198
|
+
interface SpeechPresenceWindow {
|
|
199
|
+
readonly speech: boolean;
|
|
200
|
+
readonly sampleCount: number;
|
|
201
|
+
}
|
|
202
|
+
/** Platform boundary for browser workers and native speech-presence implementations. */
|
|
203
|
+
interface SpeechPresenceDetector {
|
|
204
|
+
push(pcm: Uint8Array): Promise<readonly SpeechPresenceWindow[]>;
|
|
205
|
+
reset(): Promise<void>;
|
|
206
|
+
close(): Promise<void>;
|
|
207
|
+
}
|
|
208
|
+
/** Calculates the RMS level of complete little-endian PCM16 samples without environment-specific APIs. */
|
|
209
|
+
declare function calculateClientPcmDbfs(pcm: Uint8Array): number;
|
|
210
|
+
interface ClientCaptureSpeechClassification {
|
|
211
|
+
readonly echoReferenceActive: boolean;
|
|
212
|
+
readonly echoDiscriminated: boolean;
|
|
213
|
+
}
|
|
214
|
+
/** Portable lifecycle. Classifier windows are authoritative; RMS is level telemetry only. */
|
|
215
|
+
declare class ClientCaptureActivityLifecycle {
|
|
216
|
+
private readonly endpointSilenceMs;
|
|
217
|
+
private elapsedBytes;
|
|
218
|
+
private activityEpoch;
|
|
219
|
+
private consecutiveSpeechSamples;
|
|
220
|
+
private consecutiveEchoSpeechSamples;
|
|
221
|
+
private classifiedSpeechSamples;
|
|
222
|
+
private echoDiscriminatedSpeechSamples;
|
|
223
|
+
private trailingSilenceSamples;
|
|
224
|
+
private speechStarted;
|
|
225
|
+
private endpointReached;
|
|
226
|
+
private previousEchoDiscriminated;
|
|
227
|
+
constructor(endpointSilenceMs?: number);
|
|
228
|
+
push(pcm: Uint8Array, windows?: readonly SpeechPresenceWindow[], classification?: ClientCaptureSpeechClassification): VoiceMediaCaptureActivity;
|
|
229
|
+
/** Starts a fresh classifier phase while preserving monotonic capture time. */
|
|
230
|
+
resetActivity(): void;
|
|
231
|
+
}
|
|
232
|
+
//#endregion
|
|
233
|
+
export { VoiceMediaCaptureSpeechAnalysis as A, VoiceMediaPlaybackResult as B, VoiceClientKind as C, VoiceMediaCaptureActivityState as D, VoiceMediaCaptureActivity as E, VoiceMediaDevice as F, VoiceMediaWake as H, VoiceMediaHeartbeatResult as I, VoiceMediaPlayback as L, VoiceMediaConnectRequest as M, VoiceMediaConnectResult as N, VoiceMediaCaptureConfiguration as O, VoiceMediaControlLocation as P, VoiceMediaPlaybackDelivery as R, VOICE_MEDIA_WAKE_TYPE as S, VoiceMediaCapture as T, voiceMediaClientUrl as U, VoiceMediaTransport as V, VOICE_MEDIA_HEARTBEAT_MS as _, calculateClientPcmDbfs as a, VOICE_MEDIA_ROUTES as b, VOICE_MEDIA_ACTIVITY_EPOCH_HEADER as c, VOICE_MEDIA_ACTIVITY_STATE_HEADER as d, VOICE_MEDIA_API_BASE_PATH as f, VOICE_MEDIA_EVENT_WAIT_NONE as g, VOICE_MEDIA_CONTENT_TYPE as h, SpeechPresenceWindow as i, VoiceMediaClientEvent as j, VoiceMediaCaptureMode as k, VOICE_MEDIA_ACTIVITY_LEVEL_HEADER as l, VOICE_MEDIA_CHANNELS as m, ClientCaptureSpeechClassification as n, VOICE_MEDIA_ACTIVITY_ECHO_SPEECH_MS_HEADER as o, VOICE_MEDIA_BITS_PER_SAMPLE as p, SpeechPresenceDetector as r, VOICE_MEDIA_ACTIVITY_ELAPSED_HEADER as s, ClientCaptureActivityLifecycle as t, VOICE_MEDIA_ACTIVITY_SPEECH_MS_HEADER as u, VOICE_MEDIA_PLAYBACK_STATE_HEADER as v, VoiceMediaCapabilities as w, VOICE_MEDIA_SAMPLE_RATE as x, VOICE_MEDIA_PROTOCOL_VERSION as y, VoiceMediaPlaybackOutcome as z };
|
|
234
|
+
//# sourceMappingURL=clientCaptureActivity-DN4xQtmw.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clientCaptureActivity-DN4xQtmw.d.mts","names":[],"sources":["../src/types/realtime.ts","../src/types/clientMedia.ts","../src/types/clientCaptureActivity.ts"],"mappings":";UAuCiB;EACf;EACA;EACA;EACA;EACA;;KA8BU;KAEA;EACN;EAAkB;EAAwB;;EAC1C;EAAkB;EAAuB;;EACzC;EAAkB;EAA0B;EAAsB,QAAQ;;EAC1E;EAAkB;EAAuB;EAAsB;;;UAWpD;EACf,kBACE,kBACA,sBACA,sBACA,aACA,QAAQ,cACP;EACH,cAAc,kBAAkB,sBAAsB,sBAAsB,gBAAgB;EAC5F,cACE,kBACA,sBACA,sBACA,OAAO,uBACN;;;;cCpGQ;cACA;cACA;cACA;cACA;cACA;cACA;cACA;cACA;cACA;cACA;cACA;cACA;cACA;cACA;cACA;cAEA;WACX;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;KAGU;KACA;UAEK;EACf;EACA;EACA;EACA;EACA;EACA;;KAGU;KACA;KACA;UAEK;EACf,OAAO;EACP;EACA;EACA;EACA;EACA;;UAGe;EACf,MAAM;EACN;EACA;;UAGe;EACf,gBAAgB;EAChB;EACA;EACA,YAAY;EACZ,iBAAiB;EACjB,cAAc;;UAGC;EACf;EACA;;UAGe;EACf,gBAAgB;EAChB;EACA;EACA;;KAGU,4BAA4B;KAE5B,wBACR;EAEE;EACA;EACA;EACA,mBAAmB;EACnB,iBAAiB;EACjB,sBAAsB;EACtB,eAAe;;EAEf;EAAkB;EAAsB;;EACxC;EAAkB;EAAuB;;EAEzC;EACA;EACA;EACA;EACA,WAAW;EACX;EACA;;EAEA;EAAkB;EAAuB;;EACzC;EAAkB;EAAwB;;KAEpC;UAEK;EACf;EACA,SAAS;EACT;;UAGe,4BAA4B,QAAQ;EACnD,QACE,kBACA,sBACA,cAAc,yBACb,QAAQ;;EAEX,qBAAqB,kBAAkB,sBAAsB,cAAc,yBAAyB;EACpG,WAAW,kBAAkB,uBAAuB;EACpD,UACE,kBACA,sBACA,eACA,QAAQ,cACP,QAAQ;EACX,UACE,kBACA,sBACA,mBACA,KAAK,YACL,WAAW,4BACV;EACH,eAAe,kBAAkB,sBAAsB,mBAAmB,iBAAiB;EAC3F,sBACE,kBACA,sBACA,oBACA,QAAQ,cACP,QAAQ;EACX,iBAAiB,kBAAkB,sBAAsB,QAAQ,2BAA2B;;UAG7E;EACf,aAAa;EACb,QAAQ;;;UAIO;EACf,WAAW;EACX;EACA;;UAGe;WACN,YAAY,QAAQ;EAC7B,KAAK,SAAS,QAAQ;EACtB,MAAM,oBAAoB,gBAAgB;;;UAI3B;WACN,cAAc;;EAEvB,YAAY;EACZ,iCAAiC;EACjC,aACE,QAAQ,KAAK,YAAY,iBAAiB,2CACzC,QAAQ;EACX,MACE,SAAS,QAAQ;IAAyB;MAC1C,QAAQ,QAAQ,cACf;EACH,SAAS;;iBAGK,oBAAoB,mBAAmB,eAAe,SAAQ;;;UCtL7D;WACN;WACA;;;UAIM;EACf,KAAK,KAAK,aAAa,iBAAiB;EACxC,SAAS;EACT,SAAS;;;iBAYK,uBAAuB,KAAK;UAa3B;WACN;WACA;;;cAIE;mBAYyB;UAX5B;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;EAER,YAAoC;EAK7B,KACL,KAAK,YACL,mBAAkB,wBAClB,iBAAiB,oCAChB;;EAoEI"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { sessionApiPath } from "@agimon-ai/po-core/web";
|
|
2
|
+
//#region src/types/clientMedia.ts
|
|
3
|
+
const VOICE_MEDIA_API_BASE_PATH = "voice-media";
|
|
4
|
+
const VOICE_MEDIA_PROTOCOL_VERSION = 6;
|
|
5
|
+
const VOICE_MEDIA_SAMPLE_RATE = 16e3;
|
|
6
|
+
const VOICE_MEDIA_CHANNELS = 1;
|
|
7
|
+
const VOICE_MEDIA_BITS_PER_SAMPLE = 16;
|
|
8
|
+
const VOICE_MEDIA_CONTENT_TYPE = "application/vnd.po.pcm-s16le";
|
|
9
|
+
const VOICE_MEDIA_ACTIVITY_STATE_HEADER = "x-po-voice-activity-state";
|
|
10
|
+
const VOICE_MEDIA_PLAYBACK_STATE_HEADER = "x-po-playback-state";
|
|
11
|
+
const VOICE_MEDIA_ACTIVITY_LEVEL_HEADER = "x-po-voice-activity-level";
|
|
12
|
+
const VOICE_MEDIA_ACTIVITY_ELAPSED_HEADER = "x-po-voice-activity-elapsed";
|
|
13
|
+
const VOICE_MEDIA_ACTIVITY_EPOCH_HEADER = "x-po-voice-activity-epoch";
|
|
14
|
+
const VOICE_MEDIA_ACTIVITY_SPEECH_MS_HEADER = "x-po-voice-activity-speech-ms";
|
|
15
|
+
const VOICE_MEDIA_ACTIVITY_ECHO_SPEECH_MS_HEADER = "x-po-voice-activity-echo-speech-ms";
|
|
16
|
+
const VOICE_MEDIA_WAKE_TYPE = "voice_media_wake";
|
|
17
|
+
const VOICE_MEDIA_HEARTBEAT_MS = 5e3;
|
|
18
|
+
const VOICE_MEDIA_EVENT_WAIT_NONE = "0";
|
|
19
|
+
const VOICE_MEDIA_ROUTES = {
|
|
20
|
+
clientConnect: "/client/connect",
|
|
21
|
+
clientDisconnect: "/client/disconnect",
|
|
22
|
+
clientEvents: "/client/events",
|
|
23
|
+
clientHeartbeat: "/client/heartbeat",
|
|
24
|
+
clientAudio: "/client/audio",
|
|
25
|
+
clientCaptureStopped: "/client/capture-stopped",
|
|
26
|
+
clientPlaybackAudio: "/client/playback-audio",
|
|
27
|
+
clientPlaybackResult: "/client/playback-result",
|
|
28
|
+
hostCaptureStart: "/host/capture/start",
|
|
29
|
+
hostCaptureAudio: "/host/capture/audio",
|
|
30
|
+
hostCaptureStop: "/host/capture/stop",
|
|
31
|
+
hostCaptureAbort: "/host/capture/abort",
|
|
32
|
+
hostPlaybackStart: "/host/playback/start",
|
|
33
|
+
hostPlaybackAudio: "/host/playback/audio",
|
|
34
|
+
hostPlaybackAudioEnd: "/host/playback/audio-end",
|
|
35
|
+
hostPlaybackResult: "/host/playback/result",
|
|
36
|
+
hostPlaybackStop: "/host/playback/stop",
|
|
37
|
+
hostPlaybackAbort: "/host/playback/abort"
|
|
38
|
+
};
|
|
39
|
+
function voiceMediaClientUrl(sessionId, route, params = {}) {
|
|
40
|
+
const search = new URLSearchParams({
|
|
41
|
+
session: sessionId,
|
|
42
|
+
...params
|
|
43
|
+
});
|
|
44
|
+
return `${sessionApiPath(sessionId)}/plugins/${VOICE_MEDIA_API_BASE_PATH}${route}?${search.toString()}`;
|
|
45
|
+
}
|
|
46
|
+
//#endregion
|
|
47
|
+
export { VOICE_MEDIA_WAKE_TYPE as _, VOICE_MEDIA_ACTIVITY_SPEECH_MS_HEADER as a, VOICE_MEDIA_BITS_PER_SAMPLE as c, VOICE_MEDIA_EVENT_WAIT_NONE as d, VOICE_MEDIA_HEARTBEAT_MS as f, VOICE_MEDIA_SAMPLE_RATE as g, VOICE_MEDIA_ROUTES as h, VOICE_MEDIA_ACTIVITY_LEVEL_HEADER as i, VOICE_MEDIA_CHANNELS as l, VOICE_MEDIA_PROTOCOL_VERSION as m, VOICE_MEDIA_ACTIVITY_ELAPSED_HEADER as n, VOICE_MEDIA_ACTIVITY_STATE_HEADER as o, VOICE_MEDIA_PLAYBACK_STATE_HEADER as p, VOICE_MEDIA_ACTIVITY_EPOCH_HEADER as r, VOICE_MEDIA_API_BASE_PATH as s, VOICE_MEDIA_ACTIVITY_ECHO_SPEECH_MS_HEADER as t, VOICE_MEDIA_CONTENT_TYPE as u, voiceMediaClientUrl as v };
|
|
48
|
+
|
|
49
|
+
//# sourceMappingURL=clientMedia-CfTfc9_4.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clientMedia-CfTfc9_4.mjs","names":[],"sources":["../src/types/clientMedia.ts"],"sourcesContent":["import { sessionApiPath } from '@agimon-ai/po-core/web';\n\nimport type { SpeechPresenceDetector } from './clientCaptureActivity';\nimport type { RealtimeMediaCommand, RealtimeMediaTransport } from './realtime';\n\nexport const VOICE_MEDIA_API_BASE_PATH = 'voice-media';\nexport const VOICE_MEDIA_PROTOCOL_VERSION = 6;\nexport const VOICE_MEDIA_SAMPLE_RATE = 16_000;\nexport const VOICE_MEDIA_CHANNELS = 1;\nexport const VOICE_MEDIA_BITS_PER_SAMPLE = 16;\nexport const VOICE_MEDIA_CONTENT_TYPE = 'application/vnd.po.pcm-s16le';\nexport const VOICE_MEDIA_ACTIVITY_STATE_HEADER = 'x-po-voice-activity-state';\nexport const VOICE_MEDIA_PLAYBACK_STATE_HEADER = 'x-po-playback-state';\nexport const VOICE_MEDIA_ACTIVITY_LEVEL_HEADER = 'x-po-voice-activity-level';\nexport const VOICE_MEDIA_ACTIVITY_ELAPSED_HEADER = 'x-po-voice-activity-elapsed';\nexport const VOICE_MEDIA_ACTIVITY_EPOCH_HEADER = 'x-po-voice-activity-epoch';\nexport const VOICE_MEDIA_ACTIVITY_SPEECH_MS_HEADER = 'x-po-voice-activity-speech-ms';\nexport const VOICE_MEDIA_ACTIVITY_ECHO_SPEECH_MS_HEADER = 'x-po-voice-activity-echo-speech-ms';\nexport const VOICE_MEDIA_WAKE_TYPE = 'voice_media_wake';\nexport const VOICE_MEDIA_HEARTBEAT_MS = 5_000;\nexport const VOICE_MEDIA_EVENT_WAIT_NONE = '0';\n\nexport const VOICE_MEDIA_ROUTES = {\n clientConnect: '/client/connect',\n clientDisconnect: '/client/disconnect',\n clientEvents: '/client/events',\n clientHeartbeat: '/client/heartbeat',\n clientAudio: '/client/audio',\n clientCaptureStopped: '/client/capture-stopped',\n clientPlaybackAudio: '/client/playback-audio',\n clientPlaybackResult: '/client/playback-result',\n hostCaptureStart: '/host/capture/start',\n hostCaptureAudio: '/host/capture/audio',\n hostCaptureStop: '/host/capture/stop',\n hostCaptureAbort: '/host/capture/abort',\n hostPlaybackStart: '/host/playback/start',\n hostPlaybackAudio: '/host/playback/audio',\n hostPlaybackAudioEnd: '/host/playback/audio-end',\n hostPlaybackResult: '/host/playback/result',\n hostPlaybackStop: '/host/playback/stop',\n hostPlaybackAbort: '/host/playback/abort',\n} as const;\n\nexport type VoiceClientKind = 'browser' | 'native';\nexport type VoiceMediaControlLocation = 'local' | 'remote';\n\nexport interface VoiceMediaCapabilities {\n capture: boolean;\n playback: boolean;\n captureActivity: boolean;\n autonomousOrchestration: boolean;\n playbackDucking?: boolean;\n realtime?: boolean;\n}\n\nexport type VoiceMediaCaptureMode = 'manual' | 'autonomous';\nexport type VoiceMediaPlaybackDelivery = 'client' | 'streamed';\nexport type VoiceMediaCaptureActivityState = 'listening' | 'speech' | 'endpoint';\n\nexport interface VoiceMediaCaptureActivity {\n state: VoiceMediaCaptureActivityState;\n levelDbfs: number;\n elapsedMs: number;\n epoch?: number;\n classifiedSpeechMs?: number;\n echoDiscriminatedSpeechMs?: number;\n}\n\nexport interface VoiceMediaCaptureConfiguration {\n mode: VoiceMediaCaptureMode;\n activityControl: 'host' | 'client';\n endpointSilenceMs?: number;\n}\n\nexport interface VoiceMediaConnectRequest {\n version: typeof VOICE_MEDIA_PROTOCOL_VERSION;\n clientId: string;\n connectionId: string;\n clientKind: VoiceClientKind;\n controlLocation: VoiceMediaControlLocation;\n capabilities: VoiceMediaCapabilities;\n}\n\nexport interface VoiceMediaWake {\n eventEpoch: string;\n sequence: number;\n}\n\nexport interface VoiceMediaConnectResult {\n version: typeof VOICE_MEDIA_PROTOCOL_VERSION;\n cursor: number;\n eventEpoch?: string;\n heartbeatMs?: number;\n}\n\nexport type VoiceMediaHeartbeatResult = VoiceMediaWake;\n\nexport type VoiceMediaClientEvent =\n | RealtimeMediaCommand\n | {\n sequence: number;\n type: 'capture-start';\n captureId: string;\n sampleRate: typeof VOICE_MEDIA_SAMPLE_RATE;\n channels: typeof VOICE_MEDIA_CHANNELS;\n bitsPerSample: typeof VOICE_MEDIA_BITS_PER_SAMPLE;\n configuration: VoiceMediaCaptureConfiguration;\n }\n | { sequence: number; type: 'capture-stop'; captureId: string }\n | { sequence: number; type: 'capture-abort'; captureId: string }\n | {\n sequence: number;\n type: 'playback-start';\n playbackId: string;\n text: string;\n delivery?: VoiceMediaPlaybackDelivery;\n voice?: string;\n rate?: number;\n }\n | { sequence: number; type: 'playback-stop'; playbackId: string }\n | { sequence: number; type: 'playback-abort'; playbackId: string };\n\nexport type VoiceMediaPlaybackOutcome = 'completed' | 'stopped' | 'aborted' | 'failed';\n\nexport interface VoiceMediaPlaybackResult {\n playbackId: string;\n outcome: VoiceMediaPlaybackOutcome;\n error?: string;\n}\n\nexport interface VoiceMediaTransport extends Partial<RealtimeMediaTransport> {\n connect(\n clientId: string,\n connectionId: string,\n capabilities: VoiceMediaCapabilities,\n ): Promise<VoiceMediaConnectResult>;\n /** Refreshes optional capabilities without changing active work or event position. */\n refreshCapabilities?(clientId: string, connectionId: string, capabilities: VoiceMediaCapabilities): Promise<void>;\n disconnect(clientId: string, connectionId: string): Promise<void>;\n nextEvent(\n clientId: string,\n connectionId: string,\n after: number,\n signal: AbortSignal,\n ): Promise<VoiceMediaClientEvent | undefined>;\n sendAudio(\n clientId: string,\n connectionId: string,\n captureId: string,\n pcm: Uint8Array,\n activity?: VoiceMediaCaptureActivity,\n ): Promise<void>;\n captureStopped(clientId: string, connectionId: string, captureId: string, error?: string): Promise<void>;\n receivePlaybackAudio?(\n clientId: string,\n connectionId: string,\n playbackId: string,\n signal: AbortSignal,\n ): Promise<Uint8Array>;\n playbackFinished(clientId: string, connectionId: string, result: VoiceMediaPlaybackResult): Promise<void>;\n}\n\nexport interface VoiceMediaCapture {\n completion?: Promise<void>;\n stop(): Promise<void>;\n}\n\n/** Optional browser-local speech input. The original capture PCM remains authoritative for transport. */\nexport interface VoiceMediaCaptureSpeechAnalysis {\n speechPcm: Uint8Array;\n echoReferenceActive: boolean;\n echoDiscriminated: boolean;\n}\n\nexport interface VoiceMediaPlayback {\n readonly completion: Promise<VoiceMediaPlaybackResult>;\n stop(outcome: Extract<VoiceMediaPlaybackOutcome, 'stopped' | 'aborted'>): void;\n duck?(targetGain: number, fadeMs: number, holdMs: number): void;\n}\n\n/** Client hardware boundary. Browser and future native clients implement the same contract. */\nexport interface VoiceMediaDevice {\n readonly capabilities: VoiceMediaCapabilities;\n /** Initializes optional authoritative media processors after baseline capabilities are available. */\n prepare?(): Promise<void>;\n createSpeechPresenceDetector?(): SpeechPresenceDetector | undefined;\n startCapture(\n onPcm: (pcm: Uint8Array, speechAnalysis?: VoiceMediaCaptureSpeechAnalysis) => void,\n ): Promise<VoiceMediaCapture>;\n speak(\n request: Extract<VoiceMediaClientEvent, { type: 'playback-start' }>,\n audio?: Promise<Uint8Array>,\n ): VoiceMediaPlayback;\n close(): Promise<void>;\n}\n\nexport function voiceMediaClientUrl(sessionId: string, route: string, params: Record<string, string> = {}): string {\n const search = new URLSearchParams({ session: sessionId, ...params });\n return `${sessionApiPath(sessionId)}/plugins/${VOICE_MEDIA_API_BASE_PATH}${route}?${search.toString()}`;\n}\n\n/** What one capture opens. No `deviceId` means the input the browser is already on. */\nexport interface VoiceMicrophoneConstraints {\n audio: {\n deviceId?: { exact: string };\n channelCount: number;\n echoCancellation: boolean;\n noiseSuppression: boolean;\n autoGainControl: boolean;\n };\n video: false;\n}\n\n/** The input the browser is already on, with the processing every capture path expects. */\nexport const CLIENT_DEFAULT_MICROPHONE: VoiceMicrophoneConstraints = {\n audio: { channelCount: 1, echoCancellation: true, noiseSuppression: true, autoGainControl: true },\n video: false,\n};\n\n/** The same processing, pinned to one input. */\nexport function exactMicrophone(deviceId: string): VoiceMicrophoneConstraints {\n return {\n ...CLIENT_DEFAULT_MICROPHONE,\n audio: { ...CLIENT_DEFAULT_MICROPHONE.audio, deviceId: { exact: deviceId } },\n };\n}\n"],"mappings":";;AAKA,MAAa,4BAA4B;AACzC,MAAa,+BAA+B;AAC5C,MAAa,0BAA0B;AACvC,MAAa,uBAAuB;AACpC,MAAa,8BAA8B;AAC3C,MAAa,2BAA2B;AACxC,MAAa,oCAAoC;AACjD,MAAa,oCAAoC;AACjD,MAAa,oCAAoC;AACjD,MAAa,sCAAsC;AACnD,MAAa,oCAAoC;AACjD,MAAa,wCAAwC;AACrD,MAAa,6CAA6C;AAC1D,MAAa,wBAAwB;AACrC,MAAa,2BAA2B;AACxC,MAAa,8BAA8B;AAE3C,MAAa,qBAAqB;CAChC,eAAe;CACf,kBAAkB;CAClB,cAAc;CACd,iBAAiB;CACjB,aAAa;CACb,sBAAsB;CACtB,qBAAqB;CACrB,sBAAsB;CACtB,kBAAkB;CAClB,kBAAkB;CAClB,iBAAiB;CACjB,kBAAkB;CAClB,mBAAmB;CACnB,mBAAmB;CACnB,sBAAsB;CACtB,oBAAoB;CACpB,kBAAkB;CAClB,mBAAmB;AACrB;AA2JA,SAAgB,oBAAoB,WAAmB,OAAe,SAAiC,CAAC,GAAW;CACjH,MAAM,SAAS,IAAI,gBAAgB;EAAE,SAAS;EAAW,GAAG;CAAO,CAAC;CACpE,OAAO,GAAG,eAAe,SAAS,EAAE,WAAW,4BAA4B,MAAM,GAAG,OAAO,SAAS;AACtG"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
let _agimon_ai_po_core_web = require("@agimon-ai/po-core/web");
|
|
2
|
+
//#region src/types/clientMedia.ts
|
|
3
|
+
const VOICE_MEDIA_API_BASE_PATH = "voice-media";
|
|
4
|
+
const VOICE_MEDIA_PROTOCOL_VERSION = 6;
|
|
5
|
+
const VOICE_MEDIA_SAMPLE_RATE = 16e3;
|
|
6
|
+
const VOICE_MEDIA_CHANNELS = 1;
|
|
7
|
+
const VOICE_MEDIA_BITS_PER_SAMPLE = 16;
|
|
8
|
+
const VOICE_MEDIA_CONTENT_TYPE = "application/vnd.po.pcm-s16le";
|
|
9
|
+
const VOICE_MEDIA_ACTIVITY_STATE_HEADER = "x-po-voice-activity-state";
|
|
10
|
+
const VOICE_MEDIA_PLAYBACK_STATE_HEADER = "x-po-playback-state";
|
|
11
|
+
const VOICE_MEDIA_ACTIVITY_LEVEL_HEADER = "x-po-voice-activity-level";
|
|
12
|
+
const VOICE_MEDIA_ACTIVITY_ELAPSED_HEADER = "x-po-voice-activity-elapsed";
|
|
13
|
+
const VOICE_MEDIA_ACTIVITY_EPOCH_HEADER = "x-po-voice-activity-epoch";
|
|
14
|
+
const VOICE_MEDIA_ACTIVITY_SPEECH_MS_HEADER = "x-po-voice-activity-speech-ms";
|
|
15
|
+
const VOICE_MEDIA_ACTIVITY_ECHO_SPEECH_MS_HEADER = "x-po-voice-activity-echo-speech-ms";
|
|
16
|
+
const VOICE_MEDIA_WAKE_TYPE = "voice_media_wake";
|
|
17
|
+
const VOICE_MEDIA_HEARTBEAT_MS = 5e3;
|
|
18
|
+
const VOICE_MEDIA_EVENT_WAIT_NONE = "0";
|
|
19
|
+
const VOICE_MEDIA_ROUTES = {
|
|
20
|
+
clientConnect: "/client/connect",
|
|
21
|
+
clientDisconnect: "/client/disconnect",
|
|
22
|
+
clientEvents: "/client/events",
|
|
23
|
+
clientHeartbeat: "/client/heartbeat",
|
|
24
|
+
clientAudio: "/client/audio",
|
|
25
|
+
clientCaptureStopped: "/client/capture-stopped",
|
|
26
|
+
clientPlaybackAudio: "/client/playback-audio",
|
|
27
|
+
clientPlaybackResult: "/client/playback-result",
|
|
28
|
+
hostCaptureStart: "/host/capture/start",
|
|
29
|
+
hostCaptureAudio: "/host/capture/audio",
|
|
30
|
+
hostCaptureStop: "/host/capture/stop",
|
|
31
|
+
hostCaptureAbort: "/host/capture/abort",
|
|
32
|
+
hostPlaybackStart: "/host/playback/start",
|
|
33
|
+
hostPlaybackAudio: "/host/playback/audio",
|
|
34
|
+
hostPlaybackAudioEnd: "/host/playback/audio-end",
|
|
35
|
+
hostPlaybackResult: "/host/playback/result",
|
|
36
|
+
hostPlaybackStop: "/host/playback/stop",
|
|
37
|
+
hostPlaybackAbort: "/host/playback/abort"
|
|
38
|
+
};
|
|
39
|
+
function voiceMediaClientUrl(sessionId, route, params = {}) {
|
|
40
|
+
const search = new URLSearchParams({
|
|
41
|
+
session: sessionId,
|
|
42
|
+
...params
|
|
43
|
+
});
|
|
44
|
+
return `${(0, _agimon_ai_po_core_web.sessionApiPath)(sessionId)}/plugins/${VOICE_MEDIA_API_BASE_PATH}${route}?${search.toString()}`;
|
|
45
|
+
}
|
|
46
|
+
//#endregion
|
|
47
|
+
Object.defineProperty(exports, "VOICE_MEDIA_ACTIVITY_ECHO_SPEECH_MS_HEADER", {
|
|
48
|
+
enumerable: true,
|
|
49
|
+
get: function() {
|
|
50
|
+
return VOICE_MEDIA_ACTIVITY_ECHO_SPEECH_MS_HEADER;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
Object.defineProperty(exports, "VOICE_MEDIA_ACTIVITY_ELAPSED_HEADER", {
|
|
54
|
+
enumerable: true,
|
|
55
|
+
get: function() {
|
|
56
|
+
return VOICE_MEDIA_ACTIVITY_ELAPSED_HEADER;
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
Object.defineProperty(exports, "VOICE_MEDIA_ACTIVITY_EPOCH_HEADER", {
|
|
60
|
+
enumerable: true,
|
|
61
|
+
get: function() {
|
|
62
|
+
return VOICE_MEDIA_ACTIVITY_EPOCH_HEADER;
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
Object.defineProperty(exports, "VOICE_MEDIA_ACTIVITY_LEVEL_HEADER", {
|
|
66
|
+
enumerable: true,
|
|
67
|
+
get: function() {
|
|
68
|
+
return VOICE_MEDIA_ACTIVITY_LEVEL_HEADER;
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
Object.defineProperty(exports, "VOICE_MEDIA_ACTIVITY_SPEECH_MS_HEADER", {
|
|
72
|
+
enumerable: true,
|
|
73
|
+
get: function() {
|
|
74
|
+
return VOICE_MEDIA_ACTIVITY_SPEECH_MS_HEADER;
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
Object.defineProperty(exports, "VOICE_MEDIA_ACTIVITY_STATE_HEADER", {
|
|
78
|
+
enumerable: true,
|
|
79
|
+
get: function() {
|
|
80
|
+
return VOICE_MEDIA_ACTIVITY_STATE_HEADER;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
Object.defineProperty(exports, "VOICE_MEDIA_API_BASE_PATH", {
|
|
84
|
+
enumerable: true,
|
|
85
|
+
get: function() {
|
|
86
|
+
return VOICE_MEDIA_API_BASE_PATH;
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
Object.defineProperty(exports, "VOICE_MEDIA_BITS_PER_SAMPLE", {
|
|
90
|
+
enumerable: true,
|
|
91
|
+
get: function() {
|
|
92
|
+
return VOICE_MEDIA_BITS_PER_SAMPLE;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
Object.defineProperty(exports, "VOICE_MEDIA_CHANNELS", {
|
|
96
|
+
enumerable: true,
|
|
97
|
+
get: function() {
|
|
98
|
+
return VOICE_MEDIA_CHANNELS;
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
Object.defineProperty(exports, "VOICE_MEDIA_CONTENT_TYPE", {
|
|
102
|
+
enumerable: true,
|
|
103
|
+
get: function() {
|
|
104
|
+
return VOICE_MEDIA_CONTENT_TYPE;
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
Object.defineProperty(exports, "VOICE_MEDIA_EVENT_WAIT_NONE", {
|
|
108
|
+
enumerable: true,
|
|
109
|
+
get: function() {
|
|
110
|
+
return VOICE_MEDIA_EVENT_WAIT_NONE;
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
Object.defineProperty(exports, "VOICE_MEDIA_HEARTBEAT_MS", {
|
|
114
|
+
enumerable: true,
|
|
115
|
+
get: function() {
|
|
116
|
+
return VOICE_MEDIA_HEARTBEAT_MS;
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
Object.defineProperty(exports, "VOICE_MEDIA_PLAYBACK_STATE_HEADER", {
|
|
120
|
+
enumerable: true,
|
|
121
|
+
get: function() {
|
|
122
|
+
return VOICE_MEDIA_PLAYBACK_STATE_HEADER;
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
Object.defineProperty(exports, "VOICE_MEDIA_PROTOCOL_VERSION", {
|
|
126
|
+
enumerable: true,
|
|
127
|
+
get: function() {
|
|
128
|
+
return VOICE_MEDIA_PROTOCOL_VERSION;
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
Object.defineProperty(exports, "VOICE_MEDIA_ROUTES", {
|
|
132
|
+
enumerable: true,
|
|
133
|
+
get: function() {
|
|
134
|
+
return VOICE_MEDIA_ROUTES;
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
Object.defineProperty(exports, "VOICE_MEDIA_SAMPLE_RATE", {
|
|
138
|
+
enumerable: true,
|
|
139
|
+
get: function() {
|
|
140
|
+
return VOICE_MEDIA_SAMPLE_RATE;
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
Object.defineProperty(exports, "VOICE_MEDIA_WAKE_TYPE", {
|
|
144
|
+
enumerable: true,
|
|
145
|
+
get: function() {
|
|
146
|
+
return VOICE_MEDIA_WAKE_TYPE;
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
Object.defineProperty(exports, "voiceMediaClientUrl", {
|
|
150
|
+
enumerable: true,
|
|
151
|
+
get: function() {
|
|
152
|
+
return voiceMediaClientUrl;
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
//# sourceMappingURL=clientMedia-DuA4aYhD.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clientMedia-DuA4aYhD.cjs","names":["sessionApiPath"],"sources":["../src/types/clientMedia.ts"],"sourcesContent":["import { sessionApiPath } from '@agimon-ai/po-core/web';\n\nimport type { SpeechPresenceDetector } from './clientCaptureActivity';\nimport type { RealtimeMediaCommand, RealtimeMediaTransport } from './realtime';\n\nexport const VOICE_MEDIA_API_BASE_PATH = 'voice-media';\nexport const VOICE_MEDIA_PROTOCOL_VERSION = 6;\nexport const VOICE_MEDIA_SAMPLE_RATE = 16_000;\nexport const VOICE_MEDIA_CHANNELS = 1;\nexport const VOICE_MEDIA_BITS_PER_SAMPLE = 16;\nexport const VOICE_MEDIA_CONTENT_TYPE = 'application/vnd.po.pcm-s16le';\nexport const VOICE_MEDIA_ACTIVITY_STATE_HEADER = 'x-po-voice-activity-state';\nexport const VOICE_MEDIA_PLAYBACK_STATE_HEADER = 'x-po-playback-state';\nexport const VOICE_MEDIA_ACTIVITY_LEVEL_HEADER = 'x-po-voice-activity-level';\nexport const VOICE_MEDIA_ACTIVITY_ELAPSED_HEADER = 'x-po-voice-activity-elapsed';\nexport const VOICE_MEDIA_ACTIVITY_EPOCH_HEADER = 'x-po-voice-activity-epoch';\nexport const VOICE_MEDIA_ACTIVITY_SPEECH_MS_HEADER = 'x-po-voice-activity-speech-ms';\nexport const VOICE_MEDIA_ACTIVITY_ECHO_SPEECH_MS_HEADER = 'x-po-voice-activity-echo-speech-ms';\nexport const VOICE_MEDIA_WAKE_TYPE = 'voice_media_wake';\nexport const VOICE_MEDIA_HEARTBEAT_MS = 5_000;\nexport const VOICE_MEDIA_EVENT_WAIT_NONE = '0';\n\nexport const VOICE_MEDIA_ROUTES = {\n clientConnect: '/client/connect',\n clientDisconnect: '/client/disconnect',\n clientEvents: '/client/events',\n clientHeartbeat: '/client/heartbeat',\n clientAudio: '/client/audio',\n clientCaptureStopped: '/client/capture-stopped',\n clientPlaybackAudio: '/client/playback-audio',\n clientPlaybackResult: '/client/playback-result',\n hostCaptureStart: '/host/capture/start',\n hostCaptureAudio: '/host/capture/audio',\n hostCaptureStop: '/host/capture/stop',\n hostCaptureAbort: '/host/capture/abort',\n hostPlaybackStart: '/host/playback/start',\n hostPlaybackAudio: '/host/playback/audio',\n hostPlaybackAudioEnd: '/host/playback/audio-end',\n hostPlaybackResult: '/host/playback/result',\n hostPlaybackStop: '/host/playback/stop',\n hostPlaybackAbort: '/host/playback/abort',\n} as const;\n\nexport type VoiceClientKind = 'browser' | 'native';\nexport type VoiceMediaControlLocation = 'local' | 'remote';\n\nexport interface VoiceMediaCapabilities {\n capture: boolean;\n playback: boolean;\n captureActivity: boolean;\n autonomousOrchestration: boolean;\n playbackDucking?: boolean;\n realtime?: boolean;\n}\n\nexport type VoiceMediaCaptureMode = 'manual' | 'autonomous';\nexport type VoiceMediaPlaybackDelivery = 'client' | 'streamed';\nexport type VoiceMediaCaptureActivityState = 'listening' | 'speech' | 'endpoint';\n\nexport interface VoiceMediaCaptureActivity {\n state: VoiceMediaCaptureActivityState;\n levelDbfs: number;\n elapsedMs: number;\n epoch?: number;\n classifiedSpeechMs?: number;\n echoDiscriminatedSpeechMs?: number;\n}\n\nexport interface VoiceMediaCaptureConfiguration {\n mode: VoiceMediaCaptureMode;\n activityControl: 'host' | 'client';\n endpointSilenceMs?: number;\n}\n\nexport interface VoiceMediaConnectRequest {\n version: typeof VOICE_MEDIA_PROTOCOL_VERSION;\n clientId: string;\n connectionId: string;\n clientKind: VoiceClientKind;\n controlLocation: VoiceMediaControlLocation;\n capabilities: VoiceMediaCapabilities;\n}\n\nexport interface VoiceMediaWake {\n eventEpoch: string;\n sequence: number;\n}\n\nexport interface VoiceMediaConnectResult {\n version: typeof VOICE_MEDIA_PROTOCOL_VERSION;\n cursor: number;\n eventEpoch?: string;\n heartbeatMs?: number;\n}\n\nexport type VoiceMediaHeartbeatResult = VoiceMediaWake;\n\nexport type VoiceMediaClientEvent =\n | RealtimeMediaCommand\n | {\n sequence: number;\n type: 'capture-start';\n captureId: string;\n sampleRate: typeof VOICE_MEDIA_SAMPLE_RATE;\n channels: typeof VOICE_MEDIA_CHANNELS;\n bitsPerSample: typeof VOICE_MEDIA_BITS_PER_SAMPLE;\n configuration: VoiceMediaCaptureConfiguration;\n }\n | { sequence: number; type: 'capture-stop'; captureId: string }\n | { sequence: number; type: 'capture-abort'; captureId: string }\n | {\n sequence: number;\n type: 'playback-start';\n playbackId: string;\n text: string;\n delivery?: VoiceMediaPlaybackDelivery;\n voice?: string;\n rate?: number;\n }\n | { sequence: number; type: 'playback-stop'; playbackId: string }\n | { sequence: number; type: 'playback-abort'; playbackId: string };\n\nexport type VoiceMediaPlaybackOutcome = 'completed' | 'stopped' | 'aborted' | 'failed';\n\nexport interface VoiceMediaPlaybackResult {\n playbackId: string;\n outcome: VoiceMediaPlaybackOutcome;\n error?: string;\n}\n\nexport interface VoiceMediaTransport extends Partial<RealtimeMediaTransport> {\n connect(\n clientId: string,\n connectionId: string,\n capabilities: VoiceMediaCapabilities,\n ): Promise<VoiceMediaConnectResult>;\n /** Refreshes optional capabilities without changing active work or event position. */\n refreshCapabilities?(clientId: string, connectionId: string, capabilities: VoiceMediaCapabilities): Promise<void>;\n disconnect(clientId: string, connectionId: string): Promise<void>;\n nextEvent(\n clientId: string,\n connectionId: string,\n after: number,\n signal: AbortSignal,\n ): Promise<VoiceMediaClientEvent | undefined>;\n sendAudio(\n clientId: string,\n connectionId: string,\n captureId: string,\n pcm: Uint8Array,\n activity?: VoiceMediaCaptureActivity,\n ): Promise<void>;\n captureStopped(clientId: string, connectionId: string, captureId: string, error?: string): Promise<void>;\n receivePlaybackAudio?(\n clientId: string,\n connectionId: string,\n playbackId: string,\n signal: AbortSignal,\n ): Promise<Uint8Array>;\n playbackFinished(clientId: string, connectionId: string, result: VoiceMediaPlaybackResult): Promise<void>;\n}\n\nexport interface VoiceMediaCapture {\n completion?: Promise<void>;\n stop(): Promise<void>;\n}\n\n/** Optional browser-local speech input. The original capture PCM remains authoritative for transport. */\nexport interface VoiceMediaCaptureSpeechAnalysis {\n speechPcm: Uint8Array;\n echoReferenceActive: boolean;\n echoDiscriminated: boolean;\n}\n\nexport interface VoiceMediaPlayback {\n readonly completion: Promise<VoiceMediaPlaybackResult>;\n stop(outcome: Extract<VoiceMediaPlaybackOutcome, 'stopped' | 'aborted'>): void;\n duck?(targetGain: number, fadeMs: number, holdMs: number): void;\n}\n\n/** Client hardware boundary. Browser and future native clients implement the same contract. */\nexport interface VoiceMediaDevice {\n readonly capabilities: VoiceMediaCapabilities;\n /** Initializes optional authoritative media processors after baseline capabilities are available. */\n prepare?(): Promise<void>;\n createSpeechPresenceDetector?(): SpeechPresenceDetector | undefined;\n startCapture(\n onPcm: (pcm: Uint8Array, speechAnalysis?: VoiceMediaCaptureSpeechAnalysis) => void,\n ): Promise<VoiceMediaCapture>;\n speak(\n request: Extract<VoiceMediaClientEvent, { type: 'playback-start' }>,\n audio?: Promise<Uint8Array>,\n ): VoiceMediaPlayback;\n close(): Promise<void>;\n}\n\nexport function voiceMediaClientUrl(sessionId: string, route: string, params: Record<string, string> = {}): string {\n const search = new URLSearchParams({ session: sessionId, ...params });\n return `${sessionApiPath(sessionId)}/plugins/${VOICE_MEDIA_API_BASE_PATH}${route}?${search.toString()}`;\n}\n\n/** What one capture opens. No `deviceId` means the input the browser is already on. */\nexport interface VoiceMicrophoneConstraints {\n audio: {\n deviceId?: { exact: string };\n channelCount: number;\n echoCancellation: boolean;\n noiseSuppression: boolean;\n autoGainControl: boolean;\n };\n video: false;\n}\n\n/** The input the browser is already on, with the processing every capture path expects. */\nexport const CLIENT_DEFAULT_MICROPHONE: VoiceMicrophoneConstraints = {\n audio: { channelCount: 1, echoCancellation: true, noiseSuppression: true, autoGainControl: true },\n video: false,\n};\n\n/** The same processing, pinned to one input. */\nexport function exactMicrophone(deviceId: string): VoiceMicrophoneConstraints {\n return {\n ...CLIENT_DEFAULT_MICROPHONE,\n audio: { ...CLIENT_DEFAULT_MICROPHONE.audio, deviceId: { exact: deviceId } },\n };\n}\n"],"mappings":";;AAKA,MAAa,4BAA4B;AACzC,MAAa,+BAA+B;AAC5C,MAAa,0BAA0B;AACvC,MAAa,uBAAuB;AACpC,MAAa,8BAA8B;AAC3C,MAAa,2BAA2B;AACxC,MAAa,oCAAoC;AACjD,MAAa,oCAAoC;AACjD,MAAa,oCAAoC;AACjD,MAAa,sCAAsC;AACnD,MAAa,oCAAoC;AACjD,MAAa,wCAAwC;AACrD,MAAa,6CAA6C;AAC1D,MAAa,wBAAwB;AACrC,MAAa,2BAA2B;AACxC,MAAa,8BAA8B;AAE3C,MAAa,qBAAqB;CAChC,eAAe;CACf,kBAAkB;CAClB,cAAc;CACd,iBAAiB;CACjB,aAAa;CACb,sBAAsB;CACtB,qBAAqB;CACrB,sBAAsB;CACtB,kBAAkB;CAClB,kBAAkB;CAClB,iBAAiB;CACjB,kBAAkB;CAClB,mBAAmB;CACnB,mBAAmB;CACnB,sBAAsB;CACtB,oBAAoB;CACpB,kBAAkB;CAClB,mBAAmB;AACrB;AA2JA,SAAgB,oBAAoB,WAAmB,OAAe,SAAiC,CAAC,GAAW;CACjH,MAAM,SAAS,IAAI,gBAAgB;EAAE,SAAS;EAAW,GAAG;CAAO,CAAC;CACpE,OAAO,IAAA,GAAGA,uBAAAA,eAAAA,CAAe,SAAS,EAAE,WAAW,4BAA4B,MAAM,GAAG,OAAO,SAAS;AACtG"}
|