@realtimex/sdk 1.1.4 → 1.2.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/index.d.mts CHANGED
@@ -79,6 +79,24 @@ interface Task {
79
79
  updated_at: string;
80
80
  runs: TaskRun[];
81
81
  }
82
+ interface TTSOptions {
83
+ voice?: string;
84
+ model?: string;
85
+ speed?: number;
86
+ provider?: string;
87
+ }
88
+ interface TTSProvider {
89
+ id: string;
90
+ name: string;
91
+ type: 'remote' | 'local';
92
+ voices: string[];
93
+ }
94
+ interface TTSProvidersResponse {
95
+ success: boolean;
96
+ providers: TTSProvider[];
97
+ default: string;
98
+ error?: string;
99
+ }
82
100
 
83
101
  /**
84
102
  * Activities Module - HTTP Proxy to RealtimeX Main App
@@ -636,6 +654,49 @@ declare class LLMModule {
636
654
  search(query: string, options?: VectorQueryOptions): Promise<VectorQueryResult[]>;
637
655
  }
638
656
 
657
+ declare class TTSModule {
658
+ private baseUrl;
659
+ private appId;
660
+ private appName;
661
+ private apiKey?;
662
+ constructor(realtimexUrl: string, appId: string, appName?: string, apiKey?: string);
663
+ private get headers();
664
+ /**
665
+ * Request a single permission from Electron via internal API
666
+ */
667
+ private requestPermission;
668
+ /**
669
+ * Internal request wrapper that handles automatic permission prompts
670
+ */
671
+ private request;
672
+ /**
673
+ * Generate speech from text (returns full buffer)
674
+ *
675
+ * @example
676
+ * ```ts
677
+ * const buffer = await sdk.tts.speak("Hello world");
678
+ * // Play buffer...
679
+ * ```
680
+ */
681
+ speak(text: string, options?: TTSOptions): Promise<ArrayBuffer>;
682
+ /**
683
+ * Generate speech from text (returns stream)
684
+ *
685
+ * @example
686
+ * ```ts
687
+ * const stream = await sdk.tts.speakStream("Hello world");
688
+ * for await (const chunk of stream) {
689
+ * // Play chunk...
690
+ * }
691
+ * ```
692
+ */
693
+ speakStream(text: string, options?: TTSOptions): AsyncGenerator<Uint8Array>;
694
+ /**
695
+ * List available TTS providers
696
+ */
697
+ listProviders(): Promise<TTSProvider[]>;
698
+ }
699
+
639
700
  /**
640
701
  * RealtimeX Local App SDK
641
702
  *
@@ -650,6 +711,7 @@ declare class RealtimeXSDK {
650
711
  task: TaskModule;
651
712
  port: PortModule;
652
713
  llm: LLMModule;
714
+ tts: TTSModule;
653
715
  readonly appId: string;
654
716
  readonly appName: string | undefined;
655
717
  readonly apiKey: string | undefined;
@@ -683,4 +745,4 @@ declare class RealtimeXSDK {
683
745
  getAppDataDir(): Promise<string>;
684
746
  }
685
747
 
686
- export { ActivitiesModule, type Activity, type Agent, ApiModule, type ChatMessage, type ChatOptions, type ChatResponse, type EmbedOptions, type EmbedResponse, LLMModule, LLMPermissionError, LLMProviderError, PermissionDeniedError, PermissionRequiredError, PortModule, type Provider, type ProvidersResponse, RealtimeXSDK, type SDKConfig, type StreamChunk, type Task, TaskModule, type TaskRun, type Thread, type TriggerAgentPayload, type TriggerAgentResponse, type VectorDeleteOptions, type VectorDeleteResponse, type VectorQueryOptions, type VectorQueryResponse, type VectorQueryResult, type VectorRecord, VectorStore, type VectorUpsertOptions, type VectorUpsertResponse, WebhookModule, type Workspace };
748
+ export { ActivitiesModule, type Activity, type Agent, ApiModule, type ChatMessage, type ChatOptions, type ChatResponse, type EmbedOptions, type EmbedResponse, LLMModule, LLMPermissionError, LLMProviderError, PermissionDeniedError, PermissionRequiredError, PortModule, type Provider, type ProvidersResponse, RealtimeXSDK, type SDKConfig, type StreamChunk, TTSModule, type TTSOptions, type TTSProvider, type TTSProvidersResponse, type Task, TaskModule, type TaskRun, type Thread, type TriggerAgentPayload, type TriggerAgentResponse, type VectorDeleteOptions, type VectorDeleteResponse, type VectorQueryOptions, type VectorQueryResponse, type VectorQueryResult, type VectorRecord, VectorStore, type VectorUpsertOptions, type VectorUpsertResponse, WebhookModule, type Workspace };
package/dist/index.d.ts CHANGED
@@ -79,6 +79,24 @@ interface Task {
79
79
  updated_at: string;
80
80
  runs: TaskRun[];
81
81
  }
82
+ interface TTSOptions {
83
+ voice?: string;
84
+ model?: string;
85
+ speed?: number;
86
+ provider?: string;
87
+ }
88
+ interface TTSProvider {
89
+ id: string;
90
+ name: string;
91
+ type: 'remote' | 'local';
92
+ voices: string[];
93
+ }
94
+ interface TTSProvidersResponse {
95
+ success: boolean;
96
+ providers: TTSProvider[];
97
+ default: string;
98
+ error?: string;
99
+ }
82
100
 
83
101
  /**
84
102
  * Activities Module - HTTP Proxy to RealtimeX Main App
@@ -636,6 +654,49 @@ declare class LLMModule {
636
654
  search(query: string, options?: VectorQueryOptions): Promise<VectorQueryResult[]>;
637
655
  }
638
656
 
657
+ declare class TTSModule {
658
+ private baseUrl;
659
+ private appId;
660
+ private appName;
661
+ private apiKey?;
662
+ constructor(realtimexUrl: string, appId: string, appName?: string, apiKey?: string);
663
+ private get headers();
664
+ /**
665
+ * Request a single permission from Electron via internal API
666
+ */
667
+ private requestPermission;
668
+ /**
669
+ * Internal request wrapper that handles automatic permission prompts
670
+ */
671
+ private request;
672
+ /**
673
+ * Generate speech from text (returns full buffer)
674
+ *
675
+ * @example
676
+ * ```ts
677
+ * const buffer = await sdk.tts.speak("Hello world");
678
+ * // Play buffer...
679
+ * ```
680
+ */
681
+ speak(text: string, options?: TTSOptions): Promise<ArrayBuffer>;
682
+ /**
683
+ * Generate speech from text (returns stream)
684
+ *
685
+ * @example
686
+ * ```ts
687
+ * const stream = await sdk.tts.speakStream("Hello world");
688
+ * for await (const chunk of stream) {
689
+ * // Play chunk...
690
+ * }
691
+ * ```
692
+ */
693
+ speakStream(text: string, options?: TTSOptions): AsyncGenerator<Uint8Array>;
694
+ /**
695
+ * List available TTS providers
696
+ */
697
+ listProviders(): Promise<TTSProvider[]>;
698
+ }
699
+
639
700
  /**
640
701
  * RealtimeX Local App SDK
641
702
  *
@@ -650,6 +711,7 @@ declare class RealtimeXSDK {
650
711
  task: TaskModule;
651
712
  port: PortModule;
652
713
  llm: LLMModule;
714
+ tts: TTSModule;
653
715
  readonly appId: string;
654
716
  readonly appName: string | undefined;
655
717
  readonly apiKey: string | undefined;
@@ -683,4 +745,4 @@ declare class RealtimeXSDK {
683
745
  getAppDataDir(): Promise<string>;
684
746
  }
685
747
 
686
- export { ActivitiesModule, type Activity, type Agent, ApiModule, type ChatMessage, type ChatOptions, type ChatResponse, type EmbedOptions, type EmbedResponse, LLMModule, LLMPermissionError, LLMProviderError, PermissionDeniedError, PermissionRequiredError, PortModule, type Provider, type ProvidersResponse, RealtimeXSDK, type SDKConfig, type StreamChunk, type Task, TaskModule, type TaskRun, type Thread, type TriggerAgentPayload, type TriggerAgentResponse, type VectorDeleteOptions, type VectorDeleteResponse, type VectorQueryOptions, type VectorQueryResponse, type VectorQueryResult, type VectorRecord, VectorStore, type VectorUpsertOptions, type VectorUpsertResponse, WebhookModule, type Workspace };
748
+ export { ActivitiesModule, type Activity, type Agent, ApiModule, type ChatMessage, type ChatOptions, type ChatResponse, type EmbedOptions, type EmbedResponse, LLMModule, LLMPermissionError, LLMProviderError, PermissionDeniedError, PermissionRequiredError, PortModule, type Provider, type ProvidersResponse, RealtimeXSDK, type SDKConfig, type StreamChunk, TTSModule, type TTSOptions, type TTSProvider, type TTSProvidersResponse, type Task, TaskModule, type TaskRun, type Thread, type TriggerAgentPayload, type TriggerAgentResponse, type VectorDeleteOptions, type VectorDeleteResponse, type VectorQueryOptions, type VectorQueryResponse, type VectorQueryResult, type VectorRecord, VectorStore, type VectorUpsertOptions, type VectorUpsertResponse, WebhookModule, type Workspace };
package/dist/index.js CHANGED
@@ -39,6 +39,7 @@ __export(index_exports, {
39
39
  PermissionRequiredError: () => PermissionRequiredError,
40
40
  PortModule: () => PortModule,
41
41
  RealtimeXSDK: () => RealtimeXSDK,
42
+ TTSModule: () => TTSModule,
42
43
  TaskModule: () => TaskModule,
43
44
  VectorStore: () => VectorStore,
44
45
  WebhookModule: () => WebhookModule
@@ -980,6 +981,129 @@ var LLMModule = class {
980
981
  }
981
982
  };
982
983
 
984
+ // src/modules/tts.ts
985
+ var TTSModule = class {
986
+ constructor(realtimexUrl, appId, appName, apiKey) {
987
+ this.baseUrl = realtimexUrl.replace(/\/$/, "");
988
+ this.appId = appId;
989
+ this.appName = appName || process.env.RTX_APP_NAME || "Local App";
990
+ this.apiKey = apiKey;
991
+ }
992
+ get headers() {
993
+ if (this.apiKey) {
994
+ return {
995
+ "Content-Type": "application/json",
996
+ "Authorization": `Bearer ${this.apiKey}`
997
+ };
998
+ }
999
+ return {
1000
+ "Content-Type": "application/json",
1001
+ "x-app-id": this.appId
1002
+ };
1003
+ }
1004
+ /**
1005
+ * Request a single permission from Electron via internal API
1006
+ */
1007
+ async requestPermission(permission) {
1008
+ try {
1009
+ const response = await fetch(`${this.baseUrl}/api/local-apps/request-permission`, {
1010
+ method: "POST",
1011
+ headers: { "Content-Type": "application/json" },
1012
+ body: JSON.stringify({
1013
+ app_id: this.appId,
1014
+ app_name: this.appName,
1015
+ permission
1016
+ })
1017
+ });
1018
+ const data = await response.json();
1019
+ return data.granted === true;
1020
+ } catch (error) {
1021
+ console.error("[SDK] Permission request failed:", error);
1022
+ return false;
1023
+ }
1024
+ }
1025
+ /**
1026
+ * Internal request wrapper that handles automatic permission prompts
1027
+ */
1028
+ async request(method, endpoint, body, isStream = false) {
1029
+ const response = await fetch(`${this.baseUrl}${endpoint}`, {
1030
+ method,
1031
+ headers: this.headers,
1032
+ body: body ? JSON.stringify(body) : void 0
1033
+ });
1034
+ if (!response.ok) {
1035
+ const data = await response.json();
1036
+ if (data.code === "PERMISSION_REQUIRED") {
1037
+ const permission = data.permission || "tts.speak";
1038
+ const granted = await this.requestPermission(permission);
1039
+ if (granted) {
1040
+ return this.request(method, endpoint, body, isStream);
1041
+ }
1042
+ throw new PermissionDeniedError(permission);
1043
+ }
1044
+ throw new Error(data.error || `Request failed: ${response.status}`);
1045
+ }
1046
+ if (isStream) {
1047
+ return response.body;
1048
+ }
1049
+ const contentType = response.headers.get("content-type");
1050
+ if (contentType && contentType.includes("application/json")) {
1051
+ return response.json();
1052
+ }
1053
+ return response.arrayBuffer();
1054
+ }
1055
+ /**
1056
+ * Generate speech from text (returns full buffer)
1057
+ *
1058
+ * @example
1059
+ * ```ts
1060
+ * const buffer = await sdk.tts.speak("Hello world");
1061
+ * // Play buffer...
1062
+ * ```
1063
+ */
1064
+ async speak(text, options = {}) {
1065
+ return this.request("POST", "/sdk/tts", {
1066
+ text,
1067
+ ...options
1068
+ });
1069
+ }
1070
+ /**
1071
+ * Generate speech from text (returns stream)
1072
+ *
1073
+ * @example
1074
+ * ```ts
1075
+ * const stream = await sdk.tts.speakStream("Hello world");
1076
+ * for await (const chunk of stream) {
1077
+ * // Play chunk...
1078
+ * }
1079
+ * ```
1080
+ */
1081
+ async *speakStream(text, options = {}) {
1082
+ const body = await this.request("POST", "/sdk/tts/stream", {
1083
+ text,
1084
+ ...options
1085
+ }, true);
1086
+ if (!body) throw new Error("No response body");
1087
+ const reader = body.getReader();
1088
+ try {
1089
+ while (true) {
1090
+ const { done, value } = await reader.read();
1091
+ if (done) break;
1092
+ yield value;
1093
+ }
1094
+ } finally {
1095
+ reader.releaseLock();
1096
+ }
1097
+ }
1098
+ /**
1099
+ * List available TTS providers
1100
+ */
1101
+ async listProviders() {
1102
+ const data = await this.request("GET", "/sdk/tts/providers");
1103
+ return data.providers || [];
1104
+ }
1105
+ };
1106
+
983
1107
  // src/index.ts
