@databricks/appkit 0.16.0 → 0.17.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.
@@ -1,6 +1,6 @@
1
1
  //#region package.json
2
2
  var name = "@databricks/appkit";
3
- var version = "0.16.0";
3
+ var version = "0.17.0";
4
4
 
5
5
  //#endregion
6
6
  export { name, version };
@@ -69,20 +69,17 @@ var GenieConnector = class {
69
69
  return messageWaiter.wait(waitOptions);
70
70
  }
71
71
  async listConversationMessages(workspaceClient, spaceId, conversationId, options) {
72
- const maxMessages = options?.maxMessages ?? this.config.maxMessages;
73
- const allMessages = [];
74
- let pageToken;
75
- do {
76
- const response = await workspaceClient.genie.listConversationMessages({
77
- space_id: spaceId,
78
- conversation_id: conversationId,
79
- page_size: genieConnectorDefaults.pageSize,
80
- ...pageToken ? { page_token: pageToken } : {}
81
- });
82
- if (response.messages) allMessages.push(...response.messages);
83
- pageToken = response.next_page_token;
84
- } while (pageToken && allMessages.length < maxMessages);
85
- return allMessages.slice(0, maxMessages).reverse().map(toMessageResponse);
72
+ const pageSize = options?.pageSize ?? genieConnectorDefaults.initialPageSize;
73
+ const response = await workspaceClient.genie.listConversationMessages({
74
+ space_id: spaceId,
75
+ conversation_id: conversationId,
76
+ page_size: pageSize,
77
+ ...options?.pageToken ? { page_token: options.pageToken } : {}
78
+ });
79
+ return {
80
+ messages: (response.messages ?? []).reverse().map(toMessageResponse),
81
+ nextPageToken: response.next_page_token ?? null
82
+ };
86
83
  }
