flowquery 1.0.3 → 1.0.6
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 +182 -0
- package/dist/compute/runner.d.ts +81 -0
- package/dist/compute/runner.d.ts.map +1 -0
- package/dist/extensibility.d.ts +9 -0
- package/dist/extensibility.d.ts.map +1 -0
- package/dist/extensibility.js +25 -0
- package/dist/extensibility.js.map +1 -0
- package/dist/flowquery.min.js +1 -1
- package/dist/index.browser.d.ts +10 -0
- package/dist/index.browser.d.ts.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.node.d.ts +14 -0
- package/dist/index.node.d.ts.map +1 -0
- package/dist/io/command_line.d.ts +28 -0
- package/dist/io/command_line.d.ts.map +1 -0
- package/dist/parsing/alias.d.ts +10 -0
- package/dist/parsing/alias.d.ts.map +1 -0
- package/dist/parsing/alias_option.d.ts +6 -0
- package/dist/parsing/alias_option.d.ts.map +1 -0
- package/dist/parsing/ast_node.d.ts +100 -0
- package/dist/parsing/ast_node.d.ts.map +1 -0
- package/dist/parsing/base_parser.d.ts +49 -0
- package/dist/parsing/base_parser.d.ts.map +1 -0
- package/dist/parsing/components/csv.d.ts +6 -0
- package/dist/parsing/components/csv.d.ts.map +1 -0
- package/dist/parsing/components/from.d.ts +7 -0
- package/dist/parsing/components/from.d.ts.map +1 -0
- package/dist/parsing/components/headers.d.ts +7 -0
- package/dist/parsing/components/headers.d.ts.map +1 -0
- package/dist/parsing/components/json.d.ts +6 -0
- package/dist/parsing/components/json.d.ts.map +1 -0
- package/dist/parsing/components/null.d.ts +6 -0
- package/dist/parsing/components/null.d.ts.map +1 -0
- package/dist/parsing/components/post.d.ts +6 -0
- package/dist/parsing/components/post.d.ts.map +1 -0
- package/dist/parsing/components/text.d.ts +6 -0
- package/dist/parsing/components/text.d.ts.map +1 -0
- package/dist/parsing/context.d.ts +38 -0
- package/dist/parsing/context.d.ts.map +1 -0
- package/dist/parsing/data_structures/associative_array.d.ts +28 -0
- package/dist/parsing/data_structures/associative_array.d.ts.map +1 -0
- package/dist/parsing/data_structures/json_array.d.ts +26 -0
- package/dist/parsing/data_structures/json_array.d.ts.map +1 -0
- package/dist/parsing/data_structures/key_value_pair.d.ts +25 -0
- package/dist/parsing/data_structures/key_value_pair.d.ts.map +1 -0
- package/dist/parsing/data_structures/lookup.d.ts +25 -0
- package/dist/parsing/data_structures/lookup.d.ts.map +1 -0
- package/dist/parsing/data_structures/range_lookup.d.ts +14 -0
- package/dist/parsing/data_structures/range_lookup.d.ts.map +1 -0
- package/dist/parsing/expressions/expression.d.ts +53 -0
- package/dist/parsing/expressions/expression.d.ts.map +1 -0
- package/dist/parsing/expressions/f_string.d.ts +21 -0
- package/dist/parsing/expressions/f_string.d.ts.map +1 -0
- package/dist/parsing/expressions/identifier.d.ts +17 -0
- package/dist/parsing/expressions/identifier.d.ts.map +1 -0
- package/dist/parsing/expressions/number.d.ts +25 -0
- package/dist/parsing/expressions/number.d.ts.map +1 -0
- package/dist/parsing/expressions/operator.d.ts +79 -0
- package/dist/parsing/expressions/operator.d.ts.map +1 -0
- package/dist/parsing/expressions/reference.d.ts +29 -0
- package/dist/parsing/expressions/reference.d.ts.map +1 -0
- package/dist/parsing/expressions/string.d.ts +23 -0
- package/dist/parsing/expressions/string.d.ts.map +1 -0
- package/dist/parsing/functions/aggregate_function.d.ts +42 -0
- package/dist/parsing/functions/aggregate_function.d.ts.map +1 -0
- package/dist/parsing/functions/async_function.d.ts +52 -0
- package/dist/parsing/functions/async_function.d.ts.map +1 -0
- package/dist/parsing/functions/avg.d.ts +15 -0
- package/dist/parsing/functions/avg.d.ts.map +1 -0
- package/dist/parsing/functions/avg.js +20 -2
- package/dist/parsing/functions/avg.js.map +1 -1
- package/dist/parsing/functions/collect.d.ts +21 -0
- package/dist/parsing/functions/collect.d.ts.map +1 -0
- package/dist/parsing/functions/collect.js +20 -2
- package/dist/parsing/functions/collect.js.map +1 -1
- package/dist/parsing/functions/extensibility/index.d.ts +37 -0
- package/dist/parsing/functions/extensibility/index.d.ts.map +1 -0
- package/dist/parsing/functions/extensibility/index.js +50 -0
- package/dist/parsing/functions/extensibility/index.js.map +1 -0
- package/dist/parsing/functions/function.d.ts +36 -0
- package/dist/parsing/functions/function.d.ts.map +1 -0
- package/dist/parsing/functions/function_factory.d.ts +174 -0
- package/dist/parsing/functions/function_factory.d.ts.map +1 -0
- package/dist/parsing/functions/function_factory.js +44 -47
- package/dist/parsing/functions/function_factory.js.map +1 -1
- package/dist/parsing/functions/function_metadata.d.ts +134 -0
- package/dist/parsing/functions/function_metadata.d.ts.map +1 -0
- package/dist/parsing/functions/function_metadata.js +103 -153
- package/dist/parsing/functions/function_metadata.js.map +1 -1
- package/dist/parsing/functions/functions.d.ts +21 -0
- package/dist/parsing/functions/functions.d.ts.map +1 -0
- package/dist/parsing/functions/functions.js +37 -2
- package/dist/parsing/functions/functions.js.map +1 -1
- package/dist/parsing/functions/join.d.ts +9 -0
- package/dist/parsing/functions/join.d.ts.map +1 -0
- package/dist/parsing/functions/join.js +21 -2
- package/dist/parsing/functions/join.js.map +1 -1
- package/dist/parsing/functions/predicate_function.d.ts +19 -0
- package/dist/parsing/functions/predicate_function.d.ts.map +1 -0
- package/dist/parsing/functions/predicate_function.js +3 -0
- package/dist/parsing/functions/predicate_function.js.map +1 -1
- package/dist/parsing/functions/predicate_sum.d.ts +7 -0
- package/dist/parsing/functions/predicate_sum.d.ts.map +1 -0
- package/dist/parsing/functions/predicate_sum.js +23 -2
- package/dist/parsing/functions/predicate_sum.js.map +1 -1
- package/dist/parsing/functions/rand.d.ts +7 -0
- package/dist/parsing/functions/rand.d.ts.map +1 -0
- package/dist/parsing/functions/rand.js +18 -2
- package/dist/parsing/functions/rand.js.map +1 -1
- package/dist/parsing/functions/range.d.ts +7 -0
- package/dist/parsing/functions/range.d.ts.map +1 -0
- package/dist/parsing/functions/range.js +21 -2
- package/dist/parsing/functions/range.js.map +1 -1
- package/dist/parsing/functions/reducer_element.d.ts +6 -0
- package/dist/parsing/functions/reducer_element.d.ts.map +1 -0
- package/dist/parsing/functions/replace.d.ts +7 -0
- package/dist/parsing/functions/replace.d.ts.map +1 -0
- package/dist/parsing/functions/replace.js +22 -2
- package/dist/parsing/functions/replace.js.map +1 -1
- package/dist/parsing/functions/round.d.ts +7 -0
- package/dist/parsing/functions/round.d.ts.map +1 -0
- package/dist/parsing/functions/round.js +20 -2
- package/dist/parsing/functions/round.js.map +1 -1
- package/dist/parsing/functions/size.d.ts +7 -0
- package/dist/parsing/functions/size.d.ts.map +1 -0
- package/dist/parsing/functions/size.js +20 -2
- package/dist/parsing/functions/size.js.map +1 -1
- package/dist/parsing/functions/split.d.ts +9 -0
- package/dist/parsing/functions/split.d.ts.map +1 -0
- package/dist/parsing/functions/split.js +21 -2
- package/dist/parsing/functions/split.js.map +1 -1
- package/dist/parsing/functions/stringify.d.ts +9 -0
- package/dist/parsing/functions/stringify.d.ts.map +1 -0
- package/dist/parsing/functions/stringify.js +20 -2
- package/dist/parsing/functions/stringify.js.map +1 -1
- package/dist/parsing/functions/sum.d.ts +14 -0
- package/dist/parsing/functions/sum.d.ts.map +1 -0
- package/dist/parsing/functions/sum.js +20 -2
- package/dist/parsing/functions/sum.js.map +1 -1
- package/dist/parsing/functions/to_json.d.ts +7 -0
- package/dist/parsing/functions/to_json.d.ts.map +1 -0
- package/dist/parsing/functions/to_json.js +20 -2
- package/dist/parsing/functions/to_json.js.map +1 -1
- package/dist/parsing/functions/value_holder.d.ts +8 -0
- package/dist/parsing/functions/value_holder.d.ts.map +1 -0
- package/dist/parsing/logic/case.d.ts +7 -0
- package/dist/parsing/logic/case.d.ts.map +1 -0
- package/dist/parsing/logic/else.d.ts +7 -0
- package/dist/parsing/logic/else.d.ts.map +1 -0
- package/dist/parsing/logic/end.d.ts +6 -0
- package/dist/parsing/logic/end.d.ts.map +1 -0
- package/dist/parsing/logic/then.d.ts +7 -0
- package/dist/parsing/logic/then.d.ts.map +1 -0
- package/dist/parsing/logic/when.d.ts +7 -0
- package/dist/parsing/logic/when.d.ts.map +1 -0
- package/dist/parsing/operations/aggregated_return.d.ts +8 -0
- package/dist/parsing/operations/aggregated_return.d.ts.map +1 -0
- package/dist/parsing/operations/aggregated_with.d.ts +8 -0
- package/dist/parsing/operations/aggregated_with.d.ts.map +1 -0
- package/dist/parsing/operations/group_by.d.ts +35 -0
- package/dist/parsing/operations/group_by.d.ts.map +1 -0
- package/dist/parsing/operations/limit.d.ts +10 -0
- package/dist/parsing/operations/limit.d.ts.map +1 -0
- package/dist/parsing/operations/load.d.ts +48 -0
- package/dist/parsing/operations/load.d.ts.map +1 -0
- package/dist/parsing/operations/operation.d.ts +39 -0
- package/dist/parsing/operations/operation.d.ts.map +1 -0
- package/dist/parsing/operations/projection.d.ts +8 -0
- package/dist/parsing/operations/projection.d.ts.map +1 -0
- package/dist/parsing/operations/return.d.ts +23 -0
- package/dist/parsing/operations/return.d.ts.map +1 -0
- package/dist/parsing/operations/unwind.d.ts +12 -0
- package/dist/parsing/operations/unwind.d.ts.map +1 -0
- package/dist/parsing/operations/where.d.ts +26 -0
- package/dist/parsing/operations/where.d.ts.map +1 -0
- package/dist/parsing/operations/with.d.ts +17 -0
- package/dist/parsing/operations/with.d.ts.map +1 -0
- package/dist/parsing/parser.d.ts +66 -0
- package/dist/parsing/parser.d.ts.map +1 -0
- package/dist/parsing/parser.js +2 -3
- package/dist/parsing/parser.js.map +1 -1
- package/dist/parsing/token_to_node.d.ts +7 -0
- package/dist/parsing/token_to_node.d.ts.map +1 -0
- package/dist/tokenization/keyword.d.ts +43 -0
- package/dist/tokenization/keyword.d.ts.map +1 -0
- package/dist/tokenization/operator.d.ts +22 -0
- package/dist/tokenization/operator.d.ts.map +1 -0
- package/dist/tokenization/string_walker.d.ts +55 -0
- package/dist/tokenization/string_walker.d.ts.map +1 -0
- package/dist/tokenization/symbol.d.ts +15 -0
- package/dist/tokenization/symbol.d.ts.map +1 -0
- package/dist/tokenization/token.d.ts +176 -0
- package/dist/tokenization/token.d.ts.map +1 -0
- package/dist/tokenization/token_mapper.d.ts +40 -0
- package/dist/tokenization/token_mapper.d.ts.map +1 -0
- package/dist/tokenization/token_type.d.ts +16 -0
- package/dist/tokenization/token_type.d.ts.map +1 -0
- package/dist/tokenization/tokenizer.d.ts +45 -0
- package/dist/tokenization/tokenizer.d.ts.map +1 -0
- package/dist/tokenization/trie.d.ts +41 -0
- package/dist/tokenization/trie.d.ts.map +1 -0
- package/dist/utils/object_utils.d.ts +15 -0
- package/dist/utils/object_utils.d.ts.map +1 -0
- package/dist/utils/string_utils.d.ts +51 -0
- package/dist/utils/string_utils.d.ts.map +1 -0
- package/docs/flowquery.min.js +1 -1
- package/flowquery-vscode/flowQueryEngine/flowquery.min.js +1 -1
- package/misc/apps/RAG/.env.example +14 -0
- package/misc/apps/RAG/README.md +0 -7
- package/misc/apps/RAG/package.json +16 -7
- package/misc/apps/RAG/public/index.html +18 -0
- package/misc/apps/RAG/src/App.css +42 -0
- package/misc/apps/RAG/src/App.tsx +50 -0
- package/misc/apps/RAG/src/components/ApiKeySettings.tsx +245 -0
- package/misc/apps/RAG/src/components/ChatContainer.css +67 -0
- package/misc/apps/RAG/src/components/ChatContainer.tsx +239 -0
- package/misc/apps/RAG/src/components/ChatInput.css +23 -0
- package/misc/apps/RAG/src/components/ChatInput.tsx +62 -0
- package/misc/apps/RAG/src/components/ChatMessage.css +136 -0
- package/misc/apps/RAG/src/components/ChatMessage.tsx +152 -0
- package/misc/apps/RAG/src/components/FlowQueryAgent.ts +390 -0
- package/misc/apps/RAG/src/components/FlowQueryRunner.css +104 -0
- package/misc/apps/RAG/src/components/FlowQueryRunner.tsx +332 -0
- package/misc/apps/RAG/src/components/index.ts +15 -0
- package/misc/apps/RAG/src/index.tsx +17 -0
- package/misc/apps/RAG/src/plugins/PluginRegistry.ts +136 -0
- package/misc/apps/RAG/src/plugins/README.md +139 -0
- package/misc/apps/RAG/src/plugins/index.ts +72 -0
- package/misc/apps/RAG/src/plugins/loaders/CatFacts.ts +79 -0
- package/misc/apps/RAG/src/plugins/loaders/FetchJson.ts +71 -0
- package/misc/apps/RAG/src/plugins/loaders/Llm.ts +441 -0
- package/misc/apps/RAG/src/plugins/loaders/MockData.ts +161 -0
- package/misc/apps/RAG/src/plugins/types.ts +52 -0
- package/misc/apps/RAG/src/prompts/FlowQuerySystemPrompt.ts +385 -0
- package/misc/apps/RAG/src/prompts/index.ts +10 -0
- package/misc/apps/RAG/src/utils/FlowQueryExecutor.ts +131 -0
- package/misc/apps/RAG/src/utils/FlowQueryExtractor.ts +203 -0
- package/misc/apps/RAG/src/utils/index.ts +9 -0
- package/misc/apps/RAG/tsconfig.json +4 -2
- package/misc/apps/RAG/webpack.config.js +23 -12
- package/package.json +7 -1
- package/src/extensibility.ts +9 -0
- package/src/parsing/functions/avg.ts +10 -0
- package/src/parsing/functions/collect.ts +10 -0
- package/src/parsing/functions/extensibility/index.ts +54 -0
- package/src/parsing/functions/function_factory.ts +51 -48
- package/src/parsing/functions/function_metadata.ts +132 -156
- package/src/parsing/functions/functions.ts +27 -0
- package/src/parsing/functions/join.ts +11 -0
- package/src/parsing/functions/predicate_function.ts +4 -0
- package/src/parsing/functions/predicate_sum.ts +13 -0
- package/src/parsing/functions/rand.ts +8 -0
- package/src/parsing/functions/range.ts +11 -0
- package/src/parsing/functions/replace.ts +12 -0
- package/src/parsing/functions/round.ts +10 -0
- package/src/parsing/functions/size.ts +10 -0
- package/src/parsing/functions/split.ts +11 -0
- package/src/parsing/functions/stringify.ts +10 -0
- package/src/parsing/functions/sum.ts +10 -0
- package/src/parsing/functions/to_json.ts +10 -0
- package/src/parsing/parser.ts +2 -3
- package/tests/parsing/function_plugins.test.ts +11 -11
- package/tsconfig.json +4 -1
- package/dist/parsing/functions/predicate_function_factory.js +0 -19
- package/dist/parsing/functions/predicate_function_factory.js.map +0 -1
- package/misc/apps/RAG/src/index.ts +0 -20
- package/src/parsing/functions/predicate_function_factory.ts +0 -15
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
.chat-message {
|
|
2
|
+
display: flex;
|
|
3
|
+
gap: 12px;
|
|
4
|
+
padding: 16px;
|
|
5
|
+
border-radius: 8px;
|
|
6
|
+
margin-bottom: 8px;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.chat-message-user {
|
|
10
|
+
background-color: #e8f4fd;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.chat-message-assistant {
|
|
14
|
+
background-color: #f5f5f5;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.chat-message-avatar {
|
|
18
|
+
width: 32px;
|
|
19
|
+
height: 32px;
|
|
20
|
+
border-radius: 50%;
|
|
21
|
+
display: flex;
|
|
22
|
+
align-items: center;
|
|
23
|
+
justify-content: center;
|
|
24
|
+
flex-shrink: 0;
|
|
25
|
+
font-size: 18px;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.chat-message-user .chat-message-avatar {
|
|
29
|
+
background-color: #0078d4;
|
|
30
|
+
color: white;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.chat-message-assistant .chat-message-avatar {
|
|
34
|
+
background-color: #6b6b6b;
|
|
35
|
+
color: white;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.chat-message-content {
|
|
39
|
+
flex: 1;
|
|
40
|
+
min-width: 0;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.chat-message-header {
|
|
44
|
+
display: flex;
|
|
45
|
+
align-items: center;
|
|
46
|
+
gap: 8px;
|
|
47
|
+
margin-bottom: 4px;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.chat-message-role {
|
|
51
|
+
font-weight: 600;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.chat-message-time {
|
|
55
|
+
font-size: 12px;
|
|
56
|
+
color: #666;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.chat-message-text {
|
|
60
|
+
white-space: pre-wrap;
|
|
61
|
+
word-break: break-word;
|
|
62
|
+
line-height: 1.5;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.streaming-indicator {
|
|
66
|
+
margin-left: 8px;
|
|
67
|
+
display: inline-block;
|
|
68
|
+
vertical-align: middle;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* FlowQuery code block styling */
|
|
72
|
+
.flowquery-code-block {
|
|
73
|
+
margin: 12px 0;
|
|
74
|
+
border: 1px solid #e0e0e0;
|
|
75
|
+
border-radius: 6px;
|
|
76
|
+
overflow: hidden;
|
|
77
|
+
background-color: #f8f8f8;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.flowquery-code-header {
|
|
81
|
+
display: flex;
|
|
82
|
+
justify-content: space-between;
|
|
83
|
+
align-items: center;
|
|
84
|
+
padding: 6px 12px;
|
|
85
|
+
background-color: #e8e8e8;
|
|
86
|
+
border-bottom: 1px solid #e0e0e0;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.flowquery-code-label {
|
|
90
|
+
font-size: 11px;
|
|
91
|
+
font-weight: 600;
|
|
92
|
+
color: #666;
|
|
93
|
+
text-transform: uppercase;
|
|
94
|
+
letter-spacing: 0.5px;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.flowquery-code-actions {
|
|
98
|
+
display: flex;
|
|
99
|
+
align-items: center;
|
|
100
|
+
gap: 8px;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.flowquery-run-link {
|
|
104
|
+
font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace;
|
|
105
|
+
font-size: 13px;
|
|
106
|
+
font-weight: 600;
|
|
107
|
+
color: #0078d4;
|
|
108
|
+
text-decoration: none;
|
|
109
|
+
cursor: pointer;
|
|
110
|
+
padding: 2px 6px;
|
|
111
|
+
border-radius: 4px;
|
|
112
|
+
transition: background-color 0.15s ease;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.flowquery-run-link:hover {
|
|
116
|
+
background-color: rgba(0, 120, 212, 0.1);
|
|
117
|
+
text-decoration: none;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.flowquery-run-button {
|
|
121
|
+
font-size: 11px;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.flowquery-code-content {
|
|
125
|
+
margin: 0;
|
|
126
|
+
padding: 12px;
|
|
127
|
+
font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace;
|
|
128
|
+
font-size: 13px;
|
|
129
|
+
line-height: 1.4;
|
|
130
|
+
overflow-x: auto;
|
|
131
|
+
white-space: pre-wrap;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.flowquery-code-content code {
|
|
135
|
+
font-family: inherit;
|
|
136
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import React, { useState, useMemo } from 'react';
|
|
2
|
+
import { Body1, Spinner, Button, Tooltip } from '@fluentui/react-components';
|
|
3
|
+
import { PersonFilled, BotFilled, Play16Regular } from '@fluentui/react-icons';
|
|
4
|
+
import { FlowQueryRunner } from './FlowQueryRunner';
|
|
5
|
+
import './ChatMessage.css';
|
|
6
|
+
|
|
7
|
+
export interface Message {
|
|
8
|
+
id: string;
|
|
9
|
+
role: 'user' | 'assistant';
|
|
10
|
+
content: string;
|
|
11
|
+
timestamp: Date;
|
|
12
|
+
isStreaming?: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface ChatMessageProps {
|
|
16
|
+
message: Message;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Extract FlowQuery code blocks from markdown content.
|
|
21
|
+
* Looks for ```flowquery ... ``` code blocks.
|
|
22
|
+
*/
|
|
23
|
+
function extractFlowQueryBlocks(content: string): string[] {
|
|
24
|
+
const regex = /```flowquery\n([\s\S]*?)```/gi;
|
|
25
|
+
const matches: string[] = [];
|
|
26
|
+
let match;
|
|
27
|
+
|
|
28
|
+
while ((match = regex.exec(content)) !== null) {
|
|
29
|
+
if (match[1]?.trim()) {
|
|
30
|
+
matches.push(match[1].trim());
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return matches;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Renders message content with FlowQuery code blocks enhanced with run buttons.
|
|
39
|
+
*/
|
|
40
|
+
const MessageContent: React.FC<{ content: string; isStreaming?: boolean }> = ({ content, isStreaming }) => {
|
|
41
|
+
const [runnerQuery, setRunnerQuery] = useState<string | null>(null);
|
|
42
|
+
|
|
43
|
+
const flowQueryBlocks = useMemo(() => extractFlowQueryBlocks(content), [content]);
|
|
44
|
+
|
|
45
|
+
// If there are no FlowQuery blocks, render plain content
|
|
46
|
+
if (flowQueryBlocks.length === 0) {
|
|
47
|
+
return (
|
|
48
|
+
<>
|
|
49
|
+
{content}
|
|
50
|
+
{isStreaming && <Spinner size="tiny" className="streaming-indicator" />}
|
|
51
|
+
</>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Split content by FlowQuery code blocks and render with buttons
|
|
56
|
+
const parts: React.ReactNode[] = [];
|
|
57
|
+
let lastIndex = 0;
|
|
58
|
+
const regex = /```flowquery\n([\s\S]*?)```/gi;
|
|
59
|
+
let match;
|
|
60
|
+
let partIndex = 0;
|
|
61
|
+
|
|
62
|
+
while ((match = regex.exec(content)) !== null) {
|
|
63
|
+
// Add text before the code block
|
|
64
|
+
if (match.index > lastIndex) {
|
|
65
|
+
parts.push(
|
|
66
|
+
<span key={`text-${partIndex}`}>
|
|
67
|
+
{content.slice(lastIndex, match.index)}
|
|
68
|
+
</span>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const query = match[1]?.trim() || '';
|
|
73
|
+
|
|
74
|
+
// Add the code block with a run button and </> link
|
|
75
|
+
parts.push(
|
|
76
|
+
<div key={`code-${partIndex}`} className="flowquery-code-block">
|
|
77
|
+
<div className="flowquery-code-header">
|
|
78
|
+
<span className="flowquery-code-label">flowquery</span>
|
|
79
|
+
<div className="flowquery-code-actions">
|
|
80
|
+
<Tooltip content="Run in FlowQuery Runner" relationship="label">
|
|
81
|
+
<Button
|
|
82
|
+
appearance="subtle"
|
|
83
|
+
size="small"
|
|
84
|
+
icon={<Play16Regular />}
|
|
85
|
+
className="flowquery-run-button"
|
|
86
|
+
onClick={() => setRunnerQuery(query)}
|
|
87
|
+
>
|
|
88
|
+
Run
|
|
89
|
+
</Button>
|
|
90
|
+
</Tooltip>
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
<pre className="flowquery-code-content">
|
|
94
|
+
<code>{query}</code>
|
|
95
|
+
</pre>
|
|
96
|
+
</div>
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
lastIndex = match.index + match[0].length;
|
|
100
|
+
partIndex++;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Add remaining text after the last code block
|
|
104
|
+
if (lastIndex < content.length) {
|
|
105
|
+
parts.push(
|
|
106
|
+
<span key={`text-${partIndex}`}>
|
|
107
|
+
{content.slice(lastIndex)}
|
|
108
|
+
</span>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return (
|
|
113
|
+
<>
|
|
114
|
+
{parts}
|
|
115
|
+
{isStreaming && <Spinner size="tiny" className="streaming-indicator" />}
|
|
116
|
+
{runnerQuery !== null && (
|
|
117
|
+
<FlowQueryRunner
|
|
118
|
+
initialQuery={runnerQuery}
|
|
119
|
+
open={true}
|
|
120
|
+
onOpenChange={(open) => {
|
|
121
|
+
if (!open) setRunnerQuery(null);
|
|
122
|
+
}}
|
|
123
|
+
/>
|
|
124
|
+
)}
|
|
125
|
+
</>
|
|
126
|
+
);
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export const ChatMessage: React.FC<ChatMessageProps> = ({ message }) => {
|
|
130
|
+
const isUser = message.role === 'user';
|
|
131
|
+
|
|
132
|
+
return (
|
|
133
|
+
<div className={`chat-message ${isUser ? 'chat-message-user' : 'chat-message-assistant'}`}>
|
|
134
|
+
<div className="chat-message-avatar">
|
|
135
|
+
{isUser ? <PersonFilled /> : <BotFilled />}
|
|
136
|
+
</div>
|
|
137
|
+
<div className="chat-message-content">
|
|
138
|
+
<div className="chat-message-header">
|
|
139
|
+
<Body1 className="chat-message-role">
|
|
140
|
+
{isUser ? 'You' : 'Assistant'}
|
|
141
|
+
</Body1>
|
|
142
|
+
<span className="chat-message-time">
|
|
143
|
+
{message.timestamp.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
|
|
144
|
+
</span>
|
|
145
|
+
</div>
|
|
146
|
+
<div className="chat-message-text">
|
|
147
|
+
<MessageContent content={message.content} isStreaming={message.isStreaming} />
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
</div>
|
|
151
|
+
);
|
|
152
|
+
};
|
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FlowQuery Agent
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates the multi-step flow:
|
|
5
|
+
* 1. Send user query to LLM to generate a FlowQuery statement
|
|
6
|
+
* 2. Execute the FlowQuery statement
|
|
7
|
+
* 3. Send results back to LLM for interpretation
|
|
8
|
+
* 4. Return final response to user
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { llm, llmStream, LlmOptions, LlmResponse } from '../plugins/loaders/Llm';
|
|
12
|
+
import { FlowQueryExecutor, FlowQueryExecutionResult } from '../utils/FlowQueryExecutor';
|
|
13
|
+
import { extractFlowQuery, FlowQueryExtraction } from '../utils/FlowQueryExtractor';
|
|
14
|
+
|
|
15
|
+
// Shared executor instance
|
|
16
|
+
const flowQueryExecutor = new FlowQueryExecutor();
|
|
17
|
+
import { generateInterpretationPrompt } from '../prompts';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Represents a step in the agent's execution process.
|
|
21
|
+
*/
|
|
22
|
+
export interface AgentStep {
|
|
23
|
+
type: 'query_generation' | 'query_execution' | 'interpretation' | 'direct_response';
|
|
24
|
+
content: string;
|
|
25
|
+
timestamp: Date;
|
|
26
|
+
metadata?: {
|
|
27
|
+
query?: string;
|
|
28
|
+
executionResult?: FlowQueryExecutionResult;
|
|
29
|
+
extraction?: FlowQueryExtraction;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Result of the agent's processing.
|
|
35
|
+
*/
|
|
36
|
+
export interface AgentResult {
|
|
37
|
+
/** Final response text to show the user */
|
|
38
|
+
finalResponse: string;
|
|
39
|
+
/** Steps taken during processing (for debugging/transparency) */
|
|
40
|
+
steps: AgentStep[];
|
|
41
|
+
/** Whether processing was successful */
|
|
42
|
+
success: boolean;
|
|
43
|
+
/** Error message if processing failed */
|
|
44
|
+
error?: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Callback for streaming agent responses.
|
|
49
|
+
*/
|
|
50
|
+
export type AgentStreamCallback = (chunk: string, step: AgentStep['type']) => void;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Options for the FlowQuery agent.
|
|
54
|
+
*/
|
|
55
|
+
export interface FlowQueryAgentOptions {
|
|
56
|
+
/** System prompt for query generation */
|
|
57
|
+
systemPrompt: string;
|
|
58
|
+
/** LLM options to use */
|
|
59
|
+
llmOptions?: LlmOptions;
|
|
60
|
+
/** Conversation history */
|
|
61
|
+
conversationHistory?: Array<{ role: 'user' | 'assistant'; content: string }>;
|
|
62
|
+
/** Callback for streaming responses */
|
|
63
|
+
onStream?: AgentStreamCallback;
|
|
64
|
+
/** Whether to show intermediate steps to the user */
|
|
65
|
+
showIntermediateSteps?: boolean;
|
|
66
|
+
/** Maximum number of retry attempts for query execution */
|
|
67
|
+
maxRetries?: number;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Process a user query through the FlowQuery agent.
|
|
72
|
+
*
|
|
73
|
+
* @param userQuery - The natural language query from the user
|
|
74
|
+
* @param options - Agent configuration options
|
|
75
|
+
* @returns The agent result including final response and steps taken
|
|
76
|
+
*/
|
|
77
|
+
export async function processQuery(
|
|
78
|
+
userQuery: string,
|
|
79
|
+
options: FlowQueryAgentOptions
|
|
80
|
+
): Promise<AgentResult> {
|
|
81
|
+
const steps: AgentStep[] = [];
|
|
82
|
+
const { systemPrompt, llmOptions = {}, conversationHistory = [], onStream, showIntermediateSteps = true } = options;
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
// Step 1: Generate FlowQuery from natural language
|
|
86
|
+
const generationResponse = await llm(userQuery, {
|
|
87
|
+
...llmOptions,
|
|
88
|
+
systemPrompt,
|
|
89
|
+
messages: conversationHistory,
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
const generationContent = generationResponse.choices[0]?.message?.content || '';
|
|
93
|
+
|
|
94
|
+
steps.push({
|
|
95
|
+
type: 'query_generation',
|
|
96
|
+
content: generationContent,
|
|
97
|
+
timestamp: new Date(),
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// Step 2: Extract the FlowQuery from the response
|
|
101
|
+
const extraction = extractFlowQuery(generationContent);
|
|
102
|
+
|
|
103
|
+
// If no query needed (direct response from LLM)
|
|
104
|
+
if (extraction.noQueryNeeded || !extraction.found) {
|
|
105
|
+
const directResponse = extraction.directResponse || generationContent;
|
|
106
|
+
|
|
107
|
+
steps.push({
|
|
108
|
+
type: 'direct_response',
|
|
109
|
+
content: directResponse,
|
|
110
|
+
timestamp: new Date(),
|
|
111
|
+
metadata: { extraction }
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
return {
|
|
115
|
+
finalResponse: directResponse,
|
|
116
|
+
steps,
|
|
117
|
+
success: true,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Step 3: Execute the FlowQuery
|
|
122
|
+
const executionResult = await flowQueryExecutor.execute(extraction.query!);
|
|
123
|
+
|
|
124
|
+
steps.push({
|
|
125
|
+
type: 'query_execution',
|
|
126
|
+
content: flowQueryExecutor.formatResult(executionResult),
|
|
127
|
+
timestamp: new Date(),
|
|
128
|
+
metadata: {
|
|
129
|
+
query: extraction.query!,
|
|
130
|
+
executionResult,
|
|
131
|
+
extraction
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// If execution failed, ask LLM to fix the query or explain the error
|
|
136
|
+
if (!executionResult.success) {
|
|
137
|
+
const errorInterpretation = await interpretError(
|
|
138
|
+
userQuery,
|
|
139
|
+
extraction.query!,
|
|
140
|
+
executionResult,
|
|
141
|
+
options
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
finalResponse: errorInterpretation,
|
|
146
|
+
steps,
|
|
147
|
+
success: false,
|
|
148
|
+
error: executionResult.error
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Step 4: Send results to LLM for interpretation
|
|
153
|
+
const interpretationPrompt = buildInterpretationPrompt(
|
|
154
|
+
userQuery,
|
|
155
|
+
extraction.query!,
|
|
156
|
+
executionResult
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
let finalResponse = '';
|
|
160
|
+
|
|
161
|
+
if (onStream) {
|
|
162
|
+
// Stream the interpretation response
|
|
163
|
+
for await (const chunk of llmStream(interpretationPrompt, {
|
|
164
|
+
...llmOptions,
|
|
165
|
+
systemPrompt: generateInterpretationPrompt(),
|
|
166
|
+
messages: conversationHistory,
|
|
167
|
+
})) {
|
|
168
|
+
const deltaContent = chunk.choices?.[0]?.delta?.content || '';
|
|
169
|
+
if (deltaContent) {
|
|
170
|
+
finalResponse += deltaContent;
|
|
171
|
+
onStream(deltaContent, 'interpretation');
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
} else {
|
|
175
|
+
const interpretationResponse = await llm(interpretationPrompt, {
|
|
176
|
+
...llmOptions,
|
|
177
|
+
systemPrompt: generateInterpretationPrompt(),
|
|
178
|
+
messages: conversationHistory,
|
|
179
|
+
});
|
|
180
|
+
finalResponse = interpretationResponse.choices[0]?.message?.content || '';
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
steps.push({
|
|
184
|
+
type: 'interpretation',
|
|
185
|
+
content: finalResponse,
|
|
186
|
+
timestamp: new Date(),
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// Build the complete response with optional intermediate steps
|
|
190
|
+
let completeResponse = '';
|
|
191
|
+
|
|
192
|
+
if (showIntermediateSteps && extraction.explanation) {
|
|
193
|
+
completeResponse += extraction.explanation + '\n\n';
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (showIntermediateSteps) {
|
|
197
|
+
completeResponse += `**Query executed:**\n\`\`\`flowquery\n${extraction.query}\n\`\`\`\n\n`;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
completeResponse += finalResponse;
|
|
201
|
+
|
|
202
|
+
return {
|
|
203
|
+
finalResponse: completeResponse,
|
|
204
|
+
steps,
|
|
205
|
+
success: true,
|
|
206
|
+
};
|
|
207
|
+
} catch (error) {
|
|
208
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
209
|
+
|
|
210
|
+
return {
|
|
211
|
+
finalResponse: `⚠️ An error occurred: ${errorMessage}`,
|
|
212
|
+
steps,
|
|
213
|
+
success: false,
|
|
214
|
+
error: errorMessage,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Process a query with streaming support for the final interpretation.
|
|
221
|
+
*/
|
|
222
|
+
export async function* processQueryStream(
|
|
223
|
+
userQuery: string,
|
|
224
|
+
options: FlowQueryAgentOptions
|
|
225
|
+
): AsyncGenerator<{ chunk: string; step: AgentStep['type']; done: boolean; steps?: AgentStep[] }, void, unknown> {
|
|
226
|
+
const steps: AgentStep[] = [];
|
|
227
|
+
const { systemPrompt, llmOptions = {}, conversationHistory = [], showIntermediateSteps = true } = options;
|
|
228
|
+
|
|
229
|
+
try {
|
|
230
|
+
// Step 1: Generate FlowQuery from natural language (non-streaming for speed)
|
|
231
|
+
const generationResponse = await llm(userQuery, {
|
|
232
|
+
...llmOptions,
|
|
233
|
+
systemPrompt,
|
|
234
|
+
messages: conversationHistory,
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
const generationContent = generationResponse.choices[0]?.message?.content || '';
|
|
238
|
+
|
|
239
|
+
steps.push({
|
|
240
|
+
type: 'query_generation',
|
|
241
|
+
content: generationContent,
|
|
242
|
+
timestamp: new Date(),
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
// Step 2: Extract the FlowQuery
|
|
246
|
+
const extraction = extractFlowQuery(generationContent);
|
|
247
|
+
|
|
248
|
+
// If no query needed
|
|
249
|
+
if (extraction.noQueryNeeded || !extraction.found) {
|
|
250
|
+
const directResponse = extraction.directResponse || generationContent;
|
|
251
|
+
|
|
252
|
+
steps.push({
|
|
253
|
+
type: 'direct_response',
|
|
254
|
+
content: directResponse,
|
|
255
|
+
timestamp: new Date(),
|
|
256
|
+
metadata: { extraction }
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
yield { chunk: directResponse, step: 'direct_response', done: true, steps };
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Emit intermediate step: show the query being executed
|
|
264
|
+
if (showIntermediateSteps) {
|
|
265
|
+
yield {
|
|
266
|
+
chunk: `**Executing query:**\n\`\`\`flowquery\n${extraction.query}\n\`\`\`\n\n`,
|
|
267
|
+
step: 'query_generation',
|
|
268
|
+
done: false
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Step 3: Execute the FlowQuery
|
|
273
|
+
const executionResult = await flowQueryExecutor.execute(extraction.query!);
|
|
274
|
+
|
|
275
|
+
steps.push({
|
|
276
|
+
type: 'query_execution',
|
|
277
|
+
content: flowQueryExecutor.formatResult(executionResult),
|
|
278
|
+
timestamp: new Date(),
|
|
279
|
+
metadata: {
|
|
280
|
+
query: extraction.query!,
|
|
281
|
+
executionResult,
|
|
282
|
+
extraction
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
// Handle execution errors
|
|
287
|
+
if (!executionResult.success) {
|
|
288
|
+
const errorMessage = `⚠️ Query execution failed: ${executionResult.error}\n\nQuery attempted:\n\`\`\`flowquery\n${extraction.query}\n\`\`\``;
|
|
289
|
+
yield { chunk: errorMessage, step: 'query_execution', done: true, steps };
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Step 4: Stream the interpretation
|
|
294
|
+
const interpretationPrompt = buildInterpretationPrompt(
|
|
295
|
+
userQuery,
|
|
296
|
+
extraction.query!,
|
|
297
|
+
executionResult
|
|
298
|
+
);
|
|
299
|
+
|
|
300
|
+
let interpretationContent = '';
|
|
301
|
+
|
|
302
|
+
for await (const chunk of llmStream(interpretationPrompt, {
|
|
303
|
+
...llmOptions,
|
|
304
|
+
systemPrompt: generateInterpretationPrompt(),
|
|
305
|
+
messages: conversationHistory,
|
|
306
|
+
})) {
|
|
307
|
+
const deltaContent = chunk.choices?.[0]?.delta?.content || '';
|
|
308
|
+
if (deltaContent) {
|
|
309
|
+
interpretationContent += deltaContent;
|
|
310
|
+
yield { chunk: deltaContent, step: 'interpretation', done: false };
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
steps.push({
|
|
315
|
+
type: 'interpretation',
|
|
316
|
+
content: interpretationContent,
|
|
317
|
+
timestamp: new Date(),
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
yield { chunk: '', step: 'interpretation', done: true, steps };
|
|
321
|
+
} catch (error) {
|
|
322
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
323
|
+
yield {
|
|
324
|
+
chunk: `⚠️ An error occurred: ${errorMessage}`,
|
|
325
|
+
step: 'interpretation',
|
|
326
|
+
done: true,
|
|
327
|
+
steps
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Build the prompt for the interpretation phase.
|
|
334
|
+
*/
|
|
335
|
+
function buildInterpretationPrompt(
|
|
336
|
+
originalQuery: string,
|
|
337
|
+
flowQuery: string,
|
|
338
|
+
executionResult: FlowQueryExecutionResult
|
|
339
|
+
): string {
|
|
340
|
+
const resultsJson = JSON.stringify(executionResult.results, null, 2);
|
|
341
|
+
const resultCount = executionResult.results?.length || 0;
|
|
342
|
+
|
|
343
|
+
return `The user asked: "${originalQuery}"
|
|
344
|
+
|
|
345
|
+
This was translated to the following FlowQuery:
|
|
346
|
+
\`\`\`flowquery
|
|
347
|
+
${flowQuery}
|
|
348
|
+
\`\`\`
|
|
349
|
+
|
|
350
|
+
The query executed successfully in ${executionResult.executionTime.toFixed(2)}ms and returned ${resultCount} result(s):
|
|
351
|
+
|
|
352
|
+
\`\`\`json
|
|
353
|
+
${resultsJson}
|
|
354
|
+
\`\`\`
|
|
355
|
+
|
|
356
|
+
Please interpret these results and provide a helpful response to the user's original question.`;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Handle execution errors by asking LLM to explain or suggest fixes.
|
|
361
|
+
*/
|
|
362
|
+
async function interpretError(
|
|
363
|
+
originalQuery: string,
|
|
364
|
+
flowQuery: string,
|
|
365
|
+
executionResult: FlowQueryExecutionResult,
|
|
366
|
+
options: FlowQueryAgentOptions
|
|
367
|
+
): Promise<string> {
|
|
368
|
+
const errorPrompt = `The user asked: "${originalQuery}"
|
|
369
|
+
|
|
370
|
+
This was translated to the following FlowQuery:
|
|
371
|
+
\`\`\`flowquery
|
|
372
|
+
${flowQuery}
|
|
373
|
+
\`\`\`
|
|
374
|
+
|
|
375
|
+
However, the query failed with the following error:
|
|
376
|
+
${executionResult.error}
|
|
377
|
+
|
|
378
|
+
Please explain what went wrong in user-friendly terms and, if possible, suggest how to fix the issue or rephrase their request.`;
|
|
379
|
+
|
|
380
|
+
const response = await llm(errorPrompt, {
|
|
381
|
+
...options.llmOptions,
|
|
382
|
+
systemPrompt: 'You are a helpful assistant explaining query errors. Be concise and helpful.',
|
|
383
|
+
messages: options.conversationHistory,
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
return response.choices[0]?.message?.content ||
|
|
387
|
+
`The query failed with error: ${executionResult.error}`;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
export default { processQuery, processQueryStream };
|