@databricks/appkit 0.11.2 → 0.12.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.
- package/CLAUDE.md +4 -0
- package/NOTICE.md +1 -0
- package/dist/_virtual/_rolldown/runtime.js +0 -2
- package/dist/appkit/package.js +1 -1
- package/dist/connectors/genie/client.js +208 -0
- package/dist/connectors/genie/client.js.map +1 -0
- package/dist/connectors/genie/defaults.js +10 -0
- package/dist/connectors/genie/defaults.js.map +1 -0
- package/dist/connectors/genie/index.js +5 -0
- package/dist/connectors/genie/poll-waiter.js +54 -0
- package/dist/connectors/genie/poll-waiter.js.map +1 -0
- package/dist/connectors/genie/types.d.ts +11 -0
- package/dist/connectors/genie/types.d.ts.map +1 -0
- package/dist/connectors/index.js +4 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/logging/index.js +16 -0
- package/dist/plugins/genie/defaults.js +13 -0
- package/dist/plugins/genie/defaults.js.map +1 -0
- package/dist/plugins/genie/genie.d.ts +44 -0
- package/dist/plugins/genie/genie.d.ts.map +1 -0
- package/dist/plugins/genie/genie.js +141 -0
- package/dist/plugins/genie/genie.js.map +1 -0
- package/dist/plugins/genie/index.js +4 -0
- package/dist/plugins/genie/manifest.js +11 -0
- package/dist/plugins/genie/manifest.js.map +1 -0
- package/dist/plugins/genie/manifest.json +43 -0
- package/dist/plugins/genie/types.d.ts +14 -0
- package/dist/plugins/genie/types.d.ts.map +1 -0
- package/dist/plugins/index.js +3 -0
- package/dist/plugins/lakebase/manifest.json +1 -1
- package/dist/registry/types.generated.js.map +1 -1
- package/dist/shared/src/genie.d.ts +48 -0
- package/dist/shared/src/genie.d.ts.map +1 -0
- package/docs/docs/api/appkit/Class.AppKitError/index.html +2 -2
- package/docs/docs/api/appkit/Class.AuthenticationError/index.html +2 -2
- package/docs/docs/api/appkit/Class.ConfigurationError/index.html +2 -2
- package/docs/docs/api/appkit/Class.ConnectionError/index.html +2 -2
- package/docs/docs/api/appkit/Class.ExecutionError/index.html +2 -2
- package/docs/docs/api/appkit/Class.InitializationError/index.html +2 -2
- package/docs/docs/api/appkit/Class.Plugin/index.html +2 -2
- package/docs/docs/api/appkit/Class.ResourceRegistry/index.html +2 -2
- package/docs/docs/api/appkit/Class.ServerError/index.html +2 -2
- package/docs/docs/api/appkit/Class.TunnelError/index.html +2 -2
- package/docs/docs/api/appkit/Class.ValidationError/index.html +2 -2
- package/docs/docs/api/appkit/Enumeration.RequestedClaimsPermissionSet/index.html +2 -2
- package/docs/docs/api/appkit/Enumeration.ResourceType/index.html +2 -2
- package/docs/docs/api/appkit/Function.appKitTypesPlugin/index.html +2 -2
- package/docs/docs/api/appkit/Function.createApp/index.html +2 -2
- package/docs/docs/api/appkit/Function.createLakebasePool/index.html +2 -2
- package/docs/docs/api/appkit/Function.generateDatabaseCredential/index.html +2 -2
- package/docs/docs/api/appkit/Function.getExecutionContext/index.html +2 -2
- package/docs/docs/api/appkit/Function.getLakebaseOrmConfig/index.html +2 -2
- package/docs/docs/api/appkit/Function.getLakebasePgConfig/index.html +2 -2
- package/docs/docs/api/appkit/Function.getPluginManifest/index.html +2 -2
- package/docs/docs/api/appkit/Function.getResourceRequirements/index.html +2 -2
- package/docs/docs/api/appkit/Function.getUsernameWithApiLookup/index.html +2 -2
- package/docs/docs/api/appkit/Function.getWorkspaceClient/index.html +2 -2
- package/docs/docs/api/appkit/Function.isSQLTypeMarker/index.html +2 -2
- package/docs/docs/api/appkit/Interface.BasePluginConfig/index.html +2 -2
- package/docs/docs/api/appkit/Interface.CacheConfig/index.html +2 -2
- package/docs/docs/api/appkit/Interface.DatabaseCredential/index.html +2 -2
- package/docs/docs/api/appkit/Interface.GenerateDatabaseCredentialRequest/index.html +2 -2
- package/docs/docs/api/appkit/Interface.ITelemetry/index.html +2 -2
- package/docs/docs/api/appkit/Interface.LakebasePoolConfig/index.html +2 -2
- package/docs/docs/api/appkit/Interface.PluginManifest/index.html +2 -2
- package/docs/docs/api/appkit/Interface.RequestedClaims/index.html +2 -2
- package/docs/docs/api/appkit/Interface.RequestedResource/index.html +2 -2
- package/docs/docs/api/appkit/Interface.ResourceEntry/index.html +2 -2
- package/docs/docs/api/appkit/Interface.ResourceFieldEntry/index.html +2 -2
- package/docs/docs/api/appkit/Interface.ResourceRequirement/index.html +2 -2
- package/docs/docs/api/appkit/Interface.StreamExecutionSettings/index.html +2 -2
- package/docs/docs/api/appkit/Interface.TelemetryConfig/index.html +2 -2
- package/docs/docs/api/appkit/Interface.ValidationResult/index.html +2 -2
- package/docs/docs/api/appkit/TypeAlias.ConfigSchema/index.html +2 -2
- package/docs/docs/api/appkit/TypeAlias.IAppRouter/index.html +2 -2
- package/docs/docs/api/appkit/TypeAlias.ResourcePermission/index.html +2 -2
- package/docs/docs/api/appkit/TypeAlias.ToPlugin/index.html +2 -2
- package/docs/docs/api/appkit/Variable.sql/index.html +2 -2
- package/docs/docs/api/appkit/index.html +2 -2
- package/docs/docs/api/appkit-ui/data/AreaChart/index.html +3 -3
- package/docs/docs/api/appkit-ui/data/BarChart/index.html +3 -3
- package/docs/docs/api/appkit-ui/data/DataTable/index.html +3 -3
- package/docs/docs/api/appkit-ui/data/DonutChart/index.html +3 -3
- package/docs/docs/api/appkit-ui/data/HeatmapChart/index.html +3 -3
- package/docs/docs/api/appkit-ui/data/LineChart/index.html +3 -3
- package/docs/docs/api/appkit-ui/data/PieChart/index.html +3 -3
- package/docs/docs/api/appkit-ui/data/RadarChart/index.html +3 -3
- package/docs/docs/api/appkit-ui/data/ScatterChart/index.html +4 -4
- package/docs/docs/api/appkit-ui/genie/GenieChat/index.html +26 -0
- package/docs/docs/api/appkit-ui/genie/GenieChat.md +43 -0
- package/docs/docs/api/appkit-ui/genie/GenieChatInput/index.html +24 -0
- package/docs/docs/api/appkit-ui/genie/GenieChatInput.md +27 -0
- package/docs/docs/api/appkit-ui/genie/GenieChatMessage/index.html +24 -0
- package/docs/docs/api/appkit-ui/genie/GenieChatMessage.md +25 -0
- package/docs/docs/api/appkit-ui/genie/GenieChatMessageList/index.html +24 -0
- package/docs/docs/api/appkit-ui/genie/GenieChatMessageList.md +26 -0
- package/docs/docs/api/appkit-ui/index.html +3 -3
- package/docs/docs/api/appkit-ui/styling/index.html +4 -4
- package/docs/docs/api/appkit-ui/ui/Accordion/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Alert/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/AlertDialog/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/AspectRatio/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Avatar/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Badge/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Breadcrumb/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Button/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/ButtonGroup/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Calendar/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Card/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Carousel/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/ChartContainer/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Checkbox/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Collapsible/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Command/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/ContextMenu/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Dialog/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Drawer/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/DropdownMenu/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Empty/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Field/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/FormControl/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/HoverCard/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Input/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/InputGroup/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/InputOTP/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Item/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Kbd/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Label/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Menubar/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/NavigationMenu/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Pagination/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Popover/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Progress/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/RadioGroup/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/ResizableHandle/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/ScrollArea/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Select/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Separator/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Sheet/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Sidebar/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Skeleton/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Slider/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Spinner/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Switch/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Table/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Tabs/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Textarea/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Toaster/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Toggle/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/ToggleGroup/index.html +3 -3
- package/docs/docs/api/appkit-ui/ui/Tooltip/index.html +3 -3
- package/docs/docs/api/index.html +2 -2
- package/docs/docs/app-management/index.html +2 -2
- package/docs/docs/architecture/index.html +2 -2
- package/docs/docs/category/development/index.html +2 -2
- package/docs/docs/configuration/index.html +2 -2
- package/docs/docs/core-principles/index.html +2 -2
- package/docs/docs/development/ai-assisted-development/index.html +2 -2
- package/docs/docs/development/index.html +2 -2
- package/docs/docs/development/llm-guide/index.html +2 -2
- package/docs/docs/development/local-development/index.html +2 -2
- package/docs/docs/development/project-setup/index.html +2 -2
- package/docs/docs/development/remote-bridge/index.html +2 -2
- package/docs/docs/development/type-generation/index.html +2 -2
- package/docs/docs/index.html +2 -2
- package/docs/docs/plugins/analytics/index.html +2 -2
- package/docs/docs/plugins/caching/index.html +2 -2
- package/docs/docs/plugins/custom-plugins/index.html +2 -2
- package/docs/docs/plugins/execution-context/index.html +2 -2
- package/docs/docs/plugins/index.html +2 -2
- package/docs/docs/plugins/lakebase/index.html +4 -4
- package/docs/docs/plugins/lakebase.md +25 -24
- package/docs/docs/plugins/plugin-management/index.html +2 -2
- package/docs/docs/plugins/server/index.html +2 -2
- package/llms.txt +4 -0
- package/package.json +1 -1
package/CLAUDE.md
CHANGED
|
@@ -81,6 +81,10 @@ The CLI will display the documentation content directly in the terminal.
|
|
|
81
81
|
- [PieChart](./docs/docs/api/appkit-ui/data/PieChart.md): Pie Chart component for proportional data visualization.
|
|
82
82
|
- [RadarChart](./docs/docs/api/appkit-ui/data/RadarChart.md): Radar Chart component for multi-dimensional data comparison.
|
|
83
83
|
- [ScatterChart](./docs/docs/api/appkit-ui/data/ScatterChart.md): Scatter Chart component for correlation and distribution visualization.
|
|
84
|
+
- [GenieChat](./docs/docs/api/appkit-ui/genie/GenieChat.md): Full-featured chat interface for a single Databricks AI/BI Genie space. Handles message streaming, conversation history, and auto-reconnection via SSE.
|
|
85
|
+
- [GenieChatInput](./docs/docs/api/appkit-ui/genie/GenieChatInput.md): Auto-expanding textarea input with a send button for chat messages. Submits on Enter (Shift+Enter for newline).
|
|
86
|
+
- [GenieChatMessage](./docs/docs/api/appkit-ui/genie/GenieChatMessage.md): Renders a single Genie message bubble with optional expandable SQL query attachments.
|
|
87
|
+
- [GenieChatMessageList](./docs/docs/api/appkit-ui/genie/GenieChatMessageList.md): Scrollable message list that renders Genie chat messages with auto-scroll, skeleton loaders, and a streaming indicator.
|
|
84
88
|
- [Styling](./docs/docs/api/appkit-ui/styling.md): This guide covers how to style AppKit UI components using CSS variables and theming.
|
|
85
89
|
- [Accordion](./docs/docs/api/appkit-ui/ui/Accordion.md): Collapsible content sections organized in a vertical stack
|
|
86
90
|
- [Alert](./docs/docs/api/appkit-ui/ui/Alert.md): Displays important information with optional icon and multiple variants
|
package/NOTICE.md
CHANGED
|
@@ -66,6 +66,7 @@ This Software contains code from the following open source projects:
|
|
|
66
66
|
| [express](https://www.npmjs.com/package/express) | 4.22.0 | MIT | http://expressjs.com/ |
|
|
67
67
|
| [input-otp](https://www.npmjs.com/package/input-otp) | 1.4.2 | MIT | https://input-otp.rodz.dev/ |
|
|
68
68
|
| [lucide-react](https://www.npmjs.com/package/lucide-react) | 0.554.0 | ISC | https://lucide.dev |
|
|
69
|
+
| [marked](https://www.npmjs.com/package/marked) | 16.4.2, 17.0.3 | MIT | https://marked.js.org |
|
|
69
70
|
| [next-themes](https://www.npmjs.com/package/next-themes) | 0.4.6 | MIT | https://github.com/pacocoursey/next-themes#readme |
|
|
70
71
|
| [obug](https://www.npmjs.com/package/obug) | 2.1.1 | MIT | https://github.com/sxzz/obug#readme |
|
|
71
72
|
| [pg](https://www.npmjs.com/package/pg) | 8.18.0 | MIT | https://github.com/brianc/node-postgres |
|
package/dist/appkit/package.js
CHANGED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { createLogger } from "../../logging/logger.js";
|
|
2
|
+
import "../../logging/index.js";
|
|
3
|
+
import { genieConnectorDefaults } from "./defaults.js";
|
|
4
|
+
import { pollWaiter } from "./poll-waiter.js";
|
|
5
|
+
import { Time, TimeUnits } from "@databricks/sdk-experimental";
|
|
6
|
+
|
|
7
|
+
//#region src/connectors/genie/client.ts
|
|
8
|
+
const logger = createLogger("connectors:genie");
|
|
9
|
+
function mapAttachments(message) {
|
|
10
|
+
return message.attachments?.map((att) => ({
|
|
11
|
+
attachmentId: att.attachment_id,
|
|
12
|
+
query: att.query ? {
|
|
13
|
+
title: att.query.title,
|
|
14
|
+
description: att.query.description,
|
|
15
|
+
query: att.query.query,
|
|
16
|
+
statementId: att.query.statement_id
|
|
17
|
+
} : void 0,
|
|
18
|
+
text: att.text ? { content: att.text.content } : void 0,
|
|
19
|
+
suggestedQuestions: att.suggested_questions?.questions
|
|
20
|
+
})) ?? [];
|
|
21
|
+
}
|
|
22
|
+
function toMessageResponse(message) {
|
|
23
|
+
return {
|
|
24
|
+
messageId: message.message_id,
|
|
25
|
+
conversationId: message.conversation_id,
|
|
26
|
+
spaceId: message.space_id,
|
|
27
|
+
status: message.status ?? "COMPLETED",
|
|
28
|
+
content: message.content,
|
|
29
|
+
attachments: mapAttachments(message),
|
|
30
|
+
error: message.error?.error
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
var GenieConnector = class {
|
|
34
|
+
config;
|
|
35
|
+
constructor(config = {}) {
|
|
36
|
+
this.config = {
|
|
37
|
+
timeout: config.timeout ?? genieConnectorDefaults.timeout,
|
|
38
|
+
maxMessages: config.maxMessages ?? genieConnectorDefaults.maxMessages
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
async startMessage(workspaceClient, spaceId, content, conversationId) {
|
|
42
|
+
if (conversationId) {
|
|
43
|
+
const waiter = await workspaceClient.genie.createMessage({
|
|
44
|
+
space_id: spaceId,
|
|
45
|
+
conversation_id: conversationId,
|
|
46
|
+
content
|
|
47
|
+
});
|
|
48
|
+
return {
|
|
49
|
+
messageWaiter: waiter,
|
|
50
|
+
conversationId,
|
|
51
|
+
messageId: waiter.message_id ?? ""
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
const start = await workspaceClient.genie.startConversation({
|
|
55
|
+
space_id: spaceId,
|
|
56
|
+
content
|
|
57
|
+
});
|
|
58
|
+
return {
|
|
59
|
+
messageWaiter: start,
|
|
60
|
+
conversationId: start.conversation_id,
|
|
61
|
+
messageId: start.message_id
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
async waitForMessage(messageWaiter, options) {
|
|
65
|
+
const timeout = options?.timeout ?? this.config.timeout;
|
|
66
|
+
const waitOptions = timeout > 0 ? { timeout: new Time(timeout, TimeUnits.milliseconds) } : {};
|
|
67
|
+
return messageWaiter.wait(waitOptions);
|
|
68
|
+
}
|
|
69
|
+
async listConversationMessages(workspaceClient, spaceId, conversationId, options) {
|
|
70
|
+
const maxMessages = options?.maxMessages ?? this.config.maxMessages;
|
|
71
|
+
const allMessages = [];
|
|
72
|
+
let pageToken;
|
|
73
|
+
do {
|
|
74
|
+
const response = await workspaceClient.genie.listConversationMessages({
|
|
75
|
+
space_id: spaceId,
|
|
76
|
+
conversation_id: conversationId,
|
|
77
|
+
page_size: genieConnectorDefaults.pageSize,
|
|
78
|
+
...pageToken ? { page_token: pageToken } : {}
|
|
79
|
+
});
|
|
80
|
+
if (response.messages) allMessages.push(...response.messages);
|
|
81
|
+
pageToken = response.next_page_token;
|
|
82
|
+
} while (pageToken && allMessages.length < maxMessages);
|
|
83
|
+
return allMessages.slice(0, maxMessages).reverse().map(toMessageResponse);
|
|
84
|
+
}
|
|
85
|
+
async getMessageAttachmentQueryResult(workspaceClient, spaceId, conversationId, messageId, attachmentId, _signal) {
|
|
86
|
+
return (await workspaceClient.genie.getMessageAttachmentQueryResult({
|
|
87
|
+
space_id: spaceId,
|
|
88
|
+
conversation_id: conversationId,
|
|
89
|
+
message_id: messageId,
|
|
90
|
+
attachment_id: attachmentId
|
|
91
|
+
})).statement_response;
|
|
92
|
+
}
|
|
93
|
+
async *streamSendMessage(workspaceClient, spaceId, content, conversationId, options) {
|
|
94
|
+
try {
|
|
95
|
+
const { messageWaiter, conversationId: resultConversationId, messageId: resultMessageId } = await this.startMessage(workspaceClient, spaceId, content, conversationId);
|
|
96
|
+
yield {
|
|
97
|
+
type: "message_start",
|
|
98
|
+
conversationId: resultConversationId,
|
|
99
|
+
messageId: resultMessageId,
|
|
100
|
+
spaceId
|
|
101
|
+
};
|
|
102
|
+
const timeout = options?.timeout != null ? options.timeout : this.config.timeout;
|
|
103
|
+
const waitOptions = timeout > 0 ? { timeout: new Time(timeout, TimeUnits.milliseconds) } : {};
|
|
104
|
+
let completedMessage;
|
|
105
|
+
for await (const event of pollWaiter(messageWaiter, waitOptions)) if (event.type === "progress" && event.value.status) yield {
|
|
106
|
+
type: "status",
|
|
107
|
+
status: event.value.status
|
|
108
|
+
};
|
|
109
|
+
else if (event.type === "completed") completedMessage = event.value;
|
|
110
|
+
const messageResponse = toMessageResponse(completedMessage);
|
|
111
|
+
yield {
|
|
112
|
+
type: "message_result",
|
|
113
|
+
message: messageResponse
|
|
114
|
+
};
|
|
115
|
+
yield* this.emitQueryResults(workspaceClient, spaceId, resultConversationId, messageResponse.messageId, messageResponse);
|
|
116
|
+
} catch (error) {
|
|
117
|
+
logger.error("Genie message error: %O", error);
|
|
118
|
+
yield {
|
|
119
|
+
type: "error",
|
|
120
|
+
error: error instanceof Error ? error.message : "Genie request failed"
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
async *emitQueryResults(workspaceClient, spaceId, conversationId, messageId, messageResponse) {
|
|
125
|
+
const attachments = messageResponse.attachments ?? [];
|
|
126
|
+
for (const att of attachments) {
|
|
127
|
+
if (!att.query?.statementId || !att.attachmentId) continue;
|
|
128
|
+
try {
|
|
129
|
+
const data = await this.getMessageAttachmentQueryResult(workspaceClient, spaceId, conversationId, messageId, att.attachmentId);
|
|
130
|
+
yield {
|
|
131
|
+
type: "query_result",
|
|
132
|
+
attachmentId: att.attachmentId,
|
|
133
|
+
statementId: att.query.statementId,
|
|
134
|
+
data
|
|
135
|
+
};
|
|
136
|
+
} catch (error) {
|
|
137
|
+
logger.error("Failed to fetch query result for attachment %s: %O", att.attachmentId, error);
|
|
138
|
+
yield {
|
|
139
|
+
type: "error",
|
|
140
|
+
error: `Failed to fetch query result for attachment ${att.attachmentId}`
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
async *streamConversation(workspaceClient, spaceId, conversationId, options) {
|
|
146
|
+
const includeQueryResults = options?.includeQueryResults !== false;
|
|
147
|
+
try {
|
|
148
|
+
const messageResponses = await this.listConversationMessages(workspaceClient, spaceId, conversationId);
|
|
149
|
+
for (const messageResponse of messageResponses) yield {
|
|
150
|
+
type: "message_result",
|
|
151
|
+
message: messageResponse
|
|
152
|
+
};
|
|
153
|
+
if (includeQueryResults) {
|
|
154
|
+
const queryAttachments = [];
|
|
155
|
+
for (const msg of messageResponses) for (const att of msg.attachments ?? []) if (att.query?.statementId && att.attachmentId) queryAttachments.push({
|
|
156
|
+
messageId: msg.messageId,
|
|
157
|
+
attachmentId: att.attachmentId,
|
|
158
|
+
statementId: att.query.statementId
|
|
159
|
+
});
|
|
160
|
+
const results = await Promise.allSettled(queryAttachments.map(async (att) => {
|
|
161
|
+
const data = await this.getMessageAttachmentQueryResult(workspaceClient, spaceId, conversationId, att.messageId, att.attachmentId);
|
|
162
|
+
return {
|
|
163
|
+
attachmentId: att.attachmentId,
|
|
164
|
+
statementId: att.statementId,
|
|
165
|
+
data
|
|
166
|
+
};
|
|
167
|
+
}));
|
|
168
|
+
for (const result of results) if (result.status === "fulfilled") yield {
|
|
169
|
+
type: "query_result",
|
|
170
|
+
attachmentId: result.value.attachmentId,
|
|
171
|
+
statementId: result.value.statementId,
|
|
172
|
+
data: result.value.data
|
|
173
|
+
};
|
|
174
|
+
else {
|
|
175
|
+
logger.error("Failed to fetch query result: %O", result.reason);
|
|
176
|
+
yield {
|
|
177
|
+
type: "error",
|
|
178
|
+
error: result.reason instanceof Error ? result.reason.message : "Failed to fetch query result"
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
} catch (error) {
|
|
183
|
+
logger.error("Genie getConversation error: %O", error);
|
|
184
|
+
yield {
|
|
185
|
+
type: "error",
|
|
186
|
+
error: error instanceof Error ? error.message : "Failed to fetch conversation"
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
async sendMessage(workspaceClient, spaceId, content, conversationId) {
|
|
191
|
+
const { messageWaiter, conversationId: resultConversationId } = await this.startMessage(workspaceClient, spaceId, content, conversationId);
|
|
192
|
+
return {
|
|
193
|
+
...toMessageResponse(await this.waitForMessage(messageWaiter)),
|
|
194
|
+
conversationId: resultConversationId
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
async getConversation(workspaceClient, spaceId, conversationId) {
|
|
198
|
+
return {
|
|
199
|
+
conversationId,
|
|
200
|
+
spaceId,
|
|
201
|
+
messages: await this.listConversationMessages(workspaceClient, spaceId, conversationId)
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
//#endregion
|
|
207
|
+
export { GenieConnector };
|
|
208
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","names":[],"sources":["../../../src/connectors/genie/client.ts"],"sourcesContent":["import type { WorkspaceClient } from \"@databricks/sdk-experimental\";\nimport { Time, TimeUnits } 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 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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"}
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
//#region src/connectors/genie/poll-waiter.ts
|
|
2
|
+
/**
|
|
3
|
+
* Bridges a callback-based waiter into an async generator.
|
|
4
|
+
*
|
|
5
|
+
* The SDK's `waiter.wait({ onProgress })` API uses a callback to report
|
|
6
|
+
* progress and returns a promise that resolves with the final result.
|
|
7
|
+
* This function converts that push-based model into a pull-based async
|
|
8
|
+
* generator so callers can simply `for await (const event of pollWaiter(w))`.
|
|
9
|
+
*
|
|
10
|
+
* Yields `{ type: "progress", value }` for each `onProgress` callback,
|
|
11
|
+
* then `{ type: "completed", value }` for the final result.
|
|
12
|
+
* Throws if the waiter rejects.
|
|
13
|
+
*/
|
|
14
|
+
async function* pollWaiter(waiter, options) {
|
|
15
|
+
const queue = [];
|
|
16
|
+
let notify = () => {};
|
|
17
|
+
let done = false;
|
|
18
|
+
let result;
|
|
19
|
+
let error = null;
|
|
20
|
+
waiter.wait({
|
|
21
|
+
onProgress: async (p) => {
|
|
22
|
+
queue.push(p);
|
|
23
|
+
notify();
|
|
24
|
+
},
|
|
25
|
+
...options?.timeout != null ? { timeout: options.timeout } : {}
|
|
26
|
+
}).then((r) => {
|
|
27
|
+
result = r;
|
|
28
|
+
done = true;
|
|
29
|
+
notify();
|
|
30
|
+
}).catch((err) => {
|
|
31
|
+
error = err;
|
|
32
|
+
done = true;
|
|
33
|
+
notify();
|
|
34
|
+
});
|
|
35
|
+
while (!done || queue.length > 0) {
|
|
36
|
+
while (queue.length > 0) yield {
|
|
37
|
+
type: "progress",
|
|
38
|
+
value: queue.shift()
|
|
39
|
+
};
|
|
40
|
+
if (!done) await new Promise((resolve) => {
|
|
41
|
+
notify = resolve;
|
|
42
|
+
if (done || queue.length > 0) resolve();
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
if (error !== null) throw error;
|
|
46
|
+
yield {
|
|
47
|
+
type: "completed",
|
|
48
|
+
value: result
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
//#endregion
|
|
53
|
+
export { pollWaiter };
|
|
54
|
+
//# sourceMappingURL=poll-waiter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"poll-waiter.js","names":[],"sources":["../../../src/connectors/genie/poll-waiter.ts"],"sourcesContent":["/**\n * Structural interface matching the SDK's `Waiter.wait()` shape\n * without importing the SDK directly.\n */\nexport interface Pollable<P> {\n wait(options?: {\n onProgress?: (p: P) => Promise<void>;\n timeout?: unknown;\n }): Promise<P>;\n}\n\nexport type PollEvent<P> =\n | { type: \"progress\"; value: P }\n | { type: \"completed\"; value: P };\n\n/**\n * Bridges a callback-based waiter into an async generator.\n *\n * The SDK's `waiter.wait({ onProgress })` API uses a callback to report\n * progress and returns a promise that resolves with the final result.\n * This function converts that push-based model into a pull-based async\n * generator so callers can simply `for await (const event of pollWaiter(w))`.\n *\n * Yields `{ type: \"progress\", value }` for each `onProgress` callback,\n * then `{ type: \"completed\", value }` for the final result.\n * Throws if the waiter rejects.\n */\nexport async function* pollWaiter<P>(\n waiter: Pollable<P>,\n options?: { timeout?: unknown },\n): AsyncGenerator<PollEvent<P>> {\n const queue: P[] = [];\n let notify: () => void = () => {};\n let done = false;\n let result!: P;\n let error: unknown = null;\n\n waiter\n .wait({\n onProgress: async (p: P) => {\n queue.push(p);\n notify();\n },\n ...(options?.timeout != null ? { timeout: options.timeout } : {}),\n })\n .then((r) => {\n result = r;\n done = true;\n notify();\n })\n .catch((err) => {\n error = err;\n done = true;\n notify();\n });\n\n while (!done || queue.length > 0) {\n while (queue.length > 0) {\n const value = queue.shift() as P;\n yield { type: \"progress\", value };\n }\n\n if (!done) {\n await new Promise<void>((resolve) => {\n notify = resolve;\n if (done || queue.length > 0) resolve();\n });\n }\n }\n\n if (error !== null) {\n throw error;\n }\n\n yield { type: \"completed\", value: result };\n}\n"],"mappings":";;;;;;;;;;;;;AA2BA,gBAAuB,WACrB,QACA,SAC8B;CAC9B,MAAM,QAAa,EAAE;CACrB,IAAI,eAA2B;CAC/B,IAAI,OAAO;CACX,IAAI;CACJ,IAAI,QAAiB;AAErB,QACG,KAAK;EACJ,YAAY,OAAO,MAAS;AAC1B,SAAM,KAAK,EAAE;AACb,WAAQ;;EAEV,GAAI,SAAS,WAAW,OAAO,EAAE,SAAS,QAAQ,SAAS,GAAG,EAAE;EACjE,CAAC,CACD,MAAM,MAAM;AACX,WAAS;AACT,SAAO;AACP,UAAQ;GACR,CACD,OAAO,QAAQ;AACd,UAAQ;AACR,SAAO;AACP,UAAQ;GACR;AAEJ,QAAO,CAAC,QAAQ,MAAM,SAAS,GAAG;AAChC,SAAO,MAAM,SAAS,EAEpB,OAAM;GAAE,MAAM;GAAY,OADZ,MAAM,OAAO;GACM;AAGnC,MAAI,CAAC,KACH,OAAM,IAAI,SAAe,YAAY;AACnC,YAAS;AACT,OAAI,QAAQ,MAAM,SAAS,EAAG,UAAS;IACvC;;AAIN,KAAI,UAAU,KACZ,OAAM;AAGR,OAAM;EAAE,MAAM;EAAa,OAAO;EAAQ"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { GenieAttachmentResponse, GenieMessageResponse, GenieStreamEvent } from "../../shared/src/genie.js";
|
|
2
|
+
|
|
3
|
+
//#region src/connectors/genie/types.d.ts
|
|
4
|
+
interface GenieConversationHistoryResponse {
|
|
5
|
+
conversationId: string;
|
|
6
|
+
spaceId: string;
|
|
7
|
+
messages: GenieMessageResponse[];
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
export { GenieConversationHistoryResponse };
|
|
11
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/connectors/genie/types.ts"],"sourcesContent":[],"mappings":";;;AAUiB,UAAA,gCAAA,CAAgC;;;YAGrC"}
|
package/dist/connectors/index.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { RequestedClaimsPermissionSet, createLakebasePool, generateDatabaseCredential, getLakebaseOrmConfig, getLakebasePgConfig, getUsernameWithApiLookup, getWorkspaceClient } from "./lakebase/index.js";
|
|
2
|
+
import { genieConnectorDefaults } from "./genie/defaults.js";
|
|
3
|
+
import { pollWaiter } from "./genie/poll-waiter.js";
|
|
4
|
+
import { GenieConnector } from "./genie/client.js";
|
|
5
|
+
import "./genie/index.js";
|
|
2
6
|
import "./lakebase-v1/index.js";
|
|
3
7
|
import { SQLWarehouseConnector } from "./sql-warehouse/client.js";
|
|
4
8
|
import "./sql-warehouse/index.js";
|
package/dist/index.d.ts
CHANGED
|
@@ -24,7 +24,8 @@ import { ResourcePermission, ResourceType } from "./registry/types.generated.js"
|
|
|
24
24
|
import { ConfigSchema, PluginManifest, ResourceEntry, ResourceFieldEntry, ResourceRequirement, ValidationResult } from "./registry/types.js";
|
|
25
25
|
import { getPluginManifest, getResourceRequirements } from "./registry/manifest-loader.js";
|
|
26
26
|
import { ResourceRegistry } from "./registry/resource-registry.js";
|
|
27
|
+
import { genie } from "./plugins/genie/genie.js";
|
|
27
28
|
import { lakebase } from "./plugins/lakebase/lakebase.js";
|
|
28
29
|
import { server } from "./plugins/server/index.js";
|
|
29
30
|
import { appKitTypesPlugin } from "./type-generator/vite-plugin.js";
|
|
30
|
-
export { AppKitError, AuthenticationError, type BasePluginConfig, type CacheConfig, CacheManager, type ConfigSchema, ConfigurationError, ConnectionError, type Counter, type DatabaseCredential, ExecutionError, type GenerateDatabaseCredentialRequest, type Histogram, type IAppRouter, type ITelemetry, InitializationError, type LakebasePoolConfig, Plugin, type PluginManifest, type RequestedClaims, RequestedClaimsPermissionSet, type RequestedResource, type ResourceEntry, type ResourceFieldEntry, type ResourcePermission, ResourceRegistry, type ResourceRequirement, ResourceType, ServerError, SeverityNumber, type Span, SpanStatusCode, type StreamExecutionSettings, type TelemetryConfig, type ToPlugin, TunnelError, ValidationError, type ValidationResult, analytics, appKitTypesPlugin, createApp, createLakebasePool, generateDatabaseCredential, getExecutionContext, getLakebaseOrmConfig, getLakebasePgConfig, getPluginManifest, getResourceRequirements, getUsernameWithApiLookup, getWorkspaceClient, isSQLTypeMarker, lakebase, server, sql, toPlugin };
|
|
31
|
+
export { AppKitError, AuthenticationError, type BasePluginConfig, type CacheConfig, CacheManager, type ConfigSchema, ConfigurationError, ConnectionError, type Counter, type DatabaseCredential, ExecutionError, type GenerateDatabaseCredentialRequest, type Histogram, type IAppRouter, type ITelemetry, InitializationError, type LakebasePoolConfig, Plugin, type PluginManifest, type RequestedClaims, RequestedClaimsPermissionSet, type RequestedResource, type ResourceEntry, type ResourceFieldEntry, type ResourcePermission, ResourceRegistry, type ResourceRequirement, ResourceType, ServerError, SeverityNumber, type Span, SpanStatusCode, type StreamExecutionSettings, type TelemetryConfig, type ToPlugin, TunnelError, ValidationError, type ValidationResult, analytics, appKitTypesPlugin, createApp, createLakebasePool, generateDatabaseCredential, genie, getExecutionContext, getLakebaseOrmConfig, getLakebasePgConfig, getPluginManifest, getResourceRequirements, getUsernameWithApiLookup, getWorkspaceClient, isSQLTypeMarker, lakebase, server, sql, toPlugin };
|
package/dist/index.js
CHANGED
|
@@ -24,6 +24,7 @@ import { Plugin } from "./plugin/plugin.js";
|
|
|
24
24
|
import { toPlugin } from "./plugin/to-plugin.js";
|
|
25
25
|
import "./plugin/index.js";
|
|
26
26
|
import { analytics } from "./plugins/analytics/analytics.js";
|
|
27
|
+
import { genie } from "./plugins/genie/genie.js";
|
|
27
28
|
import { lakebase } from "./plugins/lakebase/lakebase.js";
|
|
28
29
|
import { appKitTypesPlugin } from "./type-generator/vite-plugin.js";
|
|
29
30
|
import { server } from "./plugins/server/index.js";
|
|
@@ -34,5 +35,5 @@ init_context();
|
|
|
34
35
|
init_errors();
|
|
35
36
|
|
|
36
37
|
//#endregion
|
|
37
|
-
export { AppKitError, AuthenticationError, CacheManager, ConfigurationError, ConnectionError, ExecutionError, InitializationError, Plugin, RequestedClaimsPermissionSet, ResourceRegistry, ResourceType, ServerError, SeverityNumber, SpanStatusCode, TunnelError, ValidationError, analytics, appKitTypesPlugin, createApp, createLakebasePool, generateDatabaseCredential, getExecutionContext, getLakebaseOrmConfig, getLakebasePgConfig, getPluginManifest, getResourceRequirements, getUsernameWithApiLookup, getWorkspaceClient, isSQLTypeMarker, lakebase, server, sql, toPlugin };
|
|
38
|
+
export { AppKitError, AuthenticationError, CacheManager, ConfigurationError, ConnectionError, ExecutionError, InitializationError, Plugin, RequestedClaimsPermissionSet, ResourceRegistry, ResourceType, ServerError, SeverityNumber, SpanStatusCode, TunnelError, ValidationError, analytics, appKitTypesPlugin, createApp, createLakebasePool, generateDatabaseCredential, genie, getExecutionContext, getLakebaseOrmConfig, getLakebasePgConfig, getPluginManifest, getResourceRequirements, getUsernameWithApiLookup, getWorkspaceClient, isSQLTypeMarker, lakebase, server, sql, toPlugin };
|
|
38
39
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * @packageDocumentation\n *\n * Core library for building Databricks applications with type-safe SQL queries,\n * plugin architecture, and React integration.\n */\n\n// Types from shared\nexport type {\n BasePluginConfig,\n CacheConfig,\n IAppRouter,\n StreamExecutionSettings,\n} from \"shared\";\nexport { isSQLTypeMarker, sql } from \"shared\";\nexport { CacheManager } from \"./cache\";\nexport type {\n DatabaseCredential,\n GenerateDatabaseCredentialRequest,\n LakebasePoolConfig,\n RequestedClaims,\n RequestedResource,\n} from \"./connectors/lakebase\";\n// Lakebase Autoscaling connector\nexport {\n createLakebasePool,\n generateDatabaseCredential,\n getLakebaseOrmConfig,\n getLakebasePgConfig,\n getUsernameWithApiLookup,\n getWorkspaceClient,\n RequestedClaimsPermissionSet,\n} from \"./connectors/lakebase\";\nexport { getExecutionContext } from \"./context\";\nexport { createApp } from \"./core\";\n// Errors\nexport {\n AppKitError,\n AuthenticationError,\n ConfigurationError,\n ConnectionError,\n ExecutionError,\n InitializationError,\n ServerError,\n TunnelError,\n ValidationError,\n} from \"./errors\";\n// Plugin authoring\nexport { Plugin, type ToPlugin, toPlugin } from \"./plugin\";\nexport { analytics, lakebase, server } from \"./plugins\";\n// Registry types and utilities for plugin manifests\nexport type {\n ConfigSchema,\n PluginManifest,\n ResourceEntry,\n ResourceFieldEntry,\n ResourcePermission,\n ResourceRequirement,\n ValidationResult,\n} from \"./registry\";\nexport {\n getPluginManifest,\n getResourceRequirements,\n ResourceRegistry,\n ResourceType,\n} from \"./registry\";\n// Telemetry (for advanced custom telemetry)\nexport {\n type Counter,\n type Histogram,\n type ITelemetry,\n SeverityNumber,\n type Span,\n SpanStatusCode,\n type TelemetryConfig,\n} from \"./telemetry\";\n// Vite plugin and type generation\nexport { appKitTypesPlugin } from \"./type-generator/vite-plugin\";\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * @packageDocumentation\n *\n * Core library for building Databricks applications with type-safe SQL queries,\n * plugin architecture, and React integration.\n */\n\n// Types from shared\nexport type {\n BasePluginConfig,\n CacheConfig,\n IAppRouter,\n StreamExecutionSettings,\n} from \"shared\";\nexport { isSQLTypeMarker, sql } from \"shared\";\nexport { CacheManager } from \"./cache\";\nexport type {\n DatabaseCredential,\n GenerateDatabaseCredentialRequest,\n LakebasePoolConfig,\n RequestedClaims,\n RequestedResource,\n} from \"./connectors/lakebase\";\n// Lakebase Autoscaling connector\nexport {\n createLakebasePool,\n generateDatabaseCredential,\n getLakebaseOrmConfig,\n getLakebasePgConfig,\n getUsernameWithApiLookup,\n getWorkspaceClient,\n RequestedClaimsPermissionSet,\n} from \"./connectors/lakebase\";\nexport { getExecutionContext } from \"./context\";\nexport { createApp } from \"./core\";\n// Errors\nexport {\n AppKitError,\n AuthenticationError,\n ConfigurationError,\n ConnectionError,\n ExecutionError,\n InitializationError,\n ServerError,\n TunnelError,\n ValidationError,\n} from \"./errors\";\n// Plugin authoring\nexport { Plugin, type ToPlugin, toPlugin } from \"./plugin\";\nexport { analytics, genie, lakebase, server } from \"./plugins\";\n// Registry types and utilities for plugin manifests\nexport type {\n ConfigSchema,\n PluginManifest,\n ResourceEntry,\n ResourceFieldEntry,\n ResourcePermission,\n ResourceRequirement,\n ValidationResult,\n} from \"./registry\";\nexport {\n getPluginManifest,\n getResourceRequirements,\n ResourceRegistry,\n ResourceType,\n} from \"./registry\";\n// Telemetry (for advanced custom telemetry)\nexport {\n type Counter,\n type Histogram,\n type ITelemetry,\n SeverityNumber,\n type Span,\n SpanStatusCode,\n type TelemetryConfig,\n} from \"./telemetry\";\n// Vite plugin and type generation\nexport { appKitTypesPlugin } from \"./type-generator/vite-plugin\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAiCgD;aAa9B"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { DEFAULT_SAMPLING_CONFIG, shouldSample } from "./sampling.js";
|
|
2
|
+
import { WideEvent } from "./wide-event.js";
|
|
3
|
+
import { WideEventEmitter } from "./wide-event-emitter.js";
|
|
4
|
+
import { createLogger } from "./logger.js";
|
|
5
|
+
import { AppKitError } from "../errors/base.js";
|
|
6
|
+
import { AuthenticationError } from "../errors/authentication.js";
|
|
7
|
+
import { ConfigurationError } from "../errors/configuration.js";
|
|
8
|
+
import { ConnectionError } from "../errors/connection.js";
|
|
9
|
+
import { ExecutionError } from "../errors/execution.js";
|
|
10
|
+
import { InitializationError } from "../errors/initialization.js";
|
|
11
|
+
import { ServerError } from "../errors/server.js";
|
|
12
|
+
import { TunnelError } from "../errors/tunnel.js";
|
|
13
|
+
import { ValidationError } from "../errors/validation.js";
|
|
14
|
+
import "@opentelemetry/api";
|
|
15
|
+
|
|
16
|
+
export { };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region src/plugins/genie/defaults.ts
|
|
2
|
+
const genieStreamDefaults = {
|
|
3
|
+
default: {
|
|
4
|
+
cache: { enabled: false },
|
|
5
|
+
retry: { enabled: false },
|
|
6
|
+
timeout: 12e4
|
|
7
|
+
},
|
|
8
|
+
stream: { bufferSize: 100 }
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
//#endregion
|
|
12
|
+
export { genieStreamDefaults };
|
|
13
|
+
//# sourceMappingURL=defaults.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.js","names":[],"sources":["../../../src/plugins/genie/defaults.ts"],"sourcesContent":["import type { StreamExecutionSettings } from \"shared\";\n\nexport const genieStreamDefaults: StreamExecutionSettings = {\n default: {\n // Cache disabled: chat messages are conversational and stateful, not repeatable queries.\n cache: {\n enabled: false,\n },\n // Retry disabled: Genie calls are not idempotent (retries could create duplicate\n // conversations/messages), and the SDK Waiter already handles transient polling failures.\n retry: {\n enabled: false,\n },\n timeout: 120_000,\n },\n stream: {\n bufferSize: 100,\n },\n};\n"],"mappings":";AAEA,MAAa,sBAA+C;CAC1D,SAAS;EAEP,OAAO,EACL,SAAS,OACV;EAGD,OAAO,EACL,SAAS,OACV;EACD,SAAS;EACV;CACD,QAAQ,EACN,YAAY,KACb;CACF"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { IAppRouter, ToPlugin } from "../../shared/src/plugin.js";
|
|
2
|
+
import { GenieStreamEvent } from "../../shared/src/genie.js";
|
|
3
|
+
import { Plugin } from "../../plugin/plugin.js";
|
|
4
|
+
import { PluginManifest } from "../../registry/types.js";
|
|
5
|
+
import { GenieConversationHistoryResponse } from "../../connectors/genie/types.js";
|
|
6
|
+
import { IGenieConfig } from "./types.js";
|
|
7
|
+
import express from "express";
|
|
8
|
+
|
|
9
|
+
//#region src/plugins/genie/genie.d.ts
|
|
10
|
+
declare class GeniePlugin extends Plugin {
|
|
11
|
+
name: string;
|
|
12
|
+
static manifest: PluginManifest;
|
|
13
|
+
protected static description: string;
|
|
14
|
+
protected config: IGenieConfig;
|
|
15
|
+
private readonly genieConnector;
|
|
16
|
+
constructor(config: IGenieConfig);
|
|
17
|
+
private defaultSpaces;
|
|
18
|
+
private resolveSpaceId;
|
|
19
|
+
injectRoutes(router: IAppRouter): void;
|
|
20
|
+
_handleSendMessage(req: express.Request, res: express.Response): Promise<void>;
|
|
21
|
+
_handleGetConversation(req: express.Request, res: express.Response): Promise<void>;
|
|
22
|
+
getConversation(alias: string, conversationId: string): Promise<GenieConversationHistoryResponse>;
|
|
23
|
+
/**
|
|
24
|
+
* Send a message and consume events as a stream (message_start, status,
|
|
25
|
+
* message_result, query_result, error).
|
|
26
|
+
*/
|
|
27
|
+
sendMessage(alias: string, content: string, conversationId?: string, options?: {
|
|
28
|
+
timeout?: number;
|
|
29
|
+
}): AsyncGenerator<GenieStreamEvent>;
|
|
30
|
+
shutdown(): Promise<void>;
|
|
31
|
+
exports(): {
|
|
32
|
+
sendMessage: (alias: string, content: string, conversationId?: string, options?: {
|
|
33
|
+
timeout?: number;
|
|
34
|
+
}) => AsyncGenerator<GenieStreamEvent>;
|
|
35
|
+
getConversation: (alias: string, conversationId: string) => Promise<GenieConversationHistoryResponse>;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* @internal
|
|
40
|
+
*/
|
|
41
|
+
declare const genie: ToPlugin<typeof GeniePlugin, IGenieConfig, "genie">;
|
|
42
|
+
//#endregion
|
|
43
|
+
export { genie };
|
|
44
|
+
//# sourceMappingURL=genie.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"genie.d.ts","names":[],"sources":["../../../src/plugins/genie/genie.ts"],"sourcesContent":[],"mappings":";;;;;;;;;cAkBa,WAAA,SAAoB,MAAA;;mBAAR;;oBAOG;EAPf,iBAAY,cAAA;EAAA,WAAA,CAAA,MAAA,EAWH,YAXG;UAAA,aAAA;UAOG,cAAA;cAIN,CAAA,MAAA,EAqBC,UArBD,CAAA,EAAA,IAAA;oBAqBC,CAAA,GAAA,EAqBd,OAAA,CAAQ,OArBM,EAAA,GAAA,EAsBd,OAAA,CAAQ,QAtBM,CAAA,EAuBlB,OAvBkB,CAAA,IAAA,CAAA;wBAqBN,CAAA,GAAA,EAyDR,OAAA,CAAQ,OAzDA,EAAA,GAAA,EA0DR,OAAA,CAAQ,QA1DA,CAAA,EA2DZ,OA3DY,CAAA,IAAA,CAAA;iBACA,CAAA,KAAA,EAAA,MAAA,EAAA,cAAA,EAAA,MAAA,CAAA,EAwGZ,OAxGY,CAwGJ,gCAxGI,CAAA;;;;;aAwGJ,CAAA,KAAA,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,EAAA,cAAA,CAAA,EAAA,MAAA,EAAA,QAAA,EAAA;IAAR,OAAA,CAAA,EAAA,MAAA;MAyBA,cAAe,CAAA,gBAAA,CAAA;UAAf,CAAA,CAAA,EAgBe,OAhBf,CAAA,IAAA,CAAA;SAgBe,CAAA,CAAA,EAAA;IAhBA,WAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,EAAA,cAAA,CAAA,EAAA,MAAA,EAAA,OAzBP,CAyBO,EAAA;MAAf,OAAA,CAAA,EAAA,MAAA;IAzBQ,CAAA,EAAA,GAyBR,cAzBQ,CAyBO,gBAzBP,CAAA;IAAR,eAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,cAAA,EAAA,MAAA,EAAA,GAAA,OAAA,CAAQ,gCAAR,CAAA;;;AAwDL;;;AAAkB,cAAL,KAAK,EAAA,QAAA,CAAA,OAAA,WAAA,EAAA,YAAA,EAAA,OAAA,CAAA"}
|