@shogo-ai/voice 1.10.0 → 2.4.2
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 +89 -0
- package/dist/{chunk-S3S2RNO6.js → chunk-BI6SL35K.js} +1 -184
- package/dist/chunk-IOFWML5L.js +1078 -0
- package/dist/chunk-KMSL5PWK.js +540 -0
- package/dist/chunk-ME3SIZZU.js +581 -0
- package/dist/{chunk-T3T4EBWY.js → chunk-RALZRMFL.js} +6 -2
- package/dist/chunk-TQOBJMEK.js +17 -0
- package/dist/chunk-U5UC7ZVS.js +988 -0
- package/dist/chunk-UW7VQ3S6.js +148 -0
- package/dist/chunk-ZAW6F3YT.js +172 -0
- package/dist/index.cjs +748 -25
- package/dist/index.d.cts +396 -3
- package/dist/index.d.ts +396 -3
- package/dist/index.js +63 -3
- package/dist/live/client.cjs +173 -0
- package/dist/live/client.d.cts +132 -0
- package/dist/live/client.d.ts +132 -0
- package/dist/live/client.js +9 -0
- package/dist/native/index.d.cts +5 -2
- package/dist/native/index.d.ts +5 -2
- package/dist/native/index.js +15 -11
- package/dist/{organicParticlesShaders-DIva0vBO.d.ts → organicParticlesShaders-seZq7jYX.d.cts} +1 -421
- package/dist/{organicParticlesShaders-DIva0vBO.d.cts → organicParticlesShaders-seZq7jYX.d.ts} +1 -421
- package/dist/particlesConfig-0YbdPOdY.d.cts +223 -0
- package/dist/particlesConfig-0YbdPOdY.d.ts +223 -0
- package/dist/react/conversation.cjs +789 -0
- package/dist/react/conversation.d.cts +134 -0
- package/dist/react/conversation.d.ts +134 -0
- package/dist/react/conversation.js +13 -0
- package/dist/react/index.cjs +374 -36
- package/dist/react/index.d.cts +10 -141
- package/dist/react/index.d.ts +10 -141
- package/dist/react/index.js +23 -770
- package/dist/react/visuals.cjs +1048 -0
- package/dist/react/visuals.d.cts +70 -0
- package/dist/react/visuals.d.ts +70 -0
- package/dist/react/visuals.js +10 -0
- package/dist/route/agent.cjs +1047 -85
- package/dist/route/agent.js +3 -3
- package/dist/route/audio-tags.cjs +1047 -85
- package/dist/route/audio-tags.js +3 -3
- package/dist/route/index.cjs +1051 -85
- package/dist/route/index.d.cts +19 -3
- package/dist/route/index.d.ts +19 -3
- package/dist/route/index.js +3 -3
- package/dist/route/music.cjs +1047 -85
- package/dist/route/music.js +3 -3
- package/dist/route/op.cjs +2127 -0
- package/dist/route/op.d.cts +43 -0
- package/dist/route/op.d.ts +43 -0
- package/dist/route/op.js +27 -0
- package/dist/route/signed-url.cjs +1047 -85
- package/dist/route/signed-url.js +3 -3
- package/dist/route/tts-preview.cjs +1047 -85
- package/dist/route/tts-preview.d.cts +6 -4
- package/dist/route/tts-preview.d.ts +6 -4
- package/dist/route/tts-preview.js +3 -3
- package/dist/server.cjs +1047 -85
- package/dist/server.d.cts +40 -8
- package/dist/server.d.ts +40 -8
- package/dist/server.js +2 -2
- package/dist/types-Bfhu-aQH.d.cts +199 -0
- package/dist/types-Bfhu-aQH.d.ts +199 -0
- package/dist/{types-W9y6eMj3.d.ts → types-CadjTXNH.d.cts} +193 -12
- package/dist/{types-W9y6eMj3.d.cts → types-CadjTXNH.d.ts} +193 -12
- package/package.json +21 -1
- package/dist/chunk-B4JC3DK2.js +0 -529
- package/dist/chunk-O362EJQR.js +0 -524
package/README.md
CHANGED
|
@@ -17,6 +17,95 @@ Native UI primitives.
|
|
|
17
17
|
| `@shogo-ai/voice/native` | React Native equivalents (Expo). |
|
|
18
18
|
| `@shogo-ai/voice/route/*` | Standard `(Request) => Response` route handlers. |
|
|
19
19
|
|
|
20
|
+
## Media ops: one registry, no per-endpoint code
|
|
21
|
+
|
|
22
|
+
`VOICE_OPS` (from `@shogo-ai/voice`) is the registry of every ElevenLabs media
|
|
23
|
+
endpoint the SDK exposes. A row carries the upstream path, the transport
|
|
24
|
+
(`json-binary`, `json-json`, `multipart-binary`, `multipart-json`), the project
|
|
25
|
+
permission, the body limit, the model list and the metering unit. Handlers read
|
|
26
|
+
that table — there is no hand-written route per endpoint.
|
|
27
|
+
|
|
28
|
+
| Op | Transport | Upstream |
|
|
29
|
+
| --- | --- | --- |
|
|
30
|
+
| `text-to-speech` | JSON → audio | `POST /v1/text-to-speech/{voiceId}` |
|
|
31
|
+
| `text-to-speech-with-timestamps` | JSON → JSON | `POST /v1/text-to-speech/{voiceId}/with-timestamps` |
|
|
32
|
+
| `speech-to-speech` | multipart → audio | `POST /v1/speech-to-speech/{voiceId}` |
|
|
33
|
+
| `speech-to-text` | multipart → JSON | `POST /v1/speech-to-text` |
|
|
34
|
+
| `sound-generation` | JSON → audio | `POST /v1/sound-generation` |
|
|
35
|
+
| `music` | JSON → audio | `POST /v1/music` |
|
|
36
|
+
| `voices` | JSON → JSON | `GET /v1/voices` |
|
|
37
|
+
| `models` | JSON → JSON | `GET /v1/models` |
|
|
38
|
+
|
|
39
|
+
One route file serves all of them, present and future:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
// app/api/voice/op/[opId]+api.ts
|
|
43
|
+
export { GET, POST } from '@shogo-ai/sdk/voice/route/op'
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
`handlers.op(req, opId)` is the same thing without a file convention. In proxy
|
|
47
|
+
mode every op is hosted on the Shogo API; the two legacy paths
|
|
48
|
+
(`/api/voice/tts`, `/api/voice/music`) still work because a row may keep a
|
|
49
|
+
`legacyHostedPath` for clients already in the field.
|
|
50
|
+
|
|
51
|
+
### Adding an op
|
|
52
|
+
|
|
53
|
+
1. Append a row to `VOICE_OPS` (`packages/voice/src/ops.ts`).
|
|
54
|
+
2. Add one row to `packages/voice/src/__tests__/ops.test.ts` if it needs
|
|
55
|
+
validation the declarative fields cannot express.
|
|
56
|
+
|
|
57
|
+
That is the whole change. No route file, no handler, no proxy branch, no
|
|
58
|
+
per-op test file: `handlers.op`, the `route/op` modules and the hosted
|
|
59
|
+
`/api/voice/op/:opId` executor all pick it up.
|
|
60
|
+
|
|
61
|
+
Two things a row has to state, because the code cannot infer them: a body
|
|
62
|
+
field goes in `forward` (caller name → upstream name), while an upstream
|
|
63
|
+
**query** param goes in `queryForward` under its upstream name — ElevenLabs
|
|
64
|
+
ignores a body field that belongs in the query (`sound-generation`'s
|
|
65
|
+
`output_format`), so putting it in the wrong one is a silent no-op. A path
|
|
66
|
+
param in `pathParams` may be sent by the caller as a body field or a query
|
|
67
|
+
param; the multipart rebuild drops it from the upload either way.
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
## TTS models
|
|
71
|
+
|
|
72
|
+
`VOICE_TTS_MODELS` (from `@shogo-ai/voice`) is the single source of truth for
|
|
73
|
+
model ids, per-request character caps and which models a convai agent can run
|
|
74
|
+
on (`realtime`). It covers `eleven_v4`, `eleven_v4_turbo`, `eleven_v3`,
|
|
75
|
+
`eleven_v3_conversational`, `eleven_multilingual_v2`, `eleven_flash_v2_5`,
|
|
76
|
+
`eleven_flash_v2`, `eleven_turbo_v2_5` and `eleven_turbo_v2`.
|
|
77
|
+
|
|
78
|
+
- `textToSpeech()` defaults to `eleven_v4`; convai agents default to
|
|
79
|
+
`eleven_v4_turbo` (`CONVAI_TTS_MODEL_FALLBACK`).
|
|
80
|
+
- `resolveConvaiTtsModelDetailed(requested)` returns
|
|
81
|
+
`{ modelId, requested, downgraded, reason }`; a downgrade is logged once per
|
|
82
|
+
distinct model instead of silently swapping it.
|
|
83
|
+
- `textToSpeech()` only falls back when the upstream failure is model-related
|
|
84
|
+
(402, or 400/403/404/422 mentioning model/plan/permission) and reports
|
|
85
|
+
`requestedModel` / `fellBack` / `fallbackReason`. The retry target is
|
|
86
|
+
`TTS_FALLBACK_MODEL` (`eleven_flash_v2_5`, the widest-available model) —
|
|
87
|
+
deliberately *not* `CONVAI_TTS_MODEL_FALLBACK`, so a BYO account without v4
|
|
88
|
+
entitlement still gets audio. The `tts` handler adds `x-tts-model-used`,
|
|
89
|
+
`x-tts-model-requested` and a `Warning: 199` header when they differ.
|
|
90
|
+
|
|
91
|
+
## Proxy mode (Shogo pods)
|
|
92
|
+
|
|
93
|
+
With `RUNTIME_AUTH_SECRET` + `PROJECT_ID` in env and no `apiKey`,
|
|
94
|
+
`createVoiceHandlers({})` forwards to the Shogo API (`SHOGO_API_URL`, else
|
|
95
|
+
`SHOGO_CLOUD_URL`) using the runtime token:
|
|
96
|
+
|
|
97
|
+
- `signedUrl`, `tts`, `music`, `op`, `audioTags` — hosted.
|
|
98
|
+
- `elevenLabs.textToSpeech()`, `.composeMusic()`, `.speechToSpeech()`,
|
|
99
|
+
`.soundEffects()`, `.transcribe()` — hosted.
|
|
100
|
+
- `agent.*` and the other paired-account `elevenLabs` methods (cloning,
|
|
101
|
+
dubbing, voice design) — not available; they throw and need a BYO key.
|
|
102
|
+
|
|
103
|
+
An explicit `apiKey` wins over the ambient runtime token. `mode: 'proxy'`
|
|
104
|
+
forces the runtime token, `mode: 'byo'` forces your key, `'auto'` (default)
|
|
105
|
+
prefers the key. `tts` and `music` need only `apiKey`; `getUser` and
|
|
106
|
+
`companionStore` are required only for the user-scoped handlers
|
|
107
|
+
(`signedUrl`, `agent.*`).
|
|
108
|
+
|
|
20
109
|
## Peers (all optional)
|
|
21
110
|
|
|
22
111
|
Install only the peers you actually use:
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
stripAudioTags
|
|
3
|
-
} from "./chunk-Q3TJAJ54.js";
|
|
4
|
-
|
|
5
1
|
// src/react/shaders/organicSphereShaders.ts
|
|
6
2
|
var PERLIN_4D = (
|
|
7
3
|
/* glsl */
|
|
@@ -478,186 +474,7 @@ function resolveOrganicParticlesConfig(partial) {
|
|
|
478
474
|
};
|
|
479
475
|
}
|
|
480
476
|
|
|
481
|
-
// src/shared/postJson.ts
|
|
482
|
-
function createPostJson({
|
|
483
|
-
authHeaders,
|
|
484
|
-
fetchCredentials
|
|
485
|
-
}) {
|
|
486
|
-
return async function postJson(path, body) {
|
|
487
|
-
return fetch(path, {
|
|
488
|
-
method: "POST",
|
|
489
|
-
headers: { "content-type": "application/json", ...authHeaders() },
|
|
490
|
-
credentials: fetchCredentials,
|
|
491
|
-
body: JSON.stringify(body)
|
|
492
|
-
});
|
|
493
|
-
};
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
// src/shared/memory.ts
|
|
497
|
-
function createMemoryAddTool({
|
|
498
|
-
postJson,
|
|
499
|
-
memoryAddPath
|
|
500
|
-
}) {
|
|
501
|
-
return async (params) => {
|
|
502
|
-
const fact = typeof params.fact === "string" ? params.fact : "";
|
|
503
|
-
if (!fact.trim()) return "Memory save failed: empty fact.";
|
|
504
|
-
try {
|
|
505
|
-
const res = await postJson(memoryAddPath, { fact });
|
|
506
|
-
if (!res.ok) return "Failed to save memory.";
|
|
507
|
-
return "Memory saved.";
|
|
508
|
-
} catch {
|
|
509
|
-
return "Memory save failed.";
|
|
510
|
-
}
|
|
511
|
-
};
|
|
512
|
-
}
|
|
513
|
-
function createMemoryContextInjector({
|
|
514
|
-
postJson,
|
|
515
|
-
memoryRetrievePath,
|
|
516
|
-
conversationRef,
|
|
517
|
-
enabled,
|
|
518
|
-
lastInjectedRef
|
|
519
|
-
}) {
|
|
520
|
-
return async function inject(userText) {
|
|
521
|
-
if (!enabled) return;
|
|
522
|
-
try {
|
|
523
|
-
const res = await postJson(memoryRetrievePath, { query: userText, limit: 4 });
|
|
524
|
-
if (!res.ok) return;
|
|
525
|
-
const data = await res.json();
|
|
526
|
-
const results = data.results ?? [];
|
|
527
|
-
if (!results.length) return;
|
|
528
|
-
const lines = results.map((r) => `- ${r.chunk.trim().replace(/\s+/g, " ").slice(0, 200)}`).join("\n");
|
|
529
|
-
if (lines === lastInjectedRef.current) return;
|
|
530
|
-
lastInjectedRef.current = lines;
|
|
531
|
-
const payload = `Relevant memory about this user:
|
|
532
|
-
${lines}`;
|
|
533
|
-
conversationRef.current?.sendContextualUpdate(payload);
|
|
534
|
-
} catch {
|
|
535
|
-
}
|
|
536
|
-
};
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
// src/shared/transcript.ts
|
|
540
|
-
function createTranscriptDisconnectHandler({
|
|
541
|
-
isRestartingRef,
|
|
542
|
-
weStartedSessionRef,
|
|
543
|
-
transcriptRef,
|
|
544
|
-
onTranscript,
|
|
545
|
-
transcriptIngestPath,
|
|
546
|
-
postJson
|
|
547
|
-
}) {
|
|
548
|
-
return function handleTranscriptOnDisconnect() {
|
|
549
|
-
if (isRestartingRef.current) {
|
|
550
|
-
return;
|
|
551
|
-
}
|
|
552
|
-
if (!weStartedSessionRef.current) {
|
|
553
|
-
transcriptRef.current = [];
|
|
554
|
-
return;
|
|
555
|
-
}
|
|
556
|
-
weStartedSessionRef.current = false;
|
|
557
|
-
const transcript = transcriptRef.current.join("\n");
|
|
558
|
-
transcriptRef.current = [];
|
|
559
|
-
if (onTranscript) {
|
|
560
|
-
void onTranscript(transcript);
|
|
561
|
-
return;
|
|
562
|
-
}
|
|
563
|
-
const trimmed = transcript.trim();
|
|
564
|
-
if (trimmed.length < 20) return;
|
|
565
|
-
void postJson(transcriptIngestPath, { transcript: trimmed }).catch(() => {
|
|
566
|
-
});
|
|
567
|
-
};
|
|
568
|
-
}
|
|
569
|
-
function appendTranscriptLine(msg, { transcriptRef, weStartedSessionRef }) {
|
|
570
|
-
if (!msg?.message || !msg?.source) return;
|
|
571
|
-
if (!weStartedSessionRef.current) return;
|
|
572
|
-
const speaker = msg.source === "user" ? "User" : "Agent";
|
|
573
|
-
const cleaned = msg.source === "user" ? msg.message : stripAudioTags(msg.message);
|
|
574
|
-
if (!cleaned) return;
|
|
575
|
-
transcriptRef.current.push(`${speaker}: ${cleaned}`);
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
// src/shared/sessionPayload.ts
|
|
579
|
-
function sanitizeDynamicVariables(raw) {
|
|
580
|
-
if (raw == null) return {};
|
|
581
|
-
const out = {};
|
|
582
|
-
for (const [k, v] of Object.entries(raw)) {
|
|
583
|
-
if (v == null) continue;
|
|
584
|
-
out[k] = typeof v === "string" ? v : String(v);
|
|
585
|
-
}
|
|
586
|
-
return out;
|
|
587
|
-
}
|
|
588
|
-
function buildSessionPayload(opts) {
|
|
589
|
-
const dynamicVariables = {
|
|
590
|
-
...sanitizeDynamicVariables(opts.dynamicVariables),
|
|
591
|
-
character_name: opts.characterName,
|
|
592
|
-
user_context: opts.userContext
|
|
593
|
-
};
|
|
594
|
-
if (typeof opts.conversationId === "string" && opts.conversationId.length > 0) {
|
|
595
|
-
dynamicVariables.conversation_id = opts.conversationId;
|
|
596
|
-
}
|
|
597
|
-
const payload = {
|
|
598
|
-
signedUrl: opts.signedUrl,
|
|
599
|
-
dynamicVariables
|
|
600
|
-
};
|
|
601
|
-
const agentOverrides = {};
|
|
602
|
-
if (opts.suppressFirstMessage) {
|
|
603
|
-
agentOverrides.firstMessage = "";
|
|
604
|
-
}
|
|
605
|
-
if (typeof opts.agentPromptOverride === "string" && opts.agentPromptOverride.length > 0) {
|
|
606
|
-
agentOverrides.prompt = { prompt: opts.agentPromptOverride };
|
|
607
|
-
}
|
|
608
|
-
if (Object.keys(agentOverrides).length > 0) {
|
|
609
|
-
payload.overrides = { agent: agentOverrides };
|
|
610
|
-
}
|
|
611
|
-
return payload;
|
|
612
|
-
}
|
|
613
|
-
async function fetchSignedUrl({
|
|
614
|
-
path,
|
|
615
|
-
fetchCredentials,
|
|
616
|
-
authHeaders
|
|
617
|
-
}) {
|
|
618
|
-
const res = await fetch(path, {
|
|
619
|
-
credentials: fetchCredentials,
|
|
620
|
-
headers: authHeaders()
|
|
621
|
-
});
|
|
622
|
-
if (!res.ok) throw new Error(`Signed URL request failed: ${res.status}`);
|
|
623
|
-
return await res.json();
|
|
624
|
-
}
|
|
625
|
-
function withProjectQuery(signedUrlPath, params) {
|
|
626
|
-
const tail = [];
|
|
627
|
-
if (typeof params.projectId === "string" && params.projectId.length > 0) {
|
|
628
|
-
tail.push(`projectId=${encodeURIComponent(params.projectId)}`);
|
|
629
|
-
}
|
|
630
|
-
if (typeof params.agentName === "string" && params.agentName.length > 0) {
|
|
631
|
-
tail.push(`agentName=${encodeURIComponent(params.agentName)}`);
|
|
632
|
-
}
|
|
633
|
-
if (tail.length === 0) return signedUrlPath;
|
|
634
|
-
const sep = signedUrlPath.includes("?") ? "&" : "?";
|
|
635
|
-
return `${signedUrlPath}${sep}${tail.join("&")}`;
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
// src/shared/chatUrl.ts
|
|
639
|
-
function appendChatQuery(basePath, params) {
|
|
640
|
-
const tail = [];
|
|
641
|
-
for (const [k, v] of Object.entries(params)) {
|
|
642
|
-
if (typeof v === "string" && v.length > 0) {
|
|
643
|
-
tail.push(`${k}=${encodeURIComponent(v)}`);
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
if (tail.length === 0) return basePath;
|
|
647
|
-
const sep = basePath.includes("?") ? "&" : "?";
|
|
648
|
-
return `${basePath}${sep}${tail.join("&")}`;
|
|
649
|
-
}
|
|
650
|
-
|
|
651
477
|
export {
|
|
652
|
-
createPostJson,
|
|
653
|
-
createMemoryAddTool,
|
|
654
|
-
createMemoryContextInjector,
|
|
655
|
-
createTranscriptDisconnectHandler,
|
|
656
|
-
appendTranscriptLine,
|
|
657
|
-
buildSessionPayload,
|
|
658
|
-
fetchSignedUrl,
|
|
659
|
-
withProjectQuery,
|
|
660
|
-
appendChatQuery,
|
|
661
478
|
PERLIN_4D,
|
|
662
479
|
ORGANIC_SPHERE_VERTEX_SHADER,
|
|
663
480
|
ORGANIC_SPHERE_FRAGMENT_SHADER,
|
|
@@ -668,4 +485,4 @@ export {
|
|
|
668
485
|
DEFAULT_ORGANIC_PARTICLES_CONFIG,
|
|
669
486
|
resolveOrganicParticlesConfig
|
|
670
487
|
};
|
|
671
|
-
//# sourceMappingURL=chunk-
|
|
488
|
+
//# sourceMappingURL=chunk-BI6SL35K.js.map
|