@kuralle-syrinx/grok 4.4.0 → 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.
@@ -0,0 +1,31 @@
1
+ import type { SocketFactory } from "@kuralle-syrinx/ws";
2
+ import { base64ToBytes, bytesToBase64, type RealtimeAdapter, type RealtimeToolDef } from "@kuralle-syrinx/realtime";
3
+ export interface GrokRealtimeOptions {
4
+ readonly apiKey: string;
5
+ readonly model?: string;
6
+ readonly voice?: string;
7
+ readonly socketFactory: SocketFactory;
8
+ readonly url?: () => string;
9
+ readonly turnDetection?: Record<string, unknown> | null;
10
+ readonly tools?: readonly RealtimeToolDef[];
11
+ readonly debug?: boolean;
12
+ readonly instructions?: string;
13
+ readonly inputRateHz?: number;
14
+ readonly outputRateHz?: number;
15
+ /** Input audio format. Defaults to `{ type: "audio/pcm", rate: inputRateHz }`. */
16
+ readonly inputAudioFormat?: Record<string, unknown>;
17
+ /** Output audio format. Defaults to `{ type: "audio/pcm", rate: outputRateHz }`. */
18
+ readonly outputAudioFormat?: Record<string, unknown>;
19
+ readonly temperature?: number;
20
+ readonly modalities?: readonly string[];
21
+ readonly inputTranscription?: Record<string, unknown> | boolean;
22
+ readonly toolChoice?: string | Record<string, unknown>;
23
+ /**
24
+ * Merged last into `session.update.session` for provider-specific fields the
25
+ * adapter does not enumerate. Overrides same-key defaults when both set.
26
+ */
27
+ readonly sessionConfig?: Record<string, unknown>;
28
+ }
29
+ export declare function fromGrokRealtime(opts: GrokRealtimeOptions): RealtimeAdapter;
30
+ export { base64ToBytes, bytesToBase64 };
31
+ //# sourceMappingURL=from-grok-realtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"from-grok-realtime.d.ts","sourceRoot":"","sources":["../src/from-grok-realtime.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EACL,aAAa,EACb,aAAa,EAEb,KAAK,eAAe,EACpB,KAAK,eAAe,EACrB,MAAM,0BAA0B,CAAC;AAMlC,MAAM,WAAW,mBAAmB;IAClC,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,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACxD,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IAC5C,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,kFAAkF;IAClF,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpD,oFAAoF;IACpF,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,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;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,mBAAmB,GAAG,eAAe,CAqF3E;AAED,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC"}
@@ -0,0 +1,88 @@
1
+ // SPDX-License-Identifier: MIT
2
+ import { base64ToBytes, bytesToBase64, createOpenAiCompatibleRealtimeAdapter, } from "@kuralle-syrinx/realtime";
3
+ const DEFAULT_MODEL = "grok-voice-latest";
4
+ const DEFAULT_VOICE = "eve";
5
+ const DEFAULT_SAMPLE_RATE_HZ = 24_000;
6
+ export function fromGrokRealtime(opts) {
7
+ const inputRateHz = opts.inputRateHz ?? DEFAULT_SAMPLE_RATE_HZ;
8
+ const outputRateHz = opts.outputRateHz ?? DEFAULT_SAMPLE_RATE_HZ;
9
+ const voice = opts.voice ?? DEFAULT_VOICE;
10
+ return createOpenAiCompatibleRealtimeAdapter({
11
+ apiKey: opts.apiKey,
12
+ socketFactory: opts.socketFactory,
13
+ debug: opts.debug,
14
+ debugLogPrefix: "[grok-raw]",
15
+ defaultModel: DEFAULT_MODEL,
16
+ model: opts.model,
17
+ url: opts.url,
18
+ buildUrl: (model) => `wss://api.x.ai/v1/realtime?model=${encodeURIComponent(model)}`,
19
+ caps: {
20
+ inputSampleRateHz: inputRateHz,
21
+ outputSampleRateHz: outputRateHz,
22
+ supportsConcurrentToolAudio: false,
23
+ supportsTruncate: false,
24
+ emitsServerSpeechStarted: false,
25
+ },
26
+ buildSessionUpdate: () => {
27
+ const turnDetection = "turnDetection" in opts ? opts.turnDetection : { type: "server_vad" };
28
+ const inputAudio = {
29
+ format: opts.inputAudioFormat ?? { type: "audio/pcm", rate: inputRateHz },
30
+ };
31
+ if (opts.inputTranscription !== undefined) {
32
+ inputAudio["transcription"] =
33
+ opts.inputTranscription === true ? {} : opts.inputTranscription;
34
+ }
35
+ const session = {
36
+ voice,
37
+ turn_detection: turnDetection,
38
+ tools: (opts.tools ?? []).map((t) => ({
39
+ type: "function",
40
+ name: t.name,
41
+ description: t.description,
42
+ parameters: t.parameters,
43
+ })),
44
+ audio: {
45
+ input: inputAudio,
46
+ output: {
47
+ format: opts.outputAudioFormat ?? { type: "audio/pcm", rate: outputRateHz },
48
+ voice,
49
+ },
50
+ },
51
+ };
52
+ if (opts.instructions !== undefined) {
53
+ session["instructions"] = opts.instructions;
54
+ }
55
+ if (opts.temperature !== undefined) {
56
+ session["temperature"] = opts.temperature;
57
+ }
58
+ if (opts.modalities !== undefined) {
59
+ session["output_modalities"] = opts.modalities;
60
+ }
61
+ if (opts.toolChoice !== undefined) {
62
+ session["tool_choice"] = opts.toolChoice;
63
+ }
64
+ if (opts.sessionConfig) {
65
+ Object.assign(session, opts.sessionConfig);
66
+ }
67
+ return session;
68
+ },
69
+ supportsTruncate: false,
70
+ defaultErrorMessage: "Grok Realtime error",
71
+ extendServerMessage: (type, msg, ctx) => {
72
+ if (type !== "conversation.item.input_audio_transcription.updated")
73
+ return false;
74
+ const transcript = typeof msg["transcript"] === "string" ? msg["transcript"] : "";
75
+ if (transcript.length > 0) {
76
+ ctx.push({
77
+ type: "transcript",
78
+ role: "user",
79
+ text: transcript,
80
+ final: true,
81
+ });
82
+ }
83
+ return true;
84
+ },
85
+ });
86
+ }
87
+ export { base64ToBytes, bytesToBase64 };
88
+ //# sourceMappingURL=from-grok-realtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"from-grok-realtime.js","sourceRoot":"","sources":["../src/from-grok-realtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { GrokSTTPlugin } from "./stt.js";
2
+ export { GrokTTSPlugin } from "./tts.js";
3
+ export { fromGrokRealtime, type GrokRealtimeOptions } from "./from-grok-realtime.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ // SPDX-License-Identifier: MIT
2
+ export { GrokSTTPlugin } from "./stt.js";
3
+ export { GrokTTSPlugin } from "./tts.js";
4
+ export { fromGrokRealtime } from "./from-grok-realtime.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAE/B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAA4B,MAAM,yBAAyB,CAAC"}
package/dist/stt.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ import { type PipelineBus, type PluginConfig, type VoicePlugin } from "@kuralle-syrinx/core";
2
+ import type { SocketFactory } from "@kuralle-syrinx/ws";
3
+ export declare class GrokSTTPlugin implements VoicePlugin {
4
+ private readonly socketFactory?;
5
+ readonly endpointingCapability: {
6
+ owner: "provider_stt";
7
+ disableConfig: {
8
+ emit_eos_on_final: boolean;
9
+ finalize_on_speech_final: boolean;
10
+ };
11
+ };
12
+ constructor(socketFactory?: SocketFactory | undefined);
13
+ private session;
14
+ initialize(bus: PipelineBus, config: PluginConfig): Promise<void>;
15
+ close(): Promise<void>;
16
+ }
17
+ //# sourceMappingURL=stt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stt.d.ts","sourceRoot":"","sources":["../src/stt.ts"],"names":[],"mappings":"AAMA,OAAO,EAML,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;AAQ9B,OAAO,KAAK,EAAc,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAgGpE,qBAAa,aAAc,YAAW,WAAW;IASnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC;IAR3C,QAAQ,CAAC,qBAAqB;;;;;;MAM5B;gBAE2B,aAAa,CAAC,EAAE,aAAa,YAAA;IAE1D,OAAO,CAAC,OAAO,CAAoC;IAE7C,UAAU,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAkDjE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAI7B"}
package/dist/stt.js ADDED
@@ -0,0 +1,179 @@
1
+ // SPDX-License-Identifier: MIT
2
+ //
3
+ // Grok (xAI) STT Plugin. The streaming lifecycle lives in @kuralle-syrinx/stt-core. This
4
+ // file is the Grok wire protocol: connect URL + query knobs, audio.done finalize, and
5
+ // decode of transcript.created / transcript.partial (is_final / duration / speech_final).
6
+ import { assertAudioFormat, optionalStringConfig, readProviderRetryConfig, requireStringConfig, } from "@kuralle-syrinx/core";
7
+ import { defaultNodeSocketFactory, startStreamingSttSession, } from "@kuralle-syrinx/stt-core";
8
+ const AUDIO_DONE = JSON.stringify({ type: "audio.done" });
9
+ class GrokSttWireProtocol {
10
+ ready = false;
11
+ isReady() {
12
+ return this.ready;
13
+ }
14
+ onConnectionLost() {
15
+ this.ready = false;
16
+ }
17
+ encodeFinalize() {
18
+ return [AUDIO_DONE];
19
+ }
20
+ encodeClose() {
21
+ return [AUDIO_DONE];
22
+ }
23
+ decode(data, _isBinary) {
24
+ if (typeof data !== "string")
25
+ return [];
26
+ let msg;
27
+ try {
28
+ msg = JSON.parse(data);
29
+ }
30
+ catch (err) {
31
+ return [
32
+ {
33
+ type: "error",
34
+ error: new Error(`Grok STT provider sent malformed JSON: ${err instanceof Error ? err.message : String(err)}`),
35
+ },
36
+ ];
37
+ }
38
+ const type = typeof msg["type"] === "string" ? msg["type"] : "";
39
+ switch (type) {
40
+ case "transcript.created":
41
+ this.ready = true;
42
+ return [];
43
+ case "transcript.partial":
44
+ return this.decodePartial(msg);
45
+ case "transcript.done":
46
+ return [];
47
+ case "error":
48
+ return [
49
+ {
50
+ type: "error",
51
+ error: new Error(typeof msg["message"] === "string" ? msg["message"] : "Grok STT provider error"),
52
+ },
53
+ ];
54
+ default:
55
+ return [];
56
+ }
57
+ }
58
+ decodePartial(msg) {
59
+ const text = typeof msg["text"] === "string" ? msg["text"].trim() : "";
60
+ if (!text)
61
+ return [];
62
+ const isFinal = msg["is_final"] === true;
63
+ const speechFinal = msg["speech_final"] === true;
64
+ const confidence = typeof msg["end_of_turn_confidence"] === "number" ? msg["end_of_turn_confidence"] : 0;
65
+ // contextId is stamped by the session from the audio/turn context.
66
+ const contextId = "";
67
+ if (!isFinal) {
68
+ return [{ type: "interim", contextId, text }];
69
+ }
70
+ return [
71
+ {
72
+ type: "final",
73
+ contextId,
74
+ text,
75
+ confidence,
76
+ speechFinal,
77
+ audioSeconds: typeof msg["duration"] === "number" ? msg["duration"] : undefined,
78
+ provider: {
79
+ speechFinal,
80
+ words: msg["words"],
81
+ start: msg["start"],
82
+ duration: msg["duration"],
83
+ },
84
+ },
85
+ ];
86
+ }
87
+ }
88
+ export class GrokSTTPlugin {
89
+ socketFactory;
90
+ endpointingCapability = {
91
+ owner: "provider_stt",
92
+ disableConfig: {
93
+ emit_eos_on_final: false,
94
+ finalize_on_speech_final: false,
95
+ },
96
+ };
97
+ constructor(socketFactory) {
98
+ this.socketFactory = socketFactory;
99
+ }
100
+ session = null;
101
+ async initialize(bus, config) {
102
+ const apiKey = requireStringConfig(config, "api_key");
103
+ const sampleRate = config["sample_rate"] ?? 16000;
104
+ const language = optionalStringConfig(config, "language") ?? "en";
105
+ const endpointUrl = optionalStringConfig(config, "endpoint_url") ?? "wss://api.x.ai/v1/stt";
106
+ const encoding = optionalStringConfig(config, "encoding") ?? "pcm";
107
+ const interimResults = config["interim_results"] ?? true;
108
+ const endpointing = config["endpointing"] ?? 10;
109
+ const smartTurn = typeof config["smart_turn"] === "number" ? config["smart_turn"] : undefined;
110
+ const smartTurnTimeoutMs = typeof config["smart_turn_timeout"] === "number" ? config["smart_turn_timeout"] : undefined;
111
+ const diarize = config["diarize"] ?? false;
112
+ const keyterm = optionalStringConfig(config, "keyterm");
113
+ const emitEosOnFinal = config["emit_eos_on_final"] ?? true;
114
+ const queryParams = readPlainObject(config["query_params"]);
115
+ const audioFormat = { encoding: "pcm_s16le", sampleRateHz: sampleRate, channels: 1 };
116
+ assertAudioFormat(audioFormat);
117
+ this.session = await startStreamingSttSession(bus, {
118
+ protocol: new GrokSttWireProtocol(),
119
+ provider: { name: "grok", model: "stt", region: "global" },
120
+ format: audioFormat,
121
+ language,
122
+ emitEosOnFinal,
123
+ url: () => {
124
+ const params = new URLSearchParams({
125
+ sample_rate: String(sampleRate),
126
+ encoding,
127
+ interim_results: String(interimResults),
128
+ language,
129
+ endpointing: String(endpointing),
130
+ });
131
+ if (smartTurn !== undefined)
132
+ params.set("smart_turn", String(smartTurn));
133
+ if (smartTurnTimeoutMs !== undefined) {
134
+ params.set("smart_turn_timeout", String(smartTurnTimeoutMs));
135
+ }
136
+ if (diarize)
137
+ params.set("diarize", "true");
138
+ if (keyterm)
139
+ params.set("keyterm", keyterm);
140
+ applyQueryParams(params, queryParams);
141
+ const separator = endpointUrl.includes("?") ? "&" : "?";
142
+ return `${endpointUrl}${separator}${params.toString()}`;
143
+ },
144
+ headers: { Authorization: `Bearer ${apiKey}` },
145
+ socketFactory: this.socketFactory ?? (await defaultNodeSocketFactory()),
146
+ retry: readProviderRetryConfig(config),
147
+ replayBufferSize: config["replay_buffer_size"] ?? 64,
148
+ metricPrefix: "stt.grok",
149
+ });
150
+ }
151
+ async close() {
152
+ await this.session?.dispose();
153
+ this.session = null;
154
+ }
155
+ }
156
+ function readPlainObject(value) {
157
+ if (value !== null && typeof value === "object" && !Array.isArray(value)) {
158
+ return value;
159
+ }
160
+ return undefined;
161
+ }
162
+ function applyQueryParams(params, extra) {
163
+ if (!extra)
164
+ return;
165
+ for (const [key, value] of Object.entries(extra)) {
166
+ if (value === undefined || value === null)
167
+ continue;
168
+ if (Array.isArray(value)) {
169
+ for (const item of value) {
170
+ if (item === undefined || item === null)
171
+ continue;
172
+ params.append(key, String(item));
173
+ }
174
+ continue;
175
+ }
176
+ params.set(key, String(value));
177
+ }
178
+ }
179
+ //# sourceMappingURL=stt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stt.js","sourceRoot":"","sources":["../src/stt.ts"],"names":[],"mappings":"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"}
package/dist/tts.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ import { type PipelineBus, type PluginConfig, type VoicePlugin } from "@kuralle-syrinx/core";
2
+ import type { SocketFactory } from "@kuralle-syrinx/ws";
3
+ export declare class GrokTTSPlugin implements VoicePlugin {
4
+ private readonly socketFactory?;
5
+ constructor(socketFactory?: SocketFactory | undefined);
6
+ private session;
7
+ initialize(bus: PipelineBus, config: PluginConfig): Promise<void>;
8
+ close(): Promise<void>;
9
+ }
10
+ //# sourceMappingURL=tts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tts.d.ts","sourceRoot":"","sources":["../src/tts.ts"],"names":[],"mappings":"AAQA,OAAO,EAOL,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;AAU9B,OAAO,KAAK,EAAc,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAiGpE,qBAAa,aAAc,YAAW,WAAW;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC;gBAAd,aAAa,CAAC,EAAE,aAAa,YAAA;IAE1D,OAAO,CAAC,OAAO,CAAoC;IAE7C,UAAU,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAqCjE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAI7B"}
package/dist/tts.js ADDED
@@ -0,0 +1,178 @@
1
+ // SPDX-License-Identifier: MIT
2
+ //
3
+ // Grok (xAI) TTS Plugin. The streaming lifecycle lives in @kuralle-syrinx/tts-core. This
4
+ // file is the Grok wire protocol: single-context streaming (one active utterance at a time),
5
+ // text.delta/text.done/text.clear out, base64 audio.delta in. Grok frames carry no key, so
6
+ // inbound audio is attributed to the one current context. Raw PCM may split mid-sample, so
7
+ // Grok relies on the engine's streaming carry.
8
+ import { Route, assertAudioFormat, optionalStringConfig, readProviderRetryConfig, requireStringConfig, } from "@kuralle-syrinx/core";
9
+ import { attributionKey, defaultNodeSocketFactory, startStreamingTtsSession, } from "@kuralle-syrinx/tts-core";
10
+ import { base64ToBytes } from "@kuralle-syrinx/realtime";
11
+ const KEEP_ALIVE_INTERVAL_MS = 10_000;
12
+ class GrokWireProtocol {
13
+ modelId;
14
+ // Grok streams one context at a time; inbound frames carry no key, so they're attributed
15
+ // to the current one. (Audio for an interrupted context is dropped by the engine's
16
+ // cancelled-key tracking, which subsumes Grok's old `clearedPending` race guard.)
17
+ current = null;
18
+ charactersByKey = new Map();
19
+ constructor(modelId) {
20
+ this.modelId = modelId;
21
+ }
22
+ attributionFor(contextId) {
23
+ this.current = attributionKey(contextId);
24
+ return { key: this.current, contextId };
25
+ }
26
+ encodeText(key, text) {
27
+ this.charactersByKey.set(key, (this.charactersByKey.get(key) ?? 0) + text.length);
28
+ return [JSON.stringify({ type: "text.delta", delta: text })];
29
+ }
30
+ encodeFinish() {
31
+ return [JSON.stringify({ type: "text.done" })];
32
+ }
33
+ encodeCancel(key) {
34
+ this.charactersByKey.delete(key);
35
+ return [JSON.stringify({ type: "text.clear" })];
36
+ }
37
+ encodeClose() {
38
+ return [];
39
+ }
40
+ decode(data) {
41
+ if (typeof data !== "string")
42
+ return [];
43
+ let msg;
44
+ try {
45
+ msg = JSON.parse(data);
46
+ }
47
+ catch {
48
+ return []; // Grok ignores unparseable frames (does not fail the session).
49
+ }
50
+ const key = this.current;
51
+ switch (msg["type"]) {
52
+ case "audio.delta": {
53
+ if (!key)
54
+ return [];
55
+ const delta = typeof msg["delta"] === "string" ? msg["delta"] : "";
56
+ if (delta.length === 0)
57
+ return [];
58
+ try {
59
+ return [{ type: "audio", key, pcm: base64ToBytes(delta) }];
60
+ }
61
+ catch (err) {
62
+ return [{ type: "error", key, error: err instanceof Error ? err : new Error(String(err)) }];
63
+ }
64
+ }
65
+ case "audio.done": {
66
+ const characters = key ? (this.charactersByKey.get(key) ?? 0) : 0;
67
+ if (key)
68
+ this.charactersByKey.delete(key);
69
+ this.current = null;
70
+ if (!key)
71
+ return [];
72
+ const events = [];
73
+ // Sideband before context_end so the engine still has the key→context mapping.
74
+ if (characters > 0) {
75
+ const modelId = this.modelId;
76
+ events.push({
77
+ type: "sideband",
78
+ key,
79
+ route: Route.Background,
80
+ build: (ctxId, timestampMs) => ({
81
+ kind: "usage.recorded",
82
+ contextId: ctxId,
83
+ timestampMs,
84
+ stage: "tts",
85
+ provider: "grok",
86
+ model: modelId,
87
+ characters,
88
+ }),
89
+ });
90
+ }
91
+ events.push({ type: "context_end", key });
92
+ return events;
93
+ }
94
+ case "audio.clear":
95
+ // Provider acknowledged a text.clear. Audio for the interrupted context is already
96
+ // dropped via the engine's cancelled tracking; nothing more to do.
97
+ return [];
98
+ case "error":
99
+ if (key)
100
+ this.charactersByKey.delete(key);
101
+ return key ? [{ type: "error", key, error: grokProviderError(msg) }] : [];
102
+ default:
103
+ return [];
104
+ }
105
+ }
106
+ }
107
+ export class GrokTTSPlugin {
108
+ socketFactory;
109
+ constructor(socketFactory) {
110
+ this.socketFactory = socketFactory;
111
+ }
112
+ session = null;
113
+ async initialize(bus, config) {
114
+ const apiKey = requireStringConfig(config, "api_key");
115
+ const voiceId = optionalStringConfig(config, "voice_id") ?? "eve";
116
+ const language = optionalStringConfig(config, "language") ?? "en";
117
+ const endpointUrl = optionalStringConfig(config, "endpoint_url") ?? "wss://api.x.ai/v1/tts";
118
+ const sampleRate = readPositiveInteger(config["sample_rate"], 16000);
119
+ const codec = optionalStringConfig(config, "codec") ?? "pcm";
120
+ const bitRate = readPositiveIntegerOrUndefined(config["bit_rate"]);
121
+ const audioFormat = { encoding: "pcm_s16le", sampleRateHz: sampleRate, channels: 1 };
122
+ assertAudioFormat(audioFormat);
123
+ this.session = await startStreamingTtsSession(bus, {
124
+ protocol: new GrokWireProtocol(voiceId),
125
+ provider: { name: "grok", model: voiceId, region: "global" },
126
+ format: audioFormat,
127
+ sampleRateHz: sampleRate,
128
+ url: () => {
129
+ const params = new URLSearchParams({
130
+ language,
131
+ voice: voiceId,
132
+ codec,
133
+ sample_rate: String(sampleRate),
134
+ });
135
+ if (bitRate !== undefined)
136
+ params.set("bit_rate", String(bitRate));
137
+ const separator = endpointUrl.includes("?") ? "&" : "?";
138
+ return `${endpointUrl}${separator}${params.toString()}`;
139
+ },
140
+ headers: { Authorization: `Bearer ${apiKey}` },
141
+ retry: readProviderRetryConfig(config),
142
+ finishTimeoutMs: readNonNegativeInteger(config["finish_timeout_ms"], 2000),
143
+ metricPrefix: "tts.grok",
144
+ socketFactory: this.socketFactory ?? (await defaultNodeSocketFactory()),
145
+ replayBufferSize: config["replay_buffer_size"] ?? 32,
146
+ keepAliveIntervalMs: KEEP_ALIVE_INTERVAL_MS,
147
+ });
148
+ }
149
+ async close() {
150
+ await this.session?.dispose();
151
+ this.session = null;
152
+ }
153
+ }
154
+ function grokProviderError(msg) {
155
+ const message = (typeof msg["message"] === "string" && msg["message"]) ||
156
+ (typeof msg["error"] === "string" && msg["error"]) ||
157
+ "Grok TTS provider error";
158
+ return new Error(message);
159
+ }
160
+ function readPositiveInteger(value, fallback) {
161
+ if (typeof value !== "number" || !Number.isFinite(value))
162
+ return fallback;
163
+ const integer = Math.floor(value);
164
+ return integer > 0 ? integer : fallback;
165
+ }
166
+ function readPositiveIntegerOrUndefined(value) {
167
+ if (typeof value !== "number" || !Number.isFinite(value))
168
+ return undefined;
169
+ const integer = Math.floor(value);
170
+ return integer > 0 ? integer : undefined;
171
+ }
172
+ function readNonNegativeInteger(value, fallback) {
173
+ if (typeof value !== "number" || !Number.isFinite(value))
174
+ return fallback;
175
+ const integer = Math.floor(value);
176
+ return integer >= 0 ? integer : fallback;
177
+ }
178
+ //# sourceMappingURL=tts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tts.js","sourceRoot":"","sources":["../src/tts.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kuralle-syrinx/grok",
3
- "version": "4.4.0",
3
+ "version": "4.5.0",
4
4
  "private": false,
