@budibase/frontend-core 3.25.4 → 3.26.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@budibase/frontend-core",
3
- "version": "3.25.4",
3
+ "version": "3.26.1",
4
4
  "description": "Budibase frontend core libraries used in builder and client",
5
5
  "author": "Budibase",
6
6
  "license": "MPL-2.0",
@@ -19,5 +19,5 @@
19
19
  "shortid": "2.2.15",
20
20
  "socket.io-client": "^4.7.5"
21
21
  },
22
- "gitHead": "4a51aa9f4675ffa6555788aeaf6c31b522a952b3"
22
+ "gitHead": "3ee1bf769467a216a2e44443e01810cb1b076dfc"
23
23
  }
@@ -4,6 +4,7 @@ import {
4
4
  ChatConversationRequest,
5
5
  CreateChatConversationRequest,
6
6
  ChatApp,
7
+ ChatAppAgent,
7
8
  FetchAgentHistoryResponse,
8
9
  UpdateChatAppRequest,
9
10
  AgentMessageMetadata,
@@ -28,7 +29,7 @@ export interface ChatAppEndpoints {
28
29
  ) => Promise<ChatConversation>
29
30
  fetchChatHistory: (chatAppId: string) => Promise<FetchAgentHistoryResponse>
30
31
  fetchChatApp: (workspaceId?: string) => Promise<ChatApp | null>
31
- setChatAppAgent: (chatAppId: string, agentId: string) => Promise<ChatApp>
32
+ setChatAppAgent: (chatAppId: string, agentId: string) => Promise<ChatAppAgent>
32
33
  createChatConversation: (
33
34
  chat: CreateChatConversationRequest,
34
35
  workspaceId?: string
package/src/api/index.ts CHANGED
@@ -56,7 +56,6 @@ import { buildDeploymentEndpoints } from "./deploy"
56
56
  import { buildWorkspaceFavouriteEndpoints } from "./workspaceFavourites"
57
57
  import { buildRecaptchaEndpoints } from "./recaptcha"
58
58
  import { buildAIConfigEndpoints } from "./aiConfig"
59
- import { buildRagConfigEndpoints } from "./ragConfigs"
60
59
  import { buildVectorDbEndpoints } from "./vectorDbs"
61
60
 
62
61
  export type { APIClient } from "./types"
@@ -328,7 +327,6 @@ export const createAPIClient = (config: APIClientConfig = {}): APIClient => {
328
327
  resource: buildResourceEndpoints(API),
329
328
  recaptcha: buildRecaptchaEndpoints(API),
330
329
  aiConfig: buildAIConfigEndpoints(API),
331
- ragConfig: buildRagConfigEndpoints(API),
332
330
  vectorDb: buildVectorDbEndpoints(API),
333
331
  }
334
332
  }
package/src/api/types.ts CHANGED
@@ -43,7 +43,6 @@ import { DeploymentEndpoints } from "./deploy"
43
43
  import { WorkspaceFavouriteEndpoints } from "./workspaceFavourites"
44
44
  import { RecaptchaEndpoints } from "./recaptcha"
45
45
  import { AIConfigEndpoints } from "./aiConfig"
46
- import { RagConfigEndpoints } from "./ragConfigs"
47
46
  import { VectorDbEndpoints } from "./vectorDbs"
48
47
 
49
48
  export enum HTTPMethod {
@@ -159,6 +158,5 @@ export type APIClient = BaseAPIClient &
159
158
  deployment: DeploymentEndpoints
160
159
  recaptcha: RecaptchaEndpoints
161
160
  aiConfig: AIConfigEndpoints
162
- ragConfig: RagConfigEndpoints
163
161
  vectorDb: VectorDbEndpoints
164
162
  }
@@ -30,6 +30,7 @@
30
30
  workspaceId: string
31
31
  chat: ChatConversationLike
32
32
  persistConversation?: boolean
33
+ conversationStarters?: { prompt: string }[]
33
34
  onchatsaved?: (_event: {
34
35
  detail: { chatId?: string; chat: ChatConversationLike }
35
36
  }) => void
@@ -39,6 +40,7 @@
39
40
  workspaceId,
40
41
  chat = $bindable(),
41
42
  persistConversation = true,
43
+ conversationStarters = [],
42
44
  onchatsaved,
43
45
  }: Props = $props()
44
46
 
@@ -60,6 +62,15 @@
60
62
  let resolvedChatAppId = $state<string | undefined>()
61
63
  let resolvedConversationId = $state<string | undefined>()
62
64
 
