@realtimex/sdk 1.1.3 → 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 +121 -1
- package/dist/index.d.ts +121 -1
- package/dist/index.js +183 -0
- package/dist/index.mjs +182 -0
- package/package.json +2 -2
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
|
|
@@ -396,6 +414,36 @@ interface VectorListWorkspacesResponse {
|
|
|
396
414
|
workspaces?: string[];
|
|
397
415
|
error?: string;
|
|
398
416
|
code?: string;
|
|
417
|
+
error_message?: string;
|
|
418
|
+
}
|
|
419
|
+
interface VectorRegisterResponse {
|
|
420
|
+
success: boolean;
|
|
421
|
+
message?: string;
|
|
422
|
+
error?: string;
|
|
423
|
+
code?: string;
|
|
424
|
+
}
|
|
425
|
+
interface VectorConfigResponse {
|
|
426
|
+
success: boolean;
|
|
427
|
+
provider?: string;
|
|
428
|
+
config?: Record<string, any>;
|
|
429
|
+
error?: string;
|
|
430
|
+
code?: string;
|
|
431
|
+
}
|
|
432
|
+
interface VectorProviderField {
|
|
433
|
+
name: string;
|
|
434
|
+
label: string;
|
|
435
|
+
type: 'string' | 'password';
|
|
436
|
+
placeholder?: string;
|
|
437
|
+
}
|
|
438
|
+
interface VectorProviderMetadata {
|
|
439
|
+
name: string;
|
|
440
|
+
label: string;
|
|
441
|
+
description?: string;
|
|
442
|
+
fields: VectorProviderField[];
|
|
443
|
+
}
|
|
444
|
+
interface VectorProvidersResponse {
|
|
445
|
+
success: boolean;
|
|
446
|
+
providers: VectorProviderMetadata[];
|
|
399
447
|
}
|
|
400
448
|
/**
|
|
401
449
|
* @deprecated Use PermissionRequiredError from api module instead
|
|
@@ -468,6 +516,29 @@ declare class VectorStore {
|
|
|
468
516
|
* ```
|
|
469
517
|
*/
|
|
470
518
|
listWorkspaces(): Promise<VectorListWorkspacesResponse>;
|
|
519
|
+
/**
|
|
520
|
+
* Register a custom vector database configuration for this app
|
|
521
|
+
*
|
|
522
|
+
* @example
|
|
523
|
+
* ```ts
|
|
524
|
+
* await sdk.llm.vectors.registerConfig('lancedb', { });
|
|
525
|
+
* ```
|
|
526
|
+
*/
|
|
527
|
+
registerConfig(provider: string, config: Record<string, any>): Promise<VectorRegisterResponse>;
|
|
528
|
+
/**
|
|
529
|
+
* List all supported vector database providers and their configuration requirements
|
|
530
|
+
*/
|
|
531
|
+
listProviders(): Promise<VectorProvidersResponse>;
|
|
532
|
+
/**
|
|
533
|
+
* Get the current vector database configuration for this app
|
|
534
|
+
*
|
|
535
|
+
* @example
|
|
536
|
+
* ```ts
|
|
537
|
+
* const { provider, config } = await sdk.llm.vectors.getConfig();
|
|
538
|
+
* console.log(`App is using ${provider}`);
|
|
539
|
+
* ```
|
|
540
|
+
*/
|
|
541
|
+
getConfig(): Promise<VectorConfigResponse>;
|
|
471
542
|
}
|
|
472
543
|
declare class LLMModule {
|
|
473
544
|
private baseUrl;
|
|
@@ -583,6 +654,49 @@ declare class LLMModule {
|
|
|
583
654
|
search(query: string, options?: VectorQueryOptions): Promise<VectorQueryResult[]>;
|
|
584
655
|
}
|
|
585
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
|
+
|
|
586
700
|
/**
|
|
587
701
|
* RealtimeX Local App SDK
|
|
588
702
|
*
|
|
@@ -597,6 +711,7 @@ declare class RealtimeXSDK {
|
|
|
597
711
|
task: TaskModule;
|
|
598
712
|
port: PortModule;
|
|
599
713
|
llm: LLMModule;
|
|
714
|
+
tts: TTSModule;
|
|
600
715
|
readonly appId: string;
|
|
601
716
|
readonly appName: string | undefined;
|
|
602
717
|
readonly apiKey: string | undefined;
|
|
@@ -623,6 +738,11 @@ declare class RealtimeXSDK {
|
|
|
623
738
|
appId?: string;
|
|
624
739
|
timestamp: string;
|
|
625
740
|
}>;
|
|
741
|
+
/**
|
|
742
|
+
* Get the absolute path to the data directory for this app.
|
|
743
|
+
* Path: ~/.realtimex.ai/Resources/local-apps/{appId}
|
|
744
|
+
*/
|
|
745
|
+
getAppDataDir(): Promise<string>;
|
|
626
746
|
}
|
|
627
747
|
|
|
628
|
-
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
|
|
@@ -396,6 +414,36 @@ interface VectorListWorkspacesResponse {
|
|
|
396
414
|
workspaces?: string[];
|
|
397
415
|
error?: string;
|
|
398
416
|
code?: string;
|
|
417
|
+
error_message?: string;
|
|
418
|
+
}
|
|
419
|
+
interface VectorRegisterResponse {
|
|
420
|
+
success: boolean;
|
|
421
|
+
message?: string;
|
|
422
|
+
error?: string;
|
|
423
|
+
code?: string;
|
|
424
|
+
}
|
|
425
|
+
interface VectorConfigResponse {
|
|
426
|
+
success: boolean;
|
|
427
|
+
provider?: string;
|
|
428
|
+
config?: Record<string, any>;
|
|
429
|
+
error?: string;
|
|
430
|
+
code?: string;
|
|
431
|
+
}
|
|
432
|
+
interface VectorProviderField {
|
|
433
|
+
name: string;
|
|
434
|
+
label: string;
|
|
435
|
+
type: 'string' | 'password';
|
|
436
|
+
placeholder?: string;
|
|
437
|
+
}
|
|
438
|
+
interface VectorProviderMetadata {
|
|
439
|
+
name: string;
|
|
440
|
+
label: string;
|
|
441
|
+
description?: string;
|
|
442
|
+
fields: VectorProviderField[];
|
|
443
|
+
}
|
|
444
|
+
interface VectorProvidersResponse {
|
|
445
|
+
success: boolean;
|
|
446
|
+
providers: VectorProviderMetadata[];
|
|
399
447
|
}
|
|
400
448
|
/**
|
|
401
449
|
* @deprecated Use PermissionRequiredError from api module instead
|
|
@@ -468,6 +516,29 @@ declare class VectorStore {
|
|
|
468
516
|
* ```
|
|
469
517
|
*/
|
|
470
518
|
listWorkspaces(): Promise<VectorListWorkspacesResponse>;
|
|
519
|
+
/**
|
|
520
|
+
* Register a custom vector database configuration for this app
|
|
521
|
+
*
|
|
522
|
+
* @example
|
|
523
|
+
* ```ts
|
|
524
|
+
* await sdk.llm.vectors.registerConfig('lancedb', { });
|
|
525
|
+
* ```
|
|
526
|
+
*/
|
|
527
|
+
registerConfig(provider: string, config: Record<string, any>): Promise<VectorRegisterResponse>;
|
|
528
|
+
/**
|
|
529
|
+
* List all supported vector database providers and their configuration requirements
|
|
530
|
+
*/
|
|
531
|
+
listProviders(): Promise<VectorProvidersResponse>;
|
|
532
|
+
/**
|
|
533
|
+
* Get the current vector database configuration for this app
|
|
534
|
+
*
|
|
535
|
+
* @example
|
|
536
|
+
* ```ts
|
|
537
|
+
* const { provider, config } = await sdk.llm.vectors.getConfig();
|
|
538
|
+
* console.log(`App is using ${provider}`);
|
|
539
|
+
* ```
|
|
540
|
+
*/
|
|
541
|
+
getConfig(): Promise<VectorConfigResponse>;
|
|
471
542
|
}
|
|
472
543
|
declare class LLMModule {
|
|
473
544
|
private baseUrl;
|
|
@@ -583,6 +654,49 @@ declare class LLMModule {
|
|
|
583
654
|
search(query: string, options?: VectorQueryOptions): Promise<VectorQueryResult[]>;
|
|
584
655
|
}
|
|
585
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
|
+
|
|
586
700
|
/**
|
|
587
701
|
* RealtimeX Local App SDK
|
|
588
702
|
*
|
|
@@ -597,6 +711,7 @@ declare class RealtimeXSDK {
|
|
|
597
711
|
task: TaskModule;
|
|
598
712
|
port: PortModule;
|
|
599
713
|
llm: LLMModule;
|
|
714
|
+
tts: TTSModule;
|
|
600
715
|
readonly appId: string;
|
|
601
716
|
readonly appName: string | undefined;
|
|
602
717
|
readonly apiKey: string | undefined;
|
|
@@ -623,6 +738,11 @@ declare class RealtimeXSDK {
|
|
|
623
738
|
appId?: string;
|
|
624
739
|
timestamp: string;
|
|
625
740
|
}>;
|
|
741
|
+
/**
|
|
742
|
+
* Get the absolute path to the data directory for this app.
|
|
743
|
+
* Path: ~/.realtimex.ai/Resources/local-apps/{appId}
|
|
744
|
+
*/
|
|
745
|
+
getAppDataDir(): Promise<string>;
|
|
626
746
|
}
|
|
627
747
|
|
|
628
|
-
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
|
|
@@ -643,6 +644,38 @@ var VectorStore = class {
|
|
|
643
644
|
async listWorkspaces() {
|
|
644
645
|
return this.request("GET", "/sdk/llm/vectors/workspaces");
|
|
645
646
|
}
|
|
647
|
+
/**
|
|
648
|
+
* Register a custom vector database configuration for this app
|
|
649
|
+
*
|
|
650
|
+
* @example
|
|
651
|
+
* ```ts
|
|
652
|
+
* await sdk.llm.vectors.registerConfig('lancedb', { });
|
|
653
|
+
* ```
|
|
654
|
+
*/
|
|
655
|
+
async registerConfig(provider, config) {
|
|
656
|
+
return this.request("POST", "/sdk/llm/vectors/register", {
|
|
657
|
+
provider,
|
|
658
|
+
config
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
/**
|
|
662
|
+
* List all supported vector database providers and their configuration requirements
|
|
663
|
+
*/
|
|
664
|
+
async listProviders() {
|
|
665
|
+
return this.request("GET", "/sdk/llm/vectors/providers");
|
|
666
|
+
}
|
|
667
|
+
/**
|
|
668
|
+
* Get the current vector database configuration for this app
|
|
669
|
+
*
|
|
670
|
+
* @example
|
|
671
|
+
* ```ts
|
|
672
|
+
* const { provider, config } = await sdk.llm.vectors.getConfig();
|
|
673
|
+
* console.log(`App is using ${provider}`);
|
|
674
|
+
* ```
|
|
675
|
+
*/
|
|
676
|
+
async getConfig() {
|
|
677
|
+
return this.request("GET", "/sdk/llm/vectors/config");
|
|
678
|
+
}
|
|
646
679
|
};
|
|
647
680
|
var LLMModule = class {
|
|
648
681
|
constructor(baseUrl, appId, appName = "Local App", apiKey) {
|
|
@@ -948,6 +981,129 @@ var LLMModule = class {
|
|
|
948
981
|
}
|
|
949
982
|
};
|
|
950
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
|
+
|
|
951
1107
|
// src/index.ts
|
|
952
1108
|
var _RealtimeXSDK = class _RealtimeXSDK {
|
|
953
1109
|
constructor(config = {}) {
|
|
@@ -965,6 +1121,7 @@ var _RealtimeXSDK = class _RealtimeXSDK {
|
|
|
965
1121
|
this.task = new TaskModule(this.realtimexUrl, this.appName, this.appId, this.apiKey);
|
|
966
1122
|
this.port = new PortModule(config.defaultPort);
|
|
967
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);
|
|
968
1125
|
if (this.permissions.length > 0 && this.appId && !this.apiKey) {
|
|
969
1126
|
this.register().catch((err) => {
|
|
970
1127
|
console.error("[RealtimeX SDK] Auto-registration failed:", err.message);
|
|
@@ -1034,6 +1191,31 @@ var _RealtimeXSDK = class _RealtimeXSDK {
|
|
|
1034
1191
|
throw new Error(`Connection failed: ${error.message}`);
|
|
1035
1192
|
}
|
|
1036
1193
|
}
|
|
1194
|
+
/**
|
|
1195
|
+
* Get the absolute path to the data directory for this app.
|
|
1196
|
+
* Path: ~/.realtimex.ai/Resources/local-apps/{appId}
|
|
1197
|
+
*/
|
|
1198
|
+
async getAppDataDir() {
|
|
1199
|
+
try {
|
|
1200
|
+
const headers = { "Content-Type": "application/json" };
|
|
1201
|
+
if (this.apiKey) {
|
|
1202
|
+
headers["Authorization"] = `Bearer ${this.apiKey}`;
|
|
1203
|
+
} else if (this.appId) {
|
|
1204
|
+
headers["x-app-id"] = this.appId;
|
|
1205
|
+
}
|
|
1206
|
+
const response = await fetch(`${this.realtimexUrl.replace(/\/$/, "")}/sdk/local-apps/data-dir`, {
|
|
1207
|
+
method: "GET",
|
|
1208
|
+
headers
|
|
1209
|
+
});
|
|
1210
|
+
const data = await response.json();
|
|
1211
|
+
if (!response.ok) {
|
|
1212
|
+
throw new Error(data.error || "Failed to get data directory");
|
|
1213
|
+
}
|
|
1214
|
+
return data.dataDir;
|
|
1215
|
+
} catch (error) {
|
|
1216
|
+
throw new Error(`Failed to get app data directory: ${error.message}`);
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1037
1219
|
};
|
|
1038
1220
|
_RealtimeXSDK.DEFAULT_REALTIMEX_URL = "http://localhost:3001";
|
|
1039
1221
|
var RealtimeXSDK = _RealtimeXSDK;
|
|
@@ -1048,6 +1230,7 @@ var RealtimeXSDK = _RealtimeXSDK;
|
|
|
1048
1230
|
PermissionRequiredError,
|
|
1049
1231
|
PortModule,
|
|
1050
1232
|
RealtimeXSDK,
|
|
1233
|
+
TTSModule,
|
|
1051
1234
|
TaskModule,
|
|
1052
1235
|
VectorStore,
|
|
1053
1236
|
WebhookModule
|
package/dist/index.mjs
CHANGED
|
@@ -596,6 +596,38 @@ var VectorStore = class {
|
|
|
596
596
|
async listWorkspaces() {
|
|
597
597
|
return this.request("GET", "/sdk/llm/vectors/workspaces");
|
|
598
598
|
}
|
|
599
|
+
/**
|
|
600
|
+
* Register a custom vector database configuration for this app
|
|
601
|
+
*
|
|
602
|
+
* @example
|
|
603
|
+
* ```ts
|
|
604
|
+
* await sdk.llm.vectors.registerConfig('lancedb', { });
|
|
605
|
+
* ```
|
|
606
|
+
*/
|
|
607
|
+
async registerConfig(provider, config) {
|
|
608
|
+
return this.request("POST", "/sdk/llm/vectors/register", {
|
|
609
|
+
provider,
|
|
610
|
+
config
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* List all supported vector database providers and their configuration requirements
|
|
615
|
+
*/
|
|
616
|
+
async listProviders() {
|
|
617
|
+
return this.request("GET", "/sdk/llm/vectors/providers");
|
|
618
|
+
}
|
|
619
|
+
/**
|
|
620
|
+
* Get the current vector database configuration for this app
|
|
621
|
+
*
|
|
622
|
+
* @example
|
|
623
|
+
* ```ts
|
|
624
|
+
* const { provider, config } = await sdk.llm.vectors.getConfig();
|
|
625
|
+
* console.log(`App is using ${provider}`);
|
|
626
|
+
* ```
|
|
627
|
+
*/
|
|
628
|
+
async getConfig() {
|
|
629
|
+
return this.request("GET", "/sdk/llm/vectors/config");
|
|
630
|
+
}
|
|
599
631
|
};
|
|
600
632
|
var LLMModule = class {
|
|
601
633
|
constructor(baseUrl, appId, appName = "Local App", apiKey) {
|
|
@@ -901,6 +933,129 @@ var LLMModule = class {
|
|
|
901
933
|
}
|
|
902
934
|
};
|
|
903
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
|
+
|
|
904
1059
|
// src/index.ts
|
|
905
1060
|
var _RealtimeXSDK = class _RealtimeXSDK {
|
|
906
1061
|
constructor(config = {}) {
|
|
@@ -918,6 +1073,7 @@ var _RealtimeXSDK = class _RealtimeXSDK {
|
|
|
918
1073
|
this.task = new TaskModule(this.realtimexUrl, this.appName, this.appId, this.apiKey);
|
|
919
1074
|
this.port = new PortModule(config.defaultPort);
|
|
920
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);
|
|
921
1077
|
if (this.permissions.length > 0 && this.appId && !this.apiKey) {
|
|
922
1078
|
this.register().catch((err) => {
|
|
923
1079
|
console.error("[RealtimeX SDK] Auto-registration failed:", err.message);
|
|
@@ -987,6 +1143,31 @@ var _RealtimeXSDK = class _RealtimeXSDK {
|
|
|
987
1143
|
throw new Error(`Connection failed: ${error.message}`);
|
|
988
1144
|
}
|
|
989
1145
|
}
|
|
1146
|
+
/**
|
|
1147
|
+
* Get the absolute path to the data directory for this app.
|
|
1148
|
+
* Path: ~/.realtimex.ai/Resources/local-apps/{appId}
|
|
1149
|
+
*/
|
|
1150
|
+
async getAppDataDir() {
|
|
1151
|
+
try {
|
|
1152
|
+
const headers = { "Content-Type": "application/json" };
|
|
1153
|
+
if (this.apiKey) {
|
|
1154
|
+
headers["Authorization"] = `Bearer ${this.apiKey}`;
|
|
1155
|
+
} else if (this.appId) {
|
|
1156
|
+
headers["x-app-id"] = this.appId;
|
|
1157
|
+
}
|
|
1158
|
+
const response = await fetch(`${this.realtimexUrl.replace(/\/$/, "")}/sdk/local-apps/data-dir`, {
|
|
1159
|
+
method: "GET",
|
|
1160
|
+
headers
|
|
1161
|
+
});
|
|
1162
|
+
const data = await response.json();
|
|
1163
|
+
if (!response.ok) {
|
|
1164
|
+
throw new Error(data.error || "Failed to get data directory");
|
|
1165
|
+
}
|
|
1166
|
+
return data.dataDir;
|
|
1167
|
+
} catch (error) {
|
|
1168
|
+
throw new Error(`Failed to get app data directory: ${error.message}`);
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
990
1171
|
};
|
|
991
1172
|
_RealtimeXSDK.DEFAULT_REALTIMEX_URL = "http://localhost:3001";
|
|
992
1173
|
var RealtimeXSDK = _RealtimeXSDK;
|
|
@@ -1000,6 +1181,7 @@ export {
|
|
|
1000
1181
|
PermissionRequiredError,
|
|
1001
1182
|
PortModule,
|
|
1002
1183
|
RealtimeXSDK,
|
|
1184
|
+
TTSModule,
|
|
1003
1185
|
TaskModule,
|
|
1004
1186
|
VectorStore,
|
|
1005
1187
|
WebhookModule
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@realtimex/sdk",
|
|
3
|
-
"version": "1.
|
|
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
|
+
}
|