5
5
  "description": "xAI Grok adapters for Syrinx — STT, TTS, and realtime",
6
6
  "keywords": [
@@ -23,29 +23,48 @@
23
23
  "url": "https://github.com/kuralle/syrinx/issues"
24
24
  },
25
25
  "type": "module",
26
- "main": "./src/index.ts",
27
- "types": "./src/index.ts",
26
+ "main": "./dist/index.js",
27
+ "types": "./dist/index.d.ts",
28
28
  "exports": {
29
- ".": "./src/index.ts",
30
- "./stt": "./src/stt.ts",
31
- "./tts": "./src/tts.ts",
32
- "./realtime": "./src/from-grok-realtime.ts"
29
+ ".": {
30
+ "types": "./dist/index.d.ts",
31
+ "default": "./dist/index.js"
32
+ },
33
+ "./stt": {
34
+ "types": "./dist/stt.d.ts",
35
+ "default": "./dist/stt.js"
36
+ },
37
+ "./tts": {
38
+ "types": "./dist/tts.d.ts",
39
+ "default": "./dist/tts.js"
40
+ },
41
+ "./realtime": {
42
+ "types": "./dist/from-grok-realtime.d.ts",
43
+ "default": "./dist/from-grok-realtime.js"
44
+ }
33
45
  },
