@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 +9 -11
- package/dist/client.types.d.ts +3 -0
- package/dist/index.d.ts +1 -0
- package/dist/modules/superagent.d.ts +2 -0
- package/dist/modules/superagent.js +110 -0
- package/dist/modules/superagent.types.d.ts +161 -0
- package/dist/modules/superagent.types.js +1 -0
- package/dist/utils/socket-utils.d.ts +6 -0
- package/dist/utils/socket-utils.js +3 -1
- package/package.json +1 -1
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,
|
package/dist/client.types.d.ts
CHANGED
|
@@ -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,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 =
|
|
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,
|