65
+ const applyConversationStarter = async (starterPrompt: string) => {
66
+ if (isBusy) {
67
+ return
68
+ }
69
+ inputValue = starterPrompt
70
+ await sendMessage()
71
+ tick().then(() => textareaElement?.focus())
72
+ }
73
+
63
74
  const chatInstance = new Chat<UIMessage<AgentMessageMetadata>>({
64
75
  transport: new DefaultChatTransport({
65
76
  headers: () => ({ [Header.APP_ID]: workspaceId }),
@@ -116,6 +127,10 @@
116
127
  let isBusy = $derived(
117
128
  chatInstance.status === "streaming" || chatInstance.status === "submitted"
118
129
  )
130
+ let hasMessages = $derived(Boolean(chat?.messages?.length))
131
+ let showConversationStarters = $derived(
132
+ !isBusy && !hasMessages && conversationStarters.length > 0
133
+ )
119
134
 
120
135
  let lastChatId = $state<string | undefined>(chat?._id)
121
136
  $effect(() => {
@@ -153,7 +168,9 @@
153
168
  chatAppId: "",
154
169
  agentId: "",
155
170
  }
156
- const fallbackAgentId = chatApp.enabledAgents?.[0]?.agentId
171
+ const fallbackAgentId =
172
+ chatApp.agents?.find(agent => agent.isEnabled && agent.isDefault)
173
+ ?.agentId || chatApp.agents?.find(agent => agent.isEnabled)?.agentId
157
174
  chat = {
158
175
  ...baseChat,
159
176
  chatAppId: chatApp._id,
@@ -283,6 +300,22 @@
283
300
 
284
301
  <div class="chat-area" bind:this={chatAreaElement}>
285
302
  <div class="chatbox">
303
+ {#if showConversationStarters}
304
+ <div class="starter-section">
305
+ <div class="starter-title">Conversation starters</div>
306
+ <div class="starter-grid">
307
+ {#each conversationStarters as starter, index (index)}
308
+ <button
309
+ type="button"
310
+ class="starter-card"
311
+ onclick={() => applyConversationStarter(starter.prompt)}
312
+ >
313
+ {starter.prompt}
314
+ </button>
315
+ {/each}
316
+ </div>
317
+ </div>
318
+ {/if}
286
319
  {#each messages as message (message.id)}
287
320
  {#if message.role === "user"}
288
321
  <div class="message user">
@@ -428,6 +461,41 @@
428
461
  padding: 48px 0 24px 0;
429
462
  }
430
463
 
464
+ .starter-section {
465
+ display: flex;
466
+ flex-direction: column;
467
+ gap: var(--spacing-s);
468
+ }
469
+
470
+ .starter-title {
471
+ font-size: 12px;
472
+ text-transform: uppercase;
473
+ letter-spacing: 0.08em;
474
+ color: var(--spectrum-global-color-gray-600);
475
+ }
476
+
477
+ .starter-grid {
478
+ display: grid;
479
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
480
+ gap: var(--spacing-s);
481
+ }
482
+
483
+ .starter-card {
484
+ border: 1px solid var(--grey-3);
485
+ border-radius: 12px;
486
+ padding: var(--spacing-m);
487
+ background: var(--grey-2);
488
+ color: var(--spectrum-global-color-gray-900);
489
+ font: inherit;
490
+ text-align: left;
491
+ cursor: pointer;
492
+ }
493
+
494
+ .starter-card:hover {
495
+ border-color: var(--grey-4);
496
+ background: var(--grey-1);
497
+ }
498
+
431
499
  .message {
432
500
  display: flex;
433
501
  flex-direction: column;
@@ -11,6 +11,7 @@ import BaseDataFetch, { DataFetchParams } from "./DataFetch"
11
11
 
12
12
  interface UserFetchQuery {
13
13
  appId?: string
14
+ workspaceId?: string
14
15
  paginated?: boolean
15
16
  string?: {
16
17
  email: string
@@ -57,7 +58,7 @@ export default class UserFetch extends BaseDataFetch<
57
58
  const { cursor, query } = get(this.store)
58
59
 
59
60
  // Convert old format to new one - we now allow use of the lucene format
60
- const { appId, paginated, ...rest } = query
61
+ const { appId, paginated, workspaceId, ...rest } = query
61
62
 
62
63
  const finalQuery: SearchFilters = utils.isSupportedUserSearch(rest)
63
64
  ? rest
@@ -68,6 +69,7 @@ export default class UserFetch extends BaseDataFetch<
68
69
  bookmark: cursor ?? undefined,
69
70
  query: finalQuery ?? undefined,
70
71
  appId: appId,
72
+ workspaceId,
71
73
  paginate: paginated || paginate,
72
74
  limit,
73
75
  }
@@ -1,44 +0,0 @@
1
- import {
2
- CreateRagConfigRequest,
3
- RagConfig,
4
- RagConfigListResponse,
5
- UpdateRagConfigRequest,
6
- } from "@budibase/types"
7
- import { BaseAPIClient } from "./types"
8
-
9
- export interface RagConfigEndpoints {
10
- fetch: () => Promise<RagConfigListResponse>
11
- create: (config: CreateRagConfigRequest) => Promise<RagConfig>
12
- update: (config: UpdateRagConfigRequest) => Promise<RagConfig>
13
- delete: (id: string) => Promise<{ deleted: true }>
14
- }
15
-
16
- export const buildRagConfigEndpoints = (
17
- API: BaseAPIClient
18
- ): RagConfigEndpoints => ({
19
- fetch: async () => {
20
- return await API.get({
21
- url: "/api/ragconfig",
22
- })
23
- },
24
-
25
- create: async config => {
26
- return await API.post({
27
- url: "/api/ragconfig",
28
- body: config,
29
- })
30
- },
31
-
32
- update: async config => {
33
- return await API.put({
34
- url: "/api/ragconfig",
35
- body: config,
36
- })
37
- },
38
-
39
- delete: async id => {
40
- return await API.delete({
41
- url: `/api/ragconfig/${id}`,
42
- })
43
- },
44
- })