34
46
  "dependencies": {
35
- "@kuralle-syrinx/realtime": "4.4.0",
36
- "@kuralle-syrinx/core": "4.4.0",
37
- "@kuralle-syrinx/tts-core": "4.4.0",
38
- "@kuralle-syrinx/stt-core": "4.4.0",
39
- "@kuralle-syrinx/ws": "4.4.0"
47
+ "@kuralle-syrinx/realtime": "4.5.0",
48
+ "@kuralle-syrinx/stt-core": "4.5.0",
49
+ "@kuralle-syrinx/ws": "4.5.0",
50
+ "@kuralle-syrinx/tts-core": "4.5.0",
51
+ "@kuralle-syrinx/core": "4.5.0"
40
52
  },
41
53
  "devDependencies": {
54
+ "@types/node": "^22.0.0",
42
55
  "@types/ws": "^8.5.0",
43
56
  "typescript": "^5.7.0",
44
57
  "vitest": "^3.2.6",
45
58
  "ws": "^8.21.0"
46
59
  },
60
+ "files": [
61
+ "dist",
62
+ "src",
63
+ "README.md"
64
+ ],
47
65
  "scripts": {
48
66
  "typecheck": "tsc --noEmit",
49
- "test": "vitest run"
67
+ "test": "vitest run",
68
+ "build": "tsc -p tsconfig.build.json"
50
69
  }
51
70
  }