87
84
  async getMessageAttachmentQueryResult(workspaceClient, spaceId, conversationId, messageId, attachmentId, _signal) {
88
85
  return (await workspaceClient.genie.getMessageAttachmentQueryResult({
@@ -147,11 +144,21 @@ var GenieConnector = class {
147
144
  async *streamConversation(workspaceClient, spaceId, conversationId, options) {
148
145
  const includeQueryResults = options?.includeQueryResults !== false;
149
146
  try {
150
- const messageResponses = await this.listConversationMessages(workspaceClient, spaceId, conversationId);
147
+ const { messages: messageResponses, nextPageToken } = await this.listConversationMessages(workspaceClient, spaceId, conversationId, {
148
+ pageSize: options?.pageSize,
149
+ pageToken: options?.pageToken
150
+ });
151
151
  for (const messageResponse of messageResponses) yield {
152
152
  type: "message_result",
153
153
  message: messageResponse
154
154
  };
155
+ yield {
156
+ type: "history_info",
157
+ conversationId,
158
+ spaceId,
159
+ nextPageToken,
160
+ loadedCount: messageResponses.length
161
+ };
155
162
  if (includeQueryResults) {
156
163
  const queryAttachments = [];
157
164
  for (const msg of messageResponses) for (const att of msg.attachments ?? []) if (att.query?.statementId && att.attachmentId) queryAttachments.push({
@@ -197,10 +204,20 @@ var GenieConnector = class {
197
204
  };
198
205
  }
199
206
  async getConversation(workspaceClient, spaceId, conversationId) {
207
+ const allMessages = [];
208
+ let pageToken;
209
+ do {
210
+ const { messages, nextPageToken } = await this.listConversationMessages(workspaceClient, spaceId, conversationId, {
211
+ pageSize: genieConnectorDefaults.pageSize,
212
+ pageToken
213
+ });
214
+ allMessages.push(...messages);
215
+ pageToken = nextPageToken ?? void 0;
216
+ } while (pageToken && allMessages.length < this.config.maxMessages);
200
217
  return {
201
218
  conversationId,
202
219
  spaceId,
203
- messages: await this.listConversationMessages(workspaceClient, spaceId, conversationId)
220
+ messages: allMessages.slice(0, this.config.maxMessages)
204
221
  };
205
222
  }
206
223
  };
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":[],"sources":["../../../src/connectors/genie/client.ts"],"sourcesContent":["import type { WorkspaceClient } from \"@databricks/sdk-experimental\";\nimport * as SDK from \"@databricks/sdk-experimental\";\nimport type { GenieMessage } from \"@databricks/sdk-experimental/dist/apis/dashboards\";\nimport type { Waiter } from \"@databricks/sdk-experimental/dist/wait\";\nimport { createLogger } from \"../../logging\";\nimport { genieConnectorDefaults } from \"./defaults\";\nimport { pollWaiter } from \"./poll-waiter\";\nimport type {\n GenieAttachmentResponse,\n GenieConversationHistoryResponse,\n GenieMessageResponse,\n GenieStreamEvent,\n} from \"./types\";\n\nconst { TimeUnits } = SDK;\nconst Time = SDK.Time ?? (SDK as any).default.Time;\n\nconst logger = createLogger(\"connectors:genie\");\n\ntype CreateMessageWaiter = Waiter<GenieMessage, GenieMessage>;\n\nexport interface GenieConnectorConfig {\n timeout?: number;\n maxMessages?: number;\n}\n\nfunction mapAttachments(message: GenieMessage): GenieAttachmentResponse[] {\n return (\n message.attachments?.map((att) => ({\n attachmentId: att.attachment_id,\n query: att.query\n ? {\n title: att.query.title,\n description: att.query.description,\n query: att.query.query,\n statementId: att.query.statement_id,\n }\n : undefined,\n text: att.text ? { content: att.text.content } : undefined,\n suggestedQuestions: att.suggested_questions?.questions,\n })) ?? []\n );\n}\n\nfunction toMessageResponse(message: GenieMessage): GenieMessageResponse {\n return {\n messageId: message.message_id,\n conversationId: message.conversation_id,\n spaceId: message.space_id,\n status: message.status ?? \"COMPLETED\",\n content: message.content,\n attachments: mapAttachments(message),\n error: message.error?.error,\n };\n}\n\nexport class GenieConnector {\n private readonly config: Required<GenieConnectorConfig>;\n\n constructor(config: GenieConnectorConfig = {}) {\n this.config = {\n timeout: config.timeout ?? genieConnectorDefaults.timeout,\n maxMessages: config.maxMessages ?? genieConnectorDefaults.maxMessages,\n };\n }\n\n async startMessage(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n content: string,\n conversationId: string | undefined,\n ): Promise<{\n messageWaiter: CreateMessageWaiter;\n conversationId: string;\n messageId: string;\n }> {\n if (conversationId) {\n const waiter = await workspaceClient.genie.createMessage({\n space_id: spaceId,\n conversation_id: conversationId,\n content,\n });\n return {\n messageWaiter: waiter,\n conversationId,\n messageId: waiter.message_id ?? \"\",\n };\n }\n const start = await workspaceClient.genie.startConversation({\n space_id: spaceId,\n content,\n });\n return {\n messageWaiter: start as unknown as CreateMessageWaiter,\n conversationId: start.conversation_id,\n messageId: start.message_id,\n };\n }\n\n async waitForMessage(\n messageWaiter: CreateMessageWaiter,\n options?: { timeout?: number },\n ): Promise<GenieMessage> {\n const timeout = options?.timeout ?? this.config.timeout;\n const waitOptions =\n timeout > 0 ? { timeout: new Time(timeout, TimeUnits.milliseconds) } : {};\n return messageWaiter.wait(waitOptions);\n }\n\n async listConversationMessages(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n conversationId: string,\n options?: { maxMessages?: number },\n ): Promise<GenieMessageResponse[]> {\n const maxMessages = options?.maxMessages ?? this.config.maxMessages;\n const allMessages: GenieMessage[] = [];\n let pageToken: string | undefined;\n\n do {\n const response = await workspaceClient.genie.listConversationMessages({\n space_id: spaceId,\n conversation_id: conversationId,\n page_size: genieConnectorDefaults.pageSize,\n ...(pageToken ? { page_token: pageToken } : {}),\n });\n\n if (response.messages) {\n allMessages.push(...response.messages);\n }\n\n pageToken = response.next_page_token;\n } while (pageToken && allMessages.length < maxMessages);\n\n return allMessages.slice(0, maxMessages).reverse().map(toMessageResponse);\n }\n\n async getMessageAttachmentQueryResult(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n conversationId: string,\n messageId: string,\n attachmentId: string,\n _signal?: AbortSignal,\n ): Promise<unknown> {\n const response =\n await workspaceClient.genie.getMessageAttachmentQueryResult({\n space_id: spaceId,\n conversation_id: conversationId,\n message_id: messageId,\n attachment_id: attachmentId,\n });\n return response.statement_response;\n }\n\n async *streamSendMessage(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n content: string,\n conversationId: string | undefined,\n options?: { timeout?: number },\n ): AsyncGenerator<GenieStreamEvent> {\n try {\n const {\n messageWaiter,\n conversationId: resultConversationId,\n messageId: resultMessageId,\n } = await this.startMessage(\n workspaceClient,\n spaceId,\n content,\n conversationId,\n );\n\n yield {\n type: \"message_start\",\n conversationId: resultConversationId,\n messageId: resultMessageId,\n spaceId,\n };\n\n const timeout =\n options?.timeout != null ? options.timeout : this.config.timeout;\n const waitOptions =\n timeout > 0\n ? { timeout: new Time(timeout, TimeUnits.milliseconds) }\n : {};\n\n let completedMessage!: GenieMessage;\n for await (const event of pollWaiter(messageWaiter, waitOptions)) {\n if (event.type === \"progress\" && event.value.status) {\n yield { type: \"status\", status: event.value.status };\n } else if (event.type === \"completed\") {\n completedMessage = event.value;\n }\n }\n\n const messageResponse = toMessageResponse(completedMessage);\n yield { type: \"message_result\", message: messageResponse };\n\n yield* this.emitQueryResults(\n workspaceClient,\n spaceId,\n resultConversationId,\n messageResponse.messageId,\n messageResponse,\n );\n } catch (error) {\n logger.error(\"Genie message error: %O\", error);\n yield {\n type: \"error\",\n error: error instanceof Error ? error.message : \"Genie request failed\",\n };\n }\n }\n\n private async *emitQueryResults(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n conversationId: string,\n messageId: string,\n messageResponse: GenieMessageResponse,\n ): AsyncGenerator<\n Extract<GenieStreamEvent, { type: \"query_result\" } | { type: \"error\" }>\n > {\n const attachments = messageResponse.attachments ?? [];\n for (const att of attachments) {\n if (!att.query?.statementId || !att.attachmentId) continue;\n try {\n const data = await this.getMessageAttachmentQueryResult(\n workspaceClient,\n spaceId,\n conversationId,\n messageId,\n att.attachmentId,\n );\n yield {\n type: \"query_result\",\n attachmentId: att.attachmentId,\n statementId: att.query.statementId,\n data,\n };\n } catch (error) {\n logger.error(\n \"Failed to fetch query result for attachment %s: %O\",\n att.attachmentId,\n error,\n );\n yield {\n type: \"error\",\n error: `Failed to fetch query result for attachment ${att.attachmentId}`,\n };\n }\n }\n }\n\n async *streamConversation(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n conversationId: string,\n options?: { includeQueryResults?: boolean },\n ): AsyncGenerator<GenieStreamEvent> {\n const includeQueryResults = options?.includeQueryResults !== false;\n\n try {\n const messageResponses = await this.listConversationMessages(\n workspaceClient,\n spaceId,\n conversationId,\n );\n\n for (const messageResponse of messageResponses) {\n yield { type: \"message_result\", message: messageResponse };\n }\n\n if (includeQueryResults) {\n const queryAttachments: Array<{\n messageId: string;\n attachmentId: string;\n statementId: string;\n }> = [];\n\n for (const msg of messageResponses) {\n for (const att of msg.attachments ?? []) {\n if (att.query?.statementId && att.attachmentId) {\n queryAttachments.push({\n messageId: msg.messageId,\n attachmentId: att.attachmentId,\n statementId: att.query.statementId,\n });\n }\n }\n }\n\n const results = await Promise.allSettled(\n queryAttachments.map(async (att) => {\n const data = await this.getMessageAttachmentQueryResult(\n workspaceClient,\n spaceId,\n conversationId,\n att.messageId,\n att.attachmentId,\n );\n return {\n attachmentId: att.attachmentId,\n statementId: att.statementId,\n data,\n };\n }),\n );\n\n for (const result of results) {\n if (result.status === \"fulfilled\") {\n yield {\n type: \"query_result\",\n attachmentId: result.value.attachmentId,\n statementId: result.value.statementId,\n data: result.value.data,\n };\n } else {\n logger.error(\"Failed to fetch query result: %O\", result.reason);\n yield {\n type: \"error\",\n error:\n result.reason instanceof Error\n ? result.reason.message\n : \"Failed to fetch query result\",\n };\n }\n }\n }\n } catch (error) {\n logger.error(\"Genie getConversation error: %O\", error);\n yield {\n type: \"error\",\n error:\n error instanceof Error\n ? error.message\n : \"Failed to fetch conversation\",\n };\n }\n }\n\n async sendMessage(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n content: string,\n conversationId: string | undefined,\n ): Promise<GenieMessageResponse> {\n const { messageWaiter, conversationId: resultConversationId } =\n await this.startMessage(\n workspaceClient,\n spaceId,\n content,\n conversationId,\n );\n const completedMessage = await this.waitForMessage(messageWaiter);\n const messageResponse = toMessageResponse(completedMessage);\n return {\n ...messageResponse,\n conversationId: resultConversationId,\n };\n }\n\n async getConversation(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n conversationId: string,\n ): Promise<GenieConversationHistoryResponse> {\n const messages = await this.listConversationMessages(\n workspaceClient,\n spaceId,\n conversationId,\n );\n return {\n conversationId,\n spaceId,\n messages,\n };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":[],"sources":["../../../src/connectors/genie/client.ts"],"sourcesContent":["import type { WorkspaceClient } from \"@databricks/sdk-experimental\";\nimport * as SDK from \"@databricks/sdk-experimental\";\nimport type { GenieMessage } from \"@databricks/sdk-experimental/dist/apis/dashboards\";\nimport type { Waiter } from \"@databricks/sdk-experimental/dist/wait\";\nimport { createLogger } from \"../../logging\";\nimport { genieConnectorDefaults } from \"./defaults\";\nimport { pollWaiter } from \"./poll-waiter\";\nimport type {\n GenieAttachmentResponse,\n GenieConversationHistoryResponse,\n GenieMessageResponse,\n GenieStreamEvent,\n} from \"./types\";\n\nconst { TimeUnits } = SDK;\nconst Time = SDK.Time ?? (SDK as any).default.Time;\n\nconst logger = createLogger(\"connectors:genie\");\n\ntype CreateMessageWaiter = Waiter<GenieMessage, GenieMessage>;\n\nexport interface GenieConnectorConfig {\n timeout?: number;\n maxMessages?: number;\n}\n\nfunction mapAttachments(message: GenieMessage): GenieAttachmentResponse[] {\n return (\n message.attachments?.map((att) => ({\n attachmentId: att.attachment_id,\n query: att.query\n ? {\n title: att.query.title,\n description: att.query.description,\n query: att.query.query,\n statementId: att.query.statement_id,\n }\n : undefined,\n text: att.text ? { content: att.text.content } : undefined,\n suggestedQuestions: att.suggested_questions?.questions,\n })) ?? []\n );\n}\n\nfunction toMessageResponse(message: GenieMessage): GenieMessageResponse {\n return {\n messageId: message.message_id,\n conversationId: message.conversation_id,\n spaceId: message.space_id,\n status: message.status ?? \"COMPLETED\",\n content: message.content,\n attachments: mapAttachments(message),\n error: message.error?.error,\n };\n}\n\nexport class GenieConnector {\n private readonly config: Required<GenieConnectorConfig>;\n\n constructor(config: GenieConnectorConfig = {}) {\n this.config = {\n timeout: config.timeout ?? genieConnectorDefaults.timeout,\n maxMessages: config.maxMessages ?? genieConnectorDefaults.maxMessages,\n };\n }\n\n async startMessage(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n content: string,\n conversationId: string | undefined,\n ): Promise<{\n messageWaiter: CreateMessageWaiter;\n conversationId: string;\n messageId: string;\n }> {\n if (conversationId) {\n const waiter = await workspaceClient.genie.createMessage({\n space_id: spaceId,\n conversation_id: conversationId,\n content,\n });\n return {\n messageWaiter: waiter,\n conversationId,\n messageId: waiter.message_id ?? \"\",\n };\n }\n const start = await workspaceClient.genie.startConversation({\n space_id: spaceId,\n content,\n });\n return {\n messageWaiter: start as unknown as CreateMessageWaiter,\n conversationId: start.conversation_id,\n messageId: start.message_id,\n };\n }\n\n async waitForMessage(\n messageWaiter: CreateMessageWaiter,\n options?: { timeout?: number },\n ): Promise<GenieMessage> {\n const timeout = options?.timeout ?? this.config.timeout;\n const waitOptions =\n timeout > 0 ? { timeout: new Time(timeout, TimeUnits.milliseconds) } : {};\n return messageWaiter.wait(waitOptions);\n }\n\n async listConversationMessages(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n conversationId: string,\n options?: { pageSize?: number; pageToken?: string },\n ): Promise<{\n messages: GenieMessageResponse[];\n nextPageToken: string | null;\n }> {\n const pageSize =\n options?.pageSize ?? genieConnectorDefaults.initialPageSize;\n\n const response = await workspaceClient.genie.listConversationMessages({\n space_id: spaceId,\n conversation_id: conversationId,\n page_size: pageSize,\n ...(options?.pageToken ? { page_token: options.pageToken } : {}),\n });\n\n const messages = (response.messages ?? []).reverse().map(toMessageResponse);\n\n return {\n messages,\n nextPageToken: response.next_page_token ?? null,\n };\n }\n\n async getMessageAttachmentQueryResult(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n conversationId: string,\n messageId: string,\n attachmentId: string,\n _signal?: AbortSignal,\n ): Promise<unknown> {\n const response =\n await workspaceClient.genie.getMessageAttachmentQueryResult({\n space_id: spaceId,\n conversation_id: conversationId,\n message_id: messageId,\n attachment_id: attachmentId,\n });\n return response.statement_response;\n }\n\n async *streamSendMessage(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n content: string,\n conversationId: string | undefined,\n options?: { timeout?: number },\n ): AsyncGenerator<GenieStreamEvent> {\n try {\n const {\n messageWaiter,\n conversationId: resultConversationId,\n messageId: resultMessageId,\n } = await this.startMessage(\n workspaceClient,\n spaceId,\n content,\n conversationId,\n );\n\n yield {\n type: \"message_start\",\n conversationId: resultConversationId,\n messageId: resultMessageId,\n spaceId,\n };\n\n const timeout =\n options?.timeout != null ? options.timeout : this.config.timeout;\n const waitOptions =\n timeout > 0\n ? { timeout: new Time(timeout, TimeUnits.milliseconds) }\n : {};\n\n let completedMessage!: GenieMessage;\n for await (const event of pollWaiter(messageWaiter, waitOptions)) {\n if (event.type === \"progress\" && event.value.status) {\n yield { type: \"status\", status: event.value.status };\n } else if (event.type === \"completed\") {\n completedMessage = event.value;\n }\n }\n\n const messageResponse = toMessageResponse(completedMessage);\n yield { type: \"message_result\", message: messageResponse };\n\n yield* this.emitQueryResults(\n workspaceClient,\n spaceId,\n resultConversationId,\n messageResponse.messageId,\n messageResponse,\n );\n } catch (error) {\n logger.error(\"Genie message error: %O\", error);\n yield {\n type: \"error\",\n error: error instanceof Error ? error.message : \"Genie request failed\",\n };\n }\n }\n\n private async *emitQueryResults(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n conversationId: string,\n messageId: string,\n messageResponse: GenieMessageResponse,\n ): AsyncGenerator<\n Extract<GenieStreamEvent, { type: \"query_result\" } | { type: \"error\" }>\n > {\n const attachments = messageResponse.attachments ?? [];\n for (const att of attachments) {\n if (!att.query?.statementId || !att.attachmentId) continue;\n try {\n const data = await this.getMessageAttachmentQueryResult(\n workspaceClient,\n spaceId,\n conversationId,\n messageId,\n att.attachmentId,\n );\n yield {\n type: \"query_result\",\n attachmentId: att.attachmentId,\n statementId: att.query.statementId,\n data,\n };\n } catch (error) {\n logger.error(\n \"Failed to fetch query result for attachment %s: %O\",\n att.attachmentId,\n error,\n );\n yield {\n type: \"error\",\n error: `Failed to fetch query result for attachment ${att.attachmentId}`,\n };\n }\n }\n }\n\n async *streamConversation(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n conversationId: string,\n options?: {\n includeQueryResults?: boolean;\n pageSize?: number;\n pageToken?: string;\n },\n ): AsyncGenerator<GenieStreamEvent> {\n const includeQueryResults = options?.includeQueryResults !== false;\n\n try {\n const { messages: messageResponses, nextPageToken } =\n await this.listConversationMessages(\n workspaceClient,\n spaceId,\n conversationId,\n { pageSize: options?.pageSize, pageToken: options?.pageToken },\n );\n\n for (const messageResponse of messageResponses) {\n yield { type: \"message_result\", message: messageResponse };\n }\n\n yield {\n type: \"history_info\",\n conversationId,\n spaceId,\n nextPageToken,\n loadedCount: messageResponses.length,\n };\n\n if (includeQueryResults) {\n const queryAttachments: Array<{\n messageId: string;\n attachmentId: string;\n statementId: string;\n }> = [];\n\n for (const msg of messageResponses) {\n for (const att of msg.attachments ?? []) {\n if (att.query?.statementId && att.attachmentId) {\n queryAttachments.push({\n messageId: msg.messageId,\n attachmentId: att.attachmentId,\n statementId: att.query.statementId,\n });\n }\n }\n }\n\n const results = await Promise.allSettled(\n queryAttachments.map(async (att) => {\n const data = await this.getMessageAttachmentQueryResult(\n workspaceClient,\n spaceId,\n conversationId,\n att.messageId,\n att.attachmentId,\n );\n return {\n attachmentId: att.attachmentId,\n statementId: att.statementId,\n data,\n };\n }),\n );\n\n for (const result of results) {\n if (result.status === \"fulfilled\") {\n yield {\n type: \"query_result\",\n attachmentId: result.value.attachmentId,\n statementId: result.value.statementId,\n data: result.value.data,\n };\n } else {\n logger.error(\"Failed to fetch query result: %O\", result.reason);\n yield {\n type: \"error\",\n error:\n result.reason instanceof Error\n ? result.reason.message\n : \"Failed to fetch query result\",\n };\n }\n }\n }\n } catch (error) {\n logger.error(\"Genie getConversation error: %O\", error);\n yield {\n type: \"error\",\n error:\n error instanceof Error\n ? error.message\n : \"Failed to fetch conversation\",\n };\n }\n }\n\n async sendMessage(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n content: string,\n conversationId: string | undefined,\n ): Promise<GenieMessageResponse> {\n const { messageWaiter, conversationId: resultConversationId } =\n await this.startMessage(\n workspaceClient,\n spaceId,\n content,\n conversationId,\n );\n const completedMessage = await this.waitForMessage(messageWaiter);\n const messageResponse = toMessageResponse(completedMessage);\n return {\n ...messageResponse,\n conversationId: resultConversationId,\n };\n }\n\n async getConversation(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n conversationId: string,\n ): Promise<GenieConversationHistoryResponse> {\n const allMessages: GenieMessageResponse[] = [];\n let pageToken: string | undefined;\n\n do {\n const { messages, nextPageToken } = await this.listConversationMessages(\n workspaceClient,\n spaceId,\n conversationId,\n {\n pageSize: genieConnectorDefaults.pageSize,\n pageToken,\n },\n );\n allMessages.push(...messages);\n pageToken = nextPageToken ?? undefined;\n } while (pageToken && allMessages.length < this.config.maxMessages);\n\n return {\n conversationId,\n spaceId,\n messages: allMessages.slice(0, this.config.maxMessages),\n };\n }\n}\n"],"mappings":";;;;;;;AAcA,MAAM,EAAE,cAAc;AACtB,MAAM,OAAO,IAAI,QAAS,IAAY,QAAQ;AAE9C,MAAM,SAAS,aAAa,mBAAmB;AAS/C,SAAS,eAAe,SAAkD;AACxE,QACE,QAAQ,aAAa,KAAK,SAAS;EACjC,cAAc,IAAI;EAClB,OAAO,IAAI,QACP;GACE,OAAO,IAAI,MAAM;GACjB,aAAa,IAAI,MAAM;GACvB,OAAO,IAAI,MAAM;GACjB,aAAa,IAAI,MAAM;GACxB,GACD;EACJ,MAAM,IAAI,OAAO,EAAE,SAAS,IAAI,KAAK,SAAS,GAAG;EACjD,oBAAoB,IAAI,qBAAqB;EAC9C,EAAE,IAAI,EAAE;;AAIb,SAAS,kBAAkB,SAA6C;AACtE,QAAO;EACL,WAAW,QAAQ;EACnB,gBAAgB,QAAQ;EACxB,SAAS,QAAQ;EACjB,QAAQ,QAAQ,UAAU;EAC1B,SAAS,QAAQ;EACjB,aAAa,eAAe,QAAQ;EACpC,OAAO,QAAQ,OAAO;EACvB;;AAGH,IAAa,iBAAb,MAA4B;CAC1B,AAAiB;CAEjB,YAAY,SAA+B,EAAE,EAAE;AAC7C,OAAK,SAAS;GACZ,SAAS,OAAO,WAAW,uBAAuB;GAClD,aAAa,OAAO,eAAe,uBAAuB;GAC3D;;CAGH,MAAM,aACJ,iBACA,SACA,SACA,gBAKC;AACD,MAAI,gBAAgB;GAClB,MAAM,SAAS,MAAM,gBAAgB,MAAM,cAAc;IACvD,UAAU;IACV,iBAAiB;IACjB;IACD,CAAC;AACF,UAAO;IACL,eAAe;IACf;IACA,WAAW,OAAO,cAAc;IACjC;;EAEH,MAAM,QAAQ,MAAM,gBAAgB,MAAM,kBAAkB;GAC1D,UAAU;GACV;GACD,CAAC;AACF,SAAO;GACL,eAAe;GACf,gBAAgB,MAAM;GACtB,WAAW,MAAM;GAClB;;CAGH,MAAM,eACJ,eACA,SACuB;EACvB,MAAM,UAAU,SAAS,WAAW,KAAK,OAAO;EAChD,MAAM,cACJ,UAAU,IAAI,EAAE,SAAS,IAAI,KAAK,SAAS,UAAU,aAAa,EAAE,GAAG,EAAE;AAC3E,SAAO,cAAc,KAAK,YAAY;;CAGxC,MAAM,yBACJ,iBACA,SACA,gBACA,SAIC;EACD,MAAM,WACJ,SAAS,YAAY,uBAAuB;EAE9C,MAAM,WAAW,MAAM,gBAAgB,MAAM,yBAAyB;GACpE,UAAU;GACV,iBAAiB;GACjB,WAAW;GACX,GAAI,SAAS,YAAY,EAAE,YAAY,QAAQ,WAAW,GAAG,EAAE;GAChE,CAAC;AAIF,SAAO;GACL,WAHgB,SAAS,YAAY,EAAE,EAAE,SAAS,CAAC,IAAI,kBAAkB;GAIzE,eAAe,SAAS,mBAAmB;GAC5C;;CAGH,MAAM,gCACJ,iBACA,SACA,gBACA,WACA,cACA,SACkB;AAQlB,UANE,MAAM,gBAAgB,MAAM,gCAAgC;GAC1D,UAAU;GACV,iBAAiB;GACjB,YAAY;GACZ,eAAe;GAChB,CAAC,EACY;;CAGlB,OAAO,kBACL,iBACA,SACA,SACA,gBACA,SACkC;AAClC,MAAI;GACF,MAAM,EACJ,eACA,gBAAgB,sBAChB,WAAW,oBACT,MAAM,KAAK,aACb,iBACA,SACA,SACA,eACD;AAED,SAAM;IACJ,MAAM;IACN,gBAAgB;IAChB,WAAW;IACX;IACD;GAED,MAAM,UACJ,SAAS,WAAW,OAAO,QAAQ,UAAU,KAAK,OAAO;GAC3D,MAAM,cACJ,UAAU,IACN,EAAE,SAAS,IAAI,KAAK,SAAS,UAAU,aAAa,EAAE,GACtD,EAAE;GAER,IAAI;AACJ,cAAW,MAAM,SAAS,WAAW,eAAe,YAAY,CAC9D,KAAI,MAAM,SAAS,cAAc,MAAM,MAAM,OAC3C,OAAM;IAAE,MAAM;IAAU,QAAQ,MAAM,MAAM;IAAQ;YAC3C,MAAM,SAAS,YACxB,oBAAmB,MAAM;GAI7B,MAAM,kBAAkB,kBAAkB,iBAAiB;AAC3D,SAAM;IAAE,MAAM;IAAkB,SAAS;IAAiB;AAE1D,UAAO,KAAK,iBACV,iBACA,SACA,sBACA,gBAAgB,WAChB,gBACD;WACM,OAAO;AACd,UAAO,MAAM,2BAA2B,MAAM;AAC9C,SAAM;IACJ,MAAM;IACN,OAAO,iBAAiB,QAAQ,MAAM,UAAU;IACjD;;;CAIL,OAAe,iBACb,iBACA,SACA,gBACA,WACA,iBAGA;EACA,MAAM,cAAc,gBAAgB,eAAe,EAAE;AACrD,OAAK,MAAM,OAAO,aAAa;AAC7B,OAAI,CAAC,IAAI,OAAO,eAAe,CAAC,IAAI,aAAc;AAClD,OAAI;IACF,MAAM,OAAO,MAAM,KAAK,gCACtB,iBACA,SACA,gBACA,WACA,IAAI,aACL;AACD,UAAM;KACJ,MAAM;KACN,cAAc,IAAI;KAClB,aAAa,IAAI,MAAM;KACvB;KACD;YACM,OAAO;AACd,WAAO,MACL,sDACA,IAAI,cACJ,MACD;AACD,UAAM;KACJ,MAAM;KACN,OAAO,+CAA+C,IAAI;KAC3D;;;;CAKP,OAAO,mBACL,iBACA,SACA,gBACA,SAKkC;EAClC,MAAM,sBAAsB,SAAS,wBAAwB;AAE7D,MAAI;GACF,MAAM,EAAE,UAAU,kBAAkB,kBAClC,MAAM,KAAK,yBACT,iBACA,SACA,gBACA;IAAE,UAAU,SAAS;IAAU,WAAW,SAAS;IAAW,CAC/D;AAEH,QAAK,MAAM,mBAAmB,iBAC5B,OAAM;IAAE,MAAM;IAAkB,SAAS;IAAiB;AAG5D,SAAM;IACJ,MAAM;IACN;IACA;IACA;IACA,aAAa,iBAAiB;IAC/B;AAED,OAAI,qBAAqB;IACvB,MAAM,mBAID,EAAE;AAEP,SAAK,MAAM,OAAO,iBAChB,MAAK,MAAM,OAAO,IAAI,eAAe,EAAE,CACrC,KAAI,IAAI,OAAO,eAAe,IAAI,aAChC,kBAAiB,KAAK;KACpB,WAAW,IAAI;KACf,cAAc,IAAI;KAClB,aAAa,IAAI,MAAM;KACxB,CAAC;IAKR,MAAM,UAAU,MAAM,QAAQ,WAC5B,iBAAiB,IAAI,OAAO,QAAQ;KAClC,MAAM,OAAO,MAAM,KAAK,gCACtB,iBACA,SACA,gBACA,IAAI,WACJ,IAAI,aACL;AACD,YAAO;MACL,cAAc,IAAI;MAClB,aAAa,IAAI;MACjB;MACD;MACD,CACH;AAED,SAAK,MAAM,UAAU,QACnB,KAAI,OAAO,WAAW,YACpB,OAAM;KACJ,MAAM;KACN,cAAc,OAAO,MAAM;KAC3B,aAAa,OAAO,MAAM;KAC1B,MAAM,OAAO,MAAM;KACpB;SACI;AACL,YAAO,MAAM,oCAAoC,OAAO,OAAO;AAC/D,WAAM;MACJ,MAAM;MACN,OACE,OAAO,kBAAkB,QACrB,OAAO,OAAO,UACd;MACP;;;WAIA,OAAO;AACd,UAAO,MAAM,mCAAmC,MAAM;AACtD,SAAM;IACJ,MAAM;IACN,OACE,iBAAiB,QACb,MAAM,UACN;IACP;;;CAIL,MAAM,YACJ,iBACA,SACA,SACA,gBAC+B;EAC/B,MAAM,EAAE,eAAe,gBAAgB,yBACrC,MAAM,KAAK,aACT,iBACA,SACA,SACA,eACD;AAGH,SAAO;GACL,GAFsB,kBADC,MAAM,KAAK,eAAe,cAAc,CACN;GAGzD,gBAAgB;GACjB;;CAGH,MAAM,gBACJ,iBACA,SACA,gBAC2C;EAC3C,MAAM,cAAsC,EAAE;EAC9C,IAAI;AAEJ,KAAG;GACD,MAAM,EAAE,UAAU,kBAAkB,MAAM,KAAK,yBAC7C,iBACA,SACA,gBACA;IACE,UAAU,uBAAuB;IACjC;IACD,CACF;AACD,eAAY,KAAK,GAAG,SAAS;AAC7B,eAAY,iBAAiB;WACtB,aAAa,YAAY,SAAS,KAAK,OAAO;AAEvD,SAAO;GACL;GACA;GACA,UAAU,YAAY,MAAM,GAAG,KAAK,OAAO,YAAY;GACxD"}
@@ -2,7 +2,8 @@
2
2
  const genieConnectorDefaults = {
3
3
  timeout: 12e4,
4
4
  maxMessages: 200,
5
- pageSize: 100
5
+ pageSize: 100,
6
+ initialPageSize: 20
6
7
  };
7
8
 
8
9
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"defaults.js","names":[],"sources":["../../../src/connectors/genie/defaults.ts"],"sourcesContent":["export const genieConnectorDefaults = {\n /** Genie waiter timeout in ms. 0 = indefinite. */\n timeout: 120_000,\n /** Max messages to fetch when listing a conversation. */\n maxMessages: 200,\n /** Default page size for listConversationMessages. */\n pageSize: 100,\n} as const;\n"],"mappings":";AAAA,MAAa,yBAAyB;CAEpC,SAAS;CAET,aAAa;CAEb,UAAU;CACX"}
1
+ {"version":3,"file":"defaults.js","names":[],"sources":["../../../src/connectors/genie/defaults.ts"],"sourcesContent":["export const genieConnectorDefaults = {\n /** Genie waiter timeout in ms. 0 = indefinite. */\n timeout: 120_000,\n /** Max messages to fetch when listing a conversation. */\n maxMessages: 200,\n /** Default page size for listConversationMessages. */\n pageSize: 100,\n /** Default page size for initial conversation load (lazy loading). */\n initialPageSize: 20,\n} as const;\n"],"mappings":";AAAA,MAAa,yBAAyB;CAEpC,SAAS;CAET,aAAa;CAEb,UAAU;CAEV,iBAAiB;CAClB"}
@@ -1 +1 @@
1
- {"version":3,"file":"genie.d.ts","names":[],"sources":["../../../src/plugins/genie/genie.ts"],"mappings":";;;;;;;;;;;;cAmBa,WAAA,SAAoB,MAAA;EAC/B,IAAA;EAAA,OAEO,QAAA,EAAuB,cAAA;EAAA,iBAEb,WAAA;EAAA,UAEC,MAAA,EAAQ,YAAA;EAAA,iBAET,cAAA;cAEL,MAAA,EAAQ,YAAA;EAAA,QAYZ,aAAA;EAAA,QAKA,cAAA;EAIR,YAAA,CAAa,MAAA,EAAQ,UAAA;EAoBf,kBAAA,CACJ,GAAA,EAAK,OAAA,CAAQ,OAAA,EACb,GAAA,EAAK,OAAA,CAAQ,QAAA,GACZ,OAAA;EAsDG,sBAAA,CACJ,GAAA,EAAK,OAAA,CAAQ,OAAA,EACb,GAAA,EAAK,OAAA,CAAQ,QAAA,GACZ,OAAA;EA2CG,eAAA,CACJ,KAAA,UACA,cAAA,WACC,OAAA,CAAQ,gCAAA;EA9HU;;;;EAkJd,WAAA,CACL,KAAA,UACA,OAAA,UACA,cAAA,WACA,OAAA;IAAY,OAAA;EAAA,IACX,cAAA,CAAe,gBAAA;EAgBZ,QAAA,CAAA,GAAY,OAAA;EAIlB,OAAA,CAAA;iCAxBe,OAAA,UACE,cAAA,WACQ,OAAA;MACX,OAAA;IAAA,MACX,cAAA,CAAe,gBAAA;qCA3BH,cAAA,aAEZ,OAAA,CAAQ,gCAAA;EAAA;AAAA;;;;cAwDA,KAAA,EAAK,QAAA,QAAA,WAAA,EAAA,YAAA"}
1
+ {"version":3,"file":"genie.d.ts","names":[],"sources":["../../../src/plugins/genie/genie.ts"],"mappings":";;;;;;;;;;;;cAmBa,WAAA,SAAoB,MAAA;EAC/B,IAAA;EAAA,OAEO,QAAA,EAAuB,cAAA;EAAA,iBAEb,WAAA;EAAA,UAEC,MAAA,EAAQ,YAAA;EAAA,iBAET,cAAA;cAEL,MAAA,EAAQ,YAAA;EAAA,QAYZ,aAAA;EAAA,QAKA,cAAA;EAIR,YAAA,CAAa,MAAA,EAAQ,UAAA;EAoBf,kBAAA,CACJ,GAAA,EAAK,OAAA,CAAQ,OAAA,EACb,GAAA,EAAK,OAAA,CAAQ,QAAA,GACZ,OAAA;EAwDG,sBAAA,CACJ,GAAA,EAAK,OAAA,CAAQ,OAAA,EACb,GAAA,EAAK,OAAA,CAAQ,QAAA,GACZ,OAAA;EAgDG,eAAA,CACJ,KAAA,UACA,cAAA,WACC,OAAA,CAAQ,gCAAA;EArIU;;;;EAyJd,WAAA,CACL,KAAA,UACA,OAAA,UACA,cAAA,WACA,OAAA;IAAY,OAAA;EAAA,IACX,cAAA,CAAe,gBAAA;EAgBZ,QAAA,CAAA,GAAY,OAAA;EAIlB,OAAA,CAAA;iCAxBe,OAAA,UACE,cAAA,WACQ,OAAA;MACX,OAAA;IAAA,MACX,cAAA,CAAe,gBAAA;qCA3BH,cAAA,aAEZ,OAAA,CAAQ,gCAAA;EAAA;AAAA;;;;cAwDA,KAAA,EAAK,QAAA,QAAA,WAAA,EAAA,YAAA"}
@@ -69,7 +69,7 @@ var GeniePlugin = class extends Plugin {
69
69
  }
70
70
  logger.debug("Sending message to space %s (alias=%s, conversationId=%s)", spaceId, alias, conversationId ?? "new");
71
71
  const timeout = this.config.timeout ?? 12e4;
72
- const requestId = req.query.requestId || randomUUID();
72
+ const requestId = typeof req.query.requestId === "string" && req.query.requestId || randomUUID();
73
73
  const streamSettings = {
74
74
  ...genieStreamDefaults,
75
75
  default: {
@@ -92,8 +92,9 @@ var GeniePlugin = class extends Plugin {
92
92
  return;
93
93
  }
94
94
  const includeQueryResults = req.query.includeQueryResults !== "false";
95
- const requestId = req.query.requestId || randomUUID();
96
- logger.debug("Fetching conversation %s from space %s (alias=%s, includeQueryResults=%s)", conversationId, spaceId, alias, includeQueryResults);
95
+ const pageToken = typeof req.query.pageToken === "string" ? req.query.pageToken : void 0;
96
+ const requestId = typeof req.query.requestId === "string" && req.query.requestId || randomUUID();
97
+ logger.debug("Fetching conversation %s from space %s (alias=%s, includeQueryResults=%s, pageToken=%s)", conversationId, spaceId, alias, includeQueryResults, pageToken ?? "none");
97
98
  const streamSettings = {
98
99
  ...genieStreamDefaults,
99
100
  stream: {
@@ -102,7 +103,10 @@ var GeniePlugin = class extends Plugin {
102
103
  }
103
104
  };
104
105
  const workspaceClient = getWorkspaceClient();
105
- await this.executeStream(res, () => this.genieConnector.streamConversation(workspaceClient, spaceId, conversationId, { includeQueryResults }), streamSettings);
106
+ await this.executeStream(res, () => this.genieConnector.streamConversation(workspaceClient, spaceId, conversationId, {
107
+ includeQueryResults,
108
+ pageToken
109
+ }), streamSettings);
106
110
  }
107
111
  async getConversation(alias, conversationId) {
108
112
  const spaceId = this.resolveSpaceId(alias);
@@ -1 +1 @@
1
- {"version":3,"file":"genie.js","names":["manifest"],"sources":["../../../src/plugins/genie/genie.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport type express from \"express\";\nimport type { IAppRouter, StreamExecutionSettings } from \"shared\";\nimport { GenieConnector } from \"../../connectors\";\nimport { getWorkspaceClient } from \"../../context\";\nimport { createLogger } from \"../../logging\";\nimport { Plugin, toPlugin } from \"../../plugin\";\nimport type { PluginManifest } from \"../../registry\";\nimport { genieStreamDefaults } from \"./defaults\";\nimport manifest from \"./manifest.json\";\nimport type {\n GenieConversationHistoryResponse,\n GenieSendMessageRequest,\n GenieStreamEvent,\n IGenieConfig,\n} from \"./types\";\n\nconst logger = createLogger(\"genie\");\n\nexport class GeniePlugin extends Plugin {\n name = \"genie\";\n\n static manifest = manifest as PluginManifest;\n\n protected static description =\n \"AI/BI Genie space integration for natural language data queries\";\n protected declare config: IGenieConfig;\n\n private readonly genieConnector: GenieConnector;\n\n constructor(config: IGenieConfig) {\n super(config);\n this.config = {\n ...config,\n spaces: config.spaces ?? this.defaultSpaces(),\n };\n this.genieConnector = new GenieConnector({\n timeout: this.config.timeout,\n maxMessages: 200,\n });\n }\n\n private defaultSpaces(): Record<string, string> {\n const spaceId = process.env.DATABRICKS_GENIE_SPACE_ID;\n return spaceId ? { default: spaceId } : {};\n }\n\n private resolveSpaceId(alias: string): string | null {\n return this.config.spaces?.[alias] ?? null;\n }\n\n injectRoutes(router: IAppRouter) {\n this.route(router, {\n name: \"sendMessage\",\n method: \"post\",\n path: \"/:alias/messages\",\n handler: async (req: express.Request, res: express.Response) => {\n await this.asUser(req)._handleSendMessage(req, res);\n },\n });\n\n this.route(router, {\n name: \"getConversation\",\n method: \"get\",\n path: \"/:alias/conversations/:conversationId\",\n handler: async (req: express.Request, res: express.Response) => {\n await this.asUser(req)._handleGetConversation(req, res);\n },\n });\n }\n\n async _handleSendMessage(\n req: express.Request,\n res: express.Response,\n ): Promise<void> {\n const { alias } = req.params;\n const spaceId = this.resolveSpaceId(alias);\n\n if (!spaceId) {\n res.status(404).json({ error: `Unknown space alias: ${alias}` });\n return;\n }\n\n const { content, conversationId } = req.body as GenieSendMessageRequest;\n\n if (!content) {\n res.status(400).json({ error: \"content is required\" });\n return;\n }\n\n logger.debug(\n \"Sending message to space %s (alias=%s, conversationId=%s)\",\n spaceId,\n alias,\n conversationId ?? \"new\",\n );\n\n const timeout = this.config.timeout ?? 120_000;\n const requestId = (req.query.requestId as string) || randomUUID();\n\n const streamSettings: StreamExecutionSettings = {\n ...genieStreamDefaults,\n default: {\n ...genieStreamDefaults.default,\n timeout,\n },\n stream: {\n ...genieStreamDefaults.stream,\n streamId: requestId,\n },\n };\n\n const workspaceClient = getWorkspaceClient();\n\n await this.executeStream<GenieStreamEvent>(\n res,\n () =>\n this.genieConnector.streamSendMessage(\n workspaceClient,\n spaceId,\n content,\n conversationId,\n { timeout },\n ),\n streamSettings,\n );\n }\n\n async _handleGetConversation(\n req: express.Request,\n res: express.Response,\n ): Promise<void> {\n const { alias, conversationId } = req.params;\n const spaceId = this.resolveSpaceId(alias);\n\n if (!spaceId) {\n res.status(404).json({ error: `Unknown space alias: ${alias}` });\n return;\n }\n\n const includeQueryResults = req.query.includeQueryResults !== \"false\";\n const requestId = (req.query.requestId as string) || randomUUID();\n\n logger.debug(\n \"Fetching conversation %s from space %s (alias=%s, includeQueryResults=%s)\",\n conversationId,\n spaceId,\n alias,\n includeQueryResults,\n );\n\n const streamSettings: StreamExecutionSettings = {\n ...genieStreamDefaults,\n stream: {\n ...genieStreamDefaults.stream,\n streamId: requestId,\n },\n };\n\n const workspaceClient = getWorkspaceClient();\n\n await this.executeStream<GenieStreamEvent>(\n res,\n () =>\n this.genieConnector.streamConversation(\n workspaceClient,\n spaceId,\n conversationId,\n { includeQueryResults },\n ),\n streamSettings,\n );\n }\n\n async getConversation(\n alias: string,\n conversationId: string,\n ): Promise<GenieConversationHistoryResponse> {\n const spaceId = this.resolveSpaceId(alias);\n\n if (!spaceId) {\n throw new Error(`Unknown space alias: ${alias}`);\n }\n\n const workspaceClient = getWorkspaceClient();\n\n return this.genieConnector.getConversation(\n workspaceClient,\n spaceId,\n conversationId,\n );\n }\n\n /**\n * Send a message and consume events as a stream (message_start, status,\n * message_result, query_result, error).\n */\n async *sendMessage(\n alias: string,\n content: string,\n conversationId?: string,\n options?: { timeout?: number },\n ): AsyncGenerator<GenieStreamEvent> {\n const spaceId = this.resolveSpaceId(alias);\n if (!spaceId) {\n throw new Error(`Unknown space alias: ${alias}`);\n }\n const workspaceClient = getWorkspaceClient();\n const timeout = options?.timeout ?? this.config.timeout ?? 120_000;\n yield* this.genieConnector.streamSendMessage(\n workspaceClient,\n spaceId,\n content,\n conversationId,\n { timeout },\n );\n }\n\n async shutdown(): Promise<void> {\n this.streamManager.abortAll();\n }\n\n exports() {\n return {\n sendMessage: this.sendMessage,\n getConversation: this.getConversation,\n };\n }\n}\n\n/**\n * @internal\n */\nexport const genie = toPlugin<typeof GeniePlugin, IGenieConfig, \"genie\">(\n GeniePlugin,\n \"genie\",\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"genie.js","names":["manifest"],"sources":["../../../src/plugins/genie/genie.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport type express from \"express\";\nimport type { IAppRouter, StreamExecutionSettings } from \"shared\";\nimport { GenieConnector } from \"../../connectors\";\nimport { getWorkspaceClient } from \"../../context\";\nimport { createLogger } from \"../../logging\";\nimport { Plugin, toPlugin } from \"../../plugin\";\nimport type { PluginManifest } from \"../../registry\";\nimport { genieStreamDefaults } from \"./defaults\";\nimport manifest from \"./manifest.json\";\nimport type {\n GenieConversationHistoryResponse,\n GenieSendMessageRequest,\n GenieStreamEvent,\n IGenieConfig,\n} from \"./types\";\n\nconst logger = createLogger(\"genie\");\n\nexport class GeniePlugin extends Plugin {\n name = \"genie\";\n\n static manifest = manifest as PluginManifest;\n\n protected static description =\n \"AI/BI Genie space integration for natural language data queries\";\n protected declare config: IGenieConfig;\n\n private readonly genieConnector: GenieConnector;\n\n constructor(config: IGenieConfig) {\n super(config);\n this.config = {\n ...config,\n spaces: config.spaces ?? this.defaultSpaces(),\n };\n this.genieConnector = new GenieConnector({\n timeout: this.config.timeout,\n maxMessages: 200,\n });\n }\n\n private defaultSpaces(): Record<string, string> {\n const spaceId = process.env.DATABRICKS_GENIE_SPACE_ID;\n return spaceId ? { default: spaceId } : {};\n }\n\n private resolveSpaceId(alias: string): string | null {\n return this.config.spaces?.[alias] ?? null;\n }\n\n injectRoutes(router: IAppRouter) {\n this.route(router, {\n name: \"sendMessage\",\n method: \"post\",\n path: \"/:alias/messages\",\n handler: async (req: express.Request, res: express.Response) => {\n await this.asUser(req)._handleSendMessage(req, res);\n },\n });\n\n this.route(router, {\n name: \"getConversation\",\n method: \"get\",\n path: \"/:alias/conversations/:conversationId\",\n handler: async (req: express.Request, res: express.Response) => {\n await this.asUser(req)._handleGetConversation(req, res);\n },\n });\n }\n\n async _handleSendMessage(\n req: express.Request,\n res: express.Response,\n ): Promise<void> {\n const { alias } = req.params;\n const spaceId = this.resolveSpaceId(alias);\n\n if (!spaceId) {\n res.status(404).json({ error: `Unknown space alias: ${alias}` });\n return;\n }\n\n const { content, conversationId } = req.body as GenieSendMessageRequest;\n\n if (!content) {\n res.status(400).json({ error: \"content is required\" });\n return;\n }\n\n logger.debug(\n \"Sending message to space %s (alias=%s, conversationId=%s)\",\n spaceId,\n alias,\n conversationId ?? \"new\",\n );\n\n const timeout = this.config.timeout ?? 120_000;\n const requestId =\n (typeof req.query.requestId === \"string\" && req.query.requestId) ||\n randomUUID();\n\n const streamSettings: StreamExecutionSettings = {\n ...genieStreamDefaults,\n default: {\n ...genieStreamDefaults.default,\n timeout,\n },\n stream: {\n ...genieStreamDefaults.stream,\n streamId: requestId,\n },\n };\n\n const workspaceClient = getWorkspaceClient();\n\n await this.executeStream<GenieStreamEvent>(\n res,\n () =>\n this.genieConnector.streamSendMessage(\n workspaceClient,\n spaceId,\n content,\n conversationId,\n { timeout },\n ),\n streamSettings,\n );\n }\n\n async _handleGetConversation(\n req: express.Request,\n res: express.Response,\n ): Promise<void> {\n const { alias, conversationId } = req.params;\n const spaceId = this.resolveSpaceId(alias);\n\n if (!spaceId) {\n res.status(404).json({ error: `Unknown space alias: ${alias}` });\n return;\n }\n\n const includeQueryResults = req.query.includeQueryResults !== \"false\";\n const pageToken =\n typeof req.query.pageToken === \"string\" ? req.query.pageToken : undefined;\n const requestId =\n (typeof req.query.requestId === \"string\" && req.query.requestId) ||\n randomUUID();\n\n logger.debug(\n \"Fetching conversation %s from space %s (alias=%s, includeQueryResults=%s, pageToken=%s)\",\n conversationId,\n spaceId,\n alias,\n includeQueryResults,\n pageToken ?? \"none\",\n );\n\n const streamSettings: StreamExecutionSettings = {\n ...genieStreamDefaults,\n stream: {\n ...genieStreamDefaults.stream,\n streamId: requestId,\n },\n };\n\n const workspaceClient = getWorkspaceClient();\n\n await this.executeStream<GenieStreamEvent>(\n res,\n () =>\n this.genieConnector.streamConversation(\n workspaceClient,\n spaceId,\n conversationId,\n { includeQueryResults, pageToken },\n ),\n streamSettings,\n );\n }\n\n async getConversation(\n alias: string,\n conversationId: string,\n ): Promise<GenieConversationHistoryResponse> {\n const spaceId = this.resolveSpaceId(alias);\n\n if (!spaceId) {\n throw new Error(`Unknown space alias: ${alias}`);\n }\n\n const workspaceClient = getWorkspaceClient();\n\n return this.genieConnector.getConversation(\n workspaceClient,\n spaceId,\n conversationId,\n );\n }\n\n /**\n * Send a message and consume events as a stream (message_start, status,\n * message_result, query_result, error).\n */\n async *sendMessage(\n alias: string,\n content: string,\n conversationId?: string,\n options?: { timeout?: number },\n ): AsyncGenerator<GenieStreamEvent> {\n const spaceId = this.resolveSpaceId(alias);\n if (!spaceId) {\n throw new Error(`Unknown space alias: ${alias}`);\n }\n const workspaceClient = getWorkspaceClient();\n const timeout = options?.timeout ?? this.config.timeout ?? 120_000;\n yield* this.genieConnector.streamSendMessage(\n workspaceClient,\n spaceId,\n content,\n conversationId,\n { timeout },\n );\n }\n\n async shutdown(): Promise<void> {\n this.streamManager.abortAll();\n }\n\n exports() {\n return {\n sendMessage: this.sendMessage,\n getConversation: this.getConversation,\n };\n }\n}\n\n/**\n * @internal\n */\nexport const genie = toPlugin<typeof GeniePlugin, IGenieConfig, \"genie\">(\n GeniePlugin,\n \"genie\",\n);\n"],"mappings":"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"}
@@ -19,6 +19,12 @@ type GenieStreamEvent = {
19
19
  } | {
20
20
  type: "error";
21
21
  error: string;
22
+ } | {
23
+ type: "history_info";
24
+ conversationId: string;
25
+ spaceId: string; /** Opaque token to fetch the next (older) page. Null means no more pages. */
26
+ nextPageToken: string | null; /** Total messages returned in this initial load */
27
+ loadedCount: number;
22
28
  };
23
29
  /** Cleaned response — subset of SDK GenieMessage */
24
30
  interface GenieMessageResponse {
@@ -1 +1 @@
1
- {"version":3,"file":"genie.d.ts","names":[],"sources":["../../../../shared/src/genie.ts"],"mappings":";;KACY,gBAAA;EAEN,IAAA;EACA,cAAA;EACA,SAAA;EACA,OAAA;AAAA;EAEA,IAAA;EAAgB,MAAA;AAAA;EAChB,IAAA;EAAwB,OAAA,EAAS,oBAAA;AAAA;EAEjC,IAAA;EACA,YAAA;EACA,WAAA;EACA,IAAA;AAAA;EAEA,IAAA;EAAe,KAAA;AAAA;;UAGJ,oBAAA;EACf,SAAA;EACA,cAAA;EACA,OAAA;EACA,MAAA;EACA,OAAA;EACA,WAAA,GAAc,uBAAA;EACd,KAAA;AAAA;AAAA,UAGe,uBAAA;EACf,YAAA;EACA,KAAA;IACE,KAAA;IACA,WAAA;IACA,KAAA;IACA,WAAA;EAAA;EAEF,IAAA;IAAS,OAAA;EAAA;EACT,kBAAA;AAAA"}
1
+ {"version":3,"file":"genie.d.ts","names":[],"sources":["../../../../shared/src/genie.ts"],"mappings":";;KACY,gBAAA;EAEN,IAAA;EACA,cAAA;EACA,SAAA;EACA,OAAA;AAAA;EAEA,IAAA;EAAgB,MAAA;AAAA;EAChB,IAAA;EAAwB,OAAA,EAAS,oBAAA;AAAA;EAEjC,IAAA;EACA,YAAA;EACA,WAAA;EACA,IAAA;AAAA;EAEA,IAAA;EAAe,KAAA;AAAA;EAEf,IAAA;EACA,cAAA;EACA,OAAA,UAIA;EAFA,aAAA,iBAEW;EAAX,WAAA;AAAA;;UAIW,oBAAA;EACf,SAAA;EACA,cAAA;EACA,OAAA;EACA,MAAA;EACA,OAAA;EACA,WAAA,GAAc,uBAAA;EACd,KAAA;AAAA;AAAA,UAGe,uBAAA;EACf,YAAA;EACA,KAAA;IACE,KAAA;IACA,WAAA;IACA,KAAA;IACA,WAAA;EAAA;EAEF,IAAA;IAAS,OAAA;EAAA;EACT,kBAAA;AAAA"}
@@ -10,11 +10,13 @@ Scrollable message list that renders Genie chat messages with auto-scroll, skele
10
10
 
11
11
  ### Props[​](#props "Direct link to Props")
12
12
 
13
- | Prop | Type | Required | Default | Description |
14
- | ----------- | -------------------- | -------- | ------- | --------------------------------------------------------------------------- |
15
- | `messages` | `GenieMessageItem[]` | ✓ | - | Array of messages to display |
16
- | `status` | `enum` | ✓ | - | Current chat status (controls loading indicators and skeleton placeholders) |
17
- | `className` | `string` | | - | Additional CSS class for the scroll area |
13
+ | Prop | Type | Required | Default | Description |
14
+ | --------------------- | -------------------- | -------- | ------- | --------------------------------------------------------------------------- |
15
+ | `messages` | `GenieMessageItem[]` | ✓ | - | Array of messages to display |
16
+ | `status` | `enum` | ✓ | - | Current chat status (controls loading indicators and skeleton placeholders) |
17
+ | `className` | `string` | | - | Additional CSS class for the scroll area |
18
+ | `hasPreviousPage` | `boolean` | | `false` | Whether a previous page of older messages exists |
19
+ | `onFetchPreviousPage` | `(() => void)` | | - | Callback to fetch the previous page of messages |
18
20
 
19
21
  ### Usage[​](#usage "Direct link to Usage")
20
22
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@databricks/appkit",
3
3
  "type": "module",
4
- "version": "0.16.0",
4
+ "version": "0.17.0",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
7
7
  "packageManager": "pnpm@10.21.0",