@base44-preview/sdk 0.8.38-pr.228.85deaff → 0.8.38-pr.229.6a453f4

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/client.js CHANGED
@@ -7,6 +7,7 @@ import { createConnectorsModule, createUserConnectorsModule, } from "./modules/c
7
7
  import { getAccessToken } from "./utils/auth-utils.js";
8
8
  import { createFunctionsModule } from "./modules/functions.js";
9
9
  import { createAgentsModule } from "./modules/agents.js";
10
+ import { createSuperagentModule } from "./modules/superagent.js";
10
11
  import { createAiGatewayModule } from "./modules/ai-gateway.js";
11
12
  import { createAppLogsModule } from "./modules/app-logs.js";
12
13
  import { createUsersModule } from "./modules/users.js";
@@ -160,8 +161,16 @@ export function createClient(config) {
160
161
  appId,
161
162
  userAuthModule,
162
163
  }),
164
+ // Deliberately not given the host app's token: superagent access is
165
+ // always anonymous against the sibling superagent app.
166
+ superagent: createSuperagentModule({
167
+ serverUrl,
168
+ headers: optionalHeaders,
169
+ onError: options === null || options === void 0 ? void 0 : options.onError,
170
+ }),
163
171
  cleanup: () => {
164
172
  userModules.analytics.cleanup();
173
+ userModules.superagent.cleanup();
165
174
  if (socket) {
166
175
  socket.disconnect();
167
176
  }
@@ -346,7 +355,6 @@ export function createClientFromRequest(request) {
346
355
  const serverUrlHeader = request.headers.get("Base44-Api-Url");
347
356
  const functionsVersion = request.headers.get("Base44-Functions-Version");
348
357
  const stateHeader = request.headers.get("Base44-State");
349
- const dataEnvHeader = request.headers.get("X-Data-Env");
350
358
  if (!appId) {
351
359
  throw new Error("Base44-App-Id header is required, but is was not found on the request");
352
360
  }
@@ -374,16 +382,6 @@ export function createClientFromRequest(request) {
374
382
  if (stateHeader) {
375
383
  additionalHeaders["Base44-State"] = stateHeader;
376
384
  }
377
- // Propagate the data environment so entity operations from the function stay
378
- // in the same environment (e.g. test data) as the triggering request. This
379
- // matters for the user-scoped client: unlike the service token, the user JWT
380
- // carries no data-env, so without forwarding this header the callbacks fall
381
- // back to production data even when the app runs in test-data mode.
382
- // Forward only the known closed set (matches the backend contract) rather
383
- // than relaying an arbitrary attacker-supplied header value onward.
384
- if (dataEnvHeader === "dev" || dataEnvHeader === "prod") {
385
- additionalHeaders["X-Data-Env"] = dataEnvHeader;
386
- }
387
385
  return createClient({
388
386
  serverUrl: serverUrlHeader || "https://base44.app",
389
387
  appId,
@@ -5,6 +5,7 @@ import type { SsoModule } from "./modules/sso.types.js";
5
5
  import type { ConnectorsModule, UserConnectorsModule } from "./modules/connectors.types.js";
6
6
  import type { FunctionsModule } from "./modules/functions.types.js";
7
7
  import type { AgentsModule } from "./modules/agents.types.js";
8
+ import type { SuperagentModule } from "./modules/superagent.types.js";
8
9
  import type { AiGatewayModule } from "./modules/ai-gateway.types.js";
9
10
  import type { AppLogsModule } from "./modules/app-logs.types.js";
10
11
  import type { AnalyticsModule } from "./modules/analytics.types.js";
@@ -98,6 +99,8 @@ export interface Base44Client {
98
99
  functions: FunctionsModule;
99
100
  /** {@link IntegrationsModule | Integrations module} for calling pre-built integration endpoints. */
100
101
  integrations: IntegrationsModule;
102
+ /** {@link SuperagentModule | Superagent module} for anonymous chat with the app's linked public superagent. */
103
+ superagent: SuperagentModule;
101
104
  /** Cleanup function to disconnect WebSocket connections. Call when you're done with the client. */
102
105
  cleanup: () => void;
103
106
  /**
package/dist/index.d.ts CHANGED
@@ -9,6 +9,7 @@ export type { AuthModule, LoginResponse, RegisterParams, VerifyOtpParams, Change
9
9
  export type { IntegrationsModule, IntegrationEndpointFunction, CoreIntegrations, InvokeLLMParams, GenerateImageParams, GenerateImageResult, UploadFileParams, UploadFileResult, SendEmailParams, SendEmailResult, ExtractDataFromUploadedFileParams, ExtractDataFromUploadedFileResult, UploadPrivateFileParams, UploadPrivateFileResult, CreateFileSignedUrlParams, CreateFileSignedUrlResult, } from "./modules/integrations.types.js";
10
10
  export type { FunctionsModule, FunctionName, FunctionNameRegistry, } from "./modules/functions.types.js";
11
11
  export type { AgentsModule, AgentName, AgentNameRegistry, AgentConversation, AgentMessage, AgentMessageReasoning, AgentMessageToolCall, AgentMessageUsage, AgentMessageCustomContext, AgentMessageMetadata, CreateConversationParams, } from "./modules/agents.types.js";
12
+ export type { SuperagentModule, SuperagentHandle, CreateSuperagentConversationParams, } from "./modules/superagent.types.js";
12
13
  export type { AiGatewayModule, AiGatewayConnection, } from "./modules/ai-gateway.types.js";
13
14
  export type { AppLogsModule } from "./modules/app-logs.types.js";
14
15
  export type { SsoModule, SsoAccessTokenResponse } from "./modules/sso.types.js";
@@ -0,0 +1,2 @@
1
+ import { SuperagentModule, SuperagentModuleConfig } from "./superagent.types.js";
2
+ export declare function createSuperagentModule({ serverUrl, headers, onError, }: SuperagentModuleConfig): SuperagentModule;
@@ -0,0 +1,110 @@
1
+ import { createAxiosClient } from "../utils/axios-client.js";
2
+ import { RoomsSocket } from "../utils/socket-utils.js";
3
+ // A public superagent app always exposes its agent under this fixed name.
4
+ const SUPERAGENT_AGENT_NAME = "your_agent";
5
+ export function createSuperagentModule({ serverUrl, headers, onError, }) {
6
+ const handles = {};
7
+ const sockets = {};
8
+ const createHandle = (appId) => {
9
+ const baseURL = `/apps/${appId}/agents`;
10
+ // Dedicated anonymous client for the superagent app: no Authorization
11
+ // token, so the request interceptor attaches X-Base44-Anonymous-Id and
12
+ // the backend serves the caller as an anonymous visitor of the sibling
13
+ // superagent app.
14
+ const axios = createAxiosClient({
15
+ baseURL: `${serverUrl}/api`,
16
+ headers: {
17
+ ...headers,
18
+ "X-App-Id": String(appId),
19
+ },
20
+ onError,
21
+ });
22
+ const getSocket = () => {
23
+ if (!sockets[appId]) {
24
+ sockets[appId] = RoomsSocket({
25
+ config: {
26
+ serverUrl,
27
+ mountPath: "/ws-user-apps/socket.io/",
28
+ transports: ["websocket"],
29
+ appId,
30
+ anonymous: true,
31
+ },
32
+ });
33
+ }
34
+ return sockets[appId];
35
+ };
36
+ // Track active conversations
37
+ const currentConversations = {};
38
+ const createConversation = (params = {}) => {
39
+ return axios.post(`${baseURL}/conversations`, {
40
+ agent_name: SUPERAGENT_AGENT_NAME,
41
+ ...params,
42
+ });
43
+ };
44
+ const listConversations = (filterParams = {}) => {
45
+ return axios.get(`${baseURL}/conversations`, {
46
+ params: filterParams,
47
+ });
48
+ };
49
+ const getConversation = (conversationId) => {
50
+ return axios.get(`${baseURL}/conversations/${conversationId}`);
51
+ };
52
+ const addMessage = async (conversation, message) => {
53
+ return axios.post(`${baseURL}/conversations/v2/${conversation.id}/messages`, message);
54
+ };
55
+ const subscribeToConversation = (conversationId, onUpdate) => {
56
+ const room = `/agent-conversations/${conversationId}`;
57
+ const socket = getSocket();
58
+ // Store the promise for initial conversation state
59
+ const conversationPromise = getConversation(conversationId).then((conv) => {
60
+ currentConversations[conversationId] = conv;
61
+ return conv;
62
+ });
63
+ return socket.subscribeToRoom(room, {
64
+ connect: () => { },
65
+ update_model: async ({ data: jsonStr }) => {
66
+ const data = JSON.parse(jsonStr);
67
+ if (data._message) {
68
+ // Wait for initial conversation to be loaded
69
+ await conversationPromise;
70
+ const message = data._message;
71
+ // Update shared conversation state
72
+ const currentConversation = currentConversations[conversationId];
73
+ if (currentConversation) {
74
+ const messages = currentConversation.messages || [];
75
+ const existingIndex = messages.findIndex((m) => m.id === message.id);
76
+ const updatedMessages = existingIndex !== -1
77
+ ? messages.map((m, i) => (i === existingIndex ? message : m))
78
+ : [...messages, message];
79
+ currentConversations[conversationId] = {
80
+ ...currentConversation,
81
+ messages: updatedMessages,
82
+ };
83
+ onUpdate === null || onUpdate === void 0 ? void 0 : onUpdate(currentConversations[conversationId]);
84
+ }
85
+ }
86
+ },
87
+ });
88
+ };
89
+ return {
90
+ createConversation,
91
+ listConversations,
92
+ getConversation,
93
+ addMessage,
94
+ subscribeToConversation,
95
+ };
96
+ };
97
+ const forApp = (appId) => {
98
+ if (!handles[appId]) {
99
+ handles[appId] = createHandle(appId);
100
+ }
101
+ return handles[appId];
102
+ };
103
+ const cleanup = () => {
104
+ Object.values(sockets).forEach((socket) => socket.disconnect());
105
+ };
106
+ return {
107
+ forApp,
108
+ cleanup,
109
+ };
110
+ }
@@ -0,0 +1,161 @@
1
+ import { ModelFilterParams } from "../types.js";
2
+ import { AgentConversation, AgentMessage } from "./agents.types.js";
3
+ export type { AgentConversation, AgentMessage, AgentMessageReasoning, AgentMessageToolCall, AgentMessageUsage, AgentMessageCustomContext, AgentMessageMetadata, } from "./agents.types.js";
4
+ /**
5
+ * Parameters for creating a new superagent conversation.
6
+ *
7
+ * Unlike {@linkcode CreateConversationParams | agent conversations}, no agent
8
+ * name is accepted: a public superagent is always exposed under a single
9
+ * fixed agent name, which the SDK sets internally.
10
+ */
11
+ export interface CreateSuperagentConversationParams {
12
+ /** Optional metadata to attach to the conversation. */
13
+ metadata?: Record<string, any>;
14
+ }
15
+ /**
16
+ * Configuration for creating the superagent module.
17
+ * @internal
18
+ */
19
+ export interface SuperagentModuleConfig {
20
+ /** Server URL */
21
+ serverUrl: string;
22
+ /** Additional headers to include in API requests */
23
+ headers?: Record<string, string>;
24
+ /** Optional error handler for API errors */
25
+ onError?: (error: Error) => void;
26
+ }
27
+ /**
28
+ * A handle bound to a specific public superagent app.
29
+ *
30
+ * A public superagent is a separate Base44 app linked to a host app, serving
31
+ * the host app's end users as an anonymous-visitor chat agent. All requests
32
+ * made through a handle target the superagent app's ID and are sent
33
+ * anonymously: no Authorization token is attached, and the caller is
34
+ * identified by a stable anonymous visitor ID instead (the
35
+ * `X-Base44-Anonymous-Id` header on HTTP requests, and the `anonymous_id`
36
+ * handshake parameter on the realtime socket).
37
+ */
38
+ export interface SuperagentHandle {
39
+ /**
40
+ * Creates a new conversation with the public superagent.
41
+ *
42
+ * The agent name is set internally — a public superagent always exposes a
43
+ * single fixed agent.
44
+ *
45
+ * @param params - Optional conversation parameters (metadata).
46
+ * @returns Promise resolving to the created conversation.
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * const agent = base44.superagent.forApp('superagent-app-id');
51
+ * const conversation = await agent.createConversation({
52
+ * metadata: { source: 'help-widget' }
53
+ * });
54
+ * ```
55
+ */
56
+ createConversation(params?: CreateSuperagentConversationParams): Promise<AgentConversation>;
57
+ /**
58
+ * Lists the current anonymous visitor's conversations with the superagent.
59
+ *
60
+ * @param filterParams - Optional filter parameters for querying conversations.
61
+ * @returns Promise resolving to an array of conversations.
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * const conversations = await agent.listConversations();
66
+ * ```
67
+ */
68
+ listConversations(filterParams?: ModelFilterParams): Promise<AgentConversation[]>;
69
+ /**
70
+ * Gets a specific conversation by ID, including its full message history.
71
+ *
72
+ * @param conversationId - The unique identifier of the conversation.
73
+ * @returns Promise resolving to the conversation, or undefined if not found.
74
+ */
75
+ getConversation(conversationId: string): Promise<AgentConversation | undefined>;
76
+ /**
77
+ * Adds a message to a conversation.
78
+ *
79
+ * Sends a message to the superagent and updates the conversation. The
80
+ * agent's response is delivered through the realtime subscription (see
81
+ * {@linkcode subscribeToConversation | subscribeToConversation()}).
82
+ *
83
+ * @param conversation - The conversation to add the message to.
84
+ * @param message - The message to add.
85
+ * @returns Promise resolving to the created message.
86
+ *
87
+ * @example
88
+ * ```typescript
89
+ * await agent.addMessage(conversation, {
90
+ * role: 'user',
91
+ * content: 'How do I reset my password?'
92
+ * });
93
+ * ```
94
+ */
95
+ addMessage(conversation: AgentConversation, message: Partial<AgentMessage>): Promise<AgentMessage>;
96
+ /**
97
+ * Subscribes to realtime updates for a conversation.
98
+ *
99
+ * Establishes a dedicated anonymous WebSocket connection to the superagent
100
+ * app and receives instant updates when messages are added or updated.
101
+ * Returns an unsubscribe function to clean up the subscription.
102
+ *
103
+ * @param conversationId - The conversation ID to subscribe to.
104
+ * @param onUpdate - Callback invoked with the updated conversation.
105
+ * @returns Unsubscribe function to stop receiving updates.
106
+ *
107
+ * @example
108
+ * ```typescript
109
+ * const unsubscribe = agent.subscribeToConversation(
110
+ * conversation.id,
111
+ * (updated) => {
112
+ * const latest = updated.messages[updated.messages.length - 1];
113
+ * console.log('New message:', latest.content);
114
+ * }
115
+ * );
116
+ *
117
+ * // Later, clean up the subscription
118
+ * unsubscribe();
119
+ * ```
120
+ */
121
+ subscribeToConversation(conversationId: string, onUpdate?: (conversation: AgentConversation) => void): () => void;
122
+ }
123
+ /**
124
+ * Superagent module for chatting with an app's linked public superagent.
125
+ *
126
+ * A host app can have a linked "public superagent" — a separate Base44 app
127
+ * that serves the host app's end users as a chat agent without requiring
128
+ * them to sign in. This module provides anonymous access to that superagent
129
+ * app: it never uses the host app's authentication token. Instead, requests
130
+ * carry a stable anonymous visitor ID so the backend can group conversations
131
+ * per visitor.
132
+ *
133
+ * @example
134
+ * ```typescript
135
+ * const agent = base44.superagent.forApp('superagent-app-id');
136
+ *
137
+ * const conversation = await agent.createConversation();
138
+ * const unsubscribe = agent.subscribeToConversation(
139
+ * conversation.id,
140
+ * (updated) => console.log(updated.messages)
141
+ * );
142
+ * await agent.addMessage(conversation, { role: 'user', content: 'Hi!' });
143
+ * ```
144
+ */
145
+ export interface SuperagentModule {
146
+ /**
147
+ * Gets a handle bound to a public superagent app.
148
+ *
149
+ * Handles are cached per app ID, so repeated calls with the same ID return
150
+ * the same handle (and reuse its HTTP client and socket connection).
151
+ *
152
+ * @param appId - The superagent app's ID (not the host app's ID).
153
+ * @returns A handle for interacting with the superagent.
154
+ */
155
+ forApp(appId: string): SuperagentHandle;
156
+ /**
157
+ * Disconnects all superagent socket connections.
158
+ * @internal
159
+ */
160
+ cleanup(): void;
161
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -5,6 +5,12 @@ export interface RoomsSocketConfig {
5
5
  transports: string[];
6
6
  appId: string;
7
7
  token?: string;
8
+ /**
9
+ * Force an anonymous handshake: never attach a token (including the stored
10
+ * access token fallback), so the connection is identified only by its
11
+ * anonymous visitor id.
12
+ */
13
+ anonymous?: boolean;
8
14
  }
9
15
  export type TSocketRoom = string;
10
16
  export type TJsonStr = string;
@@ -8,7 +8,9 @@ function initializeSocket(config, handlers) {
8
8
  // handshake so the backend can verify room access for anonymous agent
9
9
  // conversations (mirrors the X-Base44-Anonymous-Id HTTP header). Authenticated
10
10
  // clients are identified by their token instead.
11
- const resolvedToken = (_a = config.token) !== null && _a !== void 0 ? _a : getAccessToken();
11
+ const resolvedToken = config.anonymous
12
+ ? undefined
13
+ : (_a = config.token) !== null && _a !== void 0 ? _a : getAccessToken();
12
14
  const query = {
13
15
  app_id: config.appId,
14
16
  token: resolvedToken,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@base44-preview/sdk",
3
- "version": "0.8.38-pr.228.85deaff",
3
+ "version": "0.8.38-pr.229.6a453f4",
4
4
  "description": "JavaScript SDK for Base44 API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",