@sqlrooms/ai 0.25.0-rc.0 → 0.26.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -33
- package/dist/index.d.ts +8 -27
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -23
- package/dist/index.js.map +1 -1
- package/dist/tools/defaultInstructions.d.ts +8 -0
- package/dist/tools/defaultInstructions.d.ts.map +1 -0
- package/dist/tools/defaultInstructions.js +64 -0
- package/dist/tools/defaultInstructions.js.map +1 -0
- package/dist/tools/defaultTools.d.ts +14 -0
- package/dist/tools/defaultTools.d.ts.map +1 -0
- package/dist/tools/defaultTools.js +13 -0
- package/dist/tools/defaultTools.js.map +1 -0
- package/dist/tools/query/QueryToolResult.d.ts.map +1 -0
- package/dist/tools/query/QueryToolResult.js.map +1 -0
- package/dist/tools/query/queryTool.d.ts +25 -0
- package/dist/tools/query/queryTool.d.ts.map +1 -0
- package/dist/tools/query/queryTool.js +108 -0
- package/dist/tools/query/queryTool.js.map +1 -0
- package/package.json +13 -18
- package/dist/AiSettingsSlice.d.ts +0 -113
- package/dist/AiSettingsSlice.d.ts.map +0 -1
- package/dist/AiSettingsSlice.js +0 -174
- package/dist/AiSettingsSlice.js.map +0 -1
- package/dist/AiSlice.d.ts +0 -453
- package/dist/AiSlice.d.ts.map +0 -1
- package/dist/AiSlice.js +0 -416
- package/dist/AiSlice.js.map +0 -1
- package/dist/analysis.d.ts +0 -79
- package/dist/analysis.d.ts.map +0 -1
- package/dist/analysis.js +0 -218
- package/dist/analysis.js.map +0 -1
- package/dist/components/AnalysisAnswer.d.ts +0 -15
- package/dist/components/AnalysisAnswer.d.ts.map +0 -1
- package/dist/components/AnalysisAnswer.js +0 -102
- package/dist/components/AnalysisAnswer.js.map +0 -1
- package/dist/components/AnalysisResult.d.ts +0 -22
- package/dist/components/AnalysisResult.d.ts.map +0 -1
- package/dist/components/AnalysisResult.js +0 -39
- package/dist/components/AnalysisResult.js.map +0 -1
- package/dist/components/AnalysisResultsContainer.d.ts +0 -5
- package/dist/components/AnalysisResultsContainer.d.ts.map +0 -1
- package/dist/components/AnalysisResultsContainer.js +0 -26
- package/dist/components/AnalysisResultsContainer.js.map +0 -1
- package/dist/components/ErrorMessage.d.ts +0 -4
- package/dist/components/ErrorMessage.d.ts.map +0 -1
- package/dist/components/ErrorMessage.js +0 -8
- package/dist/components/ErrorMessage.js.map +0 -1
- package/dist/components/MessageContainer.d.ts +0 -10
- package/dist/components/MessageContainer.d.ts.map +0 -1
- package/dist/components/MessageContainer.js +0 -9
- package/dist/components/MessageContainer.js.map +0 -1
- package/dist/components/ModelSelector.d.ts +0 -13
- package/dist/components/ModelSelector.d.ts.map +0 -1
- package/dist/components/ModelSelector.js +0 -29
- package/dist/components/ModelSelector.js.map +0 -1
- package/dist/components/QueryControls.d.ts +0 -10
- package/dist/components/QueryControls.d.ts.map +0 -1
- package/dist/components/QueryControls.js +0 -55
- package/dist/components/QueryControls.js.map +0 -1
- package/dist/components/SessionControls.d.ts +0 -17
- package/dist/components/SessionControls.d.ts.map +0 -1
- package/dist/components/SessionControls.js +0 -20
- package/dist/components/SessionControls.js.map +0 -1
- package/dist/components/session/DeleteSessionButton.d.ts +0 -19
- package/dist/components/session/DeleteSessionButton.d.ts.map +0 -1
- package/dist/components/session/DeleteSessionButton.js +0 -54
- package/dist/components/session/DeleteSessionButton.js.map +0 -1
- package/dist/components/session/DeleteSessionDialog.d.ts +0 -27
- package/dist/components/session/DeleteSessionDialog.d.ts.map +0 -1
- package/dist/components/session/DeleteSessionDialog.js +0 -19
- package/dist/components/session/DeleteSessionDialog.js.map +0 -1
- package/dist/components/session/SessionActions.d.ts +0 -18
- package/dist/components/session/SessionActions.d.ts.map +0 -1
- package/dist/components/session/SessionActions.js +0 -19
- package/dist/components/session/SessionActions.js.map +0 -1
- package/dist/components/session/SessionDropdown.d.ts +0 -18
- package/dist/components/session/SessionDropdown.d.ts.map +0 -1
- package/dist/components/session/SessionDropdown.js +0 -21
- package/dist/components/session/SessionDropdown.js.map +0 -1
- package/dist/components/session/SessionTitle.d.ts +0 -18
- package/dist/components/session/SessionTitle.d.ts.map +0 -1
- package/dist/components/session/SessionTitle.js +0 -22
- package/dist/components/session/SessionTitle.js.map +0 -1
- package/dist/components/session/SessionType.d.ts +0 -24
- package/dist/components/session/SessionType.d.ts.map +0 -1
- package/dist/components/session/SessionType.js +0 -2
- package/dist/components/session/SessionType.js.map +0 -1
- package/dist/components/session/index.d.ts +0 -7
- package/dist/components/session/index.d.ts.map +0 -1
- package/dist/components/session/index.js +0 -7
- package/dist/components/session/index.js.map +0 -1
- package/dist/components/settings/AiModelParameters.d.ts +0 -6
- package/dist/components/settings/AiModelParameters.d.ts.map +0 -1
- package/dist/components/settings/AiModelParameters.js +0 -91
- package/dist/components/settings/AiModelParameters.js.map +0 -1
- package/dist/components/settings/AiModelUsage.d.ts +0 -18
- package/dist/components/settings/AiModelUsage.d.ts.map +0 -1
- package/dist/components/settings/AiModelUsage.js +0 -60
- package/dist/components/settings/AiModelUsage.js.map +0 -1
- package/dist/components/settings/AiModelsSettings.d.ts +0 -10
- package/dist/components/settings/AiModelsSettings.d.ts.map +0 -1
- package/dist/components/settings/AiModelsSettings.js +0 -229
- package/dist/components/settings/AiModelsSettings.js.map +0 -1
- package/dist/components/settings/AiProvidersSettings.d.ts +0 -3
- package/dist/components/settings/AiProvidersSettings.d.ts.map +0 -1
- package/dist/components/settings/AiProvidersSettings.js +0 -88
- package/dist/components/settings/AiProvidersSettings.js.map +0 -1
- package/dist/components/settings/AiSettingsPanel.d.ts +0 -17
- package/dist/components/settings/AiSettingsPanel.d.ts.map +0 -1
- package/dist/components/settings/AiSettingsPanel.js +0 -20
- package/dist/components/settings/AiSettingsPanel.js.map +0 -1
- package/dist/components/tools/QueryToolResult.d.ts.map +0 -1
- package/dist/components/tools/QueryToolResult.js.map +0 -1
- package/dist/components/tools/ToolErrorMessage.d.ts +0 -39
- package/dist/components/tools/ToolErrorMessage.d.ts.map +0 -1
- package/dist/components/tools/ToolErrorMessage.js +0 -20
- package/dist/components/tools/ToolErrorMessage.js.map +0 -1
- package/dist/components/tools/ToolResult.d.ts +0 -11
- package/dist/components/tools/ToolResult.d.ts.map +0 -1
- package/dist/components/tools/ToolResult.js +0 -29
- package/dist/components/tools/ToolResult.js.map +0 -1
- package/dist/components/tools/ToolResultErrorBoundary.d.ts +0 -19
- package/dist/components/tools/ToolResultErrorBoundary.d.ts.map +0 -1
- package/dist/components/tools/ToolResultErrorBoundary.js +0 -24
- package/dist/components/tools/ToolResultErrorBoundary.js.map +0 -1
- package/dist/hooks/useScrollToBottom.d.ts +0 -82
- package/dist/hooks/useScrollToBottom.d.ts.map +0 -1
- package/dist/hooks/useScrollToBottom.js +0 -142
- package/dist/hooks/useScrollToBottom.js.map +0 -1
- package/dist/schemas.d.ts +0 -512
- package/dist/schemas.d.ts.map +0 -1
- package/dist/schemas.js +0 -93
- package/dist/schemas.js.map +0 -1
- package/dist/utils.d.ts +0 -15
- package/dist/utils.d.ts.map +0 -1
- package/dist/utils.js +0 -31
- package/dist/utils.js.map +0 -1
- /package/dist/{components/tools → tools/query}/QueryToolResult.d.ts +0 -0
- /package/dist/{components/tools → tools/query}/QueryToolResult.js +0 -0
package/dist/analysis.js
DELETED
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
import { createAssistant, rebuildMessages, } from '@openassistant/core';
|
|
2
|
-
import { extendedTool } from '@openassistant/utils';
|
|
3
|
-
import { arrowTableToJson, splitSqlStatements, } from '@sqlrooms/duckdb';
|
|
4
|
-
import { QueryToolResult } from './components/tools/QueryToolResult';
|
|
5
|
-
import { QueryToolParameters } from './schemas';
|
|
6
|
-
import { convertToCoreMessages } from 'ai';
|
|
7
|
-
/**
|
|
8
|
-
* System prompt template for the AI assistant that provides instructions for:
|
|
9
|
-
* - Using DuckDB-specific SQL syntax and functions
|
|
10
|
-
* - Handling query results and error cases
|
|
11
|
-
* - Creating visualizations with VegaLite
|
|
12
|
-
* - Formatting final answers
|
|
13
|
-
*/
|
|
14
|
-
const DEFAULT_INSTRUCTIONS = `
|
|
15
|
-
You are analyzing tables in DuckDB database in the context of a room.
|
|
16
|
-
|
|
17
|
-
Instructions for analysis:
|
|
18
|
-
- When using 'query' tool, please assign parameter 'type' with value 'query'
|
|
19
|
-
- Use DuckDB-specific SQL syntax and functions (not Oracle, PostgreSQL, or other SQL dialects)
|
|
20
|
-
- Some key DuckDB-specific functions to use:
|
|
21
|
-
* regexp_matches() for regex (not regexp_like)
|
|
22
|
-
* strftime() for date formatting (not to_char)
|
|
23
|
-
* list_aggregate() for array operations
|
|
24
|
-
* unnest() for array expansion
|
|
25
|
-
* regr_sxy()
|
|
26
|
-
* corr()
|
|
27
|
-
* skewness()
|
|
28
|
-
- Please always try to use SQL queries to answer users questions
|
|
29
|
-
- Please run tool calls sequentially, don't run multiple tool calls in parallel
|
|
30
|
-
- IMPORTANT: Do not list out raw query results in your response. Instead:
|
|
31
|
-
* Describe the results in natural language
|
|
32
|
-
* Provide summary statistics
|
|
33
|
-
* Use comparisons and relative terms
|
|
34
|
-
* Include only the most relevant values if necessary
|
|
35
|
-
- Break down complex problems into smaller steps
|
|
36
|
-
- Use "SUMMARIZE table_name"for quick overview of the table
|
|
37
|
-
- Please don't modify data
|
|
38
|
-
- IMPORTANT: When you receive an error response from a tool call (where success: false):
|
|
39
|
-
* Stop making any further tool calls immediately
|
|
40
|
-
* Return a final answer that includes the error message
|
|
41
|
-
* Explain what went wrong and suggest possible fixes if applicable
|
|
42
|
-
|
|
43
|
-
When creating visualizations:
|
|
44
|
-
- Follow VegaLite syntax
|
|
45
|
-
- Choose appropriate chart types based on the data and analysis goals
|
|
46
|
-
- Use clear titles and axis labels
|
|
47
|
-
- Consider color schemes for better readability
|
|
48
|
-
- Add meaningful tooltips when relevant
|
|
49
|
-
- Format numbers and dates appropriately
|
|
50
|
-
- Use aggregations when dealing with large datasets
|
|
51
|
-
|
|
52
|
-
For your final answer:
|
|
53
|
-
- Provide an explanation for how you got it
|
|
54
|
-
- Explain your reasoning step by step
|
|
55
|
-
- Include relevant statistics or metrics
|
|
56
|
-
- For each prompt, please always provide the final answer.
|
|
57
|
-
- IMPORTANT: Query tool results may include sample rows (firstRows) or may be empty:
|
|
58
|
-
* If no sample rows provided: Never fabricate data. Direct users to the table component for actual results.
|
|
59
|
-
* If sample rows provided: Use them to enhance your analysis, but always direct users to the table component for complete results.
|
|
60
|
-
|
|
61
|
-
Please use the following schema for the tables:
|
|
62
|
-
`;
|
|
63
|
-
/**
|
|
64
|
-
* Returns the default system instructions for the AI assistant
|
|
65
|
-
*/
|
|
66
|
-
export function getDefaultInstructions(tablesSchema) {
|
|
67
|
-
return `${DEFAULT_INSTRUCTIONS}\n${JSON.stringify(tablesSchema)}`;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Generates summary statistics for a SQL query result
|
|
71
|
-
* @param connector - DuckDB connection instance
|
|
72
|
-
* @param sqlQuery - SQL SELECT query to analyze
|
|
73
|
-
* @returns Summary statistics as JSON object, or null if the query is not a SELECT statement or if summary generation fails
|
|
74
|
-
*/
|
|
75
|
-
async function getQuerySummary(connector, sqlQuery) {
|
|
76
|
-
if (!sqlQuery.toLowerCase().trim().startsWith('select')) {
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
try {
|
|
80
|
-
const summaryResult = await connector.query(`SUMMARIZE (
|
|
81
|
-
${sqlQuery}
|
|
82
|
-
)`);
|
|
83
|
-
return arrowTableToJson(summaryResult);
|
|
84
|
-
}
|
|
85
|
-
catch (error) {
|
|
86
|
-
console.warn('Failed to get summary for query. Error:', error);
|
|
87
|
-
return null;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Executes an AI analysis session on the room data
|
|
92
|
-
*
|
|
93
|
-
* @param config - Analysis configuration options. See {@link AnalysisParameters} for more details.
|
|
94
|
-
* @returns Object containing tool calls executed and the final analysis result
|
|
95
|
-
*/
|
|
96
|
-
export async function runAnalysis({ name = 'sqlrooms-ai', tableSchemas, modelProvider, model, apiKey, prompt, abortController, historyAnalysis, onStreamResult, maxSteps = 5, tools = {}, getInstructions, baseUrl, }) {
|
|
97
|
-
// get the singleton assistant instance
|
|
98
|
-
const assistant = await createAssistant({
|
|
99
|
-
name,
|
|
100
|
-
modelProvider,
|
|
101
|
-
model,
|
|
102
|
-
apiKey,
|
|
103
|
-
version: 'v1',
|
|
104
|
-
instructions: getInstructions
|
|
105
|
-
? getInstructions(tableSchemas)
|
|
106
|
-
: getDefaultInstructions(tableSchemas),
|
|
107
|
-
tools: tools,
|
|
108
|
-
temperature: 0,
|
|
109
|
-
toolChoice: 'auto', // this will enable streaming
|
|
110
|
-
maxSteps,
|
|
111
|
-
...(abortController ? { abortController } : {}),
|
|
112
|
-
baseUrl, // ollama base url or LLM proxy server url
|
|
113
|
-
});
|
|
114
|
-
// restore ai messages from historyAnalysis?
|
|
115
|
-
if (historyAnalysis) {
|
|
116
|
-
const historyMessages = historyAnalysis.map((analysis) => ({
|
|
117
|
-
prompt: analysis.prompt,
|
|
118
|
-
response: analysis.streamMessage,
|
|
119
|
-
}));
|
|
120
|
-
const initialMessages = rebuildMessages(historyMessages);
|
|
121
|
-
assistant.setMessages(convertToCoreMessages(initialMessages));
|
|
122
|
-
}
|
|
123
|
-
// process the prompt
|
|
124
|
-
const newMessages = await assistant.processTextMessage({
|
|
125
|
-
textMessage: prompt,
|
|
126
|
-
streamMessageCallback: ({ isCompleted, message, }) => {
|
|
127
|
-
onStreamResult(isCompleted ?? false, message);
|
|
128
|
-
},
|
|
129
|
-
});
|
|
130
|
-
return newMessages;
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Default tools available to the AI assistant for data analysis
|
|
134
|
-
* Includes:
|
|
135
|
-
* - query: Executes SQL queries against DuckDB
|
|
136
|
-
*/
|
|
137
|
-
export function getDefaultTools(store, options) {
|
|
138
|
-
const { readOnly = true, numberOfRowsToShareWithLLM = 0, autoSummary = true, } = options || {};
|
|
139
|
-
return {
|
|
140
|
-
query: extendedTool({
|
|
141
|
-
description: `A tool for running SQL queries on the tables in the database.
|
|
142
|
-
Please only run one query at a time.
|
|
143
|
-
If a query fails, please don't try to run it again with the same syntax.`,
|
|
144
|
-
parameters: QueryToolParameters,
|
|
145
|
-
execute: async ({ type, sqlQuery }) => {
|
|
146
|
-
try {
|
|
147
|
-
const connector = await store.getState().db.getConnector();
|
|
148
|
-
// TODO use options.abortSignal: maybe call db.cancelPendingQuery
|
|
149
|
-
const result = await connector.query(sqlQuery);
|
|
150
|
-
const parsedQuery = await store
|
|
151
|
-
.getState()
|
|
152
|
-
.db.sqlSelectToJson(sqlQuery);
|
|
153
|
-
if (parsedQuery.error &&
|
|
154
|
-
// Only SELECT statements can be serialized to json, so we ignore not implemented errors
|
|
155
|
-
parsedQuery.error_type !== 'not implemented') {
|
|
156
|
-
throw new Error(parsedQuery.error_message);
|
|
157
|
-
}
|
|
158
|
-
if (readOnly) {
|
|
159
|
-
if (parsedQuery.error) {
|
|
160
|
-
throw new Error(`Query is not a valid SELECT statement: ${parsedQuery.error_message}`);
|
|
161
|
-
}
|
|
162
|
-
if (parsedQuery.statements.length !== 1 || // only one statement allowed
|
|
163
|
-
parsedQuery.statements[0]?.node.type !== 'SELECT_NODE' // only SELECT statements allowed
|
|
164
|
-
) {
|
|
165
|
-
throw new Error('Query is not a valid SELECT statement');
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
const summaryData = await (async () => {
|
|
169
|
-
if (!autoSummary)
|
|
170
|
-
return null;
|
|
171
|
-
if (parsedQuery.error)
|
|
172
|
-
return null;
|
|
173
|
-
const lastNode = parsedQuery.statements[parsedQuery.statements.length - 1]?.node;
|
|
174
|
-
// Only get summary if the last statement isn't already a SUMMARIZE query
|
|
175
|
-
if (lastNode?.type === 'SELECT_NODE' &&
|
|
176
|
-
lastNode?.from_table?.show_type === 'SUMMARY') {
|
|
177
|
-
return arrowTableToJson(result);
|
|
178
|
-
}
|
|
179
|
-
const statements = splitSqlStatements(sqlQuery);
|
|
180
|
-
const lastStatement = statements[statements.length - 1];
|
|
181
|
-
if (!lastStatement)
|
|
182
|
-
return null;
|
|
183
|
-
return await getQuerySummary(connector, lastStatement);
|
|
184
|
-
})();
|
|
185
|
-
// Conditionally get rows of the result as a json object based on numberOfRowsToShareWithLLM
|
|
186
|
-
const firstRows = numberOfRowsToShareWithLLM > 0
|
|
187
|
-
? arrowTableToJson(result.slice(0, numberOfRowsToShareWithLLM))
|
|
188
|
-
: [];
|
|
189
|
-
return {
|
|
190
|
-
llmResult: {
|
|
191
|
-
success: true,
|
|
192
|
-
data: {
|
|
193
|
-
type,
|
|
194
|
-
summary: summaryData,
|
|
195
|
-
...(numberOfRowsToShareWithLLM > 0 ? { firstRows } : {}),
|
|
196
|
-
},
|
|
197
|
-
},
|
|
198
|
-
additionalData: {
|
|
199
|
-
title: 'Query Result',
|
|
200
|
-
sqlQuery,
|
|
201
|
-
},
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
catch (error) {
|
|
205
|
-
return {
|
|
206
|
-
llmResult: {
|
|
207
|
-
success: false,
|
|
208
|
-
details: 'Query execution failed.',
|
|
209
|
-
errorMessage: error instanceof Error ? error.message : 'Unknown error',
|
|
210
|
-
},
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
},
|
|
214
|
-
component: QueryToolResult,
|
|
215
|
-
}),
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
//# sourceMappingURL=analysis.js.map
|
package/dist/analysis.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"analysis.js","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createAssistant,\n rebuildMessages,\n StreamMessage,\n} from '@openassistant/core';\nimport {extendedTool} from '@openassistant/utils';\nimport {\n arrowTableToJson,\n DataTable,\n DuckDbConnector,\n DuckDbSliceState,\n splitSqlStatements,\n} from '@sqlrooms/duckdb';\nimport type {StoreApi} from '@sqlrooms/room-shell';\nimport {AiSliceState, AiSliceTool} from './AiSlice';\nimport {QueryToolResult} from './components/tools/QueryToolResult';\nimport {AnalysisResultSchema, QueryToolParameters} from './schemas';\nimport {convertToCoreMessages} from 'ai';\n\n/**\n * System prompt template for the AI assistant that provides instructions for:\n * - Using DuckDB-specific SQL syntax and functions\n * - Handling query results and error cases\n * - Creating visualizations with VegaLite\n * - Formatting final answers\n */\nconst DEFAULT_INSTRUCTIONS = `\nYou are analyzing tables in DuckDB database in the context of a room.\n\nInstructions for analysis:\n- When using 'query' tool, please assign parameter 'type' with value 'query'\n- Use DuckDB-specific SQL syntax and functions (not Oracle, PostgreSQL, or other SQL dialects)\n- Some key DuckDB-specific functions to use:\n * regexp_matches() for regex (not regexp_like)\n * strftime() for date formatting (not to_char)\n * list_aggregate() for array operations\n * unnest() for array expansion\n * regr_sxy()\n * corr()\n * skewness()\n- Please always try to use SQL queries to answer users questions\n- Please run tool calls sequentially, don't run multiple tool calls in parallel\n- IMPORTANT: Do not list out raw query results in your response. Instead:\n * Describe the results in natural language\n * Provide summary statistics\n * Use comparisons and relative terms\n * Include only the most relevant values if necessary\n- Break down complex problems into smaller steps\n- Use \"SUMMARIZE table_name\"for quick overview of the table\n- Please don't modify data\n- IMPORTANT: When you receive an error response from a tool call (where success: false):\n * Stop making any further tool calls immediately\n * Return a final answer that includes the error message\n * Explain what went wrong and suggest possible fixes if applicable\n\nWhen creating visualizations:\n- Follow VegaLite syntax\n- Choose appropriate chart types based on the data and analysis goals\n- Use clear titles and axis labels\n- Consider color schemes for better readability\n- Add meaningful tooltips when relevant\n- Format numbers and dates appropriately\n- Use aggregations when dealing with large datasets\n\nFor your final answer:\n- Provide an explanation for how you got it\n- Explain your reasoning step by step\n- Include relevant statistics or metrics\n- For each prompt, please always provide the final answer.\n- IMPORTANT: Query tool results may include sample rows (firstRows) or may be empty:\n * If no sample rows provided: Never fabricate data. Direct users to the table component for actual results.\n * If sample rows provided: Use them to enhance your analysis, but always direct users to the table component for complete results.\n\nPlease use the following schema for the tables:\n`;\n\n/**\n * Returns the default system instructions for the AI assistant\n */\nexport function getDefaultInstructions(tablesSchema: DataTable[]): string {\n return `${DEFAULT_INSTRUCTIONS}\\n${JSON.stringify(tablesSchema)}`;\n}\n\n/**\n * Generates summary statistics for a SQL query result\n * @param connector - DuckDB connection instance\n * @param sqlQuery - SQL SELECT query to analyze\n * @returns Summary statistics as JSON object, or null if the query is not a SELECT statement or if summary generation fails\n */\nasync function getQuerySummary(connector: DuckDbConnector, sqlQuery: string) {\n if (!sqlQuery.toLowerCase().trim().startsWith('select')) {\n return null;\n }\n\n try {\n const summaryResult = await connector.query(`SUMMARIZE (\n ${sqlQuery}\n )`);\n return arrowTableToJson(summaryResult);\n } catch (error) {\n console.warn('Failed to get summary for query. Error:', error);\n return null;\n }\n}\n\n/**\n * Configuration options for running an AI analysis session\n */\ntype AnalysisParameters = {\n tableSchemas: DataTable[];\n\n /** Assistant instance identifier (default: 'sqlrooms-ai') */\n name?: string;\n\n /** AI model provider (e.g., 'openai', 'anthropic') */\n modelProvider: string;\n\n /** Model identifier (e.g., 'gpt-4', 'claude-3') */\n model: string;\n\n /** Authentication key for the model provider's API */\n apiKey: string;\n\n /** Analysis prompt or question to be processed */\n prompt: string;\n\n /** Optional controller for canceling the analysis operation */\n abortController?: AbortController;\n\n /** Maximum number of analysis steps allowed (default: 100) */\n maxSteps?: number;\n\n /** The history of analysis results (e.g. saved in localStorage) */\n historyAnalysis?: AnalysisResultSchema[];\n\n /** Tools to use in the analysis */\n tools?: Record<string, AiSliceTool>;\n\n /** Base URL for Ollama provider (required when modelProvider is 'ollama') */\n baseUrl?: string;\n\n /**\n * Function to get custom instructions for the AI assistant\n * @param tablesSchema - The schema of the tables in the database\n * @returns The instructions string to use\n */\n getInstructions?: (tablesSchema: DataTable[]) => string;\n\n /**\n * Callback for handling streaming results\n * @param isCompleted - Indicates if this is the final message in the stream\n * @param streamMessage - Current message content being streamed\n */\n onStreamResult: (isCompleted: boolean, streamMessage?: StreamMessage) => void;\n};\n\n/**\n * Executes an AI analysis session on the room data\n *\n * @param config - Analysis configuration options. See {@link AnalysisParameters} for more details.\n * @returns Object containing tool calls executed and the final analysis result\n */\nexport async function runAnalysis({\n name = 'sqlrooms-ai',\n tableSchemas,\n modelProvider,\n model,\n apiKey,\n prompt,\n abortController,\n historyAnalysis,\n onStreamResult,\n maxSteps = 5,\n tools = {},\n getInstructions,\n baseUrl,\n}: AnalysisParameters) {\n // get the singleton assistant instance\n const assistant = await createAssistant({\n name,\n modelProvider,\n model,\n apiKey,\n version: 'v1',\n instructions: getInstructions\n ? getInstructions(tableSchemas)\n : getDefaultInstructions(tableSchemas),\n tools: tools,\n temperature: 0,\n toolChoice: 'auto', // this will enable streaming\n maxSteps,\n ...(abortController ? {abortController} : {}),\n baseUrl, // ollama base url or LLM proxy server url\n });\n\n // restore ai messages from historyAnalysis?\n if (historyAnalysis) {\n const historyMessages = historyAnalysis.map((analysis) => ({\n prompt: analysis.prompt,\n response: analysis.streamMessage as StreamMessage,\n }));\n const initialMessages = rebuildMessages(historyMessages);\n assistant.setMessages(convertToCoreMessages(initialMessages));\n }\n\n // process the prompt\n const newMessages = await assistant.processTextMessage({\n textMessage: prompt,\n streamMessageCallback: ({\n isCompleted,\n message,\n }: {\n isCompleted?: boolean;\n message?: StreamMessage;\n }) => {\n onStreamResult(isCompleted ?? false, message);\n },\n });\n\n return newMessages;\n}\n\nexport type DefaultToolsOptions = {\n /**\n * Whether to enable read only mode (default: true)\n */\n readOnly?: boolean;\n /**\n * Number of rows to share with LLM (default: 0)\n */\n\n numberOfRowsToShareWithLLM?: number;\n /**\n * Whether to automatically generate a summary of the query result (default: true)\n */\n autoSummary?: boolean;\n};\n\n/**\n * Default tools available to the AI assistant for data analysis\n * Includes:\n * - query: Executes SQL queries against DuckDB\n */\nexport function getDefaultTools(\n store: StoreApi<AiSliceState & DuckDbSliceState>,\n options?: DefaultToolsOptions,\n): Record<string, AiSliceTool> {\n const {\n readOnly = true,\n numberOfRowsToShareWithLLM = 0,\n autoSummary = true,\n } = options || {};\n return {\n query: extendedTool({\n description: `A tool for running SQL queries on the tables in the database.\nPlease only run one query at a time.\nIf a query fails, please don't try to run it again with the same syntax.`,\n parameters: QueryToolParameters,\n execute: async ({type, sqlQuery}) => {\n try {\n const connector = await store.getState().db.getConnector();\n // TODO use options.abortSignal: maybe call db.cancelPendingQuery\n const result = await connector.query(sqlQuery);\n\n const parsedQuery = await store\n .getState()\n .db.sqlSelectToJson(sqlQuery);\n\n if (\n parsedQuery.error &&\n // Only SELECT statements can be serialized to json, so we ignore not implemented errors\n parsedQuery.error_type !== 'not implemented'\n ) {\n throw new Error(parsedQuery.error_message);\n }\n\n if (readOnly) {\n if (parsedQuery.error) {\n throw new Error(\n `Query is not a valid SELECT statement: ${parsedQuery.error_message}`,\n );\n }\n if (\n parsedQuery.statements.length !== 1 || // only one statement allowed\n parsedQuery.statements[0]?.node.type !== 'SELECT_NODE' // only SELECT statements allowed\n ) {\n throw new Error('Query is not a valid SELECT statement');\n }\n }\n\n const summaryData = await (async () => {\n if (!autoSummary) return null;\n if (parsedQuery.error) return null;\n const lastNode =\n parsedQuery.statements[parsedQuery.statements.length - 1]?.node;\n\n // Only get summary if the last statement isn't already a SUMMARIZE query\n if (\n lastNode?.type === 'SELECT_NODE' &&\n lastNode?.from_table?.show_type === 'SUMMARY'\n ) {\n return arrowTableToJson(result);\n }\n const statements = splitSqlStatements(sqlQuery);\n const lastStatement = statements[statements.length - 1];\n if (!lastStatement) return null;\n return await getQuerySummary(connector, lastStatement);\n })();\n\n // Conditionally get rows of the result as a json object based on numberOfRowsToShareWithLLM\n const firstRows =\n numberOfRowsToShareWithLLM > 0\n ? arrowTableToJson(result.slice(0, numberOfRowsToShareWithLLM))\n : [];\n\n return {\n llmResult: {\n success: true,\n data: {\n type,\n summary: summaryData,\n ...(numberOfRowsToShareWithLLM > 0 ? {firstRows} : {}),\n },\n },\n additionalData: {\n title: 'Query Result',\n sqlQuery,\n },\n };\n } catch (error) {\n return {\n llmResult: {\n success: false,\n details: 'Query execution failed.',\n errorMessage:\n error instanceof Error ? error.message : 'Unknown error',\n },\n };\n }\n },\n component: QueryToolResult,\n }),\n };\n}\n"]}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
type AnalysisAnswerProps = {
|
|
3
|
-
content: string;
|
|
4
|
-
isAnswer: boolean;
|
|
5
|
-
};
|
|
6
|
-
/**
|
|
7
|
-
* Renders an analysis answer with markdown content of the final streaming response.
|
|
8
|
-
* Supports streaming think content that may arrive in chunks (e.g., "<think>Hello" before "</think>").
|
|
9
|
-
*
|
|
10
|
-
* @param {AnalysisAnswerProps} props - The component props. See {@link AnalysisAnswerProps} for more details.
|
|
11
|
-
* @returns {JSX.Element} The rendered answer tool call
|
|
12
|
-
*/
|
|
13
|
-
export declare const AnalysisAnswer: React.NamedExoticComponent<AnalysisAnswerProps>;
|
|
14
|
-
export {};
|
|
15
|
-
//# sourceMappingURL=AnalysisAnswer.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AnalysisAnswer.d.ts","sourceRoot":"","sources":["../../src/components/AnalysisAnswer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAS5D,KAAK,mBAAmB,GAAG;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AA6GF;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,iDA0EzB,CAAC"}
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import React, { useState, useCallback, useMemo } from 'react';
|
|
3
|
-
import Markdown from 'react-markdown';
|
|
4
|
-
import remarkGfm from 'remark-gfm';
|
|
5
|
-
import rehypeRaw from 'rehype-raw';
|
|
6
|
-
import { truncate } from '@sqlrooms/utils';
|
|
7
|
-
import { MessageContainer } from './MessageContainer';
|
|
8
|
-
import { BrainIcon } from 'lucide-react';
|
|
9
|
-
import { cn } from '@sqlrooms/ui';
|
|
10
|
-
// Constants moved outside component to prevent recreation
|
|
11
|
-
const THINK_WORD_LIMIT = 10;
|
|
12
|
-
const COMPLETE_THINK_REGEX = /<think>([\s\S]*?)<\/think>/g;
|
|
13
|
-
const INCOMPLETE_THINK_REGEX = /<think>([\s\S]*)$/;
|
|
14
|
-
/**
|
|
15
|
-
* Processes content and extracts think content in one pass
|
|
16
|
-
*/
|
|
17
|
-
const processContent = (originalContent) => {
|
|
18
|
-
const thinkContents = [];
|
|
19
|
-
let processedContent = originalContent;
|
|
20
|
-
let index = 0;
|
|
21
|
-
// Replace complete think tags
|
|
22
|
-
processedContent = processedContent.replace(COMPLETE_THINK_REGEX, (match, content) => {
|
|
23
|
-
if (content) {
|
|
24
|
-
thinkContents.push({
|
|
25
|
-
content: content.trim(),
|
|
26
|
-
isComplete: true,
|
|
27
|
-
index: index++,
|
|
28
|
-
});
|
|
29
|
-
return `\n\n<think-block data-index="${index - 1}"></think-block>\n\n`;
|
|
30
|
-
}
|
|
31
|
-
return match;
|
|
32
|
-
});
|
|
33
|
-
// Replace incomplete think tags (no closing tag)
|
|
34
|
-
processedContent = processedContent.replace(INCOMPLETE_THINK_REGEX, (match, content) => {
|
|
35
|
-
if (content) {
|
|
36
|
-
thinkContents.push({
|
|
37
|
-
content: content.trim(),
|
|
38
|
-
isComplete: false,
|
|
39
|
-
index: index++,
|
|
40
|
-
});
|
|
41
|
-
return `\n\n<think-block data-index="${index - 1}"></think-block>\n\n`;
|
|
42
|
-
}
|
|
43
|
-
return match;
|
|
44
|
-
});
|
|
45
|
-
return { processedContent, thinkContents };
|
|
46
|
-
};
|
|
47
|
-
/**
|
|
48
|
-
* ThinkBlock component for rendering individual think blocks
|
|
49
|
-
*/
|
|
50
|
-
const ThinkBlock = React.memo(({ thinkContent, isExpanded, onToggleExpansion, className }) => {
|
|
51
|
-
const { content, isComplete, index } = thinkContent;
|
|
52
|
-
const displayText = isComplete && !isExpanded ? truncate(content, THINK_WORD_LIMIT) : content;
|
|
53
|
-
const needsTruncation = isComplete && content.split(' ').length > THINK_WORD_LIMIT;
|
|
54
|
-
return (_jsxs("span", { className: cn('inline-block rounded-lg px-3 py-2 text-xs font-normal text-gray-100 dark:text-gray-400', isExpanded && 'bg-gray-50 dark:bg-gray-800/50', className), children: [_jsx("span", { className: "inline-flex items-start gap-2", children: _jsxs("span", { className: "text-gray-400", children: [_jsx(BrainIcon, { className: "mb-1 inline-block opacity-60 grayscale", size: 12 }), ' ', displayText] }) }), ' ', needsTruncation && (_jsx("button", { onClick: () => onToggleExpansion(content), className: "text-xs text-gray-500 underline hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300", children: isExpanded ? 'Show less' : 'Show more thinking' }))] }, `think-${index}`));
|
|
55
|
-
});
|
|
56
|
-
ThinkBlock.displayName = 'ThinkBlock';
|
|
57
|
-
/**
|
|
58
|
-
* Renders an analysis answer with markdown content of the final streaming response.
|
|
59
|
-
* Supports streaming think content that may arrive in chunks (e.g., "<think>Hello" before "</think>").
|
|
60
|
-
*
|
|
61
|
-
* @param {AnalysisAnswerProps} props - The component props. See {@link AnalysisAnswerProps} for more details.
|
|
62
|
-
* @returns {JSX.Element} The rendered answer tool call
|
|
63
|
-
*/
|
|
64
|
-
export const AnalysisAnswer = React.memo(function AnalysisAnswer(props) {
|
|
65
|
-
const [expandedThink, setExpandedThink] = useState(new Set());
|
|
66
|
-
const toggleThinkExpansion = useCallback((content) => {
|
|
67
|
-
setExpandedThink((prev) => {
|
|
68
|
-
const newExpanded = new Set(prev);
|
|
69
|
-
if (newExpanded.has(content)) {
|
|
70
|
-
newExpanded.delete(content);
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
newExpanded.add(content);
|
|
74
|
-
}
|
|
75
|
-
return newExpanded;
|
|
76
|
-
});
|
|
77
|
-
}, []);
|
|
78
|
-
// Memoize content processing to avoid recalculation on every render
|
|
79
|
-
const { processedContent, thinkContents } = useMemo(() => processContent(props.content), [props.content]);
|
|
80
|
-
// Memoize the think-block component to prevent unnecessary re-renders
|
|
81
|
-
const thinkBlockComponent = useCallback((thinkBlock) => {
|
|
82
|
-
try {
|
|
83
|
-
const index = parseInt(thinkBlock.props?.['data-index'] || '0', 10);
|
|
84
|
-
const thinkContent = thinkContents[index];
|
|
85
|
-
if (!thinkContent) {
|
|
86
|
-
console.warn(`Think content not found for index: ${index}`);
|
|
87
|
-
return null;
|
|
88
|
-
}
|
|
89
|
-
const isExpanded = expandedThink.has(thinkContent.content);
|
|
90
|
-
return (_jsx(ThinkBlock, { thinkContent: thinkContent, isExpanded: isExpanded, onToggleExpansion: toggleThinkExpansion }));
|
|
91
|
-
}
|
|
92
|
-
catch (error) {
|
|
93
|
-
console.error('Error rendering think block:', error);
|
|
94
|
-
return null;
|
|
95
|
-
}
|
|
96
|
-
}, [thinkContents, expandedThink, toggleThinkExpansion]);
|
|
97
|
-
return (_jsx("div", { className: "flex flex-col gap-5", children: _jsx(MessageContainer, { isSuccess: true, type: props.isAnswer ? 'answer' : 'thinking', content: props, children: _jsx("div", { className: "prose dark:prose-invert max-w-none text-sm", children: _jsx(Markdown, { remarkPlugins: [remarkGfm], rehypePlugins: [rehypeRaw], components: {
|
|
98
|
-
// @ts-expect-error - Custom HTML element not in react-markdown types
|
|
99
|
-
'think-block': thinkBlockComponent,
|
|
100
|
-
}, children: processedContent }) }) }) }));
|
|
101
|
-
});
|
|
102
|
-
//# sourceMappingURL=AnalysisAnswer.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AnalysisAnswer.js","sourceRoot":"","sources":["../../src/components/AnalysisAnswer.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, {useState, useCallback, useMemo} from 'react';\nimport Markdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport rehypeRaw from 'rehype-raw';\nimport {truncate} from '@sqlrooms/utils';\nimport {MessageContainer} from './MessageContainer';\nimport {BrainIcon} from 'lucide-react';\nimport {cn} from '@sqlrooms/ui';\n\ntype AnalysisAnswerProps = {\n content: string;\n isAnswer: boolean;\n};\n\ntype ThinkContent = {\n content: string;\n isComplete: boolean;\n index: number;\n};\n\n// Constants moved outside component to prevent recreation\nconst THINK_WORD_LIMIT = 10;\nconst COMPLETE_THINK_REGEX = /<think>([\\s\\S]*?)<\\/think>/g;\nconst INCOMPLETE_THINK_REGEX = /<think>([\\s\\S]*)$/;\n\n/**\n * Processes content and extracts think content in one pass\n */\nconst processContent = (\n originalContent: string,\n): {\n processedContent: string;\n thinkContents: ThinkContent[];\n} => {\n const thinkContents: ThinkContent[] = [];\n let processedContent = originalContent;\n let index = 0;\n\n // Replace complete think tags\n processedContent = processedContent.replace(\n COMPLETE_THINK_REGEX,\n (match, content) => {\n if (content) {\n thinkContents.push({\n content: content.trim(),\n isComplete: true,\n index: index++,\n });\n return `\\n\\n<think-block data-index=\"${index - 1}\"></think-block>\\n\\n`;\n }\n return match;\n },\n );\n\n // Replace incomplete think tags (no closing tag)\n processedContent = processedContent.replace(\n INCOMPLETE_THINK_REGEX,\n (match, content) => {\n if (content) {\n thinkContents.push({\n content: content.trim(),\n isComplete: false,\n index: index++,\n });\n return `\\n\\n<think-block data-index=\"${index - 1}\"></think-block>\\n\\n`;\n }\n return match;\n },\n );\n\n return {processedContent, thinkContents};\n};\n\n/**\n * ThinkBlock component for rendering individual think blocks\n */\nconst ThinkBlock = React.memo<{\n className?: string;\n thinkContent: ThinkContent;\n isExpanded: boolean;\n onToggleExpansion: (content: string) => void;\n}>(({thinkContent, isExpanded, onToggleExpansion, className}) => {\n const {content, isComplete, index} = thinkContent;\n\n const displayText =\n isComplete && !isExpanded ? truncate(content, THINK_WORD_LIMIT) : content;\n const needsTruncation =\n isComplete && content.split(' ').length > THINK_WORD_LIMIT;\n\n return (\n <span\n key={`think-${index}`}\n className={cn(\n 'inline-block rounded-lg px-3 py-2 text-xs font-normal text-gray-100 dark:text-gray-400',\n isExpanded && 'bg-gray-50 dark:bg-gray-800/50',\n className,\n )}\n >\n <span className=\"inline-flex items-start gap-2\">\n <span className=\"text-gray-400\">\n <BrainIcon\n className=\"mb-1 inline-block opacity-60 grayscale\"\n size={12}\n />{' '}\n {displayText}\n </span>\n </span>{' '}\n {needsTruncation && (\n <button\n onClick={() => onToggleExpansion(content)}\n className=\"text-xs text-gray-500 underline hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300\"\n >\n {isExpanded ? 'Show less' : 'Show more thinking'}\n </button>\n )}\n </span>\n );\n});\n\nThinkBlock.displayName = 'ThinkBlock';\n\n/**\n * Renders an analysis answer with markdown content of the final streaming response.\n * Supports streaming think content that may arrive in chunks (e.g., \"<think>Hello\" before \"</think>\").\n *\n * @param {AnalysisAnswerProps} props - The component props. See {@link AnalysisAnswerProps} for more details.\n * @returns {JSX.Element} The rendered answer tool call\n */\nexport const AnalysisAnswer = React.memo(function AnalysisAnswer(\n props: AnalysisAnswerProps,\n) {\n const [expandedThink, setExpandedThink] = useState<Set<string>>(new Set());\n\n const toggleThinkExpansion = useCallback((content: string) => {\n setExpandedThink((prev) => {\n const newExpanded = new Set(prev);\n if (newExpanded.has(content)) {\n newExpanded.delete(content);\n } else {\n newExpanded.add(content);\n }\n return newExpanded;\n });\n }, []);\n\n // Memoize content processing to avoid recalculation on every render\n const {processedContent, thinkContents} = useMemo(\n () => processContent(props.content),\n [props.content],\n );\n\n // Memoize the think-block component to prevent unnecessary re-renders\n const thinkBlockComponent = useCallback(\n (thinkBlock: any) => {\n try {\n const index = parseInt(thinkBlock.props?.['data-index'] || '0', 10);\n const thinkContent = thinkContents[index];\n\n if (!thinkContent) {\n console.warn(`Think content not found for index: ${index}`);\n return null;\n }\n\n const isExpanded = expandedThink.has(thinkContent.content);\n\n return (\n <ThinkBlock\n thinkContent={thinkContent}\n isExpanded={isExpanded}\n onToggleExpansion={toggleThinkExpansion}\n />\n );\n } catch (error) {\n console.error('Error rendering think block:', error);\n return null;\n }\n },\n [thinkContents, expandedThink, toggleThinkExpansion],\n );\n\n return (\n <div className=\"flex flex-col gap-5\">\n <MessageContainer\n isSuccess={true}\n type={props.isAnswer ? 'answer' : 'thinking'}\n content={props}\n >\n <div className=\"prose dark:prose-invert max-w-none text-sm\">\n <Markdown\n remarkPlugins={[remarkGfm]}\n rehypePlugins={[rehypeRaw]}\n components={{\n // @ts-expect-error - Custom HTML element not in react-markdown types\n 'think-block': thinkBlockComponent,\n }}\n >\n {processedContent}\n </Markdown>\n </div>\n </MessageContainer>\n </div>\n );\n});\n"]}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { AnalysisResultSchema } from '../schemas';
|
|
2
|
-
/**
|
|
3
|
-
* Props for the AnalysisResult component
|
|
4
|
-
* @property {AnalysisResultSchema} result - The result of the analysis containing prompt, tool calls, and analysis data
|
|
5
|
-
*/
|
|
6
|
-
type AnalysisResultProps = {
|
|
7
|
-
result: AnalysisResultSchema;
|
|
8
|
-
onDeleteAnalysisResult: (id: string) => void;
|
|
9
|
-
};
|
|
10
|
-
/**
|
|
11
|
-
* Component that displays the results of an AI analysis.
|
|
12
|
-
* Shows the original prompt, intermediate tool calls, final analysis text,
|
|
13
|
-
* and any tool results.
|
|
14
|
-
*
|
|
15
|
-
* @component
|
|
16
|
-
* @param props - Component props
|
|
17
|
-
* @param props.result - The analysis result data to display
|
|
18
|
-
* @returns A React component displaying the analysis results
|
|
19
|
-
*/
|
|
20
|
-
export declare const AnalysisResult: React.FC<AnalysisResultProps>;
|
|
21
|
-
export {};
|
|
22
|
-
//# sourceMappingURL=AnalysisResult.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AnalysisResult.d.ts","sourceRoot":"","sources":["../../src/components/AnalysisResult.tsx"],"names":[],"mappings":"AAuBA,OAAO,EAAC,oBAAoB,EAAC,MAAM,YAAY,CAAC;AAKhD;;;GAGG;AACH,KAAK,mBAAmB,GAAG;IACzB,MAAM,EAAE,oBAAoB,CAAC;IAC7B,sBAAsB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C,CAAC;AAaF;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CA8FxD,CAAC"}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Button, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, CopyButton, } from '@sqlrooms/ui';
|
|
3
|
-
import { SquareTerminalIcon, TrashIcon, } from 'lucide-react';
|
|
4
|
-
import { useState } from 'react';
|
|
5
|
-
import { AnalysisAnswer } from './AnalysisAnswer';
|
|
6
|
-
import { ErrorMessage } from './ErrorMessage';
|
|
7
|
-
import { ToolResult } from './tools/ToolResult';
|
|
8
|
-
/**
|
|
9
|
-
* Stringify the result of the analysis, excluding toolCallMessages.
|
|
10
|
-
* Used to display raw result data in a code view.
|
|
11
|
-
*
|
|
12
|
-
* @param result - The complete analysis result
|
|
13
|
-
* @returns A JSON string representation of the result without toolCallMessages
|
|
14
|
-
*/
|
|
15
|
-
const stringifyResult = (result) => {
|
|
16
|
-
return JSON.stringify(result, null, 2);
|
|
17
|
-
};
|
|
18
|
-
/**
|
|
19
|
-
* Component that displays the results of an AI analysis.
|
|
20
|
-
* Shows the original prompt, intermediate tool calls, final analysis text,
|
|
21
|
-
* and any tool results.
|
|
22
|
-
*
|
|
23
|
-
* @component
|
|
24
|
-
* @param props - Component props
|
|
25
|
-
* @param props.result - The analysis result data to display
|
|
26
|
-
* @returns A React component displaying the analysis results
|
|
27
|
-
*/
|
|
28
|
-
export const AnalysisResult = ({ result, onDeleteAnalysisResult, }) => {
|
|
29
|
-
// the toolResults are reasoning steps that the LLM took to achieve the final result
|
|
30
|
-
// by calling function tools to answer the prompt
|
|
31
|
-
const { id, prompt, errorMessage, streamMessage } = result;
|
|
32
|
-
const parts = streamMessage.parts;
|
|
33
|
-
const [showDeleteConfirmation, setShowDeleteConfirmation] = useState(false);
|
|
34
|
-
return (_jsxs("div", { className: "group flex w-full flex-col gap-2 pb-2 text-sm", children: [_jsx("div", { className: "mb-2 flex items-center gap-2 rounded-md text-gray-700 dark:text-gray-100", children: _jsxs("div", { className: "bg-muted flex w-full items-center gap-2 rounded-md border p-2 text-sm", children: [_jsx(SquareTerminalIcon, { className: "h-4 w-4" }), _jsx("div", { className: "flex-1", children: prompt }), _jsxs("div", { className: "flex gap-2 opacity-0 transition-opacity group-hover:opacity-100", children: [_jsx(CopyButton, { text: prompt, variant: "ghost", size: "icon", className: "h-6 w-6", ariaLabel: "Copy prompt" }), _jsx(Button, { variant: "ghost", size: "icon", className: "h-6 w-6", onClick: () => setShowDeleteConfirmation(true), children: _jsx(TrashIcon, { className: "h-4 w-4" }) }), _jsx(Dialog, { open: showDeleteConfirmation, onOpenChange: setShowDeleteConfirmation, children: _jsxs(DialogContent, { className: "sm:max-w-[425px]", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Confirm Deletion" }), _jsx(DialogDescription, { children: "Are you sure you want to delete this analysis result? This action cannot be undone." })] }), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "outline", onClick: () => setShowDeleteConfirmation(false), children: "Cancel" }), _jsx(Button, { variant: "destructive", onClick: () => {
|
|
35
|
-
onDeleteAnalysisResult(id);
|
|
36
|
-
setShowDeleteConfirmation(false);
|
|
37
|
-
}, children: "Delete" })] })] }) })] })] }) }), parts?.map((part, index) => (_jsxs("div", { children: [part.type === 'text' && (_jsx(AnalysisAnswer, { content: part.text, isAnswer: index === (streamMessage.parts?.length || 0) - 1 })), part.type === 'tool-invocation' && (_jsx("div", { children: _jsx(ToolResult, { toolInvocation: part.toolInvocation, additionalData: part.additionalData, isCompleted: result.isCompleted }, part.toolInvocation.toolCallId) }))] }, index))), errorMessage && _jsx(ErrorMessage, { errorMessage: errorMessage.error })] }));
|
|
38
|
-
};
|
|
39
|
-
//# sourceMappingURL=AnalysisResult.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AnalysisResult.js","sourceRoot":"","sources":["../../src/components/AnalysisResult.tsx"],"names":[],"mappings":"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","sourcesContent":["import {JsonMonacoEditor} from '@sqlrooms/monaco-editor';\nimport {\n Button,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Popover,\n PopoverContent,\n PopoverTrigger,\n CopyButton,\n} from '@sqlrooms/ui';\nimport {StreamMessagePart} from '@openassistant/core';\nimport {\n ClipboardIcon,\n CodeIcon,\n SquareTerminalIcon,\n TrashIcon,\n CheckIcon,\n} from 'lucide-react';\nimport {useState} from 'react';\nimport {AnalysisResultSchema} from '../schemas';\nimport {AnalysisAnswer} from './AnalysisAnswer';\nimport {ErrorMessage} from './ErrorMessage';\nimport {ToolResult} from './tools/ToolResult';\n\n/**\n * Props for the AnalysisResult component\n * @property {AnalysisResultSchema} result - The result of the analysis containing prompt, tool calls, and analysis data\n */\ntype AnalysisResultProps = {\n result: AnalysisResultSchema;\n onDeleteAnalysisResult: (id: string) => void;\n};\n\n/**\n * Stringify the result of the analysis, excluding toolCallMessages.\n * Used to display raw result data in a code view.\n *\n * @param result - The complete analysis result\n * @returns A JSON string representation of the result without toolCallMessages\n */\nconst stringifyResult = (result: AnalysisResultSchema) => {\n return JSON.stringify(result, null, 2);\n};\n\n/**\n * Component that displays the results of an AI analysis.\n * Shows the original prompt, intermediate tool calls, final analysis text,\n * and any tool results.\n *\n * @component\n * @param props - Component props\n * @param props.result - The analysis result data to display\n * @returns A React component displaying the analysis results\n */\nexport const AnalysisResult: React.FC<AnalysisResultProps> = ({\n result,\n onDeleteAnalysisResult,\n}) => {\n // the toolResults are reasoning steps that the LLM took to achieve the final result\n // by calling function tools to answer the prompt\n const {id, prompt, errorMessage, streamMessage} = result;\n const parts = streamMessage.parts as StreamMessagePart[];\n const [showDeleteConfirmation, setShowDeleteConfirmation] = useState(false);\n\n return (\n <div className=\"group flex w-full flex-col gap-2 pb-2 text-sm\">\n <div className=\"mb-2 flex items-center gap-2 rounded-md text-gray-700 dark:text-gray-100\">\n <div className=\"bg-muted flex w-full items-center gap-2 rounded-md border p-2 text-sm\">\n <SquareTerminalIcon className=\"h-4 w-4\" />\n {/** render prompt */}\n <div className=\"flex-1\">{prompt}</div>\n <div className=\"flex gap-2 opacity-0 transition-opacity group-hover:opacity-100\">\n <CopyButton\n text={prompt}\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6\"\n ariaLabel=\"Copy prompt\"\n />\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6\"\n onClick={() => setShowDeleteConfirmation(true)}\n >\n <TrashIcon className=\"h-4 w-4\" />\n </Button>\n\n {/* Delete Confirmation Dialog */}\n <Dialog\n open={showDeleteConfirmation}\n onOpenChange={setShowDeleteConfirmation}\n >\n <DialogContent className=\"sm:max-w-[425px]\">\n <DialogHeader>\n <DialogTitle>Confirm Deletion</DialogTitle>\n <DialogDescription>\n Are you sure you want to delete this analysis result? This\n action cannot be undone.\n </DialogDescription>\n </DialogHeader>\n <DialogFooter>\n <Button\n variant=\"outline\"\n onClick={() => setShowDeleteConfirmation(false)}\n >\n Cancel\n </Button>\n <Button\n variant=\"destructive\"\n onClick={() => {\n onDeleteAnalysisResult(id);\n setShowDeleteConfirmation(false);\n }}\n >\n Delete\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </div>\n </div>\n </div>\n {/** render parts */}\n {parts?.map((part, index) => (\n <div key={index}>\n {part.type === 'text' && (\n <AnalysisAnswer\n content={part.text}\n isAnswer={index === (streamMessage.parts?.length || 0) - 1}\n />\n )}\n {part.type === 'tool-invocation' && (\n <div>\n <ToolResult\n key={part.toolInvocation.toolCallId}\n toolInvocation={part.toolInvocation}\n additionalData={part.additionalData}\n isCompleted={result.isCompleted}\n />\n </div>\n )}\n </div>\n ))}\n {/** render error message */}\n {errorMessage && <ErrorMessage errorMessage={errorMessage.error} />}\n </div>\n );\n};\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AnalysisResultsContainer.d.ts","sourceRoot":"","sources":["../../src/components/AnalysisResultsContainer.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAe,MAAM,OAAO,CAAC;AAKpC,eAAO,MAAM,wBAAwB,EAAE,KAAK,CAAC,EAAE,CAAC;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAoDA,CAAC"}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { cn, ScrollArea, ScrollBar, SkeletonPane } from '@sqlrooms/ui';
|
|
3
|
-
import { ChevronDown } from 'lucide-react';
|
|
4
|
-
import { useRef } from 'react';
|
|
5
|
-
import { useStoreWithAi } from '../AiSlice';
|
|
6
|
-
import { useScrollToBottom } from '../hooks/useScrollToBottom';
|
|
7
|
-
import { AnalysisResult } from './AnalysisResult';
|
|
8
|
-
export const AnalysisResultsContainer = ({ className }) => {
|
|
9
|
-
const isRunningAnalysis = useStoreWithAi((s) => s.ai.isRunningAnalysis);
|
|
10
|
-
const currentSession = useStoreWithAi((s) => s.ai.getCurrentSession());
|
|
11
|
-
const deleteAnalysisResult = useStoreWithAi((s) => s.ai.deleteAnalysisResult);
|
|
12
|
-
const containerRef = useRef(null);
|
|
13
|
-
const endRef = useRef(null);
|
|
14
|
-
const { showScrollButton, scrollToBottom } = useScrollToBottom({
|
|
15
|
-
containerRef,
|
|
16
|
-
endRef,
|
|
17
|
-
dataToObserve: currentSession?.analysisResults,
|
|
18
|
-
});
|
|
19
|
-
const onDeleteAnalysisResult = (id) => {
|
|
20
|
-
if (currentSession) {
|
|
21
|
-
deleteAnalysisResult(currentSession.id, id);
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
|
-
return (_jsxs("div", { className: cn('relative flex h-full w-full flex-col', className), children: [_jsxs(ScrollArea, { ref: containerRef, className: "flex w-full flex-grow flex-col gap-5", children: [currentSession?.analysisResults.map((result) => (_jsx(AnalysisResult, { result: result, onDeleteAnalysisResult: onDeleteAnalysisResult }, result.id))), isRunningAnalysis && _jsx(SkeletonPane, { className: "p-4" }), _jsx("div", { ref: endRef, className: "h-10 w-full shrink-0" }), _jsx(ScrollBar, { orientation: "vertical" }), _jsx(ScrollBar, { orientation: "horizontal" })] }), _jsx("div", { className: "pointer-events-none absolute inset-x-0 bottom-0 flex justify-center", children: _jsx("button", { onClick: scrollToBottom, className: cn('bg-primary hover:bg-primary/90 text-primary-foreground pointer-events-auto z-50', 'mb-6 translate-y-4 rounded-full p-2 opacity-0 shadow-md transition-all duration-200', showScrollButton && 'translate-y-0 opacity-100'), "aria-label": "Scroll to bottom", children: _jsx(ChevronDown, { className: "h-5 w-5" }) }) })] }));
|
|
25
|
-
};
|
|
26
|
-
//# sourceMappingURL=AnalysisResultsContainer.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AnalysisResultsContainer.js","sourceRoot":"","sources":["../../src/components/AnalysisResultsContainer.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAC,MAAM,cAAc,CAAC;AACrE,OAAO,EAAC,WAAW,EAAC,MAAM,cAAc,CAAC;AACzC,OAAc,EAAC,MAAM,EAAC,MAAM,OAAO,CAAC;AACpC,OAAO,EAAC,cAAc,EAAC,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAC,iBAAiB,EAAC,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAC;AAEhD,MAAM,CAAC,MAAM,wBAAwB,GAEhC,CAAC,EAAC,SAAS,EAAC,EAAE,EAAE;IACnB,MAAM,iBAAiB,GAAG,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC;IACxE,MAAM,cAAc,GAAG,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACvE,MAAM,oBAAoB,GAAG,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,oBAAoB,CAAC,CAAC;IAE9E,MAAM,YAAY,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAC5C,MAAM,EAAC,gBAAgB,EAAE,cAAc,EAAC,GAAG,iBAAiB,CAAC;QAC3D,YAAY;QACZ,MAAM;QACN,aAAa,EAAE,cAAc,EAAE,eAAe;KAC/C,CAAC,CAAC;IAEH,MAAM,sBAAsB,GAAG,CAAC,EAAU,EAAE,EAAE;QAC5C,IAAI,cAAc,EAAE,CAAC;YACnB,oBAAoB,CAAC,cAAc,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,CACL,eAAK,SAAS,EAAE,EAAE,CAAC,sCAAsC,EAAE,SAAS,CAAC,aACnE,MAAC,UAAU,IACT,GAAG,EAAE,YAAY,EACjB,SAAS,EAAC,sCAAsC,aAE/C,cAAc,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAC/C,KAAC,cAAc,IAEb,MAAM,EAAE,MAAM,EACd,sBAAsB,EAAE,sBAAsB,IAFzC,MAAM,CAAC,EAAE,CAGd,CACH,CAAC,EACD,iBAAiB,IAAI,KAAC,YAAY,IAAC,SAAS,EAAC,KAAK,GAAG,EACtD,cAAK,GAAG,EAAE,MAAM,EAAE,SAAS,EAAC,sBAAsB,GAAG,EACrD,KAAC,SAAS,IAAC,WAAW,EAAC,UAAU,GAAG,EACpC,KAAC,SAAS,IAAC,WAAW,EAAC,YAAY,GAAG,IAC3B,EACb,cAAK,SAAS,EAAC,qEAAqE,YAClF,iBACE,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,EAAE,CACX,iFAAiF,EACjF,qFAAqF,EACrF,gBAAgB,IAAI,2BAA2B,CAChD,gBACU,kBAAkB,YAE7B,KAAC,WAAW,IAAC,SAAS,EAAC,SAAS,GAAG,GAC5B,GACL,IACF,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {cn, ScrollArea, ScrollBar, SkeletonPane} from '@sqlrooms/ui';\nimport {ChevronDown} from 'lucide-react';\nimport React, {useRef} from 'react';\nimport {useStoreWithAi} from '../AiSlice';\nimport {useScrollToBottom} from '../hooks/useScrollToBottom';\nimport {AnalysisResult} from './AnalysisResult';\n\nexport const AnalysisResultsContainer: React.FC<{\n className?: string;\n}> = ({className}) => {\n const isRunningAnalysis = useStoreWithAi((s) => s.ai.isRunningAnalysis);\n const currentSession = useStoreWithAi((s) => s.ai.getCurrentSession());\n const deleteAnalysisResult = useStoreWithAi((s) => s.ai.deleteAnalysisResult);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const endRef = useRef<HTMLDivElement>(null);\n const {showScrollButton, scrollToBottom} = useScrollToBottom({\n containerRef,\n endRef,\n dataToObserve: currentSession?.analysisResults,\n });\n\n const onDeleteAnalysisResult = (id: string) => {\n if (currentSession) {\n deleteAnalysisResult(currentSession.id, id);\n }\n };\n\n return (\n <div className={cn('relative flex h-full w-full flex-col', className)}>\n <ScrollArea\n ref={containerRef}\n className=\"flex w-full flex-grow flex-col gap-5\"\n >\n {currentSession?.analysisResults.map((result) => (\n <AnalysisResult\n key={result.id}\n result={result}\n onDeleteAnalysisResult={onDeleteAnalysisResult}\n />\n ))}\n {isRunningAnalysis && <SkeletonPane className=\"p-4\" />}\n <div ref={endRef} className=\"h-10 w-full shrink-0\" />\n <ScrollBar orientation=\"vertical\" />\n <ScrollBar orientation=\"horizontal\" />\n </ScrollArea>\n <div className=\"pointer-events-none absolute inset-x-0 bottom-0 flex justify-center\">\n <button\n onClick={scrollToBottom}\n className={cn(\n 'bg-primary hover:bg-primary/90 text-primary-foreground pointer-events-auto z-50',\n 'mb-6 translate-y-4 rounded-full p-2 opacity-0 shadow-md transition-all duration-200',\n showScrollButton && 'translate-y-0 opacity-100',\n )}\n aria-label=\"Scroll to bottom\"\n >\n <ChevronDown className=\"h-5 w-5\" />\n </button>\n </div>\n </div>\n );\n};\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ErrorMessage.d.ts","sourceRoot":"","sources":["../../src/components/ErrorMessage.tsx"],"names":[],"mappings":"AAIA,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAAC,YAAY,EAAE,MAAM,CAAA;CAAC,2CAQzD"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import Markdown from 'react-markdown';
|
|
3
|
-
import remarkGfm from 'remark-gfm';
|
|
4
|
-
import { MessageContainer } from './MessageContainer';
|
|
5
|
-
export function ErrorMessage(props) {
|
|
6
|
-
return (_jsx(MessageContainer, { isSuccess: false, type: "error", content: props, children: _jsx("div", { className: "prose dark:prose-invert max-w-none text-sm", children: _jsx(Markdown, { remarkPlugins: [remarkGfm], children: props.errorMessage }) }) }));
|
|
7
|
-
}
|
|
8
|
-
//# sourceMappingURL=ErrorMessage.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ErrorMessage.js","sourceRoot":"","sources":["../../src/components/ErrorMessage.tsx"],"names":[],"mappings":";AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AAEpD,MAAM,UAAU,YAAY,CAAC,KAA6B;IACxD,OAAO,CACL,KAAC,gBAAgB,IAAC,SAAS,EAAE,KAAK,EAAE,IAAI,EAAC,OAAO,EAAC,OAAO,EAAE,KAAK,YAC7D,cAAK,SAAS,EAAC,4CAA4C,YACzD,KAAC,QAAQ,IAAC,aAAa,EAAE,CAAC,SAAS,CAAC,YAAG,KAAK,CAAC,YAAY,GAAY,GACjE,GACW,CACpB,CAAC;AACJ,CAAC","sourcesContent":["import Markdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport {MessageContainer} from './MessageContainer';\n\nexport function ErrorMessage(props: {errorMessage: string}) {\n return (\n <MessageContainer isSuccess={false} type=\"error\" content={props}>\n <div className=\"prose dark:prose-invert max-w-none text-sm\">\n <Markdown remarkPlugins={[remarkGfm]}>{props.errorMessage}</Markdown>\n </div>\n </MessageContainer>\n );\n}\n"]}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
type MessageContainerProps = {
|
|
2
|
-
className?: string;
|
|
3
|
-
isSuccess: boolean;
|
|
4
|
-
type: string;
|
|
5
|
-
content: object;
|
|
6
|
-
children: React.ReactNode;
|
|
7
|
-
};
|
|
8
|
-
export declare const MessageContainer: React.FC<MessageContainerProps>;
|
|
9
|
-
export {};
|
|
10
|
-
//# sourceMappingURL=MessageContainer.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"MessageContainer.d.ts","sourceRoot":"","sources":["../../src/components/MessageContainer.tsx"],"names":[],"mappings":"AAWA,KAAK,qBAAqB,GAAG;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IAEnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAsC5D,CAAC"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Badge, cn, } from '@sqlrooms/ui';
|
|
3
|
-
import { XCircleIcon } from 'lucide-react';
|
|
4
|
-
export const MessageContainer = ({ className, type,
|
|
5
|
-
// borderColor,
|
|
6
|
-
content, children, }) => {
|
|
7
|
-
return (_jsxs("div", { className: cn('group relative px-5 py-2 text-xs', className, type === 'error' && 'border-destructive rounded-md border py-4'), children: [type === 'error' && (_jsxs(Badge, { variant: "secondary", className: cn('absolute left-2 top-[-12px] flex items-center gap-1 border text-xs', 'border-destructive bg-background'), children: [_jsx(XCircleIcon, { className: "h-3 w-3 text-red-500" }), type] })), _jsx("div", { className: "flex flex-col gap-5", children: children })] }));
|
|
8
|
-
};
|
|
9
|
-
//# sourceMappingURL=MessageContainer.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"MessageContainer.js","sourceRoot":"","sources":["../../src/components/MessageContainer.tsx"],"names":[],"mappings":";AACA,OAAO,EACL,KAAK,EAEL,EAAE,GAIH,MAAM,cAAc,CAAC;AACtB,OAAO,EAAW,WAAW,EAAC,MAAM,cAAc,CAAC;AAWnD,MAAM,CAAC,MAAM,gBAAgB,GAAoC,CAAC,EAChE,SAAS,EACT,IAAI;AACJ,eAAe;AACf,OAAO,EACP,QAAQ,GACT,EAAE,EAAE;IACH,OAAO,CACL,eACE,SAAS,EAAE,EAAE,CACX,kCAAkC,EAClC,SAAS,EACT,IAAI,KAAK,OAAO,IAAI,2CAA2C,CAGhE,aAEA,IAAI,KAAK,OAAO,IAAI,CACnB,MAAC,KAAK,IACJ,OAAO,EAAC,WAAW,EACnB,SAAS,EAAE,EAAE,CACX,oEAAoE,EACpE,kCAAkC,CAEnC,aAKD,KAAC,WAAW,IAAC,SAAS,EAAC,sBAAsB,GAAG,EAE/C,IAAI,IACC,CACT,EAED,cAAK,SAAS,EAAC,qBAAqB,YAAE,QAAQ,GAAO,IACjD,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {JsonMonacoEditor} from '@sqlrooms/monaco-editor';\nimport {\n Badge,\n Button,\n cn,\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@sqlrooms/ui';\nimport {CodeIcon, XCircleIcon} from 'lucide-react';\n\ntype MessageContainerProps = {\n className?: string;\n isSuccess: boolean;\n // borderColor: string;\n type: string;\n content: object;\n children: React.ReactNode;\n};\n\nexport const MessageContainer: React.FC<MessageContainerProps> = ({\n className,\n type,\n // borderColor,\n content,\n children,\n}) => {\n return (\n <div\n className={cn(\n 'group relative px-5 py-2 text-xs',\n className,\n type === 'error' && 'border-destructive rounded-md border py-4',\n // borderColor,\n // isSuccess ? borderColor : 'border-red-500',\n )}\n >\n {type === 'error' && (\n <Badge\n variant=\"secondary\"\n className={cn(\n 'absolute left-2 top-[-12px] flex items-center gap-1 border text-xs',\n 'border-destructive bg-background',\n // isSuccess ? borderColor : 'border-red-500',\n )}\n >\n {/* {isSuccess ? ( */}\n {/* <CheckCircle2Icon className=\"h-3 w-3 text-green-500\" /> */}\n {/* ) : ( */}\n <XCircleIcon className=\"h-3 w-3 text-red-500\" />\n {/* )} */}\n {type}\n </Badge>\n )}\n\n <div className=\"flex flex-col gap-5\">{children}</div>\n </div>\n );\n};\n"]}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
interface Model {
|
|
3
|
-
provider: string;
|
|
4
|
-
label: string;
|
|
5
|
-
value: string;
|
|
6
|
-
}
|
|
7
|
-
interface ModelSelectorProps {
|
|
8
|
-
className?: string;
|
|
9
|
-
models: Model[];
|
|
10
|
-
}
|
|
11
|
-
export declare const ModelSelector: React.FC<ModelSelectorProps>;
|
|
12
|
-
export {};
|
|
13
|
-
//# sourceMappingURL=ModelSelector.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ModelSelector.d.ts","sourceRoot":"","sources":["../../src/components/ModelSelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAa1B,UAAU,KAAK;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,kBAAkB;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,KAAK,EAAE,CAAC;CACjB;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CA6DtD,CAAC"}
|