@realtimex/sdk 1.3.1 → 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -167,6 +167,19 @@ const response = await sdk.llm.chat(
167
167
  );
168
168
  console.log(response.response?.content);
169
169
 
170
+ // Multimodal Chat (text + file/image blocks)
171
+ const multimodal = await sdk.llm.chat([
172
+ {
173
+ role: 'user',
174
+ content: [
175
+ { type: 'text', text: 'Summarize the attached document' },
176
+ { type: 'input_file', file_url: 'https://example.com/report.pdf' },
177
+ { type: 'input_image', image_url: 'https://example.com/chart.png' }
178
+ ]
179
+ }
180
+ ]);
181
+ console.log(multimodal.response?.content);
182
+
170
183
  // Streaming Chat
171
184
  for await (const chunk of sdk.llm.chatStream(messages, options)) {
172
185
  process.stdout.write(chunk.textResponse || '');
package/dist/index.d.mts CHANGED
@@ -380,9 +380,36 @@ declare class PortModule {
380
380
  * - Vector storage (upsert, query, delete)
381
381
  */
382
382
 
383
+ interface ChatTextBlock {
384
+ type: 'text' | 'input_text';
385
+ text: string;
386
+ [key: string]: unknown;
387
+ }
388
+ interface ChatImageUrlBlock {
389
+ type: 'image_url' | 'input_image';
390
+ image_url: string | {
391
+ url: string;
392
+ detail?: 'auto' | 'low' | 'high';
393
+ [key: string]: unknown;
394
+ };
395
+ [key: string]: unknown;
396
+ }
397
+ interface ChatFileBlock {
398
+ type: 'input_file' | 'file';
399
+ file_url?: string;
400
+ file_id?: string;
401
+ filename?: string;
402
+ [key: string]: unknown;
403
+ }
404
+ interface ChatCustomBlock {
405
+ type: string;
406
+ [key: string]: unknown;
407
+ }
408
+ type ChatContentBlock = ChatTextBlock | ChatImageUrlBlock | ChatFileBlock | ChatCustomBlock;
409
+ type ChatMessageContent = string | ChatContentBlock[];
383
410
  interface ChatMessage {
384
411
  role: 'system' | 'user' | 'assistant';
385
- content: string;
412
+ content: ChatMessageContent;
386
413
  }
387
414
  interface ChatOptions {
388
415
  model?: string;
@@ -812,6 +839,149 @@ declare class STTModule extends ApiModule {
812
839
  listen(options: STTListenOptions): Promise<STTResponse>;
813
840
  }
814
841
 
842
+ /**
843
+ * HTTP Client Module - Smart Client with Auth Handling
844
+ */
845
+ declare class HttpClient {
846
+ private baseUrl;
847
+ private appId;
848
+ private apiKey?;
849
+ private accessToken?;
850
+ constructor(baseUrl: string, appId: string, apiKey?: string);
851
+ private getAppHeaders;
852
+ private getAccessToken;
853
+ fetch(endpoint: string, options?: RequestInit): Promise<Response>;
854
+ }
855
+
856
+ /**
857
+ * Agent Module - Simple session-based agent chat
858
+ *
859
+ * This module provides the simplest way to chat with AI agents:
860
+ * 1. Create a session (optional - can just chat directly)
861
+ * 2. Send messages (context is automatically maintained)
862
+ * 3. Close session when done (optional - auto-expires)
863
+ */
864
+
865
+ interface AgentSessionOptions {
866
+ workspace_slug?: string;
867
+ thread_slug?: string;
868
+ agent_name?: string;
869
+ }
870
+ interface AgentSession {
871
+ session_id: string;
872
+ workspace: {
873
+ slug: string;
874
+ name: string;
875
+ };
876
+ thread?: {
877
+ slug: string;
878
+ name: string;
879
+ } | null;
880
+ agent: {
881
+ name: string;
882
+ provider: string;
883
+ model: string | null;
884
+ };
885
+ created_at: string;
886
+ }
887
+ interface AgentChatOptions {
888
+ message: string;
889
+ }
890
+ interface AgentChatResponse {
891
+ id: string;
892
+ session_id: string;
893
+ text: string;
894
+ thoughts: string[];
895
+ message_count: number;
896
+ }
897
+ interface AgentSessionInfo extends AgentSession {
898
+ message_count: number;
899
+ last_message_at: string | null;
900
+ }
901
+ interface StreamChunkEvent {
902
+ type: 'agentThought' | 'textResponse' | 'close' | 'error';
903
+ data: any;
904
+ }
905
+ declare class AgentModule {
906
+ private httpClient;
907
+ constructor(httpClient: HttpClient);
908
+ /**
909
+ * Create a new agent session
910
+ *
911
+ * @example
912
+ * ```typescript
913
+ * const session = await sdk.agent.createSession({
914
+ * workspace_slug: 'my-workspace',
915
+ * agent_name: '@agent'
916
+ * });
917
+ * ```
918
+ */
919
+ createSession(options?: AgentSessionOptions): Promise<AgentSession>;
920
+ /**
921
+ * Chat within a session (synchronous)
922
+ *
923
+ * @example
924
+ * ```typescript
925
+ * const response = await sdk.agent.chat(sessionId, 'Hello agent!');
926
+ * console.log(response.text);
927
+ * ```
928
+ */
929
+ chat(sessionId: string, message: string): Promise<AgentChatResponse>;
930
+ /**
931
+ * Stream chat within a session
932
+ * Returns an async iterator for SSE events
933
+ *
934
+ * @example
935
+ * ```typescript
936
+ * for await (const event of sdk.agent.streamChat(sessionId, 'Tell me a story')) {
937
+ * if (event.type === 'agentThought') {
938
+ * console.log('Thinking:', event.data.thought);
939
+ * } else if (event.type === 'textResponse') {
940
+ * console.log('Response:', event.data.textResponse);
941
+ * }
942
+ * }
943
+ * ```
944
+ */
945
+ streamChat(sessionId: string, message: string): AsyncIterableIterator<StreamChunkEvent>;
946
+ /**
947
+ * Get session information
948
+ *
949
+ * @example
950
+ * ```typescript
951
+ * const info = await sdk.agent.getSession(sessionId);
952
+ * console.log(`Messages sent: ${info.message_count}`);
953
+ * ```
954
+ */
955
+ getSession(sessionId: string): Promise<AgentSessionInfo>;
956
+ /**
957
+ * Close and delete a session
958
+ * Sessions auto-expire after 1 hour, but you can close them manually
959
+ *
960
+ * @example
961
+ * ```typescript
962
+ * await sdk.agent.closeSession(sessionId);
963
+ * ```
964
+ */
965
+ closeSession(sessionId: string): Promise<void>;
966
+ /**
967
+ * Helper: Create session and send first message in one call
968
+ * This is the simplest way to start chatting with an agent
969
+ *
970
+ * @example
971
+ * ```typescript
972
+ * const { session, response } = await sdk.agent.startChat('Hello agent!');
973
+ * console.log(response.text);
974
+ *
975
+ * // Continue chatting in the same session
976
+ * const reply = await sdk.agent.chat(session.session_id, 'Tell me more');
977
+ * ```
978
+ */
979
+ startChat(message: string, options?: AgentSessionOptions): Promise<{
980
+ session: AgentSession;
981
+ response: AgentChatResponse;
982
+ }>;
983
+ }
984
+
815
985
  /**
816
986
  * RealtimeX Local App SDK
817
987
  *
@@ -828,11 +998,13 @@ declare class RealtimeXSDK {
828
998
  llm: LLMModule;
829
999
  tts: TTSModule;
830
1000
  stt: STTModule;
1001
+ agent: AgentModule;
831
1002
  readonly appId: string;
832
1003
  readonly appName: string | undefined;
833
1004
  readonly apiKey: string | undefined;
834
1005
  private readonly realtimexUrl;
835
1006
  private readonly permissions;
1007
+ private httpClient;
836
1008
  private static DEFAULT_REALTIMEX_URL;
837
1009
  constructor(config?: SDKConfig);
838
1010
  /**
@@ -861,4 +1033,4 @@ declare class RealtimeXSDK {
861
1033
  getAppDataDir(): Promise<string>;
862
1034
  }
863
1035
 
864
- 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 STTListenOptions, type STTModel, type STTModelsResponse, STTModule, type STTProvider, type STTProvidersResponse, type STTResponse, type StreamChunk, type TTSChunk, type TTSChunkEvent, TTSModule, type TTSOptions, type TTSProvider, type TTSProviderConfig, 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 };
1036
+ export { ActivitiesModule, type Activity, type Agent, type AgentChatOptions, type AgentChatResponse, AgentModule, type AgentSession, type AgentSessionInfo, type AgentSessionOptions, ApiModule, type ChatContentBlock, type ChatCustomBlock, type ChatFileBlock, type ChatImageUrlBlock, type ChatMessage, type ChatMessageContent, type ChatOptions, type ChatResponse, type ChatTextBlock, type EmbedOptions, type EmbedResponse, LLMModule, LLMPermissionError, LLMProviderError, PermissionDeniedError, PermissionRequiredError, PortModule, type Provider, type ProvidersResponse, RealtimeXSDK, type SDKConfig, type STTListenOptions, type STTModel, type STTModelsResponse, STTModule, type STTProvider, type STTProvidersResponse, type STTResponse, type StreamChunk, type StreamChunkEvent, type TTSChunk, type TTSChunkEvent, TTSModule, type TTSOptions, type TTSProvider, type TTSProviderConfig, 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
@@ -380,9 +380,36 @@ declare class PortModule {
380
380
  * - Vector storage (upsert, query, delete)
381
381
  */
382
382
 
383
+ interface ChatTextBlock {
384
+ type: 'text' | 'input_text';
385
+ text: string;
386
+ [key: string]: unknown;
387
+ }
388
+ interface ChatImageUrlBlock {
389
+ type: 'image_url' | 'input_image';
390
+ image_url: string | {
391
+ url: string;
392
+ detail?: 'auto' | 'low' | 'high';
393
+ [key: string]: unknown;
394
+ };
395
+ [key: string]: unknown;
396
+ }
397
+ interface ChatFileBlock {
398
+ type: 'input_file' | 'file';
399
+ file_url?: string;
400
+ file_id?: string;
401
+ filename?: string;
402
+ [key: string]: unknown;
403
+ }
404
+ interface ChatCustomBlock {
405
+ type: string;
406
+ [key: string]: unknown;
407
+ }
408
+ type ChatContentBlock = ChatTextBlock | ChatImageUrlBlock | ChatFileBlock | ChatCustomBlock;
409
+ type ChatMessageContent = string | ChatContentBlock[];
383
410
  interface ChatMessage {
384
411
  role: 'system' | 'user' | 'assistant';
385
- content: string;
412
+ content: ChatMessageContent;
386
413
  }
387
414
  interface ChatOptions {
388
415
  model?: string;
@@ -812,6 +839,149 @@ declare class STTModule extends ApiModule {
812
839
  listen(options: STTListenOptions): Promise<STTResponse>;
813
840
  }
814
841
 
842
+ /**
843
+ * HTTP Client Module - Smart Client with Auth Handling
844
+ */
845
+ declare class HttpClient {
846
+ private baseUrl;
847
+ private appId;
848
+ private apiKey?;
849
+ private accessToken?;
850
+ constructor(baseUrl: string, appId: string, apiKey?: string);
851
+ private getAppHeaders;
852
+ private getAccessToken;
853
+ fetch(endpoint: string, options?: RequestInit): Promise<Response>;
854
+ }
855
+
856
+ /**
857
+ * Agent Module - Simple session-based agent chat
858
+ *
859
+ * This module provides the simplest way to chat with AI agents:
860
+ * 1. Create a session (optional - can just chat directly)
861
+ * 2. Send messages (context is automatically maintained)
862
+ * 3. Close session when done (optional - auto-expires)
863
+ */
864
+
865
+ interface AgentSessionOptions {
866
+ workspace_slug?: string;
867
+ thread_slug?: string;
868
+ agent_name?: string;
869
+ }
870
+ interface AgentSession {
871
+ session_id: string;
872
+ workspace: {
873
+ slug: string;
874
+ name: string;
875
+ };
876
+ thread?: {
877
+ slug: string;
878
+ name: string;
879
+ } | null;
880
+ agent: {
881
+ name: string;
882
+ provider: string;
883
+ model: string | null;
884
+ };
885
+ created_at: string;
886
+ }
887
+ interface AgentChatOptions {
888
+ message: string;
889
+ }
890
+ interface AgentChatResponse {
891
+ id: string;
892
+ session_id: string;
893
+ text: string;
894
+ thoughts: string[];
895
+ message_count: number;
896
+ }
897
+ interface AgentSessionInfo extends AgentSession {
898
+ message_count: number;
899
+ last_message_at: string | null;
900
+ }
901
+ interface StreamChunkEvent {
902
+ type: 'agentThought' | 'textResponse' | 'close' | 'error';
903
+ data: any;
904
+ }
905
+ declare class AgentModule {
906
+ private httpClient;
907
+ constructor(httpClient: HttpClient);
908
+ /**
909
+ * Create a new agent session
910
+ *
911
+ * @example
912
+ * ```typescript
913
+ * const session = await sdk.agent.createSession({
914
+ * workspace_slug: 'my-workspace',
915
+ * agent_name: '@agent'
916
+ * });
917
+ * ```
918
+ */
919
+ createSession(options?: AgentSessionOptions): Promise<AgentSession>;
920
+ /**
921
+ * Chat within a session (synchronous)
922
+ *
923
+ * @example
924
+ * ```typescript
925
+ * const response = await sdk.agent.chat(sessionId, 'Hello agent!');
926
+ * console.log(response.text);
927
+ * ```
928
+ */
929
+ chat(sessionId: string, message: string): Promise<AgentChatResponse>;
930
+ /**
931
+ * Stream chat within a session
932
+ * Returns an async iterator for SSE events
933
+ *
934
+ * @example
935
+ * ```typescript
936
+ * for await (const event of sdk.agent.streamChat(sessionId, 'Tell me a story')) {
937
+ * if (event.type === 'agentThought') {
938
+ * console.log('Thinking:', event.data.thought);
939
+ * } else if (event.type === 'textResponse') {
940
+ * console.log('Response:', event.data.textResponse);
941
+ * }
942
+ * }
943
+ * ```
944
+ */
945
+ streamChat(sessionId: string, message: string): AsyncIterableIterator<StreamChunkEvent>;
946
+ /**
947
+ * Get session information
948
+ *
949
+ * @example
950
+ * ```typescript
951
+ * const info = await sdk.agent.getSession(sessionId);
952
+ * console.log(`Messages sent: ${info.message_count}`);
953
+ * ```
954
+ */
955
+ getSession(sessionId: string): Promise<AgentSessionInfo>;
956
+ /**
957
+ * Close and delete a session
958
+ * Sessions auto-expire after 1 hour, but you can close them manually
959
+ *
960
+ * @example
961
+ * ```typescript
962
+ * await sdk.agent.closeSession(sessionId);
963
+ * ```
964
+ */
965
+ closeSession(sessionId: string): Promise<void>;
966
+ /**
967
+ * Helper: Create session and send first message in one call
968
+ * This is the simplest way to start chatting with an agent
969
+ *
970
+ * @example
971
+ * ```typescript
972
+ * const { session, response } = await sdk.agent.startChat('Hello agent!');
973
+ * console.log(response.text);
974
+ *
975
+ * // Continue chatting in the same session
976
+ * const reply = await sdk.agent.chat(session.session_id, 'Tell me more');
977
+ * ```
978
+ */
979
+ startChat(message: string, options?: AgentSessionOptions): Promise<{
980
+ session: AgentSession;
981
+ response: AgentChatResponse;
982
+ }>;
983
+ }
984
+
815
985
  /**
816
986
  * RealtimeX Local App SDK
817
987
  *
@@ -828,11 +998,13 @@ declare class RealtimeXSDK {
828
998
  llm: LLMModule;
829
999
  tts: TTSModule;
830
1000
  stt: STTModule;
1001
+ agent: AgentModule;
831
1002
  readonly appId: string;
832
1003
  readonly appName: string | undefined;
833
1004
  readonly apiKey: string | undefined;
834
1005
  private readonly realtimexUrl;
835
1006
  private readonly permissions;
1007
+ private httpClient;
836
1008
  private static DEFAULT_REALTIMEX_URL;
837
1009
  constructor(config?: SDKConfig);
838
1010
  /**
@@ -861,4 +1033,4 @@ declare class RealtimeXSDK {
861
1033
  getAppDataDir(): Promise<string>;
862
1034
  }
863
1035
 
864
- 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 STTListenOptions, type STTModel, type STTModelsResponse, STTModule, type STTProvider, type STTProvidersResponse, type STTResponse, type StreamChunk, type TTSChunk, type TTSChunkEvent, TTSModule, type TTSOptions, type TTSProvider, type TTSProviderConfig, 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 };
1036
+ export { ActivitiesModule, type Activity, type Agent, type AgentChatOptions, type AgentChatResponse, AgentModule, type AgentSession, type AgentSessionInfo, type AgentSessionOptions, ApiModule, type ChatContentBlock, type ChatCustomBlock, type ChatFileBlock, type ChatImageUrlBlock, type ChatMessage, type ChatMessageContent, type ChatOptions, type ChatResponse, type ChatTextBlock, type EmbedOptions, type EmbedResponse, LLMModule, LLMPermissionError, LLMProviderError, PermissionDeniedError, PermissionRequiredError, PortModule, type Provider, type ProvidersResponse, RealtimeXSDK, type SDKConfig, type STTListenOptions, type STTModel, type STTModelsResponse, STTModule, type STTProvider, type STTProvidersResponse, type STTResponse, type StreamChunk, type StreamChunkEvent, type TTSChunk, type TTSChunkEvent, TTSModule, type TTSOptions, type TTSProvider, type TTSProviderConfig, 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
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
33
  ActivitiesModule: () => ActivitiesModule,
34
+ AgentModule: () => AgentModule,
34
35
  ApiModule: () => ApiModule,
35
36
  LLMModule: () => LLMModule,
36
37
  LLMPermissionError: () => LLMPermissionError,
@@ -1202,6 +1203,218 @@ var STTModule = class extends ApiModule {
1202
1203
  }
1203
1204
  };
1204
1205
 
1206
+ // src/modules/agent.ts
1207
+ var AgentModule = class {
1208
+ constructor(httpClient) {
1209
+ this.httpClient = httpClient;
1210
+ }
1211
+ /**
1212
+ * Create a new agent session
1213
+ *
1214
+ * @example
1215
+ * ```typescript
1216
+ * const session = await sdk.agent.createSession({
1217
+ * workspace_slug: 'my-workspace',
1218
+ * agent_name: '@agent'
1219
+ * });
1220
+ * ```
1221
+ */
1222
+ async createSession(options) {
1223
+ const response = await this.httpClient.fetch("/sdk/agent/session", {
1224
+ method: "POST",
1225
+ body: JSON.stringify(options || {})
1226
+ });
1227
+ const data = await response.json();
1228
+ if (!response.ok) {
1229
+ throw new Error(data.error || "Failed to create session");
1230
+ }
1231
+ return data.session;
1232
+ }
1233
+ /**
1234
+ * Chat within a session (synchronous)
1235
+ *
1236
+ * @example
1237
+ * ```typescript
1238
+ * const response = await sdk.agent.chat(sessionId, 'Hello agent!');
1239
+ * console.log(response.text);
1240
+ * ```
1241
+ */
1242
+ async chat(sessionId, message) {
1243
+ const response = await this.httpClient.fetch(`/sdk/agent/session/${sessionId}/chat`, {
1244
+ method: "POST",
1245
+ body: JSON.stringify({ message })
1246
+ });
1247
+ const data = await response.json();
1248
+ if (!response.ok) {
1249
+ throw new Error(data.error || "Chat request failed");
1250
+ }
1251
+ return data.response;
1252
+ }
1253
+ /**
1254
+ * Stream chat within a session
1255
+ * Returns an async iterator for SSE events
1256
+ *
1257
+ * @example
1258
+ * ```typescript
1259
+ * for await (const event of sdk.agent.streamChat(sessionId, 'Tell me a story')) {
1260
+ * if (event.type === 'agentThought') {
1261
+ * console.log('Thinking:', event.data.thought);
1262
+ * } else if (event.type === 'textResponse') {
1263
+ * console.log('Response:', event.data.textResponse);
1264
+ * }
1265
+ * }
1266
+ * ```
1267
+ */
1268
+ async *streamChat(sessionId, message) {
1269
+ const response = await this.httpClient.fetch(`/sdk/agent/session/${sessionId}/chat/stream`, {
1270
+ method: "POST",
1271
+ body: JSON.stringify({ message })
1272
+ });
1273
+ if (!response.ok) {
1274
+ const data = await response.json();
1275
+ throw new Error(data.error || "Stream request failed");
1276
+ }
1277
+ if (!response.body) {
1278
+ throw new Error("Response body is null");
1279
+ }
1280
+ const reader = response.body.getReader();
1281
+ const decoder = new TextDecoder();
1282
+ let buffer = "";
1283
+ try {
1284
+ while (true) {
1285
+ const { done, value } = await reader.read();
1286
+ if (done) break;
1287
+ buffer += decoder.decode(value, { stream: true });
1288
+ const lines = buffer.split("\n");
1289
+ buffer = lines.pop() || "";
1290
+ for (const line of lines) {
1291
+ if (line.startsWith("data: ")) {
1292
+ const data = JSON.parse(line.slice(6));
1293
+ yield {
1294
+ type: data.type,
1295
+ data
1296
+ };
1297
+ }
1298
+ }
1299
+ }
1300
+ } finally {
1301
+ reader.releaseLock();
1302
+ }
1303
+ }
1304
+ /**
1305
+ * Get session information
1306
+ *
1307
+ * @example
1308
+ * ```typescript
1309
+ * const info = await sdk.agent.getSession(sessionId);
1310
+ * console.log(`Messages sent: ${info.message_count}`);
1311
+ * ```
1312
+ */
1313
+ async getSession(sessionId) {
1314
+ const response = await this.httpClient.fetch(`/sdk/agent/session/${sessionId}`, {
1315
+ method: "GET"
1316
+ });
1317
+ const data = await response.json();
1318
+ if (!response.ok) {
1319
+ throw new Error(data.error || "Failed to get session info");
1320
+ }
1321
+ return data.session;
1322
+ }
1323
+ /**
1324
+ * Close and delete a session
1325
+ * Sessions auto-expire after 1 hour, but you can close them manually
1326
+ *
1327
+ * @example
1328
+ * ```typescript
1329
+ * await sdk.agent.closeSession(sessionId);
1330
+ * ```
1331
+ */
1332
+ async closeSession(sessionId) {
1333
+ const response = await this.httpClient.fetch(`/sdk/agent/session/${sessionId}`, {
1334
+ method: "DELETE"
1335
+ });
1336
+ const data = await response.json();
1337
+ if (!response.ok) {
1338
+ throw new Error(data.error || "Failed to close session");
1339
+ }
1340
+ }
1341
+ /**
1342
+ * Helper: Create session and send first message in one call
1343
+ * This is the simplest way to start chatting with an agent
1344
+ *
1345
+ * @example
1346
+ * ```typescript
1347
+ * const { session, response } = await sdk.agent.startChat('Hello agent!');
1348
+ * console.log(response.text);
1349
+ *
1350
+ * // Continue chatting in the same session
1351
+ * const reply = await sdk.agent.chat(session.session_id, 'Tell me more');
1352
+ * ```
1353
+ */
1354
+ async startChat(message, options) {
1355
+ const session = await this.createSession(options);
1356
+ const response = await this.chat(session.session_id, message);
1357
+ return { session, response };
1358
+ }
1359
+ };
1360
+
1361
+ // src/modules/http.ts
1362
+ var HttpClient = class {
1363
+ constructor(baseUrl, appId, apiKey) {
1364
+ this.baseUrl = baseUrl.replace(/\/$/, "");
1365
+ this.appId = appId;
1366
+ this.apiKey = apiKey;
1367
+ }
1368
+ getAppHeaders() {
1369
+ const headers = {
1370
+ "Content-Type": "application/json"
1371
+ };
1372
+ if (this.appId) headers["x-app-id"] = this.appId;
1373
+ if (this.apiKey) headers["x-api-key"] = this.apiKey;
1374
+ return headers;
1375
+ }
1376
+ async getAccessToken() {
1377
+ if (this.accessToken) return this.accessToken;
1378
+ try {
1379
+ const res = await fetch(`${this.baseUrl}/sdk/auth/token`, {
1380
+ headers: this.getAppHeaders()
1381
+ });
1382
+ const data = await res.json();
1383
+ if (res.ok && data.token) {
1384
+ this.accessToken = data.token;
1385
+ return data.token;
1386
+ }
1387
+ } catch (e) {
1388
+ }
1389
+ return "";
1390
+ }
1391
+ async fetch(endpoint, options = {}) {
1392
+ const url = `${this.baseUrl}${endpoint}`;
1393
+ let token = await this.getAccessToken();
1394
+ const makeRequest = (authToken) => {
1395
+ const headers = {
1396
+ ...this.getAppHeaders(),
1397
+ ...options.headers || {}
1398
+ };
1399
+ if (authToken) {
1400
+ headers["Authorization"] = `Bearer ${authToken}`;
1401
+ }
1402
+ return fetch(url, { ...options, headers });
1403
+ };
1404
+ let response = await makeRequest(token);
1405
+ if (response.status === 401) {
1406
+ console.log("[RealtimeX SDK] 401 Unauthorized, refreshing access token...");
1407
+ this.accessToken = void 0;
1408
+ const newToken = await this.getAccessToken();
1409
+ if (newToken && newToken !== token) {
1410
+ console.log("[RealtimeX SDK] Retrying request with new token");
1411
+ response = await makeRequest(newToken);
1412
+ }
1413
+ }
1414
+ return response;
1415
+ }
1416
+ };
1417
+
1205
1418
  // src/index.ts
1206
1419
  var _RealtimeXSDK = class _RealtimeXSDK {
1207
1420
  constructor(config = {}) {
@@ -1213,6 +1426,7 @@ var _RealtimeXSDK = class _RealtimeXSDK {
1213
1426
  this.apiKey = config.realtimex?.apiKey || envApiKey;
1214
1427
  this.permissions = config.permissions || [];
1215
1428
  this.realtimexUrl = config.realtimex?.url || _RealtimeXSDK.DEFAULT_REALTIMEX_URL;
1429
+ this.httpClient = new HttpClient(this.realtimexUrl, this.appId, this.apiKey);
1216
1430
  this.activities = new ActivitiesModule(this.realtimexUrl, this.appId, this.appName, this.apiKey);
1217
1431
  this.webhook = new WebhookModule(this.realtimexUrl, this.appName, this.appId, this.apiKey);
1218
1432
  this.api = new ApiModule(this.realtimexUrl, this.appId, this.appName, this.apiKey);
@@ -1221,6 +1435,7 @@ var _RealtimeXSDK = class _RealtimeXSDK {
1221
1435
  this.llm = new LLMModule(this.realtimexUrl, this.appId, this.appName, this.apiKey);
1222
1436
  this.tts = new TTSModule(this.realtimexUrl, this.appId, this.appName, this.apiKey);
1223
1437
  this.stt = new STTModule(this.realtimexUrl, this.appId, this.appName, this.apiKey);
1438
+ this.agent = new AgentModule(this.httpClient);
1224
1439
  if (this.permissions.length > 0 && this.appId && !this.apiKey) {
1225
1440
  this.register().catch((err) => {
1226
1441
  console.error("[RealtimeX SDK] Auto-registration failed:", err.message);
@@ -1323,6 +1538,7 @@ var RealtimeXSDK = _RealtimeXSDK;
1323
1538
  // Annotate the CommonJS export names for ESM import in node:
1324
1539
  0 && (module.exports = {
1325
1540
  ActivitiesModule,
1541
+ AgentModule,
1326
1542
  ApiModule,
1327
1543
  LLMModule,
1328
1544
  LLMPermissionError,
package/dist/index.mjs CHANGED
@@ -1153,6 +1153,218 @@ var STTModule = class extends ApiModule {
1153
1153
  }
1154
1154
  };
1155
1155
 
1156
+ // src/modules/agent.ts
1157
+ var AgentModule = class {
1158
+ constructor(httpClient) {
1159
+ this.httpClient = httpClient;
1160
+ }
1161
+ /**
1162
+ * Create a new agent session
1163
+ *
1164
+ * @example
1165
+ * ```typescript
1166
+ * const session = await sdk.agent.createSession({
1167
+ * workspace_slug: 'my-workspace',
1168
+ * agent_name: '@agent'
1169
+ * });
1170
+ * ```
1171
+ */
1172
+ async createSession(options) {
1173
+ const response = await this.httpClient.fetch("/sdk/agent/session", {
1174
+ method: "POST",
1175
+ body: JSON.stringify(options || {})
1176
+ });
1177
+ const data = await response.json();
1178
+ if (!response.ok) {
1179
+ throw new Error(data.error || "Failed to create session");
1180
+ }
1181
+ return data.session;
1182
+ }
1183
+ /**
1184
+ * Chat within a session (synchronous)
1185
+ *
1186
+ * @example
1187
+ * ```typescript
1188
+ * const response = await sdk.agent.chat(sessionId, 'Hello agent!');
1189
+ * console.log(response.text);
1190
+ * ```
1191
+ */
1192
+ async chat(sessionId, message) {
1193
+ const response = await this.httpClient.fetch(`/sdk/agent/session/${sessionId}/chat`, {
1194
+ method: "POST",
1195
+ body: JSON.stringify({ message })
1196
+ });
1197
+ const data = await response.json();
1198
+ if (!response.ok) {
1199
+ throw new Error(data.error || "Chat request failed");
1200
+ }
1201
+ return data.response;
1202
+ }
1203
+ /**
1204
+ * Stream chat within a session
1205
+ * Returns an async iterator for SSE events
1206
+ *
1207
+ * @example
1208
+ * ```typescript
1209
+ * for await (const event of sdk.agent.streamChat(sessionId, 'Tell me a story')) {
1210
+ * if (event.type === 'agentThought') {
1211
+ * console.log('Thinking:', event.data.thought);
1212
+ * } else if (event.type === 'textResponse') {
1213
+ * console.log('Response:', event.data.textResponse);
1214
+ * }
1215
+ * }
1216
+ * ```
1217
+ */
1218
+ async *streamChat(sessionId, message) {
1219
+ const response = await this.httpClient.fetch(`/sdk/agent/session/${sessionId}/chat/stream`, {
1220
+ method: "POST",
1221
+ body: JSON.stringify({ message })
1222
+ });
1223
+ if (!response.ok) {
1224
+ const data = await response.json();
1225
+ throw new Error(data.error || "Stream request failed");
1226
+ }
1227
+ if (!response.body) {
1228
+ throw new Error("Response body is null");
1229
+ }
1230
+ const reader = response.body.getReader();
1231
+ const decoder = new TextDecoder();
1232
+ let buffer = "";
1233
+ try {
1234
+ while (true) {
1235
+ const { done, value } = await reader.read();
1236
+ if (done) break;
1237
+ buffer += decoder.decode(value, { stream: true });
1238
+ const lines = buffer.split("\n");
1239
+ buffer = lines.pop() || "";
1240
+ for (const line of lines) {
1241
+ if (line.startsWith("data: ")) {
1242
+ const data = JSON.parse(line.slice(6));
1243
+ yield {
1244
+ type: data.type,
1245
+ data
1246
+ };
1247
+ }
1248
+ }
1249
+ }
1250
+ } finally {
1251
+ reader.releaseLock();
1252
+ }
1253
+ }
1254
+ /**
1255
+ * Get session information
1256
+ *
1257
+ * @example
1258
+ * ```typescript
1259
+ * const info = await sdk.agent.getSession(sessionId);
1260
+ * console.log(`Messages sent: ${info.message_count}`);
1261
+ * ```
1262
+ */
1263
+ async getSession(sessionId) {
1264
+ const response = await this.httpClient.fetch(`/sdk/agent/session/${sessionId}`, {
1265
+ method: "GET"
1266
+ });
1267
+ const data = await response.json();
1268
+ if (!response.ok) {
1269
+ throw new Error(data.error || "Failed to get session info");
1270
+ }
1271
+ return data.session;
1272
+ }
1273
+ /**
1274
+ * Close and delete a session
1275
+ * Sessions auto-expire after 1 hour, but you can close them manually
1276
+ *
1277
+ * @example
1278
+ * ```typescript
1279
+ * await sdk.agent.closeSession(sessionId);
1280
+ * ```
1281
+ */
1282
+ async closeSession(sessionId) {
1283
+ const response = await this.httpClient.fetch(`/sdk/agent/session/${sessionId}`, {
1284
+ method: "DELETE"
1285
+ });
1286
+ const data = await response.json();
1287
+ if (!response.ok) {
1288
+ throw new Error(data.error || "Failed to close session");
1289
+ }
1290
+ }
1291
+ /**
1292
+ * Helper: Create session and send first message in one call
1293
+ * This is the simplest way to start chatting with an agent
1294
+ *
1295
+ * @example
1296
+ * ```typescript
1297
+ * const { session, response } = await sdk.agent.startChat('Hello agent!');
1298
+ * console.log(response.text);
1299
+ *
1300
+ * // Continue chatting in the same session
1301
+ * const reply = await sdk.agent.chat(session.session_id, 'Tell me more');
1302
+ * ```
1303
+ */
1304
+ async startChat(message, options) {
1305
+ const session = await this.createSession(options);
1306
+ const response = await this.chat(session.session_id, message);
1307
+ return { session, response };
1308
+ }
1309
+ };
1310
+
1311
+ // src/modules/http.ts
1312
+ var HttpClient = class {
1313
+ constructor(baseUrl, appId, apiKey) {
1314
+ this.baseUrl = baseUrl.replace(/\/$/, "");
1315
+ this.appId = appId;
1316
+ this.apiKey = apiKey;
1317
+ }
1318
+ getAppHeaders() {
1319
+ const headers = {
1320
+ "Content-Type": "application/json"
1321
+ };
1322
+ if (this.appId) headers["x-app-id"] = this.appId;
1323
+ if (this.apiKey) headers["x-api-key"] = this.apiKey;
1324
+ return headers;
1325
+ }
1326
+ async getAccessToken() {
1327
+ if (this.accessToken) return this.accessToken;
1328
+ try {
1329
+ const res = await fetch(`${this.baseUrl}/sdk/auth/token`, {
1330
+ headers: this.getAppHeaders()
1331
+ });
1332
+ const data = await res.json();
1333
+ if (res.ok && data.token) {
1334
+ this.accessToken = data.token;
1335
+ return data.token;
1336
+ }
1337
+ } catch (e) {
1338
+ }
1339
+ return "";
1340
+ }
1341
+ async fetch(endpoint, options = {}) {
1342
+ const url = `${this.baseUrl}${endpoint}`;
1343
+ let token = await this.getAccessToken();
1344
+ const makeRequest = (authToken) => {
1345
+ const headers = {
1346
+ ...this.getAppHeaders(),
1347
+ ...options.headers || {}
1348
+ };
1349
+ if (authToken) {
1350
+ headers["Authorization"] = `Bearer ${authToken}`;
1351
+ }
1352
+ return fetch(url, { ...options, headers });
1353
+ };
1354
+ let response = await makeRequest(token);
1355
+ if (response.status === 401) {
1356
+ console.log("[RealtimeX SDK] 401 Unauthorized, refreshing access token...");
1357
+ this.accessToken = void 0;
1358
+ const newToken = await this.getAccessToken();
1359
+ if (newToken && newToken !== token) {
1360
+ console.log("[RealtimeX SDK] Retrying request with new token");
1361
+ response = await makeRequest(newToken);
1362
+ }
1363
+ }
1364
+ return response;
1365
+ }
1366
+ };
1367
+
1156
1368
  // src/index.ts
1157
1369
  var _RealtimeXSDK = class _RealtimeXSDK {
1158
1370
  constructor(config = {}) {
@@ -1164,6 +1376,7 @@ var _RealtimeXSDK = class _RealtimeXSDK {
1164
1376
  this.apiKey = config.realtimex?.apiKey || envApiKey;
1165
1377
  this.permissions = config.permissions || [];
1166
1378
  this.realtimexUrl = config.realtimex?.url || _RealtimeXSDK.DEFAULT_REALTIMEX_URL;
1379
+ this.httpClient = new HttpClient(this.realtimexUrl, this.appId, this.apiKey);
1167
1380
  this.activities = new ActivitiesModule(this.realtimexUrl, this.appId, this.appName, this.apiKey);
1168
1381
  this.webhook = new WebhookModule(this.realtimexUrl, this.appName, this.appId, this.apiKey);
1169
1382
  this.api = new ApiModule(this.realtimexUrl, this.appId, this.appName, this.apiKey);
@@ -1172,6 +1385,7 @@ var _RealtimeXSDK = class _RealtimeXSDK {
1172
1385
  this.llm = new LLMModule(this.realtimexUrl, this.appId, this.appName, this.apiKey);
1173
1386
  this.tts = new TTSModule(this.realtimexUrl, this.appId, this.appName, this.apiKey);
1174
1387
  this.stt = new STTModule(this.realtimexUrl, this.appId, this.appName, this.apiKey);
1388
+ this.agent = new AgentModule(this.httpClient);
1175
1389
  if (this.permissions.length > 0 && this.appId && !this.apiKey) {
1176
1390
  this.register().catch((err) => {
1177
1391
  console.error("[RealtimeX SDK] Auto-registration failed:", err.message);
@@ -1273,6 +1487,7 @@ _RealtimeXSDK.DEFAULT_REALTIMEX_URL = "http://localhost:3001";
1273
1487
  var RealtimeXSDK = _RealtimeXSDK;
1274
1488
  export {
1275
1489
  ActivitiesModule,
1490
+ AgentModule,
1276
1491
  ApiModule,
1277
1492
  LLMModule,
1278
1493
  LLMPermissionError,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@realtimex/sdk",
3
- "version": "1.3.1",
3
+ "version": "1.3.3",
4
4
  "description": "SDK for building Local Apps that integrate with RealtimeX",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",