Spaces:
Running
Running
Merge pull request #129 from biggraph/feature/image-search-new
Browse files- examples/LynxScribe FAQ Chatbot Builder.lynxkite.json +605 -0
- examples/LynxScribe Image Search.lynxkite.json +419 -0
- examples/{LynxScribe demo.lynxkite.json → LynxScribe RAG Chatbot.lynxkite.json} +471 -706
- examples/uploads/image_description_prompts.yaml +90 -0
- examples/uploads/lynx_chatbot_scenario_selector.yaml +302 -0
- examples/uploads/organon_demo/backend-scenarios-en.yaml +92 -0
- examples/uploads/organon_demo/organon_en_copy.xlsx +0 -0
- lynxkite-lynxscribe/pyproject.toml +1 -1
- lynxkite-lynxscribe/src/lynxkite_lynxscribe/lynxscribe_ops.py +634 -83
examples/LynxScribe FAQ Chatbot Builder.lynxkite.json
ADDED
@@ -0,0 +1,605 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"edges": [
|
3 |
+
{
|
4 |
+
"id": "LynxScribe FAQ to RAG 1 LynxScribe RAG Graph Chatbot Builder 1",
|
5 |
+
"source": "LynxScribe FAQ to RAG 1",
|
6 |
+
"sourceHandle": "output",
|
7 |
+
"target": "LynxScribe RAG Graph Chatbot Builder 1",
|
8 |
+
"targetHandle": "rag_graph"
|
9 |
+
},
|
10 |
+
{
|
11 |
+
"id": "LynxScribe RAG Graph Chatbot Builder 1 LynxScribe RAG Graph Chatbot Backend 1",
|
12 |
+
"source": "LynxScribe RAG Graph Chatbot Builder 1",
|
13 |
+
"sourceHandle": "output",
|
14 |
+
"target": "LynxScribe RAG Graph Chatbot Backend 1",
|
15 |
+
"targetHandle": "knowledge_base"
|
16 |
+
},
|
17 |
+
{
|
18 |
+
"id": "Chat processor 1 LynxScribe RAG Graph Chatbot Backend 1",
|
19 |
+
"source": "Chat processor 1",
|
20 |
+
"sourceHandle": "output",
|
21 |
+
"target": "LynxScribe RAG Graph Chatbot Backend 1",
|
22 |
+
"targetHandle": "chat_processor"
|
23 |
+
},
|
24 |
+
{
|
25 |
+
"id": "Truncate history 1 Chat processor 1",
|
26 |
+
"source": "Truncate history 1",
|
27 |
+
"sourceHandle": "output",
|
28 |
+
"target": "Chat processor 1",
|
29 |
+
"targetHandle": "processor"
|
30 |
+
},
|
31 |
+
{
|
32 |
+
"id": "LynxScribe RAG Graph Chatbot Backend 1 Test Chat API 1",
|
33 |
+
"source": "LynxScribe RAG Graph Chatbot Backend 1",
|
34 |
+
"sourceHandle": "output",
|
35 |
+
"target": "Test Chat API 1",
|
36 |
+
"targetHandle": "chat_api"
|
37 |
+
},
|
38 |
+
{
|
39 |
+
"id": "Input chat 1 Test Chat API 1",
|
40 |
+
"source": "Input chat 1",
|
41 |
+
"sourceHandle": "output",
|
42 |
+
"target": "Test Chat API 1",
|
43 |
+
"targetHandle": "message"
|
44 |
+
},
|
45 |
+
{
|
46 |
+
"id": "Test Chat API 1 View 1",
|
47 |
+
"source": "Test Chat API 1",
|
48 |
+
"sourceHandle": "output",
|
49 |
+
"target": "View 1",
|
50 |
+
"targetHandle": "input"
|
51 |
+
}
|
52 |
+
],
|
53 |
+
"env": "LynxScribe",
|
54 |
+
"nodes": [
|
55 |
+
{
|
56 |
+
"data": {
|
57 |
+
"__execution_delay": 0.0,
|
58 |
+
"collapsed": false,
|
59 |
+
"display": null,
|
60 |
+
"error": null,
|
61 |
+
"input_metadata": null,
|
62 |
+
"meta": {
|
63 |
+
"inputs": {},
|
64 |
+
"name": "LynxScribe FAQ to RAG",
|
65 |
+
"outputs": {
|
66 |
+
"output": {
|
67 |
+
"name": "output",
|
68 |
+
"position": "right",
|
69 |
+
"type": {
|
70 |
+
"type": "None"
|
71 |
+
}
|
72 |
+
}
|
73 |
+
},
|
74 |
+
"params": {
|
75 |
+
"faq_excel_path": {
|
76 |
+
"default": "uploads/organon_demo/organon_en_copy.xlsx",
|
77 |
+
"name": "faq_excel_path",
|
78 |
+
"type": {
|
79 |
+
"type": "<class 'str'>"
|
80 |
+
}
|
81 |
+
},
|
82 |
+
"scenario_cluster_distance_pct": {
|
83 |
+
"default": 30.0,
|
84 |
+
"name": "scenario_cluster_distance_pct",
|
85 |
+
"type": {
|
86 |
+
"type": "<class 'float'>"
|
87 |
+
}
|
88 |
+
},
|
89 |
+
"text_embedder_interface": {
|
90 |
+
"default": "openai",
|
91 |
+
"name": "text_embedder_interface",
|
92 |
+
"type": {
|
93 |
+
"type": "<class 'str'>"
|
94 |
+
}
|
95 |
+
},
|
96 |
+
"text_embedder_model_name_or_path": {
|
97 |
+
"default": "text-embedding-3-large",
|
98 |
+
"name": "text_embedder_model_name_or_path",
|
99 |
+
"type": {
|
100 |
+
"type": "<class 'str'>"
|
101 |
+
}
|
102 |
+
},
|
103 |
+
"vdb_collection_name": {
|
104 |
+
"default": "lynx",
|
105 |
+
"name": "vdb_collection_name",
|
106 |
+
"type": {
|
107 |
+
"type": "<class 'str'>"
|
108 |
+
}
|
109 |
+
},
|
110 |
+
"vdb_num_dimensions": {
|
111 |
+
"default": 3072.0,
|
112 |
+
"name": "vdb_num_dimensions",
|
113 |
+
"type": {
|
114 |
+
"type": "<class 'int'>"
|
115 |
+
}
|
116 |
+
},
|
117 |
+
"vdb_provider_name": {
|
118 |
+
"default": "faiss",
|
119 |
+
"name": "vdb_provider_name",
|
120 |
+
"type": {
|
121 |
+
"type": "<class 'str'>"
|
122 |
+
}
|
123 |
+
}
|
124 |
+
},
|
125 |
+
"type": "basic"
|
126 |
+
},
|
127 |
+
"params": {
|
128 |
+
"faq_excel_path": "uploads/organon_demo/organon_en_copy.xlsx",
|
129 |
+
"scenario_cluster_distance_pct": "30",
|
130 |
+
"text_embedder_interface": "openai",
|
131 |
+
"text_embedder_model_name_or_path": "text-embedding-3-large",
|
132 |
+
"vdb_collection_name": "lynx",
|
133 |
+
"vdb_num_dimensions": 3072.0,
|
134 |
+
"vdb_provider_name": "faiss"
|
135 |
+
},
|
136 |
+
"status": "done",
|
137 |
+
"title": "LynxScribe FAQ to RAG"
|
138 |
+
},
|
139 |
+
"dragHandle": ".bg-primary",
|
140 |
+
"height": 620.0,
|
141 |
+
"id": "LynxScribe FAQ to RAG 1",
|
142 |
+
"position": {
|
143 |
+
"x": -1180.0,
|
144 |
+
"y": -76.0
|
145 |
+
},
|
146 |
+
"type": "basic",
|
147 |
+
"width": 415.0
|
148 |
+
},
|
149 |
+
{
|
150 |
+
"data": {
|
151 |
+
"__execution_delay": 0.0,
|
152 |
+
"collapsed": false,
|
153 |
+
"display": null,
|
154 |
+
"error": null,
|
155 |
+
"input_metadata": null,
|
156 |
+
"meta": {
|
157 |
+
"inputs": {
|
158 |
+
"rag_graph": {
|
159 |
+
"name": "rag_graph",
|
160 |
+
"position": "left",
|
161 |
+
"type": {
|
162 |
+
"type": "<class 'inspect._empty'>"
|
163 |
+
}
|
164 |
+
}
|
165 |
+
},
|
166 |
+
"name": "LynxScribe RAG Graph Chatbot Builder",
|
167 |
+
"outputs": {
|
168 |
+
"output": {
|
169 |
+
"name": "output",
|
170 |
+
"position": "top",
|
171 |
+
"type": {
|
172 |
+
"type": "None"
|
173 |
+
}
|
174 |
+
}
|
175 |
+
},
|
176 |
+
"params": {
|
177 |
+
"node_types": {
|
178 |
+
"default": "intent_cluster",
|
179 |
+
"name": "node_types",
|
180 |
+
"type": {
|
181 |
+
"type": "<class 'str'>"
|
182 |
+
}
|
183 |
+
},
|
184 |
+
"scenario_file": {
|
185 |
+
"default": "uploads/lynx_chatbot_scenario_selector.yaml",
|
186 |
+
"name": "scenario_file",
|
187 |
+
"type": {
|
188 |
+
"type": "<class 'str'>"
|
189 |
+
}
|
190 |
+
},
|
191 |
+
"scenario_meta_name": {
|
192 |
+
"default": "scenario_name",
|
193 |
+
"name": "scenario_meta_name",
|
194 |
+
"type": {
|
195 |
+
"type": "<class 'str'>"
|
196 |
+
}
|
197 |
+
}
|
198 |
+
},
|
199 |
+
"position": {
|
200 |
+
"x": 1569.0,
|
201 |
+
"y": 528.0
|
202 |
+
},
|
203 |
+
"type": "basic"
|
204 |
+
},
|
205 |
+
"params": {
|
206 |
+
"node_types": "intent_cluster",
|
207 |
+
"scenario_file": "uploads/organon_demo/backend-scenarios-en.yaml",
|
208 |
+
"scenario_meta_name": "scenario_name"
|
209 |
+
},
|
210 |
+
"status": "done",
|
211 |
+
"title": "LynxScribe RAG Graph Chatbot Builder"
|
212 |
+
},
|
213 |
+
"dragHandle": ".bg-primary",
|
214 |
+
"height": 296.0,
|
215 |
+
"id": "LynxScribe RAG Graph Chatbot Builder 1",
|
216 |
+
"position": {
|
217 |
+
"x": -591.0,
|
218 |
+
"y": 86.0
|
219 |
+
},
|
220 |
+
"type": "basic",
|
221 |
+
"width": 547.0
|
222 |
+
},
|
223 |
+
{
|
224 |
+
"data": {
|
225 |
+
"__execution_delay": 0.0,
|
226 |
+
"collapsed": null,
|
227 |
+
"display": null,
|
228 |
+
"error": null,
|
229 |
+
"input_metadata": null,
|
230 |
+
"meta": {
|
231 |
+
"inputs": {
|
232 |
+
"chat_processor": {
|
233 |
+
"name": "chat_processor",
|
234 |
+
"position": "bottom",
|
235 |
+
"type": {
|
236 |
+
"type": "<class 'inspect._empty'>"
|
237 |
+
}
|
238 |
+
},
|
239 |
+
"knowledge_base": {
|
240 |
+
"name": "knowledge_base",
|
241 |
+
"position": "bottom",
|
242 |
+
"type": {
|
243 |
+
"type": "<class 'inspect._empty'>"
|
244 |
+
}
|
245 |
+
}
|
246 |
+
},
|
247 |
+
"name": "LynxScribe RAG Graph Chatbot Backend",
|
248 |
+
"outputs": {
|
249 |
+
"output": {
|
250 |
+
"name": "output",
|
251 |
+
"position": "top",
|
252 |
+
"type": {
|
253 |
+
"type": "None"
|
254 |
+
}
|
255 |
+
}
|
256 |
+
},
|
257 |
+
"params": {
|
258 |
+
"llm_interface": {
|
259 |
+
"default": "openai",
|
260 |
+
"name": "llm_interface",
|
261 |
+
"type": {
|
262 |
+
"type": "<class 'str'>"
|
263 |
+
}
|
264 |
+
},
|
265 |
+
"llm_model_name": {
|
266 |
+
"default": "gpt-4o",
|
267 |
+
"name": "llm_model_name",
|
268 |
+
"type": {
|
269 |
+
"type": "<class 'str'>"
|
270 |
+
}
|
271 |
+
},
|
272 |
+
"negative_answer": {
|
273 |
+
"default": "I'm sorry, but the data I've been trained on does not contain any information related to your question.",
|
274 |
+
"name": "negative_answer",
|
275 |
+
"type": {
|
276 |
+
"type": "<class 'str'>"
|
277 |
+
}
|
278 |
+
},
|
279 |
+
"retriever_limits_by_type": {
|
280 |
+
"default": "{}",
|
281 |
+
"name": "retriever_limits_by_type",
|
282 |
+
"type": {
|
283 |
+
"type": "<class 'str'>"
|
284 |
+
}
|
285 |
+
},
|
286 |
+
"retriever_max_iterations": {
|
287 |
+
"default": 3.0,
|
288 |
+
"name": "retriever_max_iterations",
|
289 |
+
"type": {
|
290 |
+
"type": "<class 'int'>"
|
291 |
+
}
|
292 |
+
},
|
293 |
+
"retriever_overall_chunk_limit": {
|
294 |
+
"default": 20.0,
|
295 |
+
"name": "retriever_overall_chunk_limit",
|
296 |
+
"type": {
|
297 |
+
"type": "<class 'int'>"
|
298 |
+
}
|
299 |
+
},
|
300 |
+
"retriever_overall_token_limit": {
|
301 |
+
"default": 3000.0,
|
302 |
+
"name": "retriever_overall_token_limit",
|
303 |
+
"type": {
|
304 |
+
"type": "<class 'int'>"
|
305 |
+
}
|
306 |
+
},
|
307 |
+
"retriever_strict_limits": {
|
308 |
+
"default": true,
|
309 |
+
"name": "retriever_strict_limits",
|
310 |
+
"type": {
|
311 |
+
"type": "<class 'bool'>"
|
312 |
+
}
|
313 |
+
}
|
314 |
+
},
|
315 |
+
"position": {
|
316 |
+
"x": 1280.0,
|
317 |
+
"y": 450.0
|
318 |
+
},
|
319 |
+
"type": "basic"
|
320 |
+
},
|
321 |
+
"params": {
|
322 |
+
"llm_interface": "openai",
|
323 |
+
"llm_model_name": "gpt-4o",
|
324 |
+
"negative_answer": "I'm sorry, but the data I've been trained on does not contain any information related to your question.",
|
325 |
+
"retriever_limits_by_type": "{\"faq_question\": [0, 0], \"faq_answer\": [3, 3]}",
|
326 |
+
"retriever_max_iterations": "3",
|
327 |
+
"retriever_overall_chunk_limit": "3",
|
328 |
+
"retriever_overall_token_limit": "30000",
|
329 |
+
"retriever_strict_limits": true
|
330 |
+
},
|
331 |
+
"status": "done",
|
332 |
+
"title": "LynxScribe RAG Graph Chatbot Backend"
|
333 |
+
},
|
334 |
+
"dragHandle": ".bg-primary",
|
335 |
+
"height": 382.0,
|
336 |
+
"id": "LynxScribe RAG Graph Chatbot Backend 1",
|
337 |
+
"position": {
|
338 |
+
"x": -427.131476508498,
|
339 |
+
"y": -465.1194966607713
|
340 |
+
},
|
341 |
+
"type": "basic",
|
342 |
+
"width": 791.0
|
343 |
+
},
|
344 |
+
{
|
345 |
+
"data": {
|
346 |
+
"display": null,
|
347 |
+
"error": null,
|
348 |
+
"input_metadata": null,
|
349 |
+
"meta": {
|
350 |
+
"inputs": {
|
351 |
+
"processor": {
|
352 |
+
"name": "processor",
|
353 |
+
"position": "bottom",
|
354 |
+
"type": {
|
355 |
+
"type": "<class 'inspect._empty'>"
|
356 |
+
}
|
357 |
+
}
|
358 |
+
},
|
359 |
+
"name": "Chat processor",
|
360 |
+
"outputs": {
|
361 |
+
"output": {
|
362 |
+
"name": "output",
|
363 |
+
"position": "top",
|
364 |
+
"type": {
|
365 |
+
"type": "None"
|
366 |
+
}
|
367 |
+
}
|
368 |
+
},
|
369 |
+
"params": {},
|
370 |
+
"position": {
|
371 |
+
"x": 1291.0,
|
372 |
+
"y": 718.0
|
373 |
+
},
|
374 |
+
"type": "basic"
|
375 |
+
},
|
376 |
+
"params": {},
|
377 |
+
"status": "done",
|
378 |
+
"title": "Chat processor"
|
379 |
+
},
|
380 |
+
"dragHandle": ".bg-primary",
|
381 |
+
"height": 200.0,
|
382 |
+
"id": "Chat processor 1",
|
383 |
+
"position": {
|
384 |
+
"x": 252.7291107206022,
|
385 |
+
"y": 81.86852349150202
|
386 |
+
},
|
387 |
+
"type": "basic",
|
388 |
+
"width": 200.0
|
389 |
+
},
|
390 |
+
{
|
391 |
+
"data": {
|
392 |
+
"display": null,
|
393 |
+
"error": null,
|
394 |
+
"input_metadata": null,
|
395 |
+
"meta": {
|
396 |
+
"inputs": {},
|
397 |
+
"name": "Truncate history",
|
398 |
+
"outputs": {
|
399 |
+
"output": {
|
400 |
+
"name": "output",
|
401 |
+
"position": "top",
|
402 |
+
"type": {
|
403 |
+
"type": "None"
|
404 |
+
}
|
405 |
+
}
|
406 |
+
},
|
407 |
+
"params": {
|
408 |
+
"max_tokens": {
|
409 |
+
"default": 10000.0,
|
410 |
+
"name": "max_tokens",
|
411 |
+
"type": {
|
412 |
+
"type": "<class 'int'>"
|
413 |
+
}
|
414 |
+
}
|
415 |
+
},
|
416 |
+
"position": {
|
417 |
+
"x": 1440.0,
|
418 |
+
"y": 936.0
|
419 |
+
},
|
420 |
+
"type": "basic"
|
421 |
+
},
|
422 |
+
"params": {
|
423 |
+
"max_tokens": 10000.0
|
424 |
+
},
|
425 |
+
"status": "done",
|
426 |
+
"title": "Truncate history"
|
427 |
+
},
|
428 |
+
"dragHandle": ".bg-primary",
|
429 |
+
"height": 200.0,
|
430 |
+
"id": "Truncate history 1",
|
431 |
+
"position": {
|
432 |
+
"x": 253.59374153502728,
|
433 |
+
"y": 386.4661577036063
|
434 |
+
},
|
435 |
+
"type": "basic",
|
436 |
+
"width": 200.0
|
437 |
+
},
|
438 |
+
{
|
439 |
+
"data": {
|
440 |
+
"__execution_delay": 0.0,
|
441 |
+
"collapsed": null,
|
442 |
+
"display": null,
|
443 |
+
"error": null,
|
444 |
+
"input_metadata": null,
|
445 |
+
"meta": {
|
446 |
+
"inputs": {},
|
447 |
+
"name": "Input chat",
|
448 |
+
"outputs": {
|
449 |
+
"output": {
|
450 |
+
"name": "output",
|
451 |
+
"position": "right",
|
452 |
+
"type": {
|
453 |
+
"type": "None"
|
454 |
+
}
|
455 |
+
}
|
456 |
+
},
|
457 |
+
"params": {
|
458 |
+
"chat": {
|
459 |
+
"default": null,
|
460 |
+
"name": "chat",
|
461 |
+
"type": {
|
462 |
+
"type": "<class 'str'>"
|
463 |
+
}
|
464 |
+
}
|
465 |
+
},
|
466 |
+
"position": {
|
467 |
+
"x": 449.0,
|
468 |
+
"y": 172.0
|
469 |
+
},
|
470 |
+
"type": "basic"
|
471 |
+
},
|
472 |
+
"params": {
|
473 |
+
"chat": "I had headache after taking the pill"
|
474 |
+
},
|
475 |
+
"status": "done",
|
476 |
+
"title": "Input chat"
|
477 |
+
},
|
478 |
+
"dragHandle": ".bg-primary",
|
479 |
+
"height": 204.0,
|
480 |
+
"id": "Input chat 1",
|
481 |
+
"position": {
|
482 |
+
"x": -1115.7774404622555,
|
483 |
+
"y": -747.1320865489535
|
484 |
+
},
|
485 |
+
"type": "basic",
|
486 |
+
"width": 552.0
|
487 |
+
},
|
488 |
+
{
|
489 |
+
"data": {
|
490 |
+
"__execution_delay": 0.0,
|
491 |
+
"collapsed": null,
|
492 |
+
"display": null,
|
493 |
+
"error": null,
|
494 |
+
"input_metadata": null,
|
495 |
+
"meta": {
|
496 |
+
"inputs": {
|
497 |
+
"chat_api": {
|
498 |
+
"name": "chat_api",
|
499 |
+
"position": "bottom",
|
500 |
+
"type": {
|
501 |
+
"type": "<class 'inspect._empty'>"
|
502 |
+
}
|
503 |
+
},
|
504 |
+
"message": {
|
505 |
+
"name": "message",
|
506 |
+
"position": "left",
|
507 |
+
"type": {
|
508 |
+
"type": "<class 'inspect._empty'>"
|
509 |
+
}
|
510 |
+
}
|
511 |
+
},
|
512 |
+
"name": "Test Chat API",
|
513 |
+
"outputs": {
|
514 |
+
"output": {
|
515 |
+
"name": "output",
|
516 |
+
"position": "right",
|
517 |
+
"type": {
|
518 |
+
"type": "None"
|
519 |
+
}
|
520 |
+
}
|
521 |
+
},
|
522 |
+
"params": {
|
523 |
+
"show_details": {
|
524 |
+
"default": false,
|
525 |
+
"name": "show_details",
|
526 |
+
"type": {
|
527 |
+
"type": "<class 'bool'>"
|
528 |
+
}
|
529 |
+
}
|
530 |
+
},
|
531 |
+
"position": {
|
532 |
+
"x": 937.0,
|
533 |
+
"y": 213.0
|
534 |
+
},
|
535 |
+
"type": "basic"
|
536 |
+
},
|
537 |
+
"params": {
|
538 |
+
"show_details": false
|
539 |
+
},
|
540 |
+
"status": "done",
|
541 |
+
"title": "Test Chat API"
|
542 |
+
},
|
543 |
+
"dragHandle": ".bg-primary",
|
544 |
+
"height": 200.0,
|
545 |
+
"id": "Test Chat API 1",
|
546 |
+
"position": {
|
547 |
+
"x": -131.54900620226195,
|
548 |
+
"y": -745.4660726292032
|
549 |
+
},
|
550 |
+
"type": "basic",
|
551 |
+
"width": 200.0
|
552 |
+
},
|
553 |
+
{
|
554 |
+
"data": {
|
555 |
+
"display": {
|
556 |
+
"dataframes": {
|
557 |
+
"df": {
|
558 |
+
"columns": [
|
559 |
+
"answer"
|
560 |
+
],
|
561 |
+
"data": [
|
562 |
+
[
|
563 |
+
"I'm not equipped to handle adverse events or other product-related queries. Your safety is important to us, and we want to ensure you receive the appropriate support. Please report any adverse events or concerns to our dedicated support team. They can be reached at [email protected]. If you have any questions related to contraceptives or women's health, please feel free to ask, and I'll provide you with the information you need.\n"
|
564 |
+
]
|
565 |
+
]
|
566 |
+
}
|
567 |
+
}
|
568 |
+
},
|
569 |
+
"error": null,
|
570 |
+
"input_metadata": null,
|
571 |
+
"meta": {
|
572 |
+
"inputs": {
|
573 |
+
"input": {
|
574 |
+
"name": "input",
|
575 |
+
"position": "left",
|
576 |
+
"type": {
|
577 |
+
"type": "<class 'inspect._empty'>"
|
578 |
+
}
|
579 |
+
}
|
580 |
+
},
|
581 |
+
"name": "View",
|
582 |
+
"outputs": {},
|
583 |
+
"params": {},
|
584 |
+
"position": {
|
585 |
+
"x": 1547.0,
|
586 |
+
"y": 222.0
|
587 |
+
},
|
588 |
+
"type": "table_view"
|
589 |
+
},
|
590 |
+
"params": {},
|
591 |
+
"status": "done",
|
592 |
+
"title": "View"
|
593 |
+
},
|
594 |
+
"dragHandle": ".bg-primary",
|
595 |
+
"height": 483.0,
|
596 |
+
"id": "View 1",
|
597 |
+
"position": {
|
598 |
+
"x": 540.6544350347407,
|
599 |
+
"y": -886.065865503576
|
600 |
+
},
|
601 |
+
"type": "table_view",
|
602 |
+
"width": 707.0
|
603 |
+
}
|
604 |
+
]
|
605 |
+
}
|
examples/LynxScribe Image Search.lynxkite.json
ADDED
@@ -0,0 +1,419 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"edges": [
|
3 |
+
{
|
4 |
+
"id": "Cloud-sourced File Listing 1 LynxScribe Image Describer 1",
|
5 |
+
"source": "Cloud-sourced File Listing 1",
|
6 |
+
"sourceHandle": "output",
|
7 |
+
"target": "LynxScribe Image Describer 1",
|
8 |
+
"targetHandle": "file_urls"
|
9 |
+
},
|
10 |
+
{
|
11 |
+
"id": "LynxScribe Image Describer 1 LynxScribe Image RAG Builder 1",
|
12 |
+
"source": "LynxScribe Image Describer 1",
|
13 |
+
"sourceHandle": "output",
|
14 |
+
"target": "LynxScribe Image RAG Builder 1",
|
15 |
+
"targetHandle": "image_descriptions"
|
16 |
+
},
|
17 |
+
{
|
18 |
+
"id": "Input chat 1 LynxScribe Image RAG Query 1",
|
19 |
+
"source": "Input chat 1",
|
20 |
+
"sourceHandle": "output",
|
21 |
+
"target": "LynxScribe Image RAG Query 1",
|
22 |
+
"targetHandle": "text"
|
23 |
+
},
|
24 |
+
{
|
25 |
+
"id": "LynxScribe Image RAG Builder 1 LynxScribe Image RAG Query 1",
|
26 |
+
"source": "LynxScribe Image RAG Builder 1",
|
27 |
+
"sourceHandle": "output",
|
28 |
+
"target": "LynxScribe Image RAG Query 1",
|
29 |
+
"targetHandle": "rag_graph"
|
30 |
+
},
|
31 |
+
{
|
32 |
+
"id": "LynxScribe Image RAG Query 1 LynxScribe Image Result Viewer 1",
|
33 |
+
"source": "LynxScribe Image RAG Query 1",
|
34 |
+
"sourceHandle": "output",
|
35 |
+
"target": "LynxScribe Image Result Viewer 1",
|
36 |
+
"targetHandle": "embedding_similarities"
|
37 |
+
}
|
38 |
+
],
|
39 |
+
"env": "LynxScribe",
|
40 |
+
"nodes": [
|
41 |
+
{
|
42 |
+
"data": {
|
43 |
+
"__execution_delay": 0.0,
|
44 |
+
"collapsed": null,
|
45 |
+
"display": null,
|
46 |
+
"error": null,
|
47 |
+
"input_metadata": null,
|
48 |
+
"meta": {
|
49 |
+
"inputs": {},
|
50 |
+
"name": "Cloud-sourced File Listing",
|
51 |
+
"outputs": {
|
52 |
+
"output": {
|
53 |
+
"name": "output",
|
54 |
+
"position": "right",
|
55 |
+
"type": {
|
56 |
+
"type": "None"
|
57 |
+
}
|
58 |
+
}
|
59 |
+
},
|
60 |
+
"params": {
|
61 |
+
"accepted_file_types": {
|
62 |
+
"default": ".jpg, .jpeg, .png",
|
63 |
+
"name": "accepted_file_types",
|
64 |
+
"type": {
|
65 |
+
"type": "<class 'str'>"
|
66 |
+
}
|
67 |
+
},
|
68 |
+
"cloud_provider": {
|
69 |
+
"default": "gcp",
|
70 |
+
"name": "cloud_provider",
|
71 |
+
"type": {
|
72 |
+
"enum": [
|
73 |
+
"GCP",
|
74 |
+
"AWS",
|
75 |
+
"AZURE"
|
76 |
+
]
|
77 |
+
}
|
78 |
+
},
|
79 |
+
"folder_URL": {
|
80 |
+
"default": "https://storage.googleapis.com/lynxkite_public_data/lynxscribe-images/image-rag-test",
|
81 |
+
"name": "folder_URL",
|
82 |
+
"type": {
|
83 |
+
"type": "<class 'str'>"
|
84 |
+
}
|
85 |
+
}
|
86 |
+
},
|
87 |
+
"type": "basic"
|
88 |
+
},
|
89 |
+
"params": {
|
90 |
+
"accepted_file_types": ".jpg, .jpeg, .png",
|
91 |
+
"cloud_provider": "GCP",
|
92 |
+
"folder_URL": "https://storage.googleapis.com/lynxkite_public_data/lynxscribe-images/image-rag-test"
|
93 |
+
},
|
94 |
+
"status": "done",
|
95 |
+
"title": "Cloud-sourced File Listing"
|
96 |
+
},
|
97 |
+
"dragHandle": ".bg-primary",
|
98 |
+
"height": 353.0,
|
99 |
+
"id": "Cloud-sourced File Listing 1",
|
100 |
+
"position": {
|
101 |
+
"x": -365.0,
|
102 |
+
"y": 302.0
|
103 |
+
},
|
104 |
+
"type": "basic",
|
105 |
+
"width": 430.0
|
106 |
+
},
|
107 |
+
{
|
108 |
+
"data": {
|
109 |
+
"display": null,
|
110 |
+
"error": null,
|
111 |
+
"input_metadata": null,
|
112 |
+
"meta": {
|
113 |
+
"inputs": {
|
114 |
+
"file_urls": {
|
115 |
+
"name": "file_urls",
|
116 |
+
"position": "left",
|
117 |
+
"type": {
|
118 |
+
"type": "<class 'inspect._empty'>"
|
119 |
+
}
|
120 |
+
}
|
121 |
+
},
|
122 |
+
"name": "LynxScribe Image Describer",
|
123 |
+
"outputs": {
|
124 |
+
"output": {
|
125 |
+
"name": "output",
|
126 |
+
"position": "right",
|
127 |
+
"type": {
|
128 |
+
"type": "None"
|
129 |
+
}
|
130 |
+
}
|
131 |
+
},
|
132 |
+
"params": {
|
133 |
+
"llm_interface": {
|
134 |
+
"default": "openai",
|
135 |
+
"name": "llm_interface",
|
136 |
+
"type": {
|
137 |
+
"type": "<class 'str'>"
|
138 |
+
}
|
139 |
+
},
|
140 |
+
"llm_prompt_name": {
|
141 |
+
"default": "cot_picture_descriptor",
|
142 |
+
"name": "llm_prompt_name",
|
143 |
+
"type": {
|
144 |
+
"type": "<class 'str'>"
|
145 |
+
}
|
146 |
+
},
|
147 |
+
"llm_prompt_path": {
|
148 |
+
"default": "uploads/image_description_prompts.yaml",
|
149 |
+
"name": "llm_prompt_path",
|
150 |
+
"type": {
|
151 |
+
"type": "<class 'str'>"
|
152 |
+
}
|
153 |
+
},
|
154 |
+
"llm_visual_model": {
|
155 |
+
"default": "gpt-4o",
|
156 |
+
"name": "llm_visual_model",
|
157 |
+
"type": {
|
158 |
+
"type": "<class 'str'>"
|
159 |
+
}
|
160 |
+
}
|
161 |
+
},
|
162 |
+
"type": "basic"
|
163 |
+
},
|
164 |
+
"params": {
|
165 |
+
"llm_interface": "openai",
|
166 |
+
"llm_prompt_name": "cot_picture_descriptor",
|
167 |
+
"llm_prompt_path": "uploads/image_description_prompts.yaml",
|
168 |
+
"llm_visual_model": "gpt-4o"
|
169 |
+
},
|
170 |
+
"status": "done",
|
171 |
+
"title": "LynxScribe Image Describer"
|
172 |
+
},
|
173 |
+
"dragHandle": ".bg-primary",
|
174 |
+
"height": 361.0,
|
175 |
+
"id": "LynxScribe Image Describer 1",
|
176 |
+
"position": {
|
177 |
+
"x": 159.0,
|
178 |
+
"y": 298.0
|
179 |
+
},
|
180 |
+
"type": "basic",
|
181 |
+
"width": 371.0
|
182 |
+
},
|
183 |
+
{
|
184 |
+
"data": {
|
185 |
+
"display": null,
|
186 |
+
"error": null,
|
187 |
+
"input_metadata": null,
|
188 |
+
"meta": {
|
189 |
+
"inputs": {
|
190 |
+
"image_descriptions": {
|
191 |
+
"name": "image_descriptions",
|
192 |
+
"position": "left",
|
193 |
+
"type": {
|
194 |
+
"type": "<class 'inspect._empty'>"
|
195 |
+
}
|
196 |
+
}
|
197 |
+
},
|
198 |
+
"name": "LynxScribe Image RAG Builder",
|
199 |
+
"outputs": {
|
200 |
+
"output": {
|
201 |
+
"name": "output",
|
202 |
+
"position": "right",
|
203 |
+
"type": {
|
204 |
+
"type": "None"
|
205 |
+
}
|
206 |
+
}
|
207 |
+
},
|
208 |
+
"params": {
|
209 |
+
"text_embedder_interface": {
|
210 |
+
"default": "openai",
|
211 |
+
"name": "text_embedder_interface",
|
212 |
+
"type": {
|
213 |
+
"type": "<class 'str'>"
|
214 |
+
}
|
215 |
+
},
|
216 |
+
"text_embedder_model_name_or_path": {
|
217 |
+
"default": "text-embedding-3-large",
|
218 |
+
"name": "text_embedder_model_name_or_path",
|
219 |
+
"type": {
|
220 |
+
"type": "<class 'str'>"
|
221 |
+
}
|
222 |
+
},
|
223 |
+
"vdb_collection_name": {
|
224 |
+
"default": "lynx",
|
225 |
+
"name": "vdb_collection_name",
|
226 |
+
"type": {
|
227 |
+
"type": "<class 'str'>"
|
228 |
+
}
|
229 |
+
},
|
230 |
+
"vdb_num_dimensions": {
|
231 |
+
"default": 3072.0,
|
232 |
+
"name": "vdb_num_dimensions",
|
233 |
+
"type": {
|
234 |
+
"type": "<class 'int'>"
|
235 |
+
}
|
236 |
+
},
|
237 |
+
"vdb_provider_name": {
|
238 |
+
"default": "faiss",
|
239 |
+
"name": "vdb_provider_name",
|
240 |
+
"type": {
|
241 |
+
"type": "<class 'str'>"
|
242 |
+
}
|
243 |
+
}
|
244 |
+
},
|
245 |
+
"type": "basic"
|
246 |
+
},
|
247 |
+
"params": {
|
248 |
+
"text_embedder_interface": "openai",
|
249 |
+
"text_embedder_model_name_or_path": "text-embedding-3-large",
|
250 |
+
"vdb_collection_name": "lynx",
|
251 |
+
"vdb_num_dimensions": 3072.0,
|
252 |
+
"vdb_provider_name": "faiss"
|
253 |
+
},
|
254 |
+
"status": "done",
|
255 |
+
"title": "LynxScribe Image RAG Builder"
|
256 |
+
},
|
257 |
+
"dragHandle": ".bg-primary",
|
258 |
+
"height": 441.0,
|
259 |
+
"id": "LynxScribe Image RAG Builder 1",
|
260 |
+
"position": {
|
261 |
+
"x": 644.0,
|
262 |
+
"y": 259.0
|
263 |
+
},
|
264 |
+
"type": "basic",
|
265 |
+
"width": 291.0
|
266 |
+
},
|
267 |
+
{
|
268 |
+
"data": {
|
269 |
+
"__execution_delay": 0.0,
|
270 |
+
"collapsed": null,
|
271 |
+
"display": null,
|
272 |
+
"error": null,
|
273 |
+
"input_metadata": null,
|
274 |
+
"meta": {
|
275 |
+
"inputs": {},
|
276 |
+
"name": "Input chat",
|
277 |
+
"outputs": {
|
278 |
+
"output": {
|
279 |
+
"name": "output",
|
280 |
+
"position": "right",
|
281 |
+
"type": {
|
282 |
+
"type": "None"
|
283 |
+
}
|
284 |
+
}
|
285 |
+
},
|
286 |
+
"params": {
|
287 |
+
"chat": {
|
288 |
+
"default": null,
|
289 |
+
"name": "chat",
|
290 |
+
"type": {
|
291 |
+
"type": "<class 'str'>"
|
292 |
+
}
|
293 |
+
}
|
294 |
+
},
|
295 |
+
"position": {
|
296 |
+
"x": 1260.0,
|
297 |
+
"y": 166.0
|
298 |
+
},
|
299 |
+
"type": "basic"
|
300 |
+
},
|
301 |
+
"params": {
|
302 |
+
"chat": "Show me a picture about doctors and patients!"
|
303 |
+
},
|
304 |
+
"status": "done",
|
305 |
+
"title": "Input chat"
|
306 |
+
},
|
307 |
+
"dragHandle": ".bg-primary",
|
308 |
+
"height": 218.0,
|
309 |
+
"id": "Input chat 1",
|
310 |
+
"position": {
|
311 |
+
"x": 153.0,
|
312 |
+
"y": -47.0
|
313 |
+
},
|
314 |
+
"type": "basic",
|
315 |
+
"width": 776.0
|
316 |
+
},
|
317 |
+
{
|
318 |
+
"data": {
|
319 |
+
"display": null,
|
320 |
+
"error": null,
|
321 |
+
"input_metadata": null,
|
322 |
+
"meta": {
|
323 |
+
"inputs": {
|
324 |
+
"rag_graph": {
|
325 |
+
"name": "rag_graph",
|
326 |
+
"position": "bottom",
|
327 |
+
"type": {
|
328 |
+
"type": "<class 'inspect._empty'>"
|
329 |
+
}
|
330 |
+
},
|
331 |
+
"text": {
|
332 |
+
"name": "text",
|
333 |
+
"position": "left",
|
334 |
+
"type": {
|
335 |
+
"type": "<class 'inspect._empty'>"
|
336 |
+
}
|
337 |
+
}
|
338 |
+
},
|
339 |
+
"name": "LynxScribe Image RAG Query",
|
340 |
+
"outputs": {
|
341 |
+
"output": {
|
342 |
+
"name": "output",
|
343 |
+
"position": "right",
|
344 |
+
"type": {
|
345 |
+
"type": "None"
|
346 |
+
}
|
347 |
+
}
|
348 |
+
},
|
349 |
+
"params": {
|
350 |
+
"top_k": {
|
351 |
+
"default": 3.0,
|
352 |
+
"name": "top_k",
|
353 |
+
"type": {
|
354 |
+
"type": "<class 'int'>"
|
355 |
+
}
|
356 |
+
}
|
357 |
+
},
|
358 |
+
"position": {
|
359 |
+
"x": 1987.0,
|
360 |
+
"y": 365.0
|
361 |
+
},
|
362 |
+
"type": "basic"
|
363 |
+
},
|
364 |
+
"params": {
|
365 |
+
"top_k": 3.0
|
366 |
+
},
|
367 |
+
"status": "done",
|
368 |
+
"title": "LynxScribe Image RAG Query"
|
369 |
+
},
|
370 |
+
"dragHandle": ".bg-primary",
|
371 |
+
"height": 207.0,
|
372 |
+
"id": "LynxScribe Image RAG Query 1",
|
373 |
+
"position": {
|
374 |
+
"x": 1160.0,
|
375 |
+
"y": -40.0
|
376 |
+
},
|
377 |
+
"type": "basic",
|
378 |
+
"width": 283.0
|
379 |
+
},
|
380 |
+
{
|
381 |
+
"data": {
|
382 |
+
"display": "https://storage.googleapis.com/lynxkite_public_data/lynxscribe-images/image-rag-test/bethesda-naval-medical-center-80380_1280.jpg",
|
383 |
+
"error": null,
|
384 |
+
"input_metadata": null,
|
385 |
+
"meta": {
|
386 |
+
"inputs": {
|
387 |
+
"embedding_similarities": {
|
388 |
+
"name": "embedding_similarities",
|
389 |
+
"position": "left",
|
390 |
+
"type": {
|
391 |
+
"type": "<class 'inspect._empty'>"
|
392 |
+
}
|
393 |
+
}
|
394 |
+
},
|
395 |
+
"name": "LynxScribe Image Result Viewer",
|
396 |
+
"outputs": {},
|
397 |
+
"params": {},
|
398 |
+
"position": {
|
399 |
+
"x": 2326.0,
|
400 |
+
"y": 319.0
|
401 |
+
},
|
402 |
+
"type": "image"
|
403 |
+
},
|
404 |
+
"params": {},
|
405 |
+
"status": "done",
|
406 |
+
"title": "LynxScribe Image Result Viewer"
|
407 |
+
},
|
408 |
+
"dragHandle": ".bg-primary",
|
409 |
+
"height": 515.0,
|
410 |
+
"id": "LynxScribe Image Result Viewer 1",
|
411 |
+
"position": {
|
412 |
+
"x": 1657.0,
|
413 |
+
"y": -193.0
|
414 |
+
},
|
415 |
+
"type": "image",
|
416 |
+
"width": 707.0
|
417 |
+
}
|
418 |
+
]
|
419 |
+
}
|
examples/{LynxScribe demo.lynxkite.json → LynxScribe RAG Chatbot.lynxkite.json}
RENAMED
@@ -1,217 +1,243 @@
|
|
1 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
"env": "LynxScribe",
|
3 |
"nodes": [
|
4 |
{
|
5 |
-
"id": "Input chat 1",
|
6 |
-
"type": "basic",
|
7 |
"data": {
|
8 |
-
"
|
9 |
-
"
|
10 |
-
"chat": "who is the CTO of Lynx?"
|
11 |
-
},
|
12 |
"display": null,
|
13 |
"error": null,
|
14 |
-
"
|
15 |
"meta": {
|
16 |
"inputs": {},
|
17 |
-
"
|
18 |
-
"chat": {
|
19 |
-
"default": null,
|
20 |
-
"type": {
|
21 |
-
"type": "<class 'str'>"
|
22 |
-
},
|
23 |
-
"name": "chat"
|
24 |
-
}
|
25 |
-
},
|
26 |
"outputs": {
|
27 |
"output": {
|
28 |
"name": "output",
|
|
|
29 |
"type": {
|
30 |
"type": "None"
|
31 |
-
}
|
32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
}
|
34 |
},
|
35 |
-
"name": "Input chat",
|
36 |
"type": "basic"
|
37 |
},
|
38 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
},
|
|
|
|
|
|
|
40 |
"position": {
|
41 |
-
"x": -
|
42 |
-
"y":
|
43 |
},
|
44 |
-
"
|
45 |
-
"width":
|
46 |
-
"parentId": null
|
47 |
},
|
48 |
{
|
49 |
-
"id": "View 1",
|
50 |
-
"type": "table_view",
|
51 |
"data": {
|
52 |
-
"
|
53 |
-
"
|
54 |
-
"display":
|
55 |
-
"dataframes": {
|
56 |
-
"df": {
|
57 |
-
"columns": [
|
58 |
-
"answer"
|
59 |
-
],
|
60 |
-
"data": [
|
61 |
-
[
|
62 |
-
"TheThe Chief Technology Officer (CTO) of Lynx Analytics is Chema Lizano. He leads the technology strategy and roadmap at the company, overseeing the vision, development, and implementation of solutions across various clients and environments. If you have any more questions regarding our team or services, feel free to ask!\n\nPlease visit https://www.lynxanalytics.com/board for further information."
|
63 |
-
]
|
64 |
-
]
|
65 |
-
}
|
66 |
-
}
|
67 |
-
},
|
68 |
"error": null,
|
|
|
69 |
"meta": {
|
70 |
-
"type": "table_view",
|
71 |
-
"name": "View",
|
72 |
"inputs": {
|
73 |
-
"
|
74 |
-
"name": "
|
|
|
75 |
"type": {
|
76 |
"type": "<class 'inspect._empty'>"
|
77 |
-
}
|
78 |
-
"position": "left"
|
79 |
}
|
80 |
},
|
81 |
-
"
|
82 |
-
"params": {}
|
83 |
-
}
|
84 |
-
},
|
85 |
-
"position": {
|
86 |
-
"x": 731.7440706129762,
|
87 |
-
"y": -716.4943976910913
|
88 |
-
},
|
89 |
-
"width": 1256.0,
|
90 |
-
"parentId": null,
|
91 |
-
"height": 950.0
|
92 |
-
},
|
93 |
-
{
|
94 |
-
"id": "LLM 1",
|
95 |
-
"type": "basic",
|
96 |
-
"data": {
|
97 |
-
"title": "LLM",
|
98 |
-
"params": {
|
99 |
-
"name": "openai"
|
100 |
-
},
|
101 |
-
"display": null,
|
102 |
-
"error": null,
|
103 |
-
"meta": {
|
104 |
-
"inputs": {},
|
105 |
"outputs": {
|
106 |
"output": {
|
|
|
|
|
107 |
"type": {
|
108 |
"type": "None"
|
109 |
-
}
|
110 |
-
"name": "output",
|
111 |
-
"position": "top"
|
112 |
}
|
113 |
},
|
114 |
-
"type": "basic",
|
115 |
"params": {
|
116 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
"default": "openai",
|
118 |
-
"name": "
|
119 |
"type": {
|
120 |
"type": "<class 'str'>"
|
121 |
}
|
122 |
-
}
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
},
|
127 |
-
"position": {
|
128 |
-
"x": -312.5774211084781,
|
129 |
-
"y": 1093.4019527511366
|
130 |
-
},
|
131 |
-
"parentId": null,
|
132 |
-
"width": 200.0,
|
133 |
-
"height": 200.0
|
134 |
-
},
|
135 |
-
{
|
136 |
-
"id": "Scenario selector 1",
|
137 |
-
"type": "basic",
|
138 |
-
"data": {
|
139 |
-
"title": "Scenario selector",
|
140 |
-
"params": {
|
141 |
-
"scenario_file": "uploads/chat_api/scenarios.yaml",
|
142 |
-
"node_types": "intent_cluster"
|
143 |
-
},
|
144 |
-
"display": null,
|
145 |
-
"error": null,
|
146 |
-
"meta": {
|
147 |
-
"params": {
|
148 |
-
"scenario_file": {
|
149 |
"type": {
|
150 |
"type": "<class 'str'>"
|
151 |
-
}
|
152 |
-
"name": "scenario_file",
|
153 |
-
"default": null
|
154 |
},
|
155 |
-
"
|
156 |
-
"default": "
|
|
|
157 |
"type": {
|
158 |
"type": "<class 'str'>"
|
159 |
-
}
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
"outputs": {
|
165 |
-
"output": {
|
166 |
-
"position": "top",
|
167 |
-
"name": "output",
|
168 |
"type": {
|
169 |
-
"type": "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
170 |
}
|
171 |
}
|
172 |
},
|
173 |
-
"type": "basic"
|
174 |
-
|
175 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
176 |
},
|
|
|
|
|
|
|
177 |
"position": {
|
178 |
-
"x": -
|
179 |
-
"y":
|
180 |
},
|
181 |
-
"
|
182 |
-
"
|
183 |
-
"width": 200.0
|
184 |
},
|
185 |
{
|
186 |
-
"id": "Chat API 1",
|
187 |
-
"type": "basic",
|
188 |
"data": {
|
189 |
-
"
|
190 |
-
"
|
191 |
-
"model": "gpt-4o-mini"
|
192 |
-
},
|
193 |
"display": null,
|
194 |
"error": null,
|
|
|
195 |
"meta": {
|
196 |
-
"name": "Chat API",
|
197 |
-
"type": "basic",
|
198 |
-
"outputs": {
|
199 |
-
"output": {
|
200 |
-
"type": {
|
201 |
-
"type": "None"
|
202 |
-
},
|
203 |
-
"position": "top",
|
204 |
-
"name": "output"
|
205 |
-
}
|
206 |
-
},
|
207 |
"inputs": {
|
208 |
-
"chatbot": {
|
209 |
-
"name": "chatbot",
|
210 |
-
"type": {
|
211 |
-
"type": "<class 'inspect._empty'>"
|
212 |
-
},
|
213 |
-
"position": "bottom"
|
214 |
-
},
|
215 |
"chat_processor": {
|
216 |
"name": "chat_processor",
|
217 |
"position": "bottom",
|
@@ -220,126 +246,36 @@
|
|
220 |
}
|
221 |
},
|
222 |
"knowledge_base": {
|
223 |
-
"
|
224 |
-
"type": "<class 'inspect._empty'>"
|
225 |
-
},
|
226 |
"position": "bottom",
|
227 |
-
"name": "knowledge_base"
|
228 |
-
}
|
229 |
-
},
|
230 |
-
"params": {
|
231 |
-
"model": {
|
232 |
-
"default": "gpt-4o-mini",
|
233 |
-
"type": {
|
234 |
-
"type": "<class 'str'>"
|
235 |
-
},
|
236 |
-
"name": "model"
|
237 |
-
}
|
238 |
-
}
|
239 |
-
}
|
240 |
-
},
|
241 |
-
"position": {
|
242 |
-
"x": -22.866663363810787,
|
243 |
-
"y": 258.20943122219336
|
244 |
-
},
|
245 |
-
"parentId": null,
|
246 |
-
"width": 200.0,
|
247 |
-
"height": 200.0
|
248 |
-
},
|
249 |
-
{
|
250 |
-
"id": "Knowledge base 1",
|
251 |
-
"type": "basic",
|
252 |
-
"data": {
|
253 |
-
"title": "Knowledge base",
|
254 |
-
"params": {
|
255 |
-
"template_cluster_path": "uploads/chat_api/data/lynx/tempclusters.pickle",
|
256 |
-
"edges_path": "uploads/chat_api/data/lynx/edges.pickle",
|
257 |
-
"nodes_path": "uploads/chat_api/data/lynx/nodes.pickle"
|
258 |
-
},
|
259 |
-
"display": null,
|
260 |
-
"error": null,
|
261 |
-
"meta": {
|
262 |
-
"name": "Knowledge base",
|
263 |
-
"type": "basic",
|
264 |
-
"params": {
|
265 |
-
"nodes_path": {
|
266 |
-
"name": "nodes_path",
|
267 |
-
"default": "nodes.pickle",
|
268 |
-
"type": {
|
269 |
-
"type": "<class 'str'>"
|
270 |
-
}
|
271 |
-
},
|
272 |
-
"template_cluster_path": {
|
273 |
-
"type": {
|
274 |
-
"type": "<class 'str'>"
|
275 |
-
},
|
276 |
-
"name": "template_cluster_path",
|
277 |
-
"default": "tempclusters.pickle"
|
278 |
-
},
|
279 |
-
"edges_path": {
|
280 |
-
"name": "edges_path",
|
281 |
-
"default": "edges.pickle",
|
282 |
"type": {
|
283 |
-
"type": "<class '
|
284 |
}
|
285 |
}
|
286 |
},
|
287 |
-
"
|
288 |
"outputs": {
|
289 |
"output": {
|
290 |
-
"position": "top",
|
291 |
"name": "output",
|
292 |
-
"type": {
|
293 |
-
"type": "None"
|
294 |
-
}
|
295 |
-
}
|
296 |
-
}
|
297 |
-
}
|
298 |
-
},
|
299 |
-
"position": {
|
300 |
-
"x": 598.8683124946176,
|
301 |
-
"y": 609.9499973808545
|
302 |
-
},
|
303 |
-
"width": 336.0,
|
304 |
-
"height": 320.0,
|
305 |
-
"parentId": null
|
306 |
-
},
|
307 |
-
{
|
308 |
-
"id": "RAG chatbot 1",
|
309 |
-
"type": "basic",
|
310 |
-
"data": {
|
311 |
-
"title": "RAG chatbot",
|
312 |
-
"params": {
|
313 |
-
"limits_by_type": "{\"information\": [2, 3], \"summary\": [2, 3]}",
|
314 |
-
"max_results": "5",
|
315 |
-
"negative_answer": "I'm sorry, but the data I've been trained on does not contain any information related to your question.",
|
316 |
-
"strict_limits": true
|
317 |
-
},
|
318 |
-
"display": null,
|
319 |
-
"error": null,
|
320 |
-
"meta": {
|
321 |
-
"outputs": {
|
322 |
-
"output": {
|
323 |
"position": "top",
|
324 |
-
"name": "output",
|
325 |
"type": {
|
326 |
"type": "None"
|
327 |
}
|
328 |
}
|
329 |
},
|
330 |
"params": {
|
331 |
-
"
|
332 |
-
"default":
|
|
|
333 |
"type": {
|
334 |
-
"type": "<class '
|
335 |
-
}
|
336 |
-
"name": "max_results"
|
337 |
},
|
338 |
-
"
|
339 |
-
"
|
340 |
-
"
|
341 |
"type": {
|
342 |
-
"type": "<class '
|
343 |
}
|
344 |
},
|
345 |
"negative_answer": {
|
@@ -349,404 +285,395 @@
|
|
349 |
"type": "<class 'str'>"
|
350 |
}
|
351 |
},
|
352 |
-
"
|
353 |
"default": "{}",
|
354 |
-
"name": "
|
355 |
"type": {
|
356 |
"type": "<class 'str'>"
|
357 |
}
|
358 |
-
}
|
359 |
-
},
|
360 |
-
"name": "RAG chatbot",
|
361 |
-
"type": "basic",
|
362 |
-
"inputs": {
|
363 |
-
"rag_graph": {
|
364 |
-
"type": {
|
365 |
-
"type": "<class 'inspect._empty'>"
|
366 |
-
},
|
367 |
-
"name": "rag_graph",
|
368 |
-
"position": "bottom"
|
369 |
},
|
370 |
-
"
|
371 |
-
"
|
372 |
-
"
|
373 |
"type": {
|
374 |
-
"type": "<class '
|
375 |
}
|
376 |
},
|
377 |
-
"
|
|
|
|
|
378 |
"type": {
|
379 |
-
"type": "<class '
|
380 |
-
}
|
381 |
-
|
382 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
383 |
}
|
384 |
-
}
|
|
|
385 |
},
|
386 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
387 |
},
|
|
|
|
|
|
|
388 |
"position": {
|
389 |
-
"x":
|
390 |
-
"y":
|
391 |
},
|
392 |
-
"
|
393 |
-
"
|
394 |
-
"width": 339.0
|
395 |
},
|
396 |
{
|
397 |
-
"id": "RAG graph 1",
|
398 |
-
"type": "basic",
|
399 |
"data": {
|
400 |
-
"title": "RAG graph",
|
401 |
-
"params": {},
|
402 |
"display": null,
|
403 |
"error": null,
|
|
|
404 |
"meta": {
|
405 |
-
"type": "basic",
|
406 |
"inputs": {
|
407 |
-
"
|
408 |
-
"
|
409 |
-
"type": "<class 'inspect._empty'>"
|
410 |
-
},
|
411 |
-
"position": "bottom",
|
412 |
-
"name": "text_embedder"
|
413 |
-
},
|
414 |
-
"vector_store": {
|
415 |
"position": "bottom",
|
416 |
"type": {
|
417 |
"type": "<class 'inspect._empty'>"
|
418 |
-
}
|
419 |
-
"name": "vector_store"
|
420 |
}
|
421 |
},
|
422 |
-
"name": "
|
423 |
-
"params": {},
|
424 |
"outputs": {
|
425 |
"output": {
|
|
|
426 |
"position": "top",
|
427 |
"type": {
|
428 |
"type": "None"
|
429 |
-
}
|
430 |
-
"name": "output"
|
431 |
}
|
432 |
-
}
|
433 |
-
|
|
|
|
|
|
|
|
|
|
|
434 |
},
|
|
|
|
|
|
|
435 |
"position": {
|
436 |
-
"x":
|
437 |
-
"y":
|
438 |
},
|
439 |
-
"
|
440 |
-
"width":
|
441 |
-
"height": 200.0
|
442 |
},
|
443 |
{
|
444 |
-
"id": "Vector store 1",
|
445 |
-
"type": "basic",
|
446 |
"data": {
|
447 |
-
"title": "Vector store",
|
448 |
-
"params": {
|
449 |
-
"name": "chromadb",
|
450 |
-
"collection_name": "lynx"
|
451 |
-
},
|
452 |
"display": null,
|
453 |
"error": null,
|
454 |
-
"
|
455 |
"meta": {
|
456 |
-
"
|
457 |
-
|
458 |
-
"type": {
|
459 |
-
"type": "<class 'str'>"
|
460 |
-
},
|
461 |
-
"default": "lynx",
|
462 |
-
"name": "collection_name"
|
463 |
-
},
|
464 |
-
"name": {
|
465 |
-
"default": "chromadb",
|
466 |
-
"type": {
|
467 |
-
"type": "<class 'str'>"
|
468 |
-
},
|
469 |
-
"name": "name"
|
470 |
-
}
|
471 |
-
},
|
472 |
-
"type": "basic",
|
473 |
-
"name": "Vector store",
|
474 |
"outputs": {
|
475 |
"output": {
|
|
|
|
|
476 |
"type": {
|
477 |
"type": "None"
|
478 |
-
}
|
479 |
-
"position": "top",
|
480 |
-
"name": "output"
|
481 |
}
|
482 |
},
|
483 |
-
"inputs": {}
|
484 |
-
}
|
485 |
-
},
|
486 |
-
"position": {
|
487 |
-
"x": -1053.794625339574,
|
488 |
-
"y": 1347.7711940497127
|
489 |
-
},
|
490 |
-
"height": 227.0,
|
491 |
-
"parentId": null,
|
492 |
-
"width": 275.0
|
493 |
-
},
|
494 |
-
{
|
495 |
-
"id": "Text embedder 2",
|
496 |
-
"type": "basic",
|
497 |
-
"data": {
|
498 |
-
"title": "Text embedder",
|
499 |
-
"params": {
|
500 |
-
"model": "text-embedding-ada-002"
|
501 |
-
},
|
502 |
-
"display": null,
|
503 |
-
"error": null,
|
504 |
-
"meta": {
|
505 |
"params": {
|
506 |
-
"
|
507 |
-
"default":
|
508 |
-
"
|
509 |
-
"type": "<class 'str'>"
|
510 |
-
},
|
511 |
-
"name": "model"
|
512 |
-
}
|
513 |
-
},
|
514 |
-
"name": "Text embedder",
|
515 |
-
"outputs": {
|
516 |
-
"output": {
|
517 |
"type": {
|
518 |
-
"type": "
|
519 |
-
}
|
520 |
-
"position": "top",
|
521 |
-
"name": "output"
|
522 |
}
|
523 |
},
|
524 |
-
"type": "basic"
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
"position": "bottom"
|
532 |
-
}
|
533 |
-
}
|
534 |
-
}
|
535 |
},
|
|
|
|
|
|
|
536 |
"position": {
|
537 |
-
"x":
|
538 |
-
"y":
|
539 |
},
|
540 |
-
"
|
541 |
-
"
|
542 |
-
"parentId": null
|
543 |
},
|
544 |
{
|
545 |
-
"id": "LLM 2",
|
546 |
-
"type": "basic",
|
547 |
"data": {
|
548 |
-
"
|
549 |
-
"
|
550 |
-
"name": "openai"
|
551 |
-
},
|
552 |
"display": null,
|
553 |
"error": null,
|
|
|
554 |
"meta": {
|
|
|
|
|
555 |
"outputs": {
|
556 |
"output": {
|
557 |
-
"position": "top",
|
558 |
"name": "output",
|
|
|
559 |
"type": {
|
560 |
"type": "None"
|
561 |
}
|
562 |
}
|
563 |
},
|
564 |
-
"name": "LLM",
|
565 |
-
"type": "basic",
|
566 |
-
"inputs": {},
|
567 |
"params": {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
568 |
"name": {
|
569 |
-
"default": "
|
570 |
"name": "name",
|
571 |
"type": {
|
572 |
"type": "<class 'str'>"
|
573 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
574 |
}
|
575 |
-
}
|
576 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
577 |
},
|
|
|
|
|
|
|
578 |
"position": {
|
579 |
-
"x":
|
580 |
-
"y":
|
581 |
},
|
582 |
-
"
|
583 |
-
"
|
584 |
-
"height": 200.0
|
585 |
},
|
586 |
{
|
587 |
-
"id": "Truncate history 1",
|
588 |
-
"type": "basic",
|
589 |
"data": {
|
590 |
-
"
|
591 |
-
"
|
592 |
-
"max_tokens": 10000.0
|
593 |
-
},
|
594 |
"display": null,
|
595 |
"error": null,
|
|
|
596 |
"meta": {
|
|
|
|
|
597 |
"outputs": {
|
598 |
"output": {
|
|
|
|
|
599 |
"type": {
|
600 |
"type": "None"
|
601 |
-
}
|
602 |
-
"name": "output",
|
603 |
-
"position": "top"
|
604 |
}
|
605 |
},
|
606 |
-
"type": "basic",
|
607 |
"params": {
|
608 |
-
"
|
609 |
-
"default":
|
610 |
-
"name": "
|
611 |
"type": {
|
612 |
-
"type": "<class '
|
613 |
}
|
614 |
}
|
615 |
},
|
616 |
-
"
|
617 |
-
|
618 |
-
|
|
|
|
|
|
|
|
|
619 |
},
|
|
|
|
|
|
|
620 |
"position": {
|
621 |
-
"x":
|
622 |
-
"y":
|
623 |
},
|
624 |
-
"
|
625 |
-
"width":
|
626 |
-
"parentId": null
|
627 |
},
|
628 |
{
|
629 |
-
"id": "Chat processor 1",
|
630 |
-
"type": "basic",
|
631 |
"data": {
|
632 |
-
"
|
633 |
-
"
|
634 |
"display": null,
|
635 |
"error": null,
|
636 |
-
"
|
637 |
-
"collapsed": true,
|
638 |
"meta": {
|
639 |
-
"name": "Chat processor",
|
640 |
"inputs": {
|
641 |
-
"
|
642 |
-
"name": "
|
643 |
"position": "bottom",
|
644 |
"type": {
|
645 |
"type": "<class 'inspect._empty'>"
|
646 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
647 |
}
|
648 |
},
|
649 |
-
"
|
650 |
-
"type": "basic",
|
651 |
"outputs": {
|
652 |
"output": {
|
|
|
|
|
653 |
"type": {
|
654 |
"type": "None"
|
655 |
-
}
|
656 |
-
"position": "top",
|
657 |
-
"name": "output"
|
658 |
}
|
659 |
-
}
|
660 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
661 |
},
|
|
|
|
|
|
|
662 |
"position": {
|
663 |
-
"x":
|
664 |
-
"y":
|
665 |
},
|
666 |
-
"
|
667 |
-
"width":
|
668 |
-
"height": 200.0
|
669 |
},
|
670 |
{
|
671 |
-
"id": "Mask 1",
|
672 |
-
"type": "basic",
|
673 |
"data": {
|
674 |
-
"
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
680 |
},
|
681 |
-
"display": null,
|
682 |
"error": null,
|
|
|
683 |
"meta": {
|
684 |
-
"inputs": {
|
685 |
-
|
686 |
-
|
687 |
-
"position": "
|
688 |
-
"name": "output",
|
689 |
"type": {
|
690 |
-
"type": "
|
691 |
}
|
692 |
}
|
693 |
},
|
694 |
-
"
|
695 |
-
"
|
696 |
-
"params": {
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
}
|
703 |
-
},
|
704 |
-
"exceptions": {
|
705 |
-
"name": "exceptions",
|
706 |
-
"type": {
|
707 |
-
"type": "<class 'str'>"
|
708 |
-
},
|
709 |
-
"default": ""
|
710 |
-
},
|
711 |
-
"regex": {
|
712 |
-
"type": {
|
713 |
-
"type": "<class 'str'>"
|
714 |
-
},
|
715 |
-
"name": "regex",
|
716 |
-
"default": ""
|
717 |
-
},
|
718 |
-
"mask_pattern": {
|
719 |
-
"default": "",
|
720 |
-
"type": {
|
721 |
-
"type": "<class 'str'>"
|
722 |
-
},
|
723 |
-
"name": "mask_pattern"
|
724 |
-
}
|
725 |
-
}
|
726 |
-
}
|
727 |
},
|
|
|
|
|
|
|
728 |
"position": {
|
729 |
-
"x":
|
730 |
-
"y":
|
731 |
},
|
732 |
-
"
|
733 |
-
"
|
734 |
-
"width": 200.0
|
735 |
},
|
736 |
{
|
737 |
-
"id": "Mask 2",
|
738 |
-
"type": "basic",
|
739 |
"data": {
|
740 |
-
"
|
741 |
-
"
|
742 |
-
"regex": "((?:(?:\\\\d{4}[- ]?){3}\\\\d{4}|\\\\d{15,16}))(?![\\\\d])",
|
743 |
-
"exceptions": "",
|
744 |
-
"name": "credit_card",
|
745 |
-
"mask_pattern": "masked_credit_card_number_{}"
|
746 |
-
},
|
747 |
"display": null,
|
748 |
"error": null,
|
|
|
749 |
"meta": {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
750 |
"outputs": {
|
751 |
"output": {
|
752 |
"name": "output",
|
@@ -756,214 +683,52 @@
|
|
756 |
}
|
757 |
}
|
758 |
},
|
759 |
-
"inputs": {},
|
760 |
-
"name": "Mask",
|
761 |
-
"type": "basic",
|
762 |
"params": {
|
763 |
-
"
|
764 |
-
"
|
765 |
-
|
766 |
-
},
|
767 |
-
"default": "",
|
768 |
-
"name": "exceptions"
|
769 |
-
},
|
770 |
-
"regex": {
|
771 |
-
"default": "",
|
772 |
"type": {
|
773 |
"type": "<class 'str'>"
|
774 |
-
}
|
775 |
-
"name": "regex"
|
776 |
},
|
777 |
-
"
|
778 |
-
"
|
|
|
779 |
"type": {
|
780 |
"type": "<class 'str'>"
|
781 |
-
}
|
782 |
-
"default": ""
|
783 |
},
|
784 |
-
"
|
785 |
-
"
|
786 |
-
"
|
787 |
"type": {
|
788 |
"type": "<class 'str'>"
|
789 |
}
|
790 |
}
|
791 |
-
}
|
792 |
-
}
|
793 |
-
},
|
794 |
-
"position": {
|
795 |
-
"x": 513.2761671440603,
|
796 |
-
"y": 1034.8547191984255
|
797 |
-
},
|
798 |
-
"width": 200.0,
|
799 |
-
"parentId": null,
|
800 |
-
"height": 200.0
|
801 |
-
},
|
802 |
-
{
|
803 |
-
"id": "Test Chat API 2",
|
804 |
-
"type": "basic",
|
805 |
-
"data": {
|
806 |
-
"title": "Test Chat API",
|
807 |
-
"params": {
|
808 |
-
"show_details": false
|
809 |
-
},
|
810 |
-
"display": null,
|
811 |
-
"error": null,
|
812 |
-
"collapsed": false,
|
813 |
-
"__execution_delay": 0.0,
|
814 |
-
"meta": {
|
815 |
-
"params": {
|
816 |
-
"show_details": {
|
817 |
-
"default": false,
|
818 |
-
"type": {
|
819 |
-
"type": "<class 'bool'>"
|
820 |
-
},
|
821 |
-
"name": "show_details"
|
822 |
-
}
|
823 |
-
},
|
824 |
-
"inputs": {
|
825 |
-
"message": {
|
826 |
-
"name": "message",
|
827 |
-
"position": "left",
|
828 |
-
"type": {
|
829 |
-
"type": "<class 'inspect._empty'>"
|
830 |
-
}
|
831 |
-
},
|
832 |
-
"chat_api": {
|
833 |
-
"position": "bottom",
|
834 |
-
"type": {
|
835 |
-
"type": "<class 'inspect._empty'>"
|
836 |
-
},
|
837 |
-
"name": "chat_api"
|
838 |
-
}
|
839 |
},
|
840 |
-
"
|
841 |
-
"
|
842 |
-
|
843 |
-
"type": {
|
844 |
-
"type": "None"
|
845 |
-
},
|
846 |
-
"name": "output"
|
847 |
-
}
|
848 |
},
|
849 |
-
"name": "Test Chat API",
|
850 |
"type": "basic"
|
851 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
852 |
},
|
|
|
|
|
|
|
853 |
"position": {
|
854 |
-
"x":
|
855 |
-
"y":
|
856 |
},
|
857 |
-
"
|
858 |
-
"
|
859 |
-
"height": 225.0
|
860 |
-
}
|
861 |
-
],
|
862 |
-
"edges": [
|
863 |
-
{
|
864 |
-
"id": "xy-edge__Knowledge base 1output-Chat API 1knowledge_base",
|
865 |
-
"source": "Knowledge base 1",
|
866 |
-
"target": "Chat API 1",
|
867 |
-
"sourceHandle": "output",
|
868 |
-
"targetHandle": "knowledge_base"
|
869 |
-
},
|
870 |
-
{
|
871 |
-
"id": "xy-edge__RAG chatbot 1output-Chat API 1chatbot",
|
872 |
-
"source": "RAG chatbot 1",
|
873 |
-
"target": "Chat API 1",
|
874 |
-
"sourceHandle": "output",
|
875 |
-
"targetHandle": "chatbot"
|
876 |
-
},
|
877 |
-
{
|
878 |
-
"id": "xy-edge__LLM 1output-RAG chatbot 1llm",
|
879 |
-
"source": "LLM 1",
|
880 |
-
"target": "RAG chatbot 1",
|
881 |
-
"sourceHandle": "output",
|
882 |
-
"targetHandle": "llm"
|
883 |
-
},
|
884 |
-
{
|
885 |
-
"id": "xy-edge__Scenario selector 1output-RAG chatbot 1scenario_selector",
|
886 |
-
"source": "Scenario selector 1",
|
887 |
-
"target": "RAG chatbot 1",
|
888 |
-
"sourceHandle": "output",
|
889 |
-
"targetHandle": "scenario_selector"
|
890 |
-
},
|
891 |
-
{
|
892 |
-
"id": "xy-edge__RAG graph 1output-RAG chatbot 1rag_graph",
|
893 |
-
"source": "RAG graph 1",
|
894 |
-
"target": "RAG chatbot 1",
|
895 |
-
"sourceHandle": "output",
|
896 |
-
"targetHandle": "rag_graph"
|
897 |
-
},
|
898 |
-
{
|
899 |
-
"id": "xy-edge__Vector store 1output-RAG graph 1vector_store",
|
900 |
-
"source": "Vector store 1",
|
901 |
-
"target": "RAG graph 1",
|
902 |
-
"sourceHandle": "output",
|
903 |
-
"targetHandle": "vector_store"
|
904 |
-
},
|
905 |
-
{
|
906 |
-
"id": "xy-edge__Text embedder 2output-RAG graph 1text_embedder",
|
907 |
-
"source": "Text embedder 2",
|
908 |
-
"target": "RAG graph 1",
|
909 |
-
"sourceHandle": "output",
|
910 |
-
"targetHandle": "text_embedder"
|
911 |
-
},
|
912 |
-
{
|
913 |
-
"id": "xy-edge__LLM 2output-Text embedder 2llm",
|
914 |
-
"source": "LLM 2",
|
915 |
-
"target": "Text embedder 2",
|
916 |
-
"sourceHandle": "output",
|
917 |
-
"targetHandle": "llm"
|
918 |
-
},
|
919 |
-
{
|
920 |
-
"id": "xy-edge__Truncate history 1output-Chat processor 1processor",
|
921 |
-
"source": "Truncate history 1",
|
922 |
-
"target": "Chat processor 1",
|
923 |
-
"sourceHandle": "output",
|
924 |
-
"targetHandle": "processor"
|
925 |
-
},
|
926 |
-
{
|
927 |
-
"id": "xy-edge__Chat processor 1output-Chat API 1chat_processor",
|
928 |
-
"source": "Chat processor 1",
|
929 |
-
"target": "Chat API 1",
|
930 |
-
"sourceHandle": "output",
|
931 |
-
"targetHandle": "chat_processor"
|
932 |
-
},
|
933 |
-
{
|
934 |
-
"id": "xy-edge__Mask 1output-Chat processor 1processor",
|
935 |
-
"source": "Mask 1",
|
936 |
-
"target": "Chat processor 1",
|
937 |
-
"sourceHandle": "output",
|
938 |
-
"targetHandle": "processor"
|
939 |
-
},
|
940 |
-
{
|
941 |
-
"id": "xy-edge__Mask 2output-Chat processor 1processor",
|
942 |
-
"source": "Mask 2",
|
943 |
-
"target": "Chat processor 1",
|
944 |
-
"sourceHandle": "output",
|
945 |
-
"targetHandle": "processor"
|
946 |
-
},
|
947 |
-
{
|
948 |
-
"id": "xy-edge__Input chat 1output-Test Chat API 2message",
|
949 |
-
"source": "Input chat 1",
|
950 |
-
"target": "Test Chat API 2",
|
951 |
-
"sourceHandle": "output",
|
952 |
-
"targetHandle": "message"
|
953 |
-
},
|
954 |
-
{
|
955 |
-
"id": "xy-edge__Test Chat API 2output-View 1input",
|
956 |
-
"source": "Test Chat API 2",
|
957 |
-
"target": "View 1",
|
958 |
-
"sourceHandle": "output",
|
959 |
-
"targetHandle": "input"
|
960 |
-
},
|
961 |
-
{
|
962 |
-
"id": "xy-edge__Chat API 1output-Test Chat API 2chat_api",
|
963 |
-
"source": "Chat API 1",
|
964 |
-
"target": "Test Chat API 2",
|
965 |
-
"sourceHandle": "output",
|
966 |
-
"targetHandle": "chat_api"
|
967 |
}
|
968 |
]
|
969 |
}
|
|
|
1 |
{
|
2 |
+
"edges": [
|
3 |
+
{
|
4 |
+
"id": "Cloud-sourced File Listing 1 LynxScribe Text RAG Loader 1",
|
5 |
+
"source": "Cloud-sourced File Listing 1",
|
6 |
+
"sourceHandle": "output",
|
7 |
+
"target": "LynxScribe Text RAG Loader 1",
|
8 |
+
"targetHandle": "file_urls"
|
9 |
+
},
|
10 |
+
{
|
11 |
+
"id": "Truncate history 1 Chat processor 1",
|
12 |
+
"source": "Truncate history 1",
|
13 |
+
"sourceHandle": "output",
|
14 |
+
"target": "Chat processor 1",
|
15 |
+
"targetHandle": "processor"
|
16 |
+
},
|
17 |
+
{
|
18 |
+
"id": "Chat processor 1 LynxScribe RAG Graph Chatbot Backend 1",
|
19 |
+
"source": "Chat processor 1",
|
20 |
+
"sourceHandle": "output",
|
21 |
+
"target": "LynxScribe RAG Graph Chatbot Backend 1",
|
22 |
+
"targetHandle": "chat_processor"
|
23 |
+
},
|
24 |
+
{
|
25 |
+
"id": "Mask 1 Chat processor 1",
|
26 |
+
"source": "Mask 1",
|
27 |
+
"sourceHandle": "output",
|
28 |
+
"target": "Chat processor 1",
|
29 |
+
"targetHandle": "processor"
|
30 |
+
},
|
31 |
+
{
|
32 |
+
"id": "Input chat 1 Test Chat API 1",
|
33 |
+
"source": "Input chat 1",
|
34 |
+
"sourceHandle": "output",
|
35 |
+
"target": "Test Chat API 1",
|
36 |
+
"targetHandle": "message"
|
37 |
+
},
|
38 |
+
{
|
39 |
+
"id": "LynxScribe RAG Graph Chatbot Backend 1 Test Chat API 1",
|
40 |
+
"source": "LynxScribe RAG Graph Chatbot Backend 1",
|
41 |
+
"sourceHandle": "output",
|
42 |
+
"target": "Test Chat API 1",
|
43 |
+
"targetHandle": "chat_api"
|
44 |
+
},
|
45 |
+
{
|
46 |
+
"id": "Test Chat API 1 View 1",
|
47 |
+
"source": "Test Chat API 1",
|
48 |
+
"sourceHandle": "output",
|
49 |
+
"target": "View 1",
|
50 |
+
"targetHandle": "input"
|
51 |
+
},
|
52 |
+
{
|
53 |
+
"id": "LynxScribe Text RAG Loader 1 LynxScribe RAG Graph Chatbot Builder 1",
|
54 |
+
"source": "LynxScribe Text RAG Loader 1",
|
55 |
+
"sourceHandle": "output",
|
56 |
+
"target": "LynxScribe RAG Graph Chatbot Builder 1",
|
57 |
+
"targetHandle": "rag_graph"
|
58 |
+
},
|
59 |
+
{
|
60 |
+
"id": "LynxScribe RAG Graph Chatbot Builder 1 LynxScribe RAG Graph Chatbot Backend 1",
|
61 |
+
"source": "LynxScribe RAG Graph Chatbot Builder 1",
|
62 |
+
"sourceHandle": "output",
|
63 |
+
"target": "LynxScribe RAG Graph Chatbot Backend 1",
|
64 |
+
"targetHandle": "knowledge_base"
|
65 |
+
}
|
66 |
+
],
|
67 |
"env": "LynxScribe",
|
68 |
"nodes": [
|
69 |
{
|
|
|
|
|
70 |
"data": {
|
71 |
+
"__execution_delay": 0.0,
|
72 |
+
"collapsed": null,
|
|
|
|
|
73 |
"display": null,
|
74 |
"error": null,
|
75 |
+
"input_metadata": null,
|
76 |
"meta": {
|
77 |
"inputs": {},
|
78 |
+
"name": "Cloud-sourced File Listing",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
"outputs": {
|
80 |
"output": {
|
81 |
"name": "output",
|
82 |
+
"position": "right",
|
83 |
"type": {
|
84 |
"type": "None"
|
85 |
+
}
|
86 |
+
}
|
87 |
+
},
|
88 |
+
"params": {
|
89 |
+
"accepted_file_types": {
|
90 |
+
"default": ".jpg, .jpeg, .png",
|
91 |
+
"name": "accepted_file_types",
|
92 |
+
"type": {
|
93 |
+
"type": "<class 'str'>"
|
94 |
+
}
|
95 |
+
},
|
96 |
+
"cloud_provider": {
|
97 |
+
"default": "gcp",
|
98 |
+
"name": "cloud_provider",
|
99 |
+
"type": {
|
100 |
+
"enum": [
|
101 |
+
"GCP",
|
102 |
+
"AWS",
|
103 |
+
"AZURE"
|
104 |
+
]
|
105 |
+
}
|
106 |
+
},
|
107 |
+
"folder_URL": {
|
108 |
+
"default": "https://storage.googleapis.com/lynxkite_public_data/lynxscribe-images/image-rag-test",
|
109 |
+
"name": "folder_URL",
|
110 |
+
"type": {
|
111 |
+
"type": "<class 'str'>"
|
112 |
+
}
|
113 |
}
|
114 |
},
|
|
|
115 |
"type": "basic"
|
116 |
},
|
117 |
+
"params": {
|
118 |
+
"accepted_file_types": ".pickle",
|
119 |
+
"cloud_provider": "GCP",
|
120 |
+
"folder_URL": "https://storage.googleapis.com/lynxkite_public_data/lynxscribe-knowledge-graphs/lynx-chatbot"
|
121 |
+
},
|
122 |
+
"status": "done",
|
123 |
+
"title": "Cloud-sourced File Listing"
|
124 |
},
|
125 |
+
"dragHandle": ".bg-primary",
|
126 |
+
"height": 286.0,
|
127 |
+
"id": "Cloud-sourced File Listing 1",
|
128 |
"position": {
|
129 |
+
"x": -827.0,
|
130 |
+
"y": 382.0
|
131 |
},
|
132 |
+
"type": "basic",
|
133 |
+
"width": 515.0
|
|
|
134 |
},
|
135 |
{
|
|
|
|
|
136 |
"data": {
|
137 |
+
"__execution_delay": 0.0,
|
138 |
+
"collapsed": null,
|
139 |
+
"display": null,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
"error": null,
|
141 |
+
"input_metadata": null,
|
142 |
"meta": {
|
|
|
|
|
143 |
"inputs": {
|
144 |
+
"file_urls": {
|
145 |
+
"name": "file_urls",
|
146 |
+
"position": "left",
|
147 |
"type": {
|
148 |
"type": "<class 'inspect._empty'>"
|
149 |
+
}
|
|
|
150 |
}
|
151 |
},
|
152 |
+
"name": "LynxScribe Text RAG Loader",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
153 |
"outputs": {
|
154 |
"output": {
|
155 |
+
"name": "output",
|
156 |
+
"position": "right",
|
157 |
"type": {
|
158 |
"type": "None"
|
159 |
+
}
|
|
|
|
|
160 |
}
|
161 |
},
|
|
|
162 |
"params": {
|
163 |
+
"input_type": {
|
164 |
+
"default": "v1",
|
165 |
+
"name": "input_type",
|
166 |
+
"type": {
|
167 |
+
"enum": [
|
168 |
+
"V1",
|
169 |
+
"V2"
|
170 |
+
]
|
171 |
+
}
|
172 |
+
},
|
173 |
+
"text_embedder_interface": {
|
174 |
"default": "openai",
|
175 |
+
"name": "text_embedder_interface",
|
176 |
"type": {
|
177 |
"type": "<class 'str'>"
|
178 |
}
|
179 |
+
},
|
180 |
+
"text_embedder_model_name_or_path": {
|
181 |
+
"default": "text-embedding-3-large",
|
182 |
+
"name": "text_embedder_model_name_or_path",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
183 |
"type": {
|
184 |
"type": "<class 'str'>"
|
185 |
+
}
|
|
|
|
|
186 |
},
|
187 |
+
"vdb_collection_name": {
|
188 |
+
"default": "lynx",
|
189 |
+
"name": "vdb_collection_name",
|
190 |
"type": {
|
191 |
"type": "<class 'str'>"
|
192 |
+
}
|
193 |
+
},
|
194 |
+
"vdb_num_dimensions": {
|
195 |
+
"default": 3072.0,
|
196 |
+
"name": "vdb_num_dimensions",
|
|
|
|
|
|
|
|
|
197 |
"type": {
|
198 |
+
"type": "<class 'int'>"
|
199 |
+
}
|
200 |
+
},
|
201 |
+
"vdb_provider_name": {
|
202 |
+
"default": "faiss",
|
203 |
+
"name": "vdb_provider_name",
|
204 |
+
"type": {
|
205 |
+
"type": "<class 'str'>"
|
206 |
}
|
207 |
}
|
208 |
},
|
209 |
+
"type": "basic"
|
210 |
+
},
|
211 |
+
"params": {
|
212 |
+
"input_type": "V1",
|
213 |
+
"text_embedder_interface": "openai",
|
214 |
+
"text_embedder_model_name_or_path": "text-embedding-ada-002",
|
215 |
+
"vdb_collection_name": "lynx",
|
216 |
+
"vdb_num_dimensions": "1536",
|
217 |
+
"vdb_provider_name": "faiss"
|
218 |
+
},
|
219 |
+
"status": "done",
|
220 |
+
"title": "LynxScribe Text RAG Loader"
|
221 |
},
|
222 |
+
"dragHandle": ".bg-primary",
|
223 |
+
"height": 515.0,
|
224 |
+
"id": "LynxScribe Text RAG Loader 1",
|
225 |
"position": {
|
226 |
+
"x": -173.0,
|
227 |
+
"y": 268.0
|
228 |
},
|
229 |
+
"type": "basic",
|
230 |
+
"width": 290.0
|
|
|
231 |
},
|
232 |
{
|
|
|
|
|
233 |
"data": {
|
234 |
+
"__execution_delay": 0.0,
|
235 |
+
"collapsed": null,
|
|
|
|
|
236 |
"display": null,
|
237 |
"error": null,
|
238 |
+
"input_metadata": null,
|
239 |
"meta": {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
240 |
"inputs": {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
241 |
"chat_processor": {
|
242 |
"name": "chat_processor",
|
243 |
"position": "bottom",
|
|
|
246 |
}
|
247 |
},
|
248 |
"knowledge_base": {
|
249 |
+
"name": "knowledge_base",
|
|
|
|
|
250 |
"position": "bottom",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
251 |
"type": {
|
252 |
+
"type": "<class 'inspect._empty'>"
|
253 |
}
|
254 |
}
|
255 |
},
|
256 |
+
"name": "LynxScribe RAG Graph Chatbot Backend",
|
257 |
"outputs": {
|
258 |
"output": {
|
|
|
259 |
"name": "output",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
"position": "top",
|
|
|
261 |
"type": {
|
262 |
"type": "None"
|
263 |
}
|
264 |
}
|
265 |
},
|
266 |
"params": {
|
267 |
+
"llm_interface": {
|
268 |
+
"default": "openai",
|
269 |
+
"name": "llm_interface",
|
270 |
"type": {
|
271 |
+
"type": "<class 'str'>"
|
272 |
+
}
|
|
|
273 |
},
|
274 |
+
"llm_model_name": {
|
275 |
+
"default": "gpt-4o",
|
276 |
+
"name": "llm_model_name",
|
277 |
"type": {
|
278 |
+
"type": "<class 'str'>"
|
279 |
}
|
280 |
},
|
281 |
"negative_answer": {
|
|
|
285 |
"type": "<class 'str'>"
|
286 |
}
|
287 |
},
|
288 |
+
"retriever_limits_by_type": {
|
289 |
"default": "{}",
|
290 |
+
"name": "retriever_limits_by_type",
|
291 |
"type": {
|
292 |
"type": "<class 'str'>"
|
293 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
294 |
},
|
295 |
+
"retriever_max_iterations": {
|
296 |
+
"default": 3.0,
|
297 |
+
"name": "retriever_max_iterations",
|
298 |
"type": {
|
299 |
+
"type": "<class 'int'>"
|
300 |
}
|
301 |
},
|
302 |
+
"retriever_overall_chunk_limit": {
|
303 |
+
"default": 20.0,
|
304 |
+
"name": "retriever_overall_chunk_limit",
|
305 |
"type": {
|
306 |
+
"type": "<class 'int'>"
|
307 |
+
}
|
308 |
+
},
|
309 |
+
"retriever_overall_token_limit": {
|
310 |
+
"default": 3000.0,
|
311 |
+
"name": "retriever_overall_token_limit",
|
312 |
+
"type": {
|
313 |
+
"type": "<class 'int'>"
|
314 |
+
}
|
315 |
+
},
|
316 |
+
"retriever_strict_limits": {
|
317 |
+
"default": true,
|
318 |
+
"name": "retriever_strict_limits",
|
319 |
+
"type": {
|
320 |
+
"type": "<class 'bool'>"
|
321 |
+
}
|
322 |
}
|
323 |
+
},
|
324 |
+
"type": "basic"
|
325 |
},
|
326 |
+
"params": {
|
327 |
+
"llm_interface": "openai",
|
328 |
+
"llm_model_name": "gpt-4o",
|
329 |
+
"negative_answer": "I'm sorry, but the data I've been trained on does not contain any information related to your question.",
|
330 |
+
"retriever_limits_by_type": "{\"information\": [1, 5], \"summary\": [0, 2], \"template_qna\": [1, 3], \"QnA question\": [0, 0]}",
|
331 |
+
"retriever_max_iterations": "3",
|
332 |
+
"retriever_overall_chunk_limit": 20.0,
|
333 |
+
"retriever_overall_token_limit": 3000.0,
|
334 |
+
"retriever_strict_limits": true
|
335 |
+
},
|
336 |
+
"status": "done",
|
337 |
+
"title": "LynxScribe RAG Graph Chatbot Backend"
|
338 |
},
|
339 |
+
"dragHandle": ".bg-primary",
|
340 |
+
"height": 697.0,
|
341 |
+
"id": "LynxScribe RAG Graph Chatbot Backend 1",
|
342 |
"position": {
|
343 |
+
"x": 356.69268530841373,
|
344 |
+
"y": -467.49315862719016
|
345 |
},
|
346 |
+
"type": "basic",
|
347 |
+
"width": 821.0
|
|
|
348 |
},
|
349 |
{
|
|
|
|
|
350 |
"data": {
|
|
|
|
|
351 |
"display": null,
|
352 |
"error": null,
|
353 |
+
"input_metadata": null,
|
354 |
"meta": {
|
|
|
355 |
"inputs": {
|
356 |
+
"processor": {
|
357 |
+
"name": "processor",
|
|
|
|
|
|
|
|
|
|
|
|
|
358 |
"position": "bottom",
|
359 |
"type": {
|
360 |
"type": "<class 'inspect._empty'>"
|
361 |
+
}
|
|
|
362 |
}
|
363 |
},
|
364 |
+
"name": "Chat processor",
|
|
|
365 |
"outputs": {
|
366 |
"output": {
|
367 |
+
"name": "output",
|
368 |
"position": "top",
|
369 |
"type": {
|
370 |
"type": "None"
|
371 |
+
}
|
|
|
372 |
}
|
373 |
+
},
|
374 |
+
"params": {},
|
375 |
+
"type": "basic"
|
376 |
+
},
|
377 |
+
"params": {},
|
378 |
+
"status": "done",
|
379 |
+
"title": "Chat processor"
|
380 |
},
|
381 |
+
"dragHandle": ".bg-primary",
|
382 |
+
"height": 220.0,
|
383 |
+
"id": "Chat processor 1",
|
384 |
"position": {
|
385 |
+
"x": 907.3546850533578,
|
386 |
+
"y": 381.09754180073975
|
387 |
},
|
388 |
+
"type": "basic",
|
389 |
+
"width": 387.0
|
|
|
390 |
},
|
391 |
{
|
|
|
|
|
392 |
"data": {
|
|
|
|
|
|
|
|
|
|
|
393 |
"display": null,
|
394 |
"error": null,
|
395 |
+
"input_metadata": null,
|
396 |
"meta": {
|
397 |
+
"inputs": {},
|
398 |
+
"name": "Truncate history",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
399 |
"outputs": {
|
400 |
"output": {
|
401 |
+
"name": "output",
|
402 |
+
"position": "top",
|
403 |
"type": {
|
404 |
"type": "None"
|
405 |
+
}
|
|
|
|
|
406 |
}
|
407 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
408 |
"params": {
|
409 |
+
"max_tokens": {
|
410 |
+
"default": 10000.0,
|
411 |
+
"name": "max_tokens",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
412 |
"type": {
|
413 |
+
"type": "<class 'int'>"
|
414 |
+
}
|
|
|
|
|
415 |
}
|
416 |
},
|
417 |
+
"type": "basic"
|
418 |
+
},
|
419 |
+
"params": {
|
420 |
+
"max_tokens": 10000.0
|
421 |
+
},
|
422 |
+
"status": "done",
|
423 |
+
"title": "Truncate history"
|
|
|
|
|
|
|
|
|
424 |
},
|
425 |
+
"dragHandle": ".bg-primary",
|
426 |
+
"height": 200.0,
|
427 |
+
"id": "Truncate history 1",
|
428 |
"position": {
|
429 |
+
"x": 931.4096899549071,
|
430 |
+
"y": 703.2861674410822
|
431 |
},
|
432 |
+
"type": "basic",
|
433 |
+
"width": 200.0
|
|
|
434 |
},
|
435 |
{
|
|
|
|
|
436 |
"data": {
|
437 |
+
"__execution_delay": 0.0,
|
438 |
+
"collapsed": false,
|
|
|
|
|
439 |
"display": null,
|
440 |
"error": null,
|
441 |
+
"input_metadata": null,
|
442 |
"meta": {
|
443 |
+
"inputs": {},
|
444 |
+
"name": "Mask",
|
445 |
"outputs": {
|
446 |
"output": {
|
|
|
447 |
"name": "output",
|
448 |
+
"position": "top",
|
449 |
"type": {
|
450 |
"type": "None"
|
451 |
}
|
452 |
}
|
453 |
},
|
|
|
|
|
|
|
454 |
"params": {
|
455 |
+
"exceptions": {
|
456 |
+
"default": "",
|
457 |
+
"name": "exceptions",
|
458 |
+
"type": {
|
459 |
+
"type": "<class 'str'>"
|
460 |
+
}
|
461 |
+
},
|
462 |
+
"mask_pattern": {
|
463 |
+
"default": "",
|
464 |
+
"name": "mask_pattern",
|
465 |
+
"type": {
|
466 |
+
"type": "<class 'str'>"
|
467 |
+
}
|
468 |
+
},
|
469 |
"name": {
|
470 |
+
"default": "",
|
471 |
"name": "name",
|
472 |
"type": {
|
473 |
"type": "<class 'str'>"
|
474 |
}
|
475 |
+
},
|
476 |
+
"regex": {
|
477 |
+
"default": "",
|
478 |
+
"name": "regex",
|
479 |
+
"type": {
|
480 |
+
"type": "<class 'str'>"
|
481 |
+
}
|
482 |
}
|
483 |
+
},
|
484 |
+
"type": "basic"
|
485 |
+
},
|
486 |
+
"params": {
|
487 |
+
"exceptions": "[email protected],[email protected],[email protected],[email protected]",
|
488 |
+
"mask_pattern": "masked_email_address_{}",
|
489 |
+
"name": "email",
|
490 |
+
"regex": "([a-z0-9!#$%&'*+\\/=?^_`{|.}~-]+@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)"
|
491 |
+
},
|
492 |
+
"status": "done",
|
493 |
+
"title": "Mask"
|
494 |
},
|
495 |
+
"dragHandle": ".bg-primary",
|
496 |
+
"height": 366.0,
|
497 |
+
"id": "Mask 1",
|
498 |
"position": {
|
499 |
+
"x": 1163.4170914925835,
|
500 |
+
"y": 712.6187958660655
|
501 |
},
|
502 |
+
"type": "basic",
|
503 |
+
"width": 281.0
|
|
|
504 |
},
|
505 |
{
|
|
|
|
|
506 |
"data": {
|
507 |
+
"__execution_delay": 0.0,
|
508 |
+
"collapsed": null,
|
|
|
|
|
509 |
"display": null,
|
510 |
"error": null,
|
511 |
+
"input_metadata": null,
|
512 |
"meta": {
|
513 |
+
"inputs": {},
|
514 |
+
"name": "Input chat",
|
515 |
"outputs": {
|
516 |
"output": {
|
517 |
+
"name": "output",
|
518 |
+
"position": "right",
|
519 |
"type": {
|
520 |
"type": "None"
|
521 |
+
}
|
|
|
|
|
522 |
}
|
523 |
},
|
|
|
524 |
"params": {
|
525 |
+
"chat": {
|
526 |
+
"default": null,
|
527 |
+
"name": "chat",
|
528 |
"type": {
|
529 |
+
"type": "<class 'str'>"
|
530 |
}
|
531 |
}
|
532 |
},
|
533 |
+
"type": "basic"
|
534 |
+
},
|
535 |
+
"params": {
|
536 |
+
"chat": "Who is the CEO of Lynx?"
|
537 |
+
},
|
538 |
+
"status": "done",
|
539 |
+
"title": "Input chat"
|
540 |
},
|
541 |
+
"dragHandle": ".bg-primary",
|
542 |
+
"height": 198.0,
|
543 |
+
"id": "Input chat 1",
|
544 |
"position": {
|
545 |
+
"x": -854.3584473819146,
|
546 |
+
"y": -770.2371549901112
|
547 |
},
|
548 |
+
"type": "basic",
|
549 |
+
"width": 910.0
|
|
|
550 |
},
|
551 |
{
|
|
|
|
|
552 |
"data": {
|
553 |
+
"__execution_delay": 0.0,
|
554 |
+
"collapsed": null,
|
555 |
"display": null,
|
556 |
"error": null,
|
557 |
+
"input_metadata": null,
|
|
|
558 |
"meta": {
|
|
|
559 |
"inputs": {
|
560 |
+
"chat_api": {
|
561 |
+
"name": "chat_api",
|
562 |
"position": "bottom",
|
563 |
"type": {
|
564 |
"type": "<class 'inspect._empty'>"
|
565 |
}
|
566 |
+
},
|
567 |
+
"message": {
|
568 |
+
"name": "message",
|
569 |
+
"position": "left",
|
570 |
+
"type": {
|
571 |
+
"type": "<class 'inspect._empty'>"
|
572 |
+
}
|
573 |
}
|
574 |
},
|
575 |
+
"name": "Test Chat API",
|
|
|
576 |
"outputs": {
|
577 |
"output": {
|
578 |
+
"name": "output",
|
579 |
+
"position": "right",
|
580 |
"type": {
|
581 |
"type": "None"
|
582 |
+
}
|
|
|
|
|
583 |
}
|
584 |
+
},
|
585 |
+
"params": {
|
586 |
+
"show_details": {
|
587 |
+
"default": false,
|
588 |
+
"name": "show_details",
|
589 |
+
"type": {
|
590 |
+
"type": "<class 'bool'>"
|
591 |
+
}
|
592 |
+
}
|
593 |
+
},
|
594 |
+
"type": "basic"
|
595 |
+
},
|
596 |
+
"params": {
|
597 |
+
"show_details": false
|
598 |
+
},
|
599 |
+
"status": "done",
|
600 |
+
"title": "Test Chat API"
|
601 |
},
|
602 |
+
"dragHandle": ".bg-primary",
|
603 |
+
"height": 260.0,
|
604 |
+
"id": "Test Chat API 1",
|
605 |
"position": {
|
606 |
+
"x": 356.57819670145534,
|
607 |
+
"y": -803.3229228909706
|
608 |
},
|
609 |
+
"type": "basic",
|
610 |
+
"width": 820.0
|
|
|
611 |
},
|
612 |
{
|
|
|
|
|
613 |
"data": {
|
614 |
+
"display": {
|
615 |
+
"dataframes": {
|
616 |
+
"df": {
|
617 |
+
"columns": [
|
618 |
+
"answer"
|
619 |
+
],
|
620 |
+
"data": [
|
621 |
+
[
|
622 |
+
"The CEO of Lynx Analytics is Gyorgy Lajtai. He is also a co-founder of the company and has a rich background in CRM, marketing automation, and systems."
|
623 |
+
]
|
624 |
+
]
|
625 |
+
}
|
626 |
+
}
|
627 |
},
|
|
|
628 |
"error": null,
|
629 |
+
"input_metadata": null,
|
630 |
"meta": {
|
631 |
+
"inputs": {
|
632 |
+
"input": {
|
633 |
+
"name": "input",
|
634 |
+
"position": "left",
|
|
|
635 |
"type": {
|
636 |
+
"type": "<class 'inspect._empty'>"
|
637 |
}
|
638 |
}
|
639 |
},
|
640 |
+
"name": "View",
|
641 |
+
"outputs": {},
|
642 |
+
"params": {},
|
643 |
+
"type": "table_view"
|
644 |
+
},
|
645 |
+
"params": {},
|
646 |
+
"status": "done",
|
647 |
+
"title": "View"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
648 |
},
|
649 |
+
"dragHandle": ".bg-primary",
|
650 |
+
"height": 627.0,
|
651 |
+
"id": "View 1",
|
652 |
"position": {
|
653 |
+
"x": 1497.8623453933426,
|
654 |
+
"y": -810.6258103791108
|
655 |
},
|
656 |
+
"type": "table_view",
|
657 |
+
"width": 995.0
|
|
|
658 |
},
|
659 |
{
|
|
|
|
|
660 |
"data": {
|
661 |
+
"__execution_delay": 0.0,
|
662 |
+
"collapsed": null,
|
|
|
|
|
|
|
|
|
|
|
663 |
"display": null,
|
664 |
"error": null,
|
665 |
+
"input_metadata": null,
|
666 |
"meta": {
|
667 |
+
"inputs": {
|
668 |
+
"rag_graph": {
|
669 |
+
"name": "rag_graph",
|
670 |
+
"position": "left",
|
671 |
+
"type": {
|
672 |
+
"type": "<class 'inspect._empty'>"
|
673 |
+
}
|
674 |
+
}
|
675 |
+
},
|
676 |
+
"name": "LynxScribe RAG Graph Chatbot Builder",
|
677 |
"outputs": {
|
678 |
"output": {
|
679 |
"name": "output",
|
|
|
683 |
}
|
684 |
}
|
685 |
},
|
|
|
|
|
|
|
686 |
"params": {
|
687 |
+
"node_types": {
|
688 |
+
"default": "intent_cluster",
|
689 |
+
"name": "node_types",
|
|
|
|
|
|
|
|
|
|
|
|
|
690 |
"type": {
|
691 |
"type": "<class 'str'>"
|
692 |
+
}
|
|
|
693 |
},
|
694 |
+
"scenario_file": {
|
695 |
+
"default": "uploads/lynx_chatbot_scenario_selector.yaml",
|
696 |
+
"name": "scenario_file",
|
697 |
"type": {
|
698 |
"type": "<class 'str'>"
|
699 |
+
}
|
|
|
700 |
},
|
701 |
+
"scenario_meta_name": {
|
702 |
+
"default": "scenario_name",
|
703 |
+
"name": "scenario_meta_name",
|
704 |
"type": {
|
705 |
"type": "<class 'str'>"
|
706 |
}
|
707 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
708 |
},
|
709 |
+
"position": {
|
710 |
+
"x": 1121.0,
|
711 |
+
"y": 813.0
|
|
|
|
|
|
|
|
|
|
|
712 |
},
|
|
|
713 |
"type": "basic"
|
714 |
+
},
|
715 |
+
"params": {
|
716 |
+
"node_types": "intent_cluster",
|
717 |
+
"scenario_file": "uploads/lynx_chatbot_scenario_selector.yaml",
|
718 |
+
"scenario_meta_name": ""
|
719 |
+
},
|
720 |
+
"status": "done",
|
721 |
+
"title": "LynxScribe RAG Graph Chatbot Builder"
|
722 |
},
|
723 |
+
"dragHandle": ".bg-primary",
|
724 |
+
"height": 297.0,
|
725 |
+
"id": "LynxScribe RAG Graph Chatbot Builder 1",
|
726 |
"position": {
|
727 |
+
"x": 328.41755532473496,
|
728 |
+
"y": 378.2277574498554
|
729 |
},
|
730 |
+
"type": "basic",
|
731 |
+
"width": 396.0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
732 |
}
|
733 |
]
|
734 |
}
|
examples/uploads/image_description_prompts.yaml
ADDED
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
cot_picture_descriptor:
|
2 |
+
- role: system
|
3 |
+
content: &cot_starter >
|
4 |
+
You are an advanced AI specializing in structured image descriptions using a Chain-of-Thought (CoT) approach.
|
5 |
+
Your goal is to analyze an image and return a detailed dictionary containing relevant details categorized by elements.
|
6 |
+
|
7 |
+
- role: system
|
8 |
+
content: &cot_details >
|
9 |
+
You should always return a dictionary with the following main keys:
|
10 |
+
- "image type": Identify whether the image is a "picture", "diagram", "flowchart", "advertisement", or "other".
|
11 |
+
- "overall description": A concise but clear summary of the entire image.
|
12 |
+
- "details": A dictionary containing all significant elements in the image, where:
|
13 |
+
* Each key represents a major object or entity in the image.
|
14 |
+
* Each value is a detailed description of that entity.
|
15 |
+
|
16 |
+
- role: system
|
17 |
+
content: &cot_normal_pic >
|
18 |
+
If the image is a normal picture (e.g., a scene with people, animals, landscapes, or objects in a real-world setting),
|
19 |
+
follow these steps:
|
20 |
+
1. Identify and describe the background (e.g., sky, buildings, landscape).
|
21 |
+
2. Identify the main action happening (e.g., a dog chasing a ball).
|
22 |
+
3. Break down individual objects and provide a description for each, including attributes like color, size, texture, and their relationship with other objects.
|
23 |
+
In this case, the sub-dictionary under the "details" key should contain the following keys:
|
24 |
+
* "background": A description of the background elements.
|
25 |
+
* "main scene": A summary of the primary action taking place.
|
26 |
+
* Individual keys for all identified objects, each with a detailed description.
|
27 |
+
While describing the objects, be very detailed. Not just mention person, but mention: middle-aged women with brown curly hair, ...
|
28 |
+
|
29 |
+
- role: system
|
30 |
+
content: &cot_diagrams >
|
31 |
+
If the image is a diagram, identify key labeled components and describe their meaning.
|
32 |
+
- Describe the meaning of the diagram, and if there are axes, explain their purpose.
|
33 |
+
- Provide an interpretation of the overall meaning and takeaway from the chart, including relationships between elements if applicable.
|
34 |
+
In this case, the sub-dictionary under the "details" key should contain the following keys:
|
35 |
+
* "x-axis", "y-axis" (or variations like "y1-axis" and "y2-axis") if applicable.
|
36 |
+
* "legend": A description of the plotted data, including sources if available.
|
37 |
+
* "takeaway": A summary of the main insights derived from the chart.
|
38 |
+
* Additional structured details, such as grouped data (e.g., individual timelines in a line chart).
|
39 |
+
|
40 |
+
- role: system
|
41 |
+
content: &cot_flowcharts >
|
42 |
+
If the image is a flowchart:
|
43 |
+
- Identify the start and end points.
|
44 |
+
- List key process steps and decision nodes.
|
45 |
+
- Describe directional flows and relationships between components.
|
46 |
+
In this case, the sub-dictionary under the "details" key should contain the following keys:
|
47 |
+
* "start points": The identified starting nodes of the flowchart.
|
48 |
+
* "end points": The final outcome(s) of the flowchart.
|
49 |
+
* "detailed description": A natural language explanation of the entire flow.
|
50 |
+
* Additional keys for each process step and decision point, described in detail.
|
51 |
+
|
52 |
+
- role: system
|
53 |
+
content: &cot_ads >
|
54 |
+
If the image is an advertisement:
|
55 |
+
- Describe the main subject and any branding elements.
|
56 |
+
- Identify slogans, logos, and promotional text.
|
57 |
+
- Analyze the visual strategy used (e.g., color scheme, emotional appeal, focal points).
|
58 |
+
In this case, the sub-dictionary under the "details" key should contain the following keys:
|
59 |
+
* "advertised brand": The brand being promoted.
|
60 |
+
* "advertised product": The product or service being advertised.
|
61 |
+
* "background": The background setting of the advertisement.
|
62 |
+
* "main scene": The primary subject or action depicted.
|
63 |
+
* "used slogans": Any slogans or catchphrases appearing in the advertisement.
|
64 |
+
* "visual strategy": An analysis of the design and emotional impact.
|
65 |
+
* Additional keys for individual objects, just like in the case of normal pictures.
|
66 |
+
|
67 |
+
- role: system
|
68 |
+
content: &cot_output_example >
|
69 |
+
Example output for a normal picture:
|
70 |
+
|
71 |
+
```json
|
72 |
+
{
|
73 |
+
"image type": "picture",
|
74 |
+
"overall description": "A peaceful rural landscape featuring a cow chained to a tree in a field with mountains in the background.",
|
75 |
+
"details": {
|
76 |
+
"background": "A large open field with patches of grass and dirt, surrounded by distant mountains under a clear blue sky.",
|
77 |
+
"main scene": "A cow chained to a tree in the middle of a grassy field.",
|
78 |
+
"cow": "A brown and white cow standing near the tree, appearing calm.",
|
79 |
+
"tree": "A sturdy oak tree with green leaves and a metal chain wrapped around its trunk.",
|
80 |
+
"mountain": "Tall, rocky mountains stretching across the horizon.",
|
81 |
+
"chain": "A shiny metal chain, slightly rusty in some places."
|
82 |
+
}
|
83 |
+
}
|
84 |
+
```
|
85 |
+
- role: user
|
86 |
+
content:
|
87 |
+
- type: text
|
88 |
+
text: "Describe this image as you trained. Only output the dictionary add nothing else."
|
89 |
+
- type: "image_url"
|
90 |
+
image_url: {image_address}
|
examples/uploads/lynx_chatbot_scenario_selector.yaml
ADDED
@@ -0,0 +1,302 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
- name: general_interest
|
2 |
+
mode: retrieve_llm # Literal[retrieve_llm, retrieve_only, llm_only, fixed_answer, sticky_answer]
|
3 |
+
prompt_messages: # Answer prompts in [role, content] format, should contain {context}
|
4 |
+
- role: system # Literal[system, assistant, user, tool]
|
5 |
+
content: &role >
|
6 |
+
You are LynxScribe, a chatbot representing Lynx Analytics, a leading Singaporean analytics
|
7 |
+
company specializing in pharma, life sciences, generative AI, and graph AI. Your role is to
|
8 |
+
respond to inquiries on the Lynx Analytics website. To better understand the visitors'
|
9 |
+
needs, you may ask follow-up questions as detailed in subsequent instructions.
|
10 |
+
- role: system
|
11 |
+
content: &preferences >
|
12 |
+
Lynx Analytics specializes in a range of areas including pharma (with a focus on marketing
|
13 |
+
support), life sciences, graph AI, and generative AI solutions. When responding to inquiries
|
14 |
+
about our solutions or products, give priority to those related to generative AI (chatbots
|
15 |
+
for pharma and service providers), graph AI (graph reasoning), and pharma (research, key
|
16 |
+
opinion leaders, brand adoption ladder). Also, briefly touch upon our offerings in retail
|
17 |
+
(price AI, assort AI, promo AI) and finance (digital banking, Customer Happiness Index), as
|
18 |
+
these are areas of secondary priority. Additionally, although telecommunication is worth
|
19 |
+
mentioning briefly to highlight our comprehensive range of expertise and solutions.
|
20 |
+
- role: system
|
21 |
+
content: &context >
|
22 |
+
Respond to questions solely based on the context outlined below:\n\n{context}
|
23 |
+
- role: system
|
24 |
+
content: &instr_prices >
|
25 |
+
If inquiries about pricing arise, suggest contacting Lynx Analytics for detailed
|
26 |
+
information. Additionally, emphasize that Lynx Analytics offers solutions at competitive
|
27 |
+
prices without compromising on quality.
|
28 |
+
- role: system
|
29 |
+
content: &ask_industry >
|
30 |
+
If it's not mentioned in the chat history, include a question at the end of your response
|
31 |
+
to inquire about their industry interest or employment. For example: 'May I know which
|
32 |
+
specific domain or industry you are interested in or work in?'
|
33 |
+
- role: system
|
34 |
+
content: &ask_visit_reason >
|
35 |
+
If the chat history does not reveal it, ask about their reason for visiting the website. For
|
36 |
+
instance, you might say: 'Could you share what prompted your visit to our website today?'
|
37 |
+
- role: system
|
38 |
+
content: &final_instr >
|
39 |
+
Carefully answer questions based on the provided context. Refrain from introducing new
|
40 |
+
names; use only those within your context. Respond in the language of the question. If
|
41 |
+
necessary, ask follow-up questions. Ensure your answers are clear, utilizing bullet points
|
42 |
+
where appropriate. Avoid phrases like 'According to this article' to maintain a natural
|
43 |
+
tone.
|
44 |
+
link_answer: &link # When present, formatted node link appends to answer, should contain {link}
|
45 |
+
"\n\nPlease visit <a href='{link}' target='_blank'>{link}</a> for further information."
|
46 |
+
min_similarity_score: -1 # Only need to specify if > -1 and in RETRIEVE_LLM or RETRIEVE_ONLY mode
|
47 |
+
- name: life_sciences_interest
|
48 |
+
mode: retrieve_llm
|
49 |
+
prompt_messages:
|
50 |
+
- role: system
|
51 |
+
content: *role
|
52 |
+
- role: system
|
53 |
+
content: *preferences
|
54 |
+
- role: system
|
55 |
+
content: *context
|
56 |
+
- role: system
|
57 |
+
content: *instr_prices
|
58 |
+
- role: system
|
59 |
+
content: &ask_profession >
|
60 |
+
If their job is not mentioned in the chat history, add a question at the end of your answer
|
61 |
+
about their profession. For example: 'Could you please tell me about your current profession
|
62 |
+
or occupation?'
|
63 |
+
- role: system
|
64 |
+
content: *ask_visit_reason
|
65 |
+
- role: system
|
66 |
+
content: &ask_email >
|
67 |
+
If their email is not already in the chat history, suggest that they can provide their email
|
68 |
+
address for further contact. For instance: 'Should you wish for further communication
|
69 |
+
regarding your queries, feel free to provide your email address.'
|
70 |
+
- role: system
|
71 |
+
content: *final_instr
|
72 |
+
link_answer: *link
|
73 |
+
min_similarity_score: -1
|
74 |
+
- name: finance_interest
|
75 |
+
mode: retrieve_llm
|
76 |
+
prompt_messages:
|
77 |
+
- role: system
|
78 |
+
content: *role
|
79 |
+
- role: system
|
80 |
+
content: *context
|
81 |
+
- role: system
|
82 |
+
content: *instr_prices
|
83 |
+
- role: system
|
84 |
+
content: &ask_responsibilities >
|
85 |
+
If their job or responsibilities are not detailed in the chat history, include a question
|
86 |
+
at the end of your response. For example: 'Would you mind sharing some details about the
|
87 |
+
specific responsibilities you manage in your role?'
|
88 |
+
- role: system
|
89 |
+
content: *ask_visit_reason
|
90 |
+
- role: system
|
91 |
+
content: *ask_email
|
92 |
+
- role: system
|
93 |
+
content: *final_instr
|
94 |
+
link_answer: *link
|
95 |
+
min_similarity_score: -1
|
96 |
+
- name: telco_interest
|
97 |
+
mode: retrieve_llm
|
98 |
+
prompt_messages:
|
99 |
+
- role: system
|
100 |
+
content: *role
|
101 |
+
- role: system
|
102 |
+
content: *context
|
103 |
+
- role: system
|
104 |
+
content: *instr_prices
|
105 |
+
- role: system
|
106 |
+
content: *ask_responsibilities
|
107 |
+
- role: system
|
108 |
+
content: *ask_visit_reason
|
109 |
+
- role: system
|
110 |
+
content: *ask_email
|
111 |
+
- role: system
|
112 |
+
content: *final_instr
|
113 |
+
link_answer: *link
|
114 |
+
min_similarity_score: -1
|
115 |
+
- name: retail_interest
|
116 |
+
mode: retrieve_llm
|
117 |
+
prompt_messages:
|
118 |
+
- role: system
|
119 |
+
content: *role
|
120 |
+
- role: system
|
121 |
+
content: *context
|
122 |
+
- role: system
|
123 |
+
content: *instr_prices
|
124 |
+
- role: system
|
125 |
+
content: *ask_responsibilities
|
126 |
+
- role: system
|
127 |
+
content: *ask_visit_reason
|
128 |
+
- role: system
|
129 |
+
content: *ask_email
|
130 |
+
- role: system
|
131 |
+
content: *final_instr
|
132 |
+
link_answer: *link
|
133 |
+
min_similarity_score: -1
|
134 |
+
- name: lynx_kite
|
135 |
+
mode: retrieve_llm
|
136 |
+
prompt_messages:
|
137 |
+
- role: system
|
138 |
+
content: *role
|
139 |
+
- role: system
|
140 |
+
content: *preferences
|
141 |
+
- role: system
|
142 |
+
content: *context
|
143 |
+
- role: system
|
144 |
+
content: *instr_prices
|
145 |
+
- role: system
|
146 |
+
content: *ask_industry
|
147 |
+
- role: system
|
148 |
+
content: &ask_graph >
|
149 |
+
If it's not mentioned in the chat history, include a question at the end of your response to
|
150 |
+
inquire about their specific needs related to graph analytics. For example: 'May I know
|
151 |
+
which particular graph-related problem you are looking to solve with graph analytics?'
|
152 |
+
- role: system
|
153 |
+
content: *ask_email
|
154 |
+
- role: system
|
155 |
+
content: *final_instr
|
156 |
+
link_answer: *link
|
157 |
+
min_similarity_score: -1
|
158 |
+
- name: lynx_team
|
159 |
+
mode: retrieve_llm
|
160 |
+
prompt_messages:
|
161 |
+
- role: system
|
162 |
+
content: *role
|
163 |
+
- role: system
|
164 |
+
content: *context
|
165 |
+
- role: system
|
166 |
+
content: *instr_prices
|
167 |
+
- role: system
|
168 |
+
content: *ask_visit_reason
|
169 |
+
- role: system
|
170 |
+
content: >
|
171 |
+
When they inquire about names that could refer to multiple individuals, provide the names
|
172 |
+
along with a brief description of each. Then, ask for clarification on which specific
|
173 |
+
individual they are referring to.
|
174 |
+
- role: system
|
175 |
+
content: *final_instr
|
176 |
+
link_answer: *link
|
177 |
+
min_similarity_score: -1
|
178 |
+
- name: lynx_career
|
179 |
+
mode: retrieve_llm
|
180 |
+
prompt_messages:
|
181 |
+
- role: system
|
182 |
+
content: *role
|
183 |
+
- role: system
|
184 |
+
content: *context
|
185 |
+
- role: system
|
186 |
+
content: *instr_prices
|
187 |
+
- role: system
|
188 |
+
content: *ask_responsibilities
|
189 |
+
- role: system
|
190 |
+
content: >
|
191 |
+
If it's not already mentioned in the chat history, include a question at the end of your
|
192 |
+
response to inquire about their motivation for wanting to work with us. For example: 'Could
|
193 |
+
you share what motivates you to seek a position with our team?'
|
194 |
+
- role: system
|
195 |
+
content: *ask_email
|
196 |
+
- role: system
|
197 |
+
content: *final_instr
|
198 |
+
link_answer: *link
|
199 |
+
min_similarity_score: -1
|
200 |
+
- name: lynxscribe
|
201 |
+
mode: retrieve_llm
|
202 |
+
prompt_messages:
|
203 |
+
- role: system
|
204 |
+
content: *role
|
205 |
+
- role: system
|
206 |
+
content: *preferences
|
207 |
+
- role: system
|
208 |
+
content: *context
|
209 |
+
- role: system
|
210 |
+
content: *instr_prices
|
211 |
+
- role: system
|
212 |
+
content: *ask_industry
|
213 |
+
- role: system
|
214 |
+
content: >
|
215 |
+
If the chat history does not already include this information, add a question at the end of
|
216 |
+
your response to identify their specific needs in generative AI. For example: 'Could you
|
217 |
+
please specify the problem you are aiming to address using generative AI?'
|
218 |
+
- role: system
|
219 |
+
content: *ask_email
|
220 |
+
- role: system
|
221 |
+
content: *final_instr
|
222 |
+
link_answer: *link
|
223 |
+
min_similarity_score: -1
|
224 |
+
- name: general_ds
|
225 |
+
mode: retrieve_llm
|
226 |
+
prompt_messages:
|
227 |
+
- role: system
|
228 |
+
content: *role
|
229 |
+
- role: system
|
230 |
+
content: *context
|
231 |
+
- role: system
|
232 |
+
content: *instr_prices
|
233 |
+
- role: system
|
234 |
+
content: *ask_industry
|
235 |
+
- role: system
|
236 |
+
content: *ask_visit_reason
|
237 |
+
- role: system
|
238 |
+
content: *ask_email
|
239 |
+
- role: system
|
240 |
+
content: *final_instr
|
241 |
+
link_answer: *link
|
242 |
+
min_similarity_score: -1
|
243 |
+
- name: general_graph
|
244 |
+
mode: retrieve_llm
|
245 |
+
prompt_messages:
|
246 |
+
- role: system
|
247 |
+
content: *role
|
248 |
+
- role: system
|
249 |
+
content: *preferences
|
250 |
+
- role: system
|
251 |
+
content: *context
|
252 |
+
- role: system
|
253 |
+
content: *instr_prices
|
254 |
+
- role: system
|
255 |
+
content: *ask_graph
|
256 |
+
- role: system
|
257 |
+
content: *ask_industry
|
258 |
+
- role: system
|
259 |
+
content: *ask_email
|
260 |
+
- role: system
|
261 |
+
content: *final_instr
|
262 |
+
link_answer: *link
|
263 |
+
min_similarity_score: -1
|
264 |
+
- name: other_okay
|
265 |
+
mode: retrieve_llm
|
266 |
+
prompt_messages:
|
267 |
+
- role: system
|
268 |
+
content: *role
|
269 |
+
- role: system
|
270 |
+
content: *preferences
|
271 |
+
- role: system
|
272 |
+
content: *context
|
273 |
+
- role: system
|
274 |
+
content: *instr_prices
|
275 |
+
- role: system
|
276 |
+
content: *ask_industry
|
277 |
+
- role: system
|
278 |
+
content: *ask_visit_reason
|
279 |
+
- role: system
|
280 |
+
content: *final_instr
|
281 |
+
link_answer: *link
|
282 |
+
min_similarity_score: -1
|
283 |
+
- name: contact_us
|
284 |
+
mode: retrieve_llm
|
285 |
+
prompt_messages:
|
286 |
+
- role: system
|
287 |
+
content: *role
|
288 |
+
- role: system
|
289 |
+
content: *context
|
290 |
+
- role: system
|
291 |
+
content: *instr_prices
|
292 |
+
- role: system
|
293 |
+
content: *ask_email
|
294 |
+
- role: system
|
295 |
+
content: *final_instr
|
296 |
+
link_answer: *link
|
297 |
+
min_similarity_score: -1
|
298 |
+
- name: malicious
|
299 |
+
mode: fixed_answer # Could be sticky, but if we want the user to rephrase, let's give 2nd chance
|
300 |
+
fixed_answer: >
|
301 |
+
I am sorry, but I feel you want me use in a wrong way. If I feel it wrong, please try to
|
302 |
+
rephrase your question.
|
examples/uploads/organon_demo/backend-scenarios-en.yaml
ADDED
@@ -0,0 +1,92 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
- name: general_contraception_information # Must match the scenario name found in RAG graph
|
2 |
+
mode: retrieve_only # Literal[retrieve_llm, retrieve_only, llm_only, fixed_answer, sticky_answer]
|
3 |
+
min_pass_similarity_score: 0.55 # Custom value: if any answer is above, give three results
|
4 |
+
single_similarity_score: 0.86 # Custom value: is best answer is above, give single result
|
5 |
+
# min_similarity_score not used (stays -1.0) because it ditches all lower-score docs from results
|
6 |
+
- name: intrauterine_devices
|
7 |
+
mode: retrieve_only
|
8 |
+
min_pass_similarity_score: 0.55 # Sim Score = 2 * (1 - Distance) - 1
|
9 |
+
single_similarity_score: 0.86 # Sim Score = 2 * (1 - Distance) - 1
|
10 |
+
- name: contraceptive_injection
|
11 |
+
mode: retrieve_only
|
12 |
+
min_pass_similarity_score: 0.55
|
13 |
+
single_similarity_score: 0.86
|
14 |
+
- name: emergency_contraceptive_pills
|
15 |
+
mode: retrieve_only
|
16 |
+
min_pass_similarity_score: 0.55
|
17 |
+
single_similarity_score: 0.86
|
18 |
+
- name: contraceptive_implant
|
19 |
+
mode: retrieve_only
|
20 |
+
min_pass_similarity_score: 0.55
|
21 |
+
single_similarity_score: 0.86
|
22 |
+
- name: combined_contraceptive_pills
|
23 |
+
mode: retrieve_only
|
24 |
+
min_pass_similarity_score: 0.55
|
25 |
+
single_similarity_score: 0.86
|
26 |
+
- name: other_okay
|
27 |
+
mode: retrieve_only
|
28 |
+
min_pass_similarity_score: 0.55
|
29 |
+
single_similarity_score: 0.86
|
30 |
+
- name: own_side_effect
|
31 |
+
mode: fixed_answer
|
32 |
+
fixed_answer:
|
33 |
+
&abort_side_eff > # Anchors are added only for reference to old V1 template file
|
34 |
+
I'm not equipped to handle adverse events or other product-related queries. Your safety is
|
35 |
+
important to us, and we want to ensure you receive the appropriate support. Please report any
|
36 |
+
adverse events or concerns to our dedicated support team.
|
37 |
+
They can be reached at [email protected].
|
38 |
+
If you have any questions related to contraceptives or women's health, please feel free to ask,
|
39 |
+
and I'll provide you with the information you need.
|
40 |
+
keywords: [Mercilon, Marvelon, Implanon]
|
41 |
+
keyword_answer: &alternative_side_eff >
|
42 |
+
I'm not equipped to handle adverse events or other product-related queries. Your safety is
|
43 |
+
important to us, and we want to ensure you receive the appropriate support. Please report any
|
44 |
+
adverse events or concerns related to Organon products to our dedicated support team.
|
45 |
+
They can be reached at [email protected].
|
46 |
+
If you have any questions related to contraceptives or women's health, please feel free to ask,
|
47 |
+
and I'll provide you with the information you need.
|
48 |
+
- name: own_dosage
|
49 |
+
mode: fixed_answer
|
50 |
+
fixed_answer: &abort_dosage >
|
51 |
+
I'm not equipped to handle adverse events, dosage-related questions or other product-related
|
52 |
+
queries. Your safety is important to us, and we want to ensure you receive the appropriate
|
53 |
+
support. Please consult with the prescribing doctor about the details on how to use the
|
54 |
+
medication. For further information, please write a message to our dedicated support team.
|
55 |
+
They can be reached at [email protected].
|
56 |
+
If you have any questions related to contraceptives or women's health, please feel free to ask,
|
57 |
+
and I'll provide you with the information you need.
|
58 |
+
- name: brand_specific_information
|
59 |
+
mode: fixed_answer
|
60 |
+
fixed_answer: &brand_selection >
|
61 |
+
I appreciate your question about brand recommendations. For personalized advice related to
|
62 |
+
healthcare or specific products, it's always best to consult with a healthcare professional
|
63 |
+
who can consider your individual needs and provide tailored recommendations. They have the
|
64 |
+
expertise to guide you in the right direction.
|
65 |
+
If you have any questions related to contraceptives or women's health, please feel free to ask,
|
66 |
+
and I'll provide you with the information you need.
|
67 |
+
- name: greetings_hay
|
68 |
+
mode: fixed_answer
|
69 |
+
fixed_answer: &how_are_you_hi >
|
70 |
+
I am fine thanks, hope you feel the same! Feel free to ask any contraception related question.
|
71 |
+
- name: greetings_hi
|
72 |
+
mode: fixed_answer
|
73 |
+
fixed_answer: &say_hi >
|
74 |
+
Hi, nice to meet you! Feel free to ask any contraception related question.
|
75 |
+
- name: emailthanks
|
76 |
+
mode: fixed_answer
|
77 |
+
fixed_answer: &email_thanks >
|
78 |
+
Thank you. Could I help with something else?
|
79 |
+
- name: thanks
|
80 |
+
mode: fixed_answer
|
81 |
+
fixed_answer: &thanks_answer >
|
82 |
+
Not at all. Could I help with something else?
|
83 |
+
- name: confirmation
|
84 |
+
mode: fixed_answer
|
85 |
+
fixed_answer: &confirmation_answer >
|
86 |
+
Thank you. Could I help with something else?
|
87 |
+
- name: malicious
|
88 |
+
mode: sticky_answer
|
89 |
+
fixed_answer: &malicious_message >
|
90 |
+
I am sorry, but I feel you want me use in a wrong way.
|
91 |
+
If I feel it wrong, please try to rephrase your question.
|
92 |
+
Refresh your browser if you'd like to ask more questions.
|
examples/uploads/organon_demo/organon_en_copy.xlsx
ADDED
Binary file (66.9 kB). View file
|
|
lynxkite-lynxscribe/pyproject.toml
CHANGED
@@ -6,7 +6,7 @@ readme = "README.md"
|
|
6 |
requires-python = ">=3.11"
|
7 |
dependencies = [
|
8 |
"lynxkite-core",
|
9 |
-
"lynxscribe[openai] @ git+ssh://[email protected]/biggraph/lynxscribe@main",
|
10 |
]
|
11 |
|
12 |
[tool.uv.sources]
|
|
|
6 |
requires-python = ">=3.11"
|
7 |
dependencies = [
|
8 |
"lynxkite-core",
|
9 |
+
"lynxscribe[openai,faiss-cpu,litellm,google] @ git+ssh://[email protected]/biggraph/lynxscribe@main",
|
10 |
]
|
11 |
|
12 |
[tool.uv.sources]
|
lynxkite-lynxscribe/src/lynxkite_lynxscribe/lynxscribe_ops.py
CHANGED
@@ -1,12 +1,24 @@
|
|
1 |
"""
|
2 |
LynxScribe configuration and testing in LynxKite.
|
|
|
3 |
"""
|
4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
import pathlib
|
6 |
from lynxscribe.core.llm.base import get_llm_engine
|
7 |
from lynxscribe.core.vector_store.base import get_vector_store
|
8 |
from lynxscribe.common.config import load_config
|
9 |
from lynxscribe.components.text.embedder import TextEmbedder
|
|
|
|
|
|
|
10 |
from lynxscribe.components.rag.rag_graph import RAGGraph
|
11 |
from lynxscribe.components.rag.knowledge_base_graph import PandasKnowledgeBaseGraph
|
12 |
from lynxscribe.components.rag.rag_chatbot import Scenario, ScenarioSelector, RAGChatbot
|
@@ -17,94 +29,621 @@ from lynxscribe.components.chat.processors import (
|
|
17 |
)
|
18 |
from lynxscribe.components.chat.api import ChatAPI
|
19 |
from lynxscribe.core.models.prompts import ChatCompletionPrompt
|
|
|
20 |
|
21 |
from lynxkite.core import ops
|
22 |
import json
|
23 |
from lynxkite.core.executors import one_by_one
|
24 |
|
|
|
|
|
25 |
ENV = "LynxScribe"
|
26 |
one_by_one.register(ENV)
|
|
|
27 |
op = ops.op_registration(ENV)
|
28 |
output_on_top = ops.output_position(output="top")
|
29 |
|
30 |
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
|
37 |
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
llm = get_llm_engine(name=name)
|
42 |
-
return {"llm": llm}
|
43 |
|
44 |
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
rag_graph = RAGGraph(
|
61 |
PandasKnowledgeBaseGraph(vector_store=vector_store, text_embedder=text_embedder)
|
62 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
return {"rag_graph": rag_graph}
|
64 |
|
65 |
|
66 |
@output_on_top
|
67 |
-
@op("
|
68 |
-
def
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
scenarios = load_config(scenario_file)
|
70 |
node_types = [t.strip() for t in node_types.split(",")]
|
71 |
-
scenario_selector = ScenarioSelector(
|
72 |
-
scenarios=[Scenario(**scenario) for scenario in scenarios],
|
73 |
-
node_types=node_types,
|
74 |
-
)
|
75 |
-
return {"scenario_selector": scenario_selector}
|
76 |
|
|
|
|
|
77 |
|
78 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
|
80 |
|
81 |
@output_on_top
|
82 |
-
@ops.input_position(
|
83 |
-
@op("RAG
|
84 |
-
def
|
85 |
-
|
86 |
-
|
87 |
-
llm,
|
88 |
*,
|
89 |
negative_answer=DEFAULT_NEGATIVE_ANSWER,
|
90 |
-
|
91 |
-
|
92 |
-
|
|
|
|
|
|
|
|
|
|
|
93 |
):
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
rag_chatbot = RAGChatbot(
|
99 |
rag_graph=rag_graph,
|
100 |
scenario_selector=scenario_selector,
|
101 |
llm=llm,
|
102 |
negative_answer=negative_answer,
|
103 |
-
|
104 |
-
|
105 |
-
|
|
|
|
|
|
|
|
|
|
|
106 |
)
|
107 |
-
|
|
|
108 |
|
109 |
|
110 |
@output_on_top
|
@@ -162,7 +701,12 @@ async def test_chat_api(message, chat_api, *, show_details=False):
|
|
162 |
messages=[{"role": "user", "content": message["text"]}],
|
163 |
)
|
164 |
response = await chat_api.answer(request, stream=False)
|
165 |
-
|
|
|
|
|
|
|
|
|
|
|
166 |
if show_details:
|
167 |
return {"answer": answer, **response.__dict__}
|
168 |
else:
|
@@ -174,39 +718,6 @@ def input_chat(*, chat: str):
|
|
174 |
return {"text": chat}
|
175 |
|
176 |
|
177 |
-
@output_on_top
|
178 |
-
@ops.input_position(chatbot="bottom", chat_processor="bottom", knowledge_base="bottom")
|
179 |
-
@op("Chat API")
|
180 |
-
def chat_api(chatbot, chat_processor, knowledge_base, *, model="gpt-4o-mini"):
|
181 |
-
chatbot = chatbot[0]["chatbot"]
|
182 |
-
chat_processor = chat_processor[0]["chat_processor"]
|
183 |
-
knowledge_base = knowledge_base[0]
|
184 |
-
c = ChatAPI(
|
185 |
-
chatbot=chatbot,
|
186 |
-
chat_processor=chat_processor,
|
187 |
-
model=model,
|
188 |
-
)
|
189 |
-
if knowledge_base:
|
190 |
-
c.chatbot.rag_graph.kg_base.load_v1_knowledge_base(**knowledge_base)
|
191 |
-
c.chatbot.scenario_selector.check_compatibility(c.chatbot.rag_graph)
|
192 |
-
return {"chat_api": c}
|
193 |
-
|
194 |
-
|
195 |
-
@output_on_top
|
196 |
-
@op("Knowledge base")
|
197 |
-
def knowledge_base(
|
198 |
-
*,
|
199 |
-
nodes_path="nodes.pickle",
|
200 |
-
edges_path="edges.pickle",
|
201 |
-
template_cluster_path="tempclusters.pickle",
|
202 |
-
):
|
203 |
-
return {
|
204 |
-
"nodes_path": nodes_path,
|
205 |
-
"edges_path": edges_path,
|
206 |
-
"template_cluster_path": template_cluster_path,
|
207 |
-
}
|
208 |
-
|
209 |
-
|
210 |
@op("View", view="table_view")
|
211 |
def view(input):
|
212 |
columns = [str(c) for c in input.keys() if not str(c).startswith("_")]
|
@@ -230,7 +741,7 @@ async def get_chat_api(ws: str):
|
|
230 |
assert path.exists(), f"Workspace {path} does not exist"
|
231 |
ws = workspace.load(path)
|
232 |
contexts = await ops.EXECUTORS[ENV](ws)
|
233 |
-
nodes = [op for op in ws.nodes if op.data.title == "
|
234 |
[node] = nodes
|
235 |
context = contexts[node.id]
|
236 |
return context.last_result["chat_api"]
|
@@ -299,3 +810,43 @@ def get_lynxscribe_workspaces():
|
|
299 |
pass # Ignore files that are not valid workspaces.
|
300 |
workspaces.sort()
|
301 |
return workspaces
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
"""
|
2 |
LynxScribe configuration and testing in LynxKite.
|
3 |
+
TODO: all these outputs should contain metadata. So the next task can check the input type, etc.
|
4 |
"""
|
5 |
|
6 |
+
from google.cloud import storage
|
7 |
+
from copy import deepcopy
|
8 |
+
from enum import Enum
|
9 |
+
import asyncio
|
10 |
+
import pandas as pd
|
11 |
+
import joblib
|
12 |
+
from pydantic import BaseModel, ConfigDict
|
13 |
+
|
14 |
import pathlib
|
15 |
from lynxscribe.core.llm.base import get_llm_engine
|
16 |
from lynxscribe.core.vector_store.base import get_vector_store
|
17 |
from lynxscribe.common.config import load_config
|
18 |
from lynxscribe.components.text.embedder import TextEmbedder
|
19 |
+
from lynxscribe.core.models.embedding import Embedding
|
20 |
+
from lynxscribe.components.embedding_clustering import FclusterBasedClustering
|
21 |
+
|
22 |
from lynxscribe.components.rag.rag_graph import RAGGraph
|
23 |
from lynxscribe.components.rag.knowledge_base_graph import PandasKnowledgeBaseGraph
|
24 |
from lynxscribe.components.rag.rag_chatbot import Scenario, ScenarioSelector, RAGChatbot
|
|
|
29 |
)
|
30 |
from lynxscribe.components.chat.api import ChatAPI
|
31 |
from lynxscribe.core.models.prompts import ChatCompletionPrompt
|
32 |
+
from lynxscribe.components.rag.loaders import FAQTemplateLoader
|
33 |
|
34 |
from lynxkite.core import ops
|
35 |
import json
|
36 |
from lynxkite.core.executors import one_by_one
|
37 |
|
38 |
+
DEFAULT_NEGATIVE_ANSWER = "I'm sorry, but the data I've been trained on does not contain any information related to your question."
|
39 |
+
|
40 |
ENV = "LynxScribe"
|
41 |
one_by_one.register(ENV)
|
42 |
+
mem = joblib.Memory("joblib-cache")
|
43 |
op = ops.op_registration(ENV)
|
44 |
output_on_top = ops.output_position(output="top")
|
45 |
|
46 |
|
47 |
+
# defining the cloud provider enum
|
48 |
+
class CloudProvider(Enum):
|
49 |
+
GCP = "gcp"
|
50 |
+
AWS = "aws"
|
51 |
+
AZURE = "azure"
|
52 |
|
53 |
|
54 |
+
class RAGVersion(Enum):
|
55 |
+
V1 = "v1"
|
56 |
+
V2 = "v2"
|
|
|
|
|
57 |
|
58 |
|
59 |
+
class RAGTemplate(BaseModel):
|
60 |
+
"""
|
61 |
+
Model for RAG templates consisting of three tables: they are connected via scenario names.
|
62 |
+
One table (FAQs) contains scenario-denoted nodes to upsert into the knowledge base, the other
|
63 |
+
two tables serve as the configuration for the scenario selector.
|
64 |
+
Attributes:
|
65 |
+
faq_data:
|
66 |
+
Table where each row is an FAQ question, and possibly its answer pair. Will be fed into
|
67 |
+
`FAQTemplateLoader.load_nodes_and_edges()`. For configuration of this table see the
|
68 |
+
loader's init arguments.
|
69 |
+
scenario_data:
|
70 |
+
Table where each row is a Scenario, column names are thus scenario attributes. Will be
|
71 |
+
fed into `ScenarioSelector.from_data()`.
|
72 |
+
prompt_codes:
|
73 |
+
Optional helper for the scenario table, may contain prompt code mappings to real prompt
|
74 |
+
messages. It's enough then to use the codes instead of the full messages in the
|
75 |
+
scenarios table. Will be fed into `ScenarioSelector.from_data()`.
|
76 |
+
"""
|
77 |
|
78 |
+
model_config = ConfigDict(arbitrary_types_allowed=True)
|
79 |
+
|
80 |
+
faq_data: pd.DataFrame
|
81 |
+
scenario_data: pd.DataFrame
|
82 |
+
prompt_codes: dict[str, str] = {}
|
83 |
+
|
84 |
+
@classmethod
|
85 |
+
def from_excel_path(
|
86 |
+
cls,
|
87 |
+
path: str,
|
88 |
+
faq_data_sheet_name: str,
|
89 |
+
scenario_data_sheet_name: str,
|
90 |
+
prompt_codes_sheet_name: str | None = None,
|
91 |
+
) -> "RAGTemplate":
|
92 |
+
"""Spawn a RAGTemplate from an Excel file containing the two needed (plus one optional) sheets."""
|
93 |
+
|
94 |
+
def transform_codes(prompt_codes: pd.DataFrame) -> dict[str, str]:
|
95 |
+
"""Check and transform prompt codes table into a code dictionary."""
|
96 |
+
if (len_columns := len(prompt_codes.columns)) != 2:
|
97 |
+
raise ValueError(
|
98 |
+
f"Prompt codes should contain exactly 2 columns, {len_columns} found."
|
99 |
+
)
|
100 |
+
return prompt_codes.set_index(prompt_codes.columns[0])[
|
101 |
+
prompt_codes.columns[1]
|
102 |
+
].to_dict()
|
103 |
+
|
104 |
+
return cls(
|
105 |
+
faq_data=pd.read_excel(path, sheet_name=faq_data_sheet_name),
|
106 |
+
scenario_data=pd.read_excel(path, sheet_name=scenario_data_sheet_name),
|
107 |
+
prompt_codes=transform_codes(pd.read_excel(path, sheet_name=prompt_codes_sheet_name))
|
108 |
+
if prompt_codes_sheet_name
|
109 |
+
else {},
|
110 |
+
)
|
111 |
+
|
112 |
+
|
113 |
+
@op("Cloud-sourced File Listing")
|
114 |
+
def cloud_file_loader(
|
115 |
+
*,
|
116 |
+
cloud_provider: CloudProvider = CloudProvider.GCP,
|
117 |
+
folder_URL: str = "https://storage.googleapis.com/lynxkite_public_data/lynxscribe-images/image-rag-test",
|
118 |
+
accepted_file_types: str = ".jpg, .jpeg, .png",
|
119 |
+
):
|
120 |
+
"""
|
121 |
+
Gives back the list of URLs of all the images from a cloud-based folder.
|
122 |
+
Currently only supports GCP storage.
|
123 |
+
"""
|
124 |
+
if folder_URL[-1].endswith("/"):
|
125 |
+
folder_URL = folder_URL[:-1]
|
126 |
+
|
127 |
+
accepted_file_types = tuple([t.strip() for t in accepted_file_types.split(",")])
|
128 |
+
|
129 |
+
if cloud_provider == CloudProvider.GCP:
|
130 |
+
client = storage.Client()
|
131 |
+
url_useful_part = folder_URL.split(".com/")[-1]
|
132 |
+
bucket_name = url_useful_part.split("/")[0]
|
133 |
+
if bucket_name == url_useful_part:
|
134 |
+
prefix = ""
|
135 |
+
else:
|
136 |
+
prefix = url_useful_part.split(bucket_name + "/")[-1]
|
137 |
+
|
138 |
+
bucket = client.bucket(bucket_name)
|
139 |
+
blobs = bucket.list_blobs(prefix=prefix)
|
140 |
+
file_urls = [blob.public_url for blob in blobs if blob.name.endswith(accepted_file_types)]
|
141 |
+
return {"file_urls": file_urls}
|
142 |
+
else:
|
143 |
+
raise ValueError(f"Cloud provider '{cloud_provider}' is not supported.")
|
144 |
+
|
145 |
+
|
146 |
+
# @output_on_top
|
147 |
+
# @op("LynxScribe RAG Graph Vector Store")
|
148 |
+
# @mem.cache
|
149 |
+
# def ls_rag_graph(
|
150 |
+
# *,
|
151 |
+
# name: str = "faiss",
|
152 |
+
# num_dimensions: int = 3072,
|
153 |
+
# collection_name: str = "lynx",
|
154 |
+
# text_embedder_interface: str = "openai",
|
155 |
+
# text_embedder_model_name_or_path: str = "text-embedding-3-large",
|
156 |
+
# # api_key_name: str = "OPENAI_API_KEY",
|
157 |
+
# ):
|
158 |
+
# """
|
159 |
+
# Returns with a vector store instance.
|
160 |
+
# """
|
161 |
+
|
162 |
+
# # getting the text embedder instance
|
163 |
+
# llm_params = {"name": text_embedder_interface}
|
164 |
+
# # if api_key_name:
|
165 |
+
# # llm_params["api_key"] = os.getenv(api_key_name)
|
166 |
+
# llm = get_llm_engine(**llm_params)
|
167 |
+
# text_embedder = TextEmbedder(llm=llm, model=text_embedder_model_name_or_path)
|
168 |
+
|
169 |
+
# # getting the vector store
|
170 |
+
# if name == "chromadb":
|
171 |
+
# vector_store = get_vector_store(name=name, collection_name=collection_name)
|
172 |
+
# elif name == "faiss":
|
173 |
+
# vector_store = get_vector_store(name=name, num_dimensions=num_dimensions)
|
174 |
+
# else:
|
175 |
+
# raise ValueError(f"Vector store name '{name}' is not supported.")
|
176 |
+
|
177 |
+
# # building up the RAG graph
|
178 |
+
# rag_graph = RAGGraph(
|
179 |
+
# PandasKnowledgeBaseGraph(vector_store=vector_store, text_embedder=text_embedder)
|
180 |
+
# )
|
181 |
+
|
182 |
+
# return {"rag_graph": rag_graph}
|
183 |
+
|
184 |
+
|
185 |
+
@op("LynxScribe Image Describer")
|
186 |
+
@mem.cache
|
187 |
+
async def ls_image_describer(
|
188 |
+
file_urls,
|
189 |
+
*,
|
190 |
+
llm_interface: str = "openai",
|
191 |
+
llm_visual_model: str = "gpt-4o",
|
192 |
+
llm_prompt_path: str = "uploads/image_description_prompts.yaml",
|
193 |
+
llm_prompt_name: str = "cot_picture_descriptor",
|
194 |
+
# api_key_name: str = "OPENAI_API_KEY",
|
195 |
+
):
|
196 |
+
"""
|
197 |
+
Returns with image descriptions from a list of image URLs.
|
198 |
|
199 |
+
TODO: making the inputs more flexible (e.g. accepting file locations, URLs, binaries, etc.).
|
200 |
+
the input dictionary should contain some meta info: e.g., what is in the list...
|
201 |
+
"""
|
202 |
+
|
203 |
+
# handling inputs
|
204 |
+
image_urls = file_urls["file_urls"]
|
205 |
+
|
206 |
+
# loading the LLM
|
207 |
+
llm_params = {"name": llm_interface}
|
208 |
+
# if api_key_name:
|
209 |
+
# llm_params["api_key"] = os.getenv(api_key_name)
|
210 |
+
llm = get_llm_engine(**llm_params)
|
211 |
+
|
212 |
+
# preparing the prompts
|
213 |
+
prompt_base = load_config(llm_prompt_path)[llm_prompt_name]
|
214 |
+
prompt_list = []
|
215 |
+
|
216 |
+
for i in range(len(image_urls)):
|
217 |
+
image = image_urls[i]
|
218 |
+
|
219 |
+
_prompt = deepcopy(prompt_base)
|
220 |
+
for message in _prompt:
|
221 |
+
if isinstance(message["content"], list):
|
222 |
+
for _message_part in message["content"]:
|
223 |
+
if "image_url" in _message_part:
|
224 |
+
_message_part["image_url"] = {"url": image}
|
225 |
+
|
226 |
+
prompt_list.append(_prompt)
|
227 |
+
|
228 |
+
# creating the prompt objects
|
229 |
+
ch_prompt_list = [
|
230 |
+
ChatCompletionPrompt(model=llm_visual_model, messages=prompt) for prompt in prompt_list
|
231 |
+
]
|
232 |
+
|
233 |
+
# get the image descriptions
|
234 |
+
tasks = [llm.acreate_completion(completion_prompt=_prompt) for _prompt in ch_prompt_list]
|
235 |
+
out_completions = await asyncio.gather(*tasks)
|
236 |
+
results = [
|
237 |
+
dictionary_corrector(result.choices[0].message.content) for result in out_completions
|
238 |
+
]
|
239 |
+
|
240 |
+
# getting the image descriptions (list of dictionaries {image_url: URL, description: description})
|
241 |
+
# TODO: some result class could be a better idea (will be developed in LynxScribe)
|
242 |
+
image_descriptions = [
|
243 |
+
{"image_url": image_urls[i], "description": results[i]} for i in range(len(image_urls))
|
244 |
+
]
|
245 |
+
|
246 |
+
return {"image_descriptions": image_descriptions}
|
247 |
+
|
248 |
+
|
249 |
+
@op("LynxScribe Image RAG Builder")
|
250 |
+
@mem.cache
|
251 |
+
async def ls_image_rag_builder(
|
252 |
+
image_descriptions,
|
253 |
+
*,
|
254 |
+
vdb_provider_name: str = "faiss",
|
255 |
+
vdb_num_dimensions: int = 3072,
|
256 |
+
vdb_collection_name: str = "lynx",
|
257 |
+
text_embedder_interface: str = "openai",
|
258 |
+
text_embedder_model_name_or_path: str = "text-embedding-3-large",
|
259 |
+
# api_key_name: str = "OPENAI_API_KEY",
|
260 |
+
):
|
261 |
+
"""
|
262 |
+
Based on image descriptions, and embedding/VDB parameters,
|
263 |
+
the function builds up an image RAG graph, where the nodes are the
|
264 |
+
descriptions of the images (and of all image objects).
|
265 |
+
|
266 |
+
In a later phase, synthetic questions and "named entities" will also
|
267 |
+
be added to the graph.
|
268 |
+
"""
|
269 |
+
|
270 |
+
# handling inputs
|
271 |
+
image_descriptions = image_descriptions["image_descriptions"]
|
272 |
+
|
273 |
+
# Building up the empty RAG graph
|
274 |
+
|
275 |
+
# a) Define LLM interface and get a text embedder
|
276 |
+
llm_params = {"name": text_embedder_interface}
|
277 |
+
# if api_key_name:
|
278 |
+
# llm_params["api_key"] = os.getenv(api_key_name)
|
279 |
+
llm = get_llm_engine(**llm_params)
|
280 |
+
text_embedder = TextEmbedder(llm=llm, model=text_embedder_model_name_or_path)
|
281 |
+
|
282 |
+
# b) getting the vector store
|
283 |
+
# TODO: vdb_provider_name should be ENUM, and other parameters should appear accordingly
|
284 |
+
if vdb_provider_name == "chromadb":
|
285 |
+
vector_store = get_vector_store(name=vdb_provider_name, collection_name=vdb_collection_name)
|
286 |
+
elif vdb_provider_name == "faiss":
|
287 |
+
vector_store = get_vector_store(name=vdb_provider_name, num_dimensions=vdb_num_dimensions)
|
288 |
+
else:
|
289 |
+
raise ValueError(f"Vector store name '{vdb_provider_name}' is not supported.")
|
290 |
+
|
291 |
+
# c) building up the RAG graph
|
292 |
rag_graph = RAGGraph(
|
293 |
PandasKnowledgeBaseGraph(vector_store=vector_store, text_embedder=text_embedder)
|
294 |
)
|
295 |
+
|
296 |
+
dict_list_df = []
|
297 |
+
for image_description_tuple in image_descriptions:
|
298 |
+
image_url = image_description_tuple["image_url"]
|
299 |
+
image_description = image_description_tuple["description"]
|
300 |
+
|
301 |
+
if "overall description" in image_description:
|
302 |
+
dict_list_df.append(
|
303 |
+
{
|
304 |
+
"image_url": image_url,
|
305 |
+
"description": image_description["overall description"],
|
306 |
+
"source": "overall description",
|
307 |
+
}
|
308 |
+
)
|
309 |
+
|
310 |
+
if "details" in image_description:
|
311 |
+
for dkey in image_description["details"].keys():
|
312 |
+
text = f"The picture's description is: {image_description['overall description']}\n\nThe description of the {dkey} is: {image_description['details'][dkey]}"
|
313 |
+
dict_list_df.append(
|
314 |
+
{"image_url": image_url, "description": text, "source": "details"}
|
315 |
+
)
|
316 |
+
|
317 |
+
pdf_descriptions = pd.DataFrame(dict_list_df)
|
318 |
+
pdf_descriptions["embedding_values"] = await text_embedder.acreate_embedding(
|
319 |
+
pdf_descriptions["description"].to_list()
|
320 |
+
)
|
321 |
+
pdf_descriptions["id"] = "im_" + pdf_descriptions.index.astype(str)
|
322 |
+
|
323 |
+
# adding the embeddings to the RAG graph with metadata
|
324 |
+
pdf_descriptions["embedding"] = pdf_descriptions.apply(
|
325 |
+
lambda row: Embedding(
|
326 |
+
id=row["id"],
|
327 |
+
value=row["embedding_values"],
|
328 |
+
metadata={
|
329 |
+
"image_url": row["image_url"],
|
330 |
+
"image_part": row["source"],
|
331 |
+
"type": "image_description",
|
332 |
+
},
|
333 |
+
document=row["description"],
|
334 |
+
),
|
335 |
+
axis=1,
|
336 |
+
)
|
337 |
+
embedding_list = pdf_descriptions["embedding"].tolist()
|
338 |
+
|
339 |
+
# adding the embeddings to the RAG graph
|
340 |
+
rag_graph.kg_base.vector_store.upsert(embedding_list)
|
341 |
+
|
342 |
+
# # saving the RAG graph
|
343 |
+
# rag_graph.kg_base.save(image_rag_out_path)
|
344 |
+
|
345 |
+
return {"rag_graph": rag_graph}
|
346 |
+
|
347 |
+
|
348 |
+
@op("LynxScribe RAG Graph Saver")
|
349 |
+
def ls_save_rag_graph(
|
350 |
+
rag_graph,
|
351 |
+
*,
|
352 |
+
image_rag_out_path: str = "image_test_rag_graph.pickle",
|
353 |
+
):
|
354 |
+
"""
|
355 |
+
Saves the RAG graph to a pickle file.
|
356 |
+
"""
|
357 |
+
|
358 |
+
# reading inputs
|
359 |
+
rag_graph = rag_graph[0]["rag_graph"]
|
360 |
+
|
361 |
+
rag_graph.kg_base.save(image_rag_out_path)
|
362 |
+
return None
|
363 |
+
|
364 |
+
|
365 |
+
@ops.input_position(rag_graph="bottom")
|
366 |
+
@op("LynxScribe Image RAG Query")
|
367 |
+
async def search_context(rag_graph, text, *, top_k=3):
|
368 |
+
message = text["text"]
|
369 |
+
rag_graph = rag_graph[0]["rag_graph"]
|
370 |
+
|
371 |
+
# get all similarities
|
372 |
+
emb_similarities = await rag_graph.search_context(
|
373 |
+
message, max_results=top_k, unique_metadata_key="image_url"
|
374 |
+
)
|
375 |
+
|
376 |
+
# get the image urls, scores and descriptions
|
377 |
+
result_list = []
|
378 |
+
|
379 |
+
for emb_sim in emb_similarities:
|
380 |
+
image_url = emb_sim.embedding.metadata["image_url"]
|
381 |
+
score = emb_sim.score
|
382 |
+
description = emb_sim.embedding.document
|
383 |
+
result_list.append({"image_url": image_url, "score": score, "description": description})
|
384 |
+
|
385 |
+
return {"embedding_similarities": result_list}
|
386 |
+
|
387 |
+
|
388 |
+
@op("LynxScribe Image Result Viewer", view="image")
|
389 |
+
def view_image(embedding_similarities):
|
390 |
+
"""
|
391 |
+
Plotting the TOP images (from embedding similarities).
|
392 |
+
|
393 |
+
TODO: later on, the user can scroll the images and send feedbacks
|
394 |
+
"""
|
395 |
+
embedding_similarities = embedding_similarities["embedding_similarities"]
|
396 |
+
return embedding_similarities[0]["image_url"]
|
397 |
+
|
398 |
+
|
399 |
+
@op("LynxScribe Text RAG Loader")
|
400 |
+
@mem.cache
|
401 |
+
def ls_text_rag_loader(
|
402 |
+
file_urls,
|
403 |
+
*,
|
404 |
+
input_type: RAGVersion = RAGVersion.V1,
|
405 |
+
vdb_provider_name: str = "faiss",
|
406 |
+
vdb_num_dimensions: int = 3072,
|
407 |
+
vdb_collection_name: str = "lynx",
|
408 |
+
text_embedder_interface: str = "openai",
|
409 |
+
text_embedder_model_name_or_path: str = "text-embedding-3-large",
|
410 |
+
# api_key_name: str = "OPENAI_API_KEY",
|
411 |
+
):
|
412 |
+
"""
|
413 |
+
Loading a text-based RAG graph from saved files (getting pandas readable links).
|
414 |
+
"""
|
415 |
+
|
416 |
+
# handling inputs
|
417 |
+
file_urls = file_urls["file_urls"]
|
418 |
+
|
419 |
+
# getting the text embedder instance
|
420 |
+
llm_params = {"name": text_embedder_interface}
|
421 |
+
# if api_key_name:
|
422 |
+
# llm_params["api_key"] = os.getenv(api_key_name)
|
423 |
+
llm = get_llm_engine(**llm_params)
|
424 |
+
text_embedder = TextEmbedder(llm=llm, model=text_embedder_model_name_or_path)
|
425 |
+
|
426 |
+
# getting the vector store
|
427 |
+
if vdb_provider_name == "chromadb":
|
428 |
+
vector_store = get_vector_store(name=vdb_provider_name, collection_name=vdb_collection_name)
|
429 |
+
elif vdb_provider_name == "faiss":
|
430 |
+
vector_store = get_vector_store(name=vdb_provider_name, num_dimensions=vdb_num_dimensions)
|
431 |
+
else:
|
432 |
+
raise ValueError(f"Vector store name '{vdb_provider_name}' is not supported.")
|
433 |
+
|
434 |
+
# building up the RAG graph
|
435 |
+
rag_graph = RAGGraph(
|
436 |
+
PandasKnowledgeBaseGraph(vector_store=vector_store, text_embedder=text_embedder)
|
437 |
+
)
|
438 |
+
|
439 |
+
# loading the knowledge base (temporary + TODO: adding v2)
|
440 |
+
if input_type == RAGVersion.V1:
|
441 |
+
node_file = [f for f in file_urls if "nodes.p" in f][0]
|
442 |
+
edge_file = [f for f in file_urls if "edges.p" in f][0]
|
443 |
+
tempcluster_file = [f for f in file_urls if "clusters.p" in f][0]
|
444 |
+
rag_graph.kg_base.load_v1_knowledge_base(
|
445 |
+
nodes_path=node_file,
|
446 |
+
edges_path=edge_file,
|
447 |
+
template_cluster_path=tempcluster_file,
|
448 |
+
)
|
449 |
+
elif input_type == RAGVersion.V2:
|
450 |
+
raise ValueError("Currently only v1 input type is supported.")
|
451 |
+
else:
|
452 |
+
raise ValueError(f"Input type '{input_type}' is not supported.")
|
453 |
+
|
454 |
+
return {"rag_graph": rag_graph}
|
455 |
+
|
456 |
+
|
457 |
+
@op("LynxScribe FAQ to RAG")
|
458 |
+
@mem.cache
|
459 |
+
async def ls_faq_to_rag(
|
460 |
+
*,
|
461 |
+
faq_excel_path: str = "",
|
462 |
+
vdb_provider_name: str = "faiss",
|
463 |
+
vdb_num_dimensions: int = 3072,
|
464 |
+
vdb_collection_name: str = "lynx",
|
465 |
+
text_embedder_interface: str = "openai",
|
466 |
+
text_embedder_model_name_or_path: str = "text-embedding-3-large",
|
467 |
+
scenario_cluster_distance_pct: int = 30,
|
468 |
+
):
|
469 |
+
"""
|
470 |
+
Loading a text-based RAG graph from saved files (getting pandas readable links).
|
471 |
+
"""
|
472 |
+
|
473 |
+
# getting the text embedder instance
|
474 |
+
llm_params = {"name": text_embedder_interface}
|
475 |
+
llm = get_llm_engine(**llm_params)
|
476 |
+
text_embedder = TextEmbedder(llm=llm, model=text_embedder_model_name_or_path)
|
477 |
+
|
478 |
+
# getting the vector store
|
479 |
+
if vdb_provider_name == "chromadb":
|
480 |
+
vector_store = get_vector_store(name=vdb_provider_name, collection_name=vdb_collection_name)
|
481 |
+
elif vdb_provider_name == "faiss":
|
482 |
+
vector_store = get_vector_store(name=vdb_provider_name, num_dimensions=vdb_num_dimensions)
|
483 |
+
else:
|
484 |
+
raise ValueError(f"Vector store name '{vdb_provider_name}' is not supported.")
|
485 |
+
|
486 |
+
# building up the RAG graph
|
487 |
+
rag_graph = RAGGraph(
|
488 |
+
PandasKnowledgeBaseGraph(vector_store=vector_store, text_embedder=text_embedder)
|
489 |
+
)
|
490 |
+
|
491 |
+
# loading the knowledge base from the FAQ file
|
492 |
+
rag_template = RAGTemplate.from_excel_path(
|
493 |
+
path=faq_excel_path,
|
494 |
+
faq_data_sheet_name="scenario_examples",
|
495 |
+
scenario_data_sheet_name="scenario_scripts",
|
496 |
+
prompt_codes_sheet_name="prompt_dictionary",
|
497 |
+
)
|
498 |
+
|
499 |
+
faq_loader_params = {
|
500 |
+
"id_column": "scenario_example_ID",
|
501 |
+
"timestamp_column": "last_modified_timestamp",
|
502 |
+
"validity_column": "valid_flg",
|
503 |
+
"question_type_contents_id": ["faq_question", "faq_question", "q_{id}"],
|
504 |
+
"answer_type_contents_id": ["faq_answer", "{faq_question}\n\n{faq_answer}", "a_{id}"],
|
505 |
+
"question_to_answer_edge_type_weight": ["qna", 1.0],
|
506 |
+
}
|
507 |
+
|
508 |
+
nodes, edges = FAQTemplateLoader(**faq_loader_params).load_nodes_and_edges(
|
509 |
+
rag_template.faq_data
|
510 |
+
)
|
511 |
+
|
512 |
+
await rag_graph.kg_base.upsert_nodes(*nodes)
|
513 |
+
rag_graph.kg_base.upsert_edges(edges)
|
514 |
+
|
515 |
+
# Generating scenario clusters
|
516 |
+
question_ids = [_id for _id in nodes[0] if _id.startswith("q_")]
|
517 |
+
stored_embeddings = rag_graph.kg_base.vector_store.get(
|
518 |
+
question_ids, include=["embeddings", "metadatas"]
|
519 |
+
)
|
520 |
+
embedding_vals = pd.Series([_emb.value for _emb in stored_embeddings], index=question_ids)
|
521 |
+
labels = pd.Series(
|
522 |
+
[_emb.metadata["scenario_name"] for _emb in stored_embeddings], index=question_ids
|
523 |
+
)
|
524 |
+
temp_cls = FclusterBasedClustering(distance_percentile=scenario_cluster_distance_pct)
|
525 |
+
temp_cls.fit(embedding_vals, labels)
|
526 |
+
df_tempclusters = temp_cls.get_cluster_centers()
|
527 |
+
|
528 |
+
# Adding the scenario clusters to the RAG Graph
|
529 |
+
df_tempclusters["template_id"] = "t_" + df_tempclusters.index.astype(str)
|
530 |
+
df_tempclusters["embedding"] = df_tempclusters.apply(
|
531 |
+
lambda row: Embedding(
|
532 |
+
id=row["template_id"],
|
533 |
+
value=row["cluster_center"],
|
534 |
+
metadata={"scenario_name": row["control_label"], "type": "intent_cluster"},
|
535 |
+
),
|
536 |
+
axis=1,
|
537 |
+
)
|
538 |
+
embedding_list = df_tempclusters["embedding"].tolist()
|
539 |
+
rag_graph.kg_base.vector_store.upsert(embedding_list)
|
540 |
+
|
541 |
return {"rag_graph": rag_graph}
|
542 |
|
543 |
|
544 |
@output_on_top
|
545 |
+
@op("LynxScribe RAG Graph Chatbot Builder")
|
546 |
+
def ls_rag_chatbot_builder(
|
547 |
+
rag_graph,
|
548 |
+
*,
|
549 |
+
scenario_file: str = "uploads/lynx_chatbot_scenario_selector.yaml",
|
550 |
+
node_types: str = "intent_cluster",
|
551 |
+
scenario_meta_name: str = "",
|
552 |
+
):
|
553 |
+
"""
|
554 |
+
Builds up a RAG Graph-based chatbot (basically the loaded RAG graph +
|
555 |
+
a scenario selector).
|
556 |
+
|
557 |
+
TODO: Later, the scenario selector can be built up synthetically from
|
558 |
+
the input documents - or semi-automated, not just from the scenario
|
559 |
+
yaml.
|
560 |
+
"""
|
561 |
+
|
562 |
scenarios = load_config(scenario_file)
|
563 |
node_types = [t.strip() for t in node_types.split(",")]
|
|
|
|
|
|
|
|
|
|
|
564 |
|
565 |
+
# handling inputs
|
566 |
+
rag_graph = rag_graph["rag_graph"]
|
567 |
|
568 |
+
parameters = {
|
569 |
+
"scenarios": [Scenario(**scenario) for scenario in scenarios],
|
570 |
+
"node_types": node_types,
|
571 |
+
}
|
572 |
+
if len(scenario_meta_name) > 0:
|
573 |
+
parameters["get_scenario_name"] = lambda node: node.metadata[scenario_meta_name]
|
574 |
+
|
575 |
+
# loading the scenarios
|
576 |
+
scenario_selector = ScenarioSelector(**parameters)
|
577 |
+
|
578 |
+
# TODO: later we should unify this "knowledge base" object across the functions
|
579 |
+
# this could be always an input of a RAG Chatbot, but also for other apps.
|
580 |
+
return {
|
581 |
+
"knowledge_base": {
|
582 |
+
"rag_graph": rag_graph,
|
583 |
+
"scenario_selector": scenario_selector,
|
584 |
+
}
|
585 |
+
}
|
586 |
|
587 |
|
588 |
@output_on_top
|
589 |
+
@ops.input_position(knowledge_base="bottom", chat_processor="bottom")
|
590 |
+
@op("LynxScribe RAG Graph Chatbot Backend")
|
591 |
+
def ls_rag_chatbot_backend(
|
592 |
+
knowledge_base,
|
593 |
+
chat_processor,
|
|
|
594 |
*,
|
595 |
negative_answer=DEFAULT_NEGATIVE_ANSWER,
|
596 |
+
retriever_limits_by_type="{}",
|
597 |
+
retriever_strict_limits=True,
|
598 |
+
retriever_overall_chunk_limit=20,
|
599 |
+
retriever_overall_token_limit=3000,
|
600 |
+
retriever_max_iterations=3,
|
601 |
+
llm_interface: str = "openai",
|
602 |
+
llm_model_name: str = "gpt-4o",
|
603 |
+
# api_key_name: str = "OPENAI_API_KEY",
|
604 |
):
|
605 |
+
"""
|
606 |
+
Returns with a chatbot instance.
|
607 |
+
"""
|
608 |
+
|
609 |
+
# handling_inputs
|
610 |
+
rag_graph = knowledge_base[0]["knowledge_base"]["rag_graph"]
|
611 |
+
scenario_selector = knowledge_base[0]["knowledge_base"]["scenario_selector"]
|
612 |
+
chat_processor = chat_processor[0]["chat_processor"]
|
613 |
+
limits_by_type = json.loads(retriever_limits_by_type)
|
614 |
+
|
615 |
+
# connecting to the LLM
|
616 |
+
llm_params = {"name": llm_interface}
|
617 |
+
# if api_key_name:
|
618 |
+
# llm_params["api_key"] = os.getenv(api_key_name)
|
619 |
+
llm = get_llm_engine(**llm_params)
|
620 |
+
|
621 |
+
# setting the parameters
|
622 |
+
params = {
|
623 |
+
"limits_by_type": limits_by_type,
|
624 |
+
"strict_limits": retriever_strict_limits,
|
625 |
+
"max_results": retriever_overall_chunk_limit,
|
626 |
+
"token_limit": retriever_overall_token_limit,
|
627 |
+
"max_iterations": retriever_max_iterations,
|
628 |
+
}
|
629 |
+
|
630 |
+
# generating the RAG Chatbot
|
631 |
rag_chatbot = RAGChatbot(
|
632 |
rag_graph=rag_graph,
|
633 |
scenario_selector=scenario_selector,
|
634 |
llm=llm,
|
635 |
negative_answer=negative_answer,
|
636 |
+
**params,
|
637 |
+
)
|
638 |
+
|
639 |
+
# generating the chatbot back-end
|
640 |
+
c = ChatAPI(
|
641 |
+
chatbot=rag_chatbot,
|
642 |
+
chat_processor=chat_processor,
|
643 |
+
model=llm_model_name,
|
644 |
)
|
645 |
+
|
646 |
+
return {"chat_api": c}
|
647 |
|
648 |
|
649 |
@output_on_top
|
|
|
701 |
messages=[{"role": "user", "content": message["text"]}],
|
702 |
)
|
703 |
response = await chat_api.answer(request, stream=False)
|
704 |
+
if len(response.choices) == 0:
|
705 |
+
answer = "The following FAQ items are similar to the question:\n"
|
706 |
+
for item in response.sources:
|
707 |
+
answer += f"------------------------------------------------------ \n{item.body}\n\n"
|
708 |
+
else:
|
709 |
+
answer = response.choices[0].message.content
|
710 |
if show_details:
|
711 |
return {"answer": answer, **response.__dict__}
|
712 |
else:
|
|
|
718 |
return {"text": chat}
|
719 |
|
720 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
721 |
@op("View", view="table_view")
|
722 |
def view(input):
|
723 |
columns = [str(c) for c in input.keys() if not str(c).startswith("_")]
|
|
|
741 |
assert path.exists(), f"Workspace {path} does not exist"
|
742 |
ws = workspace.load(path)
|
743 |
contexts = await ops.EXECUTORS[ENV](ws)
|
744 |
+
nodes = [op for op in ws.nodes if op.data.title == "LynxScribe RAG Graph Chatbot Backend"]
|
745 |
[node] = nodes
|
746 |
context = contexts[node.id]
|
747 |
return context.last_result["chat_api"]
|
|
|
810 |
pass # Ignore files that are not valid workspaces.
|
811 |
workspaces.sort()
|
812 |
return workspaces
|
813 |
+
|
814 |
+
|
815 |
+
def dictionary_corrector(dict_string: str, expected_keys: list | None = None) -> dict:
|
816 |
+
"""
|
817 |
+
Processing LLM outputs: when the LLM returns with a dictionary (in a string format). It optionally
|
818 |
+
crosschecks the input with the expected keys and return a dictionary with the expected keys and their
|
819 |
+
values ('unknown' if not present). If there is an error during the processing, it will return with
|
820 |
+
a dictionary of the expected keys, all with 'error' as a value (or with an empty dictionary).
|
821 |
+
|
822 |
+
Currently the function does not delete the extra key-value pairs.
|
823 |
+
"""
|
824 |
+
|
825 |
+
out_dict = {}
|
826 |
+
|
827 |
+
if len(dict_string) == 0:
|
828 |
+
return out_dict
|
829 |
+
|
830 |
+
# deleting the optional text before the first and after the last curly brackets
|
831 |
+
dstring_prc = dict_string
|
832 |
+
if dstring_prc[0] != "{":
|
833 |
+
dstring_prc = "{" + "{".join(dstring_prc.split("{")[1:])
|
834 |
+
if dstring_prc[-1] != "}":
|
835 |
+
dstring_prc = "}".join(dstring_prc.split("}")[:-1]) + "}"
|
836 |
+
|
837 |
+
try:
|
838 |
+
trf_dict = json.loads(dstring_prc)
|
839 |
+
if expected_keys:
|
840 |
+
for _key in expected_keys:
|
841 |
+
if _key in trf_dict:
|
842 |
+
out_dict[_key] = trf_dict[_key]
|
843 |
+
else:
|
844 |
+
out_dict[_key] = "unknown"
|
845 |
+
else:
|
846 |
+
out_dict = trf_dict
|
847 |
+
except Exception:
|
848 |
+
if expected_keys:
|
849 |
+
for _key in expected_keys:
|
850 |
+
out_dict[_key] = "error"
|
851 |
+
|
852 |
+
return out_dict
|