@kuralle-syrinx/realtime 4.4.1 → 4.5.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/dist/base64.d.ts +3 -0
- package/dist/base64.d.ts.map +1 -0
- package/dist/base64.js +16 -0
- package/dist/base64.js.map +1 -0
- package/dist/from-gemini-live.d.ts +67 -0
- package/dist/from-gemini-live.d.ts.map +1 -0
- package/dist/from-gemini-live.js +299 -0
- package/dist/from-gemini-live.js.map +1 -0
- package/dist/from-openai-realtime.d.ts +49 -0
- package/dist/from-openai-realtime.d.ts.map +1 -0
- package/dist/from-openai-realtime.js +80 -0
- package/dist/from-openai-realtime.js.map +1 -0
- package/dist/gemini-translate.d.ts +17 -0
- package/dist/gemini-translate.d.ts.map +1 -0
- package/dist/gemini-translate.js +89 -0
- package/dist/gemini-translate.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/openai-compatible-realtime.d.ts +37 -0
- package/dist/openai-compatible-realtime.d.ts.map +1 -0
- package/dist/openai-compatible-realtime.js +416 -0
- package/dist/openai-compatible-realtime.js.map +1 -0
- package/dist/realtime-adapter.d.ts +100 -0
- package/dist/realtime-adapter.d.ts.map +1 -0
- package/dist/realtime-adapter.js +3 -0
- package/dist/realtime-adapter.js.map +1 -0
- package/dist/realtime-bridge.d.ts +130 -0
- package/dist/realtime-bridge.d.ts.map +1 -0
- package/dist/realtime-bridge.js +659 -0
- package/dist/realtime-bridge.js.map +1 -0
- package/dist/realtime-event-stream.d.ts +16 -0
- package/dist/realtime-event-stream.d.ts.map +1 -0
- package/dist/realtime-event-stream.js +47 -0
- package/dist/realtime-event-stream.js.map +1 -0
- package/package.json +13 -6
- package/src/edge-safety.test.ts +173 -0
- package/src/from-gemini-live.test.ts +366 -0
- package/src/from-openai-realtime.test.ts +769 -0
- package/src/gemini-translate.test.ts +82 -0
- package/src/openai-compatible-realtime.test.ts +293 -0
- package/src/realtime-bridge.test.ts +1573 -0
- package/src/workers-seam.test.ts +143 -0
package/dist/base64.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base64.d.ts","sourceRoot":"","sources":["../src/base64.ts"],"names":[],"mappings":"AAEA,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAMvD;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAKxD"}
|
package/dist/base64.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
export function bytesToBase64(bytes) {
|
|
3
|
+
let binary = "";
|
|
4
|
+
for (let i = 0; i < bytes.length; i += 0x8000) {
|
|
5
|
+
binary += String.fromCharCode(...bytes.subarray(i, i + 0x8000));
|
|
6
|
+
}
|
|
7
|
+
return globalThis.btoa(binary);
|
|
8
|
+
}
|
|
9
|
+
export function base64ToBytes(base64) {
|
|
10
|
+
const raw = globalThis.atob(base64);
|
|
11
|
+
const bytes = new Uint8Array(raw.length);
|
|
12
|
+
for (let i = 0; i < raw.length; i += 1)
|
|
13
|
+
bytes[i] = raw.charCodeAt(i);
|
|
14
|
+
return bytes;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=base64.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base64.js","sourceRoot":"","sources":["../src/base64.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAE/B,MAAM,UAAU,aAAa,CAAC,KAAiB;IAC7C,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,MAAM,EAAE,CAAC;QAC9C,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC;QAAE,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IACrE,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { RealtimeAdapter, RealtimeToolDef } from "./realtime-adapter.js";
|
|
2
|
+
export interface GeminiLiveTranscriptionOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Enable input transcription, or provide Gemini's AudioTranscriptionConfig. Enabled by default.
|
|
5
|
+
*
|
|
6
|
+
* Default stays ON because `RealtimeBridge` turns `role: "user"` transcripts into `stt.result`
|
|
7
|
+
* packets — defaulting this off would silently remove all user-side text on the Gemini front.
|
|
8
|
+
* Issue #32 asked for it to be *configurable*, not disabled.
|
|
9
|
+
*/
|
|
10
|
+
readonly input?: boolean | Record<string, unknown>;
|
|
11
|
+
/** Enable output transcription, or provide Gemini's AudioTranscriptionConfig. Enabled by default. */
|
|
12
|
+
readonly output?: boolean | Record<string, unknown>;
|
|
13
|
+
}
|
|
14
|
+
export interface GeminiLiveSpeechConfig {
|
|
15
|
+
/** Prebuilt Gemini voice name, mapped to speechConfig.voiceConfig.prebuiltVoiceConfig.voiceName. */
|
|
16
|
+
readonly voice?: string;
|
|
17
|
+
/** ISO language code for speech synthesis. */
|
|
18
|
+
readonly languageCode?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface GeminiLiveOptions {
|
|
21
|
+
readonly apiKey: string;
|
|
22
|
+
readonly model?: string;
|
|
23
|
+
readonly systemInstruction?: string;
|
|
24
|
+
readonly tools?: readonly RealtimeToolDef[];
|
|
25
|
+
readonly transcription?: GeminiLiveTranscriptionOptions;
|
|
26
|
+
readonly speechConfig?: GeminiLiveSpeechConfig;
|
|
27
|
+
/** Gemini Developer API version, e.g. `v1alpha` for preview-only Live features. */
|
|
28
|
+
readonly apiVersion?: string;
|
|
29
|
+
/**
|
|
30
|
+
* G4 native resume: a `sessionResumption` handle from a prior session's
|
|
31
|
+
* `resumption_handle` events. Gemini restores the conversation server-side —
|
|
32
|
+
* do NOT also replay the transcript (that would double-apply history, R6).
|
|
33
|
+
* Session resumption is always enabled so handles are issued; this passes a
|
|
34
|
+
* prior handle back on reconnect.
|
|
35
|
+
*/
|
|
36
|
+
readonly sessionResumptionHandle?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Full `sessionResumption` LiveConnectConfig. Defaults to `{}` (handles issued)
|
|
39
|
+
* or `{ handle }` when `sessionResumptionHandle` is set. Pass `false` to omit.
|
|
40
|
+
*/
|
|
41
|
+
readonly sessionResumption?: Record<string, unknown> | false;
|
|
42
|
+
/** Response modalities. Defaults to `["AUDIO"]` (previous hard-pin). */
|
|
43
|
+
readonly responseModalities?: readonly string[];
|
|
44
|
+
/** LiveConnectConfig `generationConfig` (subset supported by Live). */
|
|
45
|
+
readonly generationConfig?: Record<string, unknown>;
|
|
46
|
+
/** LiveConnectConfig `safetySettings`. */
|
|
47
|
+
readonly safetySettings?: readonly Record<string, unknown>[];
|
|
48
|
+
readonly temperature?: number;
|
|
49
|
+
readonly topP?: number;
|
|
50
|
+
readonly topK?: number;
|
|
51
|
+
readonly maxOutputTokens?: number;
|
|
52
|
+
readonly mediaResolution?: string;
|
|
53
|
+
readonly seed?: number;
|
|
54
|
+
readonly thinkingConfig?: Record<string, unknown>;
|
|
55
|
+
readonly enableAffectiveDialog?: boolean;
|
|
56
|
+
readonly realtimeInputConfig?: Record<string, unknown>;
|
|
57
|
+
readonly contextWindowCompression?: Record<string, unknown>;
|
|
58
|
+
readonly proactivity?: Record<string, unknown>;
|
|
59
|
+
readonly explicitVadSignal?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Merged last into `live.connect` config for any LiveConnectConfig field the
|
|
62
|
+
* adapter does not enumerate (avatarConfig, …). Overrides same-key defaults.
|
|
63
|
+
*/
|
|
64
|
+
readonly connectConfig?: Record<string, unknown>;
|
|
65
|
+
}
|
|
66
|
+
export declare function fromGeminiLive(opts: GeminiLiveOptions): RealtimeAdapter;
|
|
67
|
+
//# sourceMappingURL=from-gemini-live.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"from-gemini-live.d.ts","sourceRoot":"","sources":["../src/from-gemini-live.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAiB,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAM7F,MAAM,WAAW,8BAA8B;IAC7C;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnD,qGAAqG;IACrG,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,sBAAsB;IACrC,oGAAoG;IACpG,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,8CAA8C;IAC9C,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IAC5C,QAAQ,CAAC,aAAa,CAAC,EAAE,8BAA8B,CAAC;IACxD,QAAQ,CAAC,YAAY,CAAC,EAAE,sBAAsB,CAAC;IAC/C,mFAAmF;IACnF,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IAC1C;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC;IAC7D,wEAAwE;IACxE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChD,uEAAuE;IACvE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpD,0CAA0C;IAC1C,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAC7D,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClD,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IACzC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvD,QAAQ,CAAC,wBAAwB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5D,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/C,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IACrC;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClD;AA8TD,wBAAgB,cAAc,CAAC,IAAI,EAAE,iBAAiB,GAAG,eAAe,CAEvE"}
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
import { bytesToBase64, base64ToBytes } from "./base64.js";
|
|
3
|
+
import { RealtimeEventStream } from "./realtime-event-stream.js";
|
|
4
|
+
const DEFAULT_MODEL = "gemini-3.1-flash-live-preview";
|
|
5
|
+
const INPUT_SAMPLE_RATE_HZ = 16_000;
|
|
6
|
+
const OUTPUT_SAMPLE_RATE_HZ = 24_000;
|
|
7
|
+
class GeminiLiveAdapter {
|
|
8
|
+
opts;
|
|
9
|
+
caps = {
|
|
10
|
+
inputSampleRateHz: INPUT_SAMPLE_RATE_HZ,
|
|
11
|
+
outputSampleRateHz: OUTPUT_SAMPLE_RATE_HZ,
|
|
12
|
+
supportsConcurrentToolAudio: false,
|
|
13
|
+
supportsTruncate: false,
|
|
14
|
+
emitsServerSpeechStarted: true,
|
|
15
|
+
supportsNativeResume: true,
|
|
16
|
+
};
|
|
17
|
+
events;
|
|
18
|
+
stream = new RealtimeEventStream();
|
|
19
|
+
session = null;
|
|
20
|
+
abortHandler = null;
|
|
21
|
+
openResolver = null;
|
|
22
|
+
openRejecter = null;
|
|
23
|
+
activeResponse = false;
|
|
24
|
+
toolNames = new Map();
|
|
25
|
+
constructor(opts) {
|
|
26
|
+
this.opts = opts;
|
|
27
|
+
this.events = this.stream;
|
|
28
|
+
}
|
|
29
|
+
async open(signal) {
|
|
30
|
+
const { GoogleGenAI, Modality } = await import("@google/genai");
|
|
31
|
+
const model = this.opts.model ?? DEFAULT_MODEL;
|
|
32
|
+
const tools = (this.opts.tools ?? []).map((t) => ({
|
|
33
|
+
functionDeclarations: [{
|
|
34
|
+
name: t.name,
|
|
35
|
+
description: t.description,
|
|
36
|
+
parametersJsonSchema: t.parameters,
|
|
37
|
+
}],
|
|
38
|
+
}));
|
|
39
|
+
const transcription = this.opts.transcription;
|
|
40
|
+
const config = {
|
|
41
|
+
// Default preserves the prior hard-pin of AUDIO-only responses.
|
|
42
|
+
responseModalities: this.opts.responseModalities
|
|
43
|
+
? [...this.opts.responseModalities]
|
|
44
|
+
: [Modality.AUDIO],
|
|
45
|
+
};
|
|
46
|
+
// G4: session resumption defaults ON so the server issues handles; a prior
|
|
47
|
+
// handle resumes server-side (native resume — no replay). Override via
|
|
48
|
+
// sessionResumption (full object) or disable with false.
|
|
49
|
+
if (!("sessionResumption" in this.opts) || this.opts.sessionResumption !== false) {
|
|
50
|
+
const base = typeof this.opts.sessionResumption === "object" && this.opts.sessionResumption !== null
|
|
51
|
+
? { ...this.opts.sessionResumption }
|
|
52
|
+
: {};
|
|
53
|
+
if (this.opts.sessionResumptionHandle !== undefined) {
|
|
54
|
+
base["handle"] = this.opts.sessionResumptionHandle;
|
|
55
|
+
}
|
|
56
|
+
config["sessionResumption"] = base;
|
|
57
|
+
}
|
|
58
|
+
const inputTranscription = transcription?.input ?? true;
|
|
59
|
+
const outputTranscription = transcription?.output ?? true;
|
|
60
|
+
if (inputTranscription !== false) {
|
|
61
|
+
config["inputAudioTranscription"] = inputTranscription === true ? {} : inputTranscription;
|
|
62
|
+
}
|
|
63
|
+
if (outputTranscription !== false) {
|
|
64
|
+
config["outputAudioTranscription"] = outputTranscription === true ? {} : outputTranscription;
|
|
65
|
+
}
|
|
66
|
+
const speechConfig = this.opts.speechConfig;
|
|
67
|
+
if (speechConfig && (speechConfig.voice !== undefined || speechConfig.languageCode !== undefined)) {
|
|
68
|
+
config["speechConfig"] = {
|
|
69
|
+
...(speechConfig.voice === undefined
|
|
70
|
+
? {}
|
|
71
|
+
: { voiceConfig: { prebuiltVoiceConfig: { voiceName: speechConfig.voice } } }),
|
|
72
|
+
...(speechConfig.languageCode === undefined ? {} : { languageCode: speechConfig.languageCode }),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
if (this.opts.systemInstruction) {
|
|
76
|
+
config["systemInstruction"] = this.opts.systemInstruction;
|
|
77
|
+
}
|
|
78
|
+
if (tools.length > 0) {
|
|
79
|
+
config["tools"] = tools;
|
|
80
|
+
}
|
|
81
|
+
if (this.opts.generationConfig !== undefined) {
|
|
82
|
+
config["generationConfig"] = this.opts.generationConfig;
|
|
83
|
+
}
|
|
84
|
+
if (this.opts.safetySettings !== undefined) {
|
|
85
|
+
config["safetySettings"] = this.opts.safetySettings;
|
|
86
|
+
}
|
|
87
|
+
if (this.opts.temperature !== undefined) {
|
|
88
|
+
config["temperature"] = this.opts.temperature;
|
|
89
|
+
}
|
|
90
|
+
if (this.opts.topP !== undefined) {
|
|
91
|
+
config["topP"] = this.opts.topP;
|
|
92
|
+
}
|
|
93
|
+
if (this.opts.topK !== undefined) {
|
|
94
|
+
config["topK"] = this.opts.topK;
|
|
95
|
+
}
|
|
96
|
+
if (this.opts.maxOutputTokens !== undefined) {
|
|
97
|
+
config["maxOutputTokens"] = this.opts.maxOutputTokens;
|
|
98
|
+
}
|
|
99
|
+
if (this.opts.mediaResolution !== undefined) {
|
|
100
|
+
config["mediaResolution"] = this.opts.mediaResolution;
|
|
101
|
+
}
|
|
102
|
+
if (this.opts.seed !== undefined) {
|
|
103
|
+
config["seed"] = this.opts.seed;
|
|
104
|
+
}
|
|
105
|
+
if (this.opts.thinkingConfig !== undefined) {
|
|
106
|
+
config["thinkingConfig"] = this.opts.thinkingConfig;
|
|
107
|
+
}
|
|
108
|
+
if (this.opts.enableAffectiveDialog !== undefined) {
|
|
109
|
+
config["enableAffectiveDialog"] = this.opts.enableAffectiveDialog;
|
|
110
|
+
}
|
|
111
|
+
if (this.opts.realtimeInputConfig !== undefined) {
|
|
112
|
+
config["realtimeInputConfig"] = this.opts.realtimeInputConfig;
|
|
113
|
+
}
|
|
114
|
+
if (this.opts.contextWindowCompression !== undefined) {
|
|
115
|
+
config["contextWindowCompression"] = this.opts.contextWindowCompression;
|
|
116
|
+
}
|
|
117
|
+
if (this.opts.proactivity !== undefined) {
|
|
118
|
+
config["proactivity"] = this.opts.proactivity;
|
|
119
|
+
}
|
|
120
|
+
if (this.opts.explicitVadSignal !== undefined) {
|
|
121
|
+
config["explicitVadSignal"] = this.opts.explicitVadSignal;
|
|
122
|
+
}
|
|
123
|
+
if (this.opts.connectConfig) {
|
|
124
|
+
Object.assign(config, this.opts.connectConfig);
|
|
125
|
+
}
|
|
126
|
+
const openPromise = new Promise((resolve, reject) => {
|
|
127
|
+
this.openResolver = resolve;
|
|
128
|
+
this.openRejecter = reject;
|
|
129
|
+
});
|
|
130
|
+
const ai = new GoogleGenAI({
|
|
131
|
+
apiKey: this.opts.apiKey,
|
|
132
|
+
...(this.opts.apiVersion === undefined
|
|
133
|
+
? {}
|
|
134
|
+
: { httpOptions: { apiVersion: this.opts.apiVersion } }),
|
|
135
|
+
});
|
|
136
|
+
this.session = await ai.live.connect({
|
|
137
|
+
model,
|
|
138
|
+
config,
|
|
139
|
+
callbacks: {
|
|
140
|
+
onopen: () => this.resolveOpen(),
|
|
141
|
+
onmessage: (msg) => this.handleMessage(msg),
|
|
142
|
+
onerror: (ev) => {
|
|
143
|
+
const cause = ev instanceof Error ? ev : new Error(String(ev));
|
|
144
|
+
this.stream.push({ type: "error", cause, recoverable: true });
|
|
145
|
+
this.rejectOpen(cause);
|
|
146
|
+
},
|
|
147
|
+
onclose: () => this.stream.close(),
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
this.abortHandler = () => {
|
|
151
|
+
void this.close();
|
|
152
|
+
this.rejectOpen(new Error("Gemini Live adapter open aborted"));
|
|
153
|
+
};
|
|
154
|
+
signal.addEventListener("abort", this.abortHandler, { once: true });
|
|
155
|
+
await openPromise;
|
|
156
|
+
}
|
|
157
|
+
sendAudio(pcm16) {
|
|
158
|
+
this.requireSession().sendRealtimeInput({
|
|
159
|
+
audio: {
|
|
160
|
+
data: bytesToBase64(pcm16),
|
|
161
|
+
mimeType: "audio/pcm;rate=16000",
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
sendText(text) {
|
|
166
|
+
this.requireSession().sendClientContent({
|
|
167
|
+
turns: [{ role: "user", parts: [{ text }] }],
|
|
168
|
+
turnComplete: true,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
injectContext(text) {
|
|
172
|
+
// Gemini Live drops system/developer roles from conversation history. A silent,
|
|
173
|
+
// incomplete user turn preserves the steering context without requesting a response.
|
|
174
|
+
this.requireSession().sendClientContent({
|
|
175
|
+
turns: [{ role: "user", parts: [{ text: `[Context-only instruction]\n${text}` }] }],
|
|
176
|
+
turnComplete: false,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
cancelResponse(_audioEndMs) {
|
|
180
|
+
// Gemini handles interruption server-side via `interrupted`; no truncate API.
|
|
181
|
+
}
|
|
182
|
+
injectToolResult(toolId, text) {
|
|
183
|
+
const name = this.toolNames.get(toolId);
|
|
184
|
+
if (!name) {
|
|
185
|
+
this.stream.push({
|
|
186
|
+
type: "error",
|
|
187
|
+
cause: new Error(`unknown tool id "${toolId}" for Gemini tool response`),
|
|
188
|
+
recoverable: false,
|
|
189
|
+
});
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
this.requireSession().sendToolResponse({
|
|
193
|
+
functionResponses: [{
|
|
194
|
+
id: toolId,
|
|
195
|
+
name,
|
|
196
|
+
response: { result: text },
|
|
197
|
+
}],
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
async close() {
|
|
201
|
+
if (this.abortHandler) {
|
|
202
|
+
// signal may already be gone; best-effort cleanup
|
|
203
|
+
}
|
|
204
|
+
this.session?.close();
|
|
205
|
+
this.session = null;
|
|
206
|
+
this.stream.close();
|
|
207
|
+
}
|
|
208
|
+
requireSession() {
|
|
209
|
+
if (!this.session)
|
|
210
|
+
throw new Error("Gemini Live adapter is not open");
|
|
211
|
+
return this.session;
|
|
212
|
+
}
|
|
213
|
+
rejectOpen(err) {
|
|
214
|
+
this.openRejecter?.(err);
|
|
215
|
+
this.openResolver = null;
|
|
216
|
+
this.openRejecter = null;
|
|
217
|
+
}
|
|
218
|
+
resolveOpen() {
|
|
219
|
+
this.openResolver?.();
|
|
220
|
+
this.openResolver = null;
|
|
221
|
+
this.openRejecter = null;
|
|
222
|
+
}
|
|
223
|
+
handleMessage(msg) {
|
|
224
|
+
// G4: surface fresh resumption handles so a durable host can persist the latest.
|
|
225
|
+
const resumption = msg.sessionResumptionUpdate;
|
|
226
|
+
if (resumption?.resumable && resumption.newHandle) {
|
|
227
|
+
this.stream.push({ type: "resumption_handle", handle: resumption.newHandle });
|
|
228
|
+
}
|
|
229
|
+
if (msg.setupComplete) {
|
|
230
|
+
if (!this.activeResponse) {
|
|
231
|
+
this.activeResponse = true;
|
|
232
|
+
this.stream.push({ type: "response_started" });
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
const content = msg.serverContent;
|
|
236
|
+
if (content) {
|
|
237
|
+
if (content.interrupted) {
|
|
238
|
+
this.stream.push({ type: "speech_started" });
|
|
239
|
+
}
|
|
240
|
+
if (content.inputTranscription?.text) {
|
|
241
|
+
this.stream.push({
|
|
242
|
+
type: "transcript",
|
|
243
|
+
role: "user",
|
|
244
|
+
text: content.inputTranscription.text,
|
|
245
|
+
final: content.inputTranscription.finished ?? false,
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
if (content.outputTranscription?.text) {
|
|
249
|
+
this.stream.push({
|
|
250
|
+
type: "transcript",
|
|
251
|
+
role: "assistant",
|
|
252
|
+
text: content.outputTranscription.text,
|
|
253
|
+
final: content.outputTranscription.finished ?? false,
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
const parts = content.modelTurn?.parts;
|
|
257
|
+
if (parts) {
|
|
258
|
+
if (!this.activeResponse) {
|
|
259
|
+
this.activeResponse = true;
|
|
260
|
+
this.stream.push({ type: "response_started" });
|
|
261
|
+
}
|
|
262
|
+
for (const part of parts) {
|
|
263
|
+
const inline = part.inlineData;
|
|
264
|
+
if (inline?.data && inline.mimeType?.startsWith("audio/")) {
|
|
265
|
+
const rateMatch = /rate=(\d+)/.exec(inline.mimeType);
|
|
266
|
+
const sampleRateHz = rateMatch ? Number(rateMatch[1]) : OUTPUT_SAMPLE_RATE_HZ;
|
|
267
|
+
this.stream.push({
|
|
268
|
+
type: "audio",
|
|
269
|
+
pcm16: base64ToBytes(inline.data),
|
|
270
|
+
sampleRateHz,
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
if (content.turnComplete) {
|
|
276
|
+
this.activeResponse = false;
|
|
277
|
+
this.stream.push({ type: "response_done" });
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
const calls = msg.toolCall?.functionCalls;
|
|
281
|
+
if (calls) {
|
|
282
|
+
for (const call of calls) {
|
|
283
|
+
const toolId = call.id ?? crypto.randomUUID();
|
|
284
|
+
const toolName = call.name ?? "unknown";
|
|
285
|
+
this.toolNames.set(toolId, toolName);
|
|
286
|
+
this.stream.push({
|
|
287
|
+
type: "tool_call",
|
|
288
|
+
toolId,
|
|
289
|
+
toolName,
|
|
290
|
+
args: (call.args ?? {}),
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
export function fromGeminiLive(opts) {
|
|
297
|
+
return new GeminiLiveAdapter(opts);
|
|
298
|
+
}
|
|
299
|
+
//# sourceMappingURL=from-gemini-live.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"from-gemini-live.js","sourceRoot":"","sources":["../src/from-gemini-live.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { SocketFactory } from "@kuralle-syrinx/ws";
|
|
2
|
+
import { base64ToBytes, bytesToBase64 } from "./base64.js";
|
|
3
|
+
import type { RealtimeAdapter, RealtimeResumeMessage, RealtimeToolDef } from "./realtime-adapter.js";
|
|
4
|
+
export interface OpenAIRealtimeOptions {
|
|
5
|
+
readonly apiKey: string;
|
|
6
|
+
readonly model?: string;
|
|
7
|
+
readonly voice?: string;
|
|
8
|
+
readonly socketFactory: SocketFactory;
|
|
9
|
+
readonly url?: () => string;
|
|
10
|
+
/** Server turn-detection config. Defaults to semantic_vad; pass `server_vad` or `null` to override. */
|
|
11
|
+
readonly turnDetection?: Record<string, unknown> | null;
|
|
12
|
+
/**
|
|
13
|
+
* Function tools the front model may call (e.g. a delegate tool routed to a Reasoner). Domain-neutral
|
|
14
|
+
* — the caller supplies these. Empty by default (standalone s2s, no delegation).
|
|
15
|
+
*/
|
|
16
|
+
readonly tools?: readonly RealtimeToolDef[];
|
|
17
|
+
readonly debug?: boolean;
|
|
18
|
+
/** gpt-realtime-2 requires response.create after function_call_output; set false for providers that do not. */
|
|
19
|
+
readonly requiresResponseCreateAfterToolOutput?: boolean;
|
|
20
|
+
readonly instructions?: string;
|
|
21
|
+
readonly modalities?: readonly string[];
|
|
22
|
+
readonly temperature?: number;
|
|
23
|
+
readonly inputTranscription?: Record<string, unknown> | boolean;
|
|
24
|
+
readonly toolChoice?: string | Record<string, unknown>;
|
|
25
|
+
readonly inputRateHz?: number;
|
|
26
|
+
readonly outputRateHz?: number;
|
|
27
|
+
/** Input audio format object. Defaults to `{ type: "audio/pcm", rate: inputRateHz }`. */
|
|
28
|
+
readonly inputAudioFormat?: Record<string, unknown>;
|
|
29
|
+
/** Output audio format object. Defaults to `{ type: "audio/pcm", rate: outputRateHz }`. */
|
|
30
|
+
readonly outputAudioFormat?: Record<string, unknown>;
|
|
31
|
+
/** OpenAI Realtime `audio.input.noise_reduction` (e.g. `{ type: "near_field" }`). */
|
|
32
|
+
readonly noiseReduction?: Record<string, unknown> | null;
|
|
33
|
+
/** OpenAI Realtime `max_output_tokens` session field. */
|
|
34
|
+
readonly maxOutputTokens?: number | "inf";
|
|
35
|
+
/**
|
|
36
|
+
* Merged last into `session.update.session` for any provider field the adapter does not enumerate
|
|
37
|
+
* (speed, tracing, prompt, include, …). Overrides same-key defaults when both set.
|
|
38
|
+
*/
|
|
39
|
+
readonly sessionConfig?: Record<string, unknown>;
|
|
40
|
+
/**
|
|
41
|
+
* G4 resume-by-replay: returns the prior conversation to replay as
|
|
42
|
+
* `conversation.item.create` items on every (re)connect — OpenAI Realtime has no
|
|
43
|
+
* native session resume. Replay never triggers a response (no double-answer).
|
|
44
|
+
*/
|
|
45
|
+
readonly resumeHistory?: () => readonly RealtimeResumeMessage[];
|
|
46
|
+
}
|
|
47
|
+
export declare function fromOpenAIRealtime(opts: OpenAIRealtimeOptions): RealtimeAdapter;
|
|
48
|
+
export { bytesToBase64, base64ToBytes };
|
|
49
|
+
//# sourceMappingURL=from-openai-realtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"from-openai-realtime.d.ts","sourceRoot":"","sources":["../src/from-openai-realtime.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE3D,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAMrG,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B,uGAAuG;IACvG,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACxD;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IAC5C,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,+GAA+G;IAC/G,QAAQ,CAAC,qCAAqC,CAAC,EAAE,OAAO,CAAC;IACzD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;IAChE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,yFAAyF;IACzF,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpD,2FAA2F;IAC3F,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrD,qFAAqF;IACrF,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzD,yDAAyD;IACzD,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC1C;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjD;;;;OAIG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,SAAS,qBAAqB,EAAE,CAAC;CACjE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,qBAAqB,GAAG,eAAe,CA6E/E;AAED,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
import { base64ToBytes, bytesToBase64 } from "./base64.js";
|
|
3
|
+
import { createOpenAiCompatibleRealtimeAdapter } from "./openai-compatible-realtime.js";
|
|
4
|
+
const DEFAULT_MODEL = "gpt-realtime-2";
|
|
5
|
+
const DEFAULT_VOICE = "marin";
|
|
6
|
+
const DEFAULT_SAMPLE_RATE_HZ = 24_000;
|
|
7
|
+
export function fromOpenAIRealtime(opts) {
|
|
8
|
+
const inputRateHz = opts.inputRateHz ?? DEFAULT_SAMPLE_RATE_HZ;
|
|
9
|
+
const outputRateHz = opts.outputRateHz ?? DEFAULT_SAMPLE_RATE_HZ;
|
|
10
|
+
const model = opts.model ?? DEFAULT_MODEL;
|
|
11
|
+
const voice = opts.voice ?? DEFAULT_VOICE;
|
|
12
|
+
return createOpenAiCompatibleRealtimeAdapter({
|
|
13
|
+
apiKey: opts.apiKey,
|
|
14
|
+
socketFactory: opts.socketFactory,
|
|
15
|
+
debug: opts.debug,
|
|
16
|
+
defaultModel: DEFAULT_MODEL,
|
|
17
|
+
model: opts.model,
|
|
18
|
+
url: opts.url,
|
|
19
|
+
caps: {
|
|
20
|
+
inputSampleRateHz: inputRateHz,
|
|
21
|
+
outputSampleRateHz: outputRateHz,
|
|
22
|
+
supportsConcurrentToolAudio: true,
|
|
23
|
+
supportsTruncate: true,
|
|
24
|
+
emitsServerSpeechStarted: true,
|
|
25
|
+
supportsTextOnlyModality: opts.modalities?.length === 1 && opts.modalities[0] === "text",
|
|
26
|
+
},
|
|
27
|
+
buildSessionUpdate: () => {
|
|
28
|
+
const inputAudio = {
|
|
29
|
+
format: opts.inputAudioFormat ?? { type: "audio/pcm", rate: inputRateHz },
|
|
30
|
+
turn_detection: "turnDetection" in opts ? opts.turnDetection : { type: "semantic_vad" },
|
|
31
|
+
};
|
|
32
|
+
if (opts.inputTranscription !== undefined) {
|
|
33
|
+
inputAudio["transcription"] =
|
|
34
|
+
opts.inputTranscription === true ? { model: "whisper-1" } : opts.inputTranscription;
|
|
35
|
+
}
|
|
36
|
+
if (opts.noiseReduction !== undefined) {
|
|
37
|
+
inputAudio["noise_reduction"] = opts.noiseReduction;
|
|
38
|
+
}
|
|
39
|
+
const outputAudio = {
|
|
40
|
+
format: opts.outputAudioFormat ?? { type: "audio/pcm", rate: outputRateHz },
|
|
41
|
+
voice,
|
|
42
|
+
};
|
|
43
|
+
const session = {
|
|
44
|
+
type: "realtime",
|
|
45
|
+
model,
|
|
46
|
+
output_modalities: opts.modalities ?? ["audio"],
|
|
47
|
+
audio: {
|
|
48
|
+
input: inputAudio,
|
|
49
|
+
output: outputAudio,
|
|
50
|
+
},
|
|
51
|
+
tools: (opts.tools ?? []).map((t) => ({
|
|
52
|
+
type: "function",
|
|
53
|
+
name: t.name,
|
|
54
|
+
description: t.description,
|
|
55
|
+
parameters: t.parameters,
|
|
56
|
+
})),
|
|
57
|
+
tool_choice: opts.toolChoice ?? "auto",
|
|
58
|
+
};
|
|
59
|
+
if (opts.instructions !== undefined) {
|
|
60
|
+
session["instructions"] = opts.instructions;
|
|
61
|
+
}
|
|
62
|
+
if (opts.temperature !== undefined) {
|
|
63
|
+
session["temperature"] = opts.temperature;
|
|
64
|
+
}
|
|
65
|
+
if (opts.maxOutputTokens !== undefined) {
|
|
66
|
+
session["max_output_tokens"] = opts.maxOutputTokens;
|
|
67
|
+
}
|
|
68
|
+
if (opts.sessionConfig) {
|
|
69
|
+
Object.assign(session, opts.sessionConfig);
|
|
70
|
+
}
|
|
71
|
+
return session;
|
|
72
|
+
},
|
|
73
|
+
supportsTruncate: true,
|
|
74
|
+
requiresResponseCreateAfterToolOutput: opts.requiresResponseCreateAfterToolOutput,
|
|
75
|
+
defaultErrorMessage: "OpenAI Realtime error",
|
|
76
|
+
...(opts.resumeHistory ? { buildResumeItems: opts.resumeHistory } : {}),
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
export { bytesToBase64, base64ToBytes };
|
|
80
|
+
//# sourceMappingURL=from-openai-realtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"from-openai-realtime.js","sourceRoot":"","sources":["../src/from-openai-realtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
declare const DEFAULT_MODEL = "gemini-3.5-live-translate-preview";
|
|
2
|
+
export interface GeminiTranslateSession {
|
|
3
|
+
sendAudio(pcm16: Uint8Array): void;
|
|
4
|
+
signalAudioStreamEnd(): void;
|
|
5
|
+
close(): Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
export interface GeminiTranslateSessionOptions {
|
|
8
|
+
readonly apiKey: string;
|
|
9
|
+
readonly targetLanguageCode: string;
|
|
10
|
+
readonly echoTargetLanguage?: boolean;
|
|
11
|
+
readonly onAudio: (pcm16: Uint8Array, sampleRateHz: number) => void;
|
|
12
|
+
readonly onText?: (text: string, role: "input" | "output", final: boolean) => void;
|
|
13
|
+
readonly onError?: (cause: Error) => void;
|
|
14
|
+
}
|
|
15
|
+
export declare function createGeminiTranslateSession(opts: GeminiTranslateSessionOptions): Promise<GeminiTranslateSession>;
|
|
16
|
+
export { DEFAULT_MODEL as GEMINI_TRANSLATE_MODEL };
|
|
17
|
+
//# sourceMappingURL=gemini-translate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-translate.d.ts","sourceRoot":"","sources":["../src/gemini-translate.ts"],"names":[],"mappings":"AAMA,QAAA,MAAM,aAAa,sCAAsC,CAAC;AAG1D,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACnC,oBAAoB,IAAI,IAAI,CAAC;IAC7B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACpE,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,QAAQ,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnF,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC3C;AAED,wBAAsB,4BAA4B,CAChD,IAAI,EAAE,6BAA6B,GAClC,OAAO,CAAC,sBAAsB,CAAC,CA+DjC;AAsCD,OAAO,EAAE,aAAa,IAAI,sBAAsB,EAAE,CAAC"}
|