984
1108
  var _RealtimeXSDK = class _RealtimeXSDK {
985
1109
  constructor(config = {}) {
@@ -997,6 +1121,7 @@ var _RealtimeXSDK = class _RealtimeXSDK {
997
1121
  this.task = new TaskModule(this.realtimexUrl, this.appName, this.appId, this.apiKey);
998
1122
  this.port = new PortModule(config.defaultPort);
999
1123
  this.llm = new LLMModule(this.realtimexUrl, this.appId, this.appName, this.apiKey);
1124
+ this.tts = new TTSModule(this.realtimexUrl, this.appId, this.appName, this.apiKey);
1000
1125
  if (this.permissions.length > 0 && this.appId && !this.apiKey) {
1001
1126
  this.register().catch((err) => {
1002
1127
  console.error("[RealtimeX SDK] Auto-registration failed:", err.message);
@@ -1105,6 +1230,7 @@ var RealtimeXSDK = _RealtimeXSDK;
1105
1230
  PermissionRequiredError,
1106
1231
  PortModule,
1107
1232
  RealtimeXSDK,
1233
+ TTSModule,
1108
1234
  TaskModule,
1109
1235
  VectorStore,
1110
1236
  WebhookModule
package/dist/index.mjs CHANGED
@@ -933,6 +933,129 @@ var LLMModule = class {
933
933
  }
934
934
  };
935
935
 
936
+ // src/modules/tts.ts
937
+ var TTSModule = class {
938
+ constructor(realtimexUrl, appId, appName, apiKey) {
939
+ this.baseUrl = realtimexUrl.replace(/\/$/, "");
940
+ this.appId = appId;
941
+ this.appName = appName || process.env.RTX_APP_NAME || "Local App";
942
+ this.apiKey = apiKey;
943
+ }
944
+ get headers() {
945
+ if (this.apiKey) {
946
+ return {
947
+ "Content-Type": "application/json",
948
+ "Authorization": `Bearer ${this.apiKey}`
949
+ };
950
+ }
951
+ return {
952
+ "Content-Type": "application/json",
953
+ "x-app-id": this.appId
954
+ };
955
+ }
956
+ /**
957
+ * Request a single permission from Electron via internal API
958
+ */
959
+ async requestPermission(permission) {
960
+ try {
961
+ const response = await fetch(`${this.baseUrl}/api/local-apps/request-permission`, {
962
+ method: "POST",
963
+ headers: { "Content-Type": "application/json" },
964
+ body: JSON.stringify({
965
+ app_id: this.appId,
966
+ app_name: this.appName,
967
+ permission
968
+ })
969
+ });
970
+ const data = await response.json();
971
+ return data.granted === true;
972
+ } catch (error) {
973
+ console.error("[SDK] Permission request failed:", error);
974
+ return false;
975
+ }
976
+ }
977
+ /**
978
+ * Internal request wrapper that handles automatic permission prompts
979
+ */
980
+ async request(method, endpoint, body, isStream = false) {
981
+ const response = await fetch(`${this.baseUrl}${endpoint}`, {
982
+ method,
983
+ headers: this.headers,
984
+ body: body ? JSON.stringify(body) : void 0
985
+ });
986
+ if (!response.ok) {
987
+ const data = await response.json();
988
+ if (data.code === "PERMISSION_REQUIRED") {
989
+ const permission = data.permission || "tts.speak";
990
+ const granted = await this.requestPermission(permission);
991
+ if (granted) {
992
+ return this.request(method, endpoint, body, isStream);
993
+ }
994
+ throw new PermissionDeniedError(permission);
995
+ }
996
+ throw new Error(data.error || `Request failed: ${response.status}`);
997
+ }
998
+ if (isStream) {
999
+ return response.body;
1000
+ }
1001
+ const contentType = response.headers.get("content-type");
1002
+ if (contentType && contentType.includes("application/json")) {
1003
+ return response.json();
1004
+ }
1005
+ return response.arrayBuffer();
1006
+ }
1007
+ /**
1008
+ * Generate speech from text (returns full buffer)
1009
+ *
1010
+ * @example
1011
+ * ```ts
1012
+ * const buffer = await sdk.tts.speak("Hello world");
1013
+ * // Play buffer...
1014
+ * ```
1015
+ */
1016
+ async speak(text, options = {}) {
1017
+ return this.request("POST", "/sdk/tts", {
1018
+ text,
1019
+ ...options
1020
+ });
1021
+ }
1022
+ /**
1023
+ * Generate speech from text (returns stream)
1024
+ *
1025
+ * @example
1026
+ * ```ts
1027
+ * const stream = await sdk.tts.speakStream("Hello world");
1028
+ * for await (const chunk of stream) {
1029
+ * // Play chunk...
1030
+ * }
1031
+ * ```
1032
+ */
1033
+ async *speakStream(text, options = {}) {
1034
+ const body = await this.request("POST", "/sdk/tts/stream", {
1035
+ text,
1036
+ ...options
1037
+ }, true);
1038
+ if (!body) throw new Error("No response body");
1039
+ const reader = body.getReader();
1040
+ try {
1041
+ while (true) {
1042
+ const { done, value } = await reader.read();
1043
+ if (done) break;
1044
+ yield value;
1045
+ }
1046
+ } finally {
1047
+ reader.releaseLock();
1048
+ }
1049
+ }
1050
+ /**
1051
+ * List available TTS providers
1052
+ */
1053
+ async listProviders() {
1054
+ const data = await this.request("GET", "/sdk/tts/providers");
1055
+ return data.providers || [];
1056
+ }
1057
+ };
1058
+
936
1059
  // src/index.ts
937
1060
  var _RealtimeXSDK = class _RealtimeXSDK {
938
1061
  constructor(config = {}) {
@@ -950,6 +1073,7 @@ var _RealtimeXSDK = class _RealtimeXSDK {
950
1073
  this.task = new TaskModule(this.realtimexUrl, this.appName, this.appId, this.apiKey);
951
1074
  this.port = new PortModule(config.defaultPort);
952
1075
  this.llm = new LLMModule(this.realtimexUrl, this.appId, this.appName, this.apiKey);
1076
+ this.tts = new TTSModule(this.realtimexUrl, this.appId, this.appName, this.apiKey);
953
1077
  if (this.permissions.length > 0 && this.appId && !this.apiKey) {
954
1078
  this.register().catch((err) => {
955
1079
  console.error("[RealtimeX SDK] Auto-registration failed:", err.message);
@@ -1057,6 +1181,7 @@ export {
1057
1181
  PermissionRequiredError,
1058
1182
  PortModule,
1059
1183
  RealtimeXSDK,
1184
+ TTSModule,
1060
1185
  TaskModule,
1061
1186
  VectorStore,
1062
1187
  WebhookModule
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@realtimex/sdk",
3
- "version": "1.1.4",
3
+ "version": "1.2.0",
4
4
  "description": "SDK for building Local Apps that integrate with RealtimeX",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -40,4 +40,4 @@
40
40
  "engines": {
41
41
  "node": ">=18.0.0"
42
42
  }
43
- }
43
+ }