@saltcorn/agents 0.4.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent-view.js +79 -20
- package/common.js +12 -0
- package/locales/de.json +1 -0
- package/package.json +1 -1
- package/skills/FTSRetrieval.js +69 -26
- package/skills/PreloadData.js +97 -19
package/agent-view.js
CHANGED
|
@@ -42,6 +42,7 @@ const {
|
|
|
42
42
|
process_interaction,
|
|
43
43
|
find_image_tool,
|
|
44
44
|
is_debug_mode,
|
|
45
|
+
get_initial_interactions,
|
|
45
46
|
} = require("./common");
|
|
46
47
|
const MarkdownIt = require("markdown-it"),
|
|
47
48
|
md = new MarkdownIt();
|
|
@@ -81,6 +82,11 @@ const configuration_workflow = (req) =>
|
|
|
81
82
|
label: "Show previous runs",
|
|
82
83
|
type: "Bool",
|
|
83
84
|
},
|
|
85
|
+
{
|
|
86
|
+
name: "prev_runs_closed",
|
|
87
|
+
label: "Initially closed",
|
|
88
|
+
type: "Bool",
|
|
89
|
+
},
|
|
84
90
|
{
|
|
85
91
|
name: "placeholder",
|
|
86
92
|
label: "Placeholder",
|
|
@@ -148,7 +154,14 @@ const uploadForm = (viewname, req) =>
|
|
|
148
154
|
const run = async (
|
|
149
155
|
table_id,
|
|
150
156
|
viewname,
|
|
151
|
-
{
|
|
157
|
+
{
|
|
158
|
+
action_id,
|
|
159
|
+
show_prev_runs,
|
|
160
|
+
prev_runs_closed,
|
|
161
|
+
placeholder,
|
|
162
|
+
explainer,
|
|
163
|
+
image_upload,
|
|
164
|
+
},
|
|
152
165
|
state,
|
|
153
166
|
{ res, req }
|
|
154
167
|
) => {
|
|
@@ -171,6 +184,7 @@ const run = async (
|
|
|
171
184
|
//triggering_row = await table.getRow({ [pk]: state[pk] });
|
|
172
185
|
triggering_row_id = state[pk];
|
|
173
186
|
}
|
|
187
|
+
const initial_q = state.run_id ? undefined : state._q;
|
|
174
188
|
if (state.run_id) {
|
|
175
189
|
const run = prevRuns.find((r) => r.id == state.run_id);
|
|
176
190
|
const interactMarkups = [];
|
|
@@ -328,15 +342,18 @@ const run = async (
|
|
|
328
342
|
}),
|
|
329
343
|
div(
|
|
330
344
|
{ class: "copilot-entry" },
|
|
331
|
-
textarea(
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
345
|
+
textarea(
|
|
346
|
+
{
|
|
347
|
+
class: "form-control",
|
|
348
|
+
name: "userinput",
|
|
349
|
+
"data-fieldname": "userinput",
|
|
350
|
+
placeholder: placeholder || "How can I help you?",
|
|
351
|
+
id: "inputuserinput",
|
|
352
|
+
rows: "3",
|
|
353
|
+
autofocus: true,
|
|
354
|
+
},
|
|
355
|
+
initial_q
|
|
356
|
+
),
|
|
340
357
|
span(
|
|
341
358
|
{ class: "submit-button p-2", onclick: "$('form.copilot').submit()" },
|
|
342
359
|
i({ id: "sendbuttonicon", class: "far fa-paper-plane" })
|
|
@@ -356,8 +373,14 @@ const run = async (
|
|
|
356
373
|
{
|
|
357
374
|
class: "d-flex justify-content-between align-middle mb-2",
|
|
358
375
|
},
|
|
359
|
-
|
|
360
|
-
|
|
376
|
+
div(
|
|
377
|
+
{ class: "d-flex" },
|
|
378
|
+
i({
|
|
379
|
+
class: "fas fa-caret-down me-1 session-open-sessions",
|
|
380
|
+
onclick: "close_session_list()",
|
|
381
|
+
}),
|
|
382
|
+
h5(req.__("Sessions"))
|
|
383
|
+
),
|
|
361
384
|
button(
|
|
362
385
|
{
|
|
363
386
|
type: "button",
|
|
@@ -392,6 +415,17 @@ const run = async (
|
|
|
392
415
|
{ class: "card" },
|
|
393
416
|
div(
|
|
394
417
|
{ class: "card-body" },
|
|
418
|
+
div(
|
|
419
|
+
{
|
|
420
|
+
class: "open-prev-runs",
|
|
421
|
+
style: prev_runs_closed ? {} : { display: "none" },
|
|
422
|
+
onclick: "open_session_list()",
|
|
423
|
+
},
|
|
424
|
+
i({
|
|
425
|
+
class: "fas fa-caret-right me-1",
|
|
426
|
+
}),
|
|
427
|
+
req.__("Sessions")
|
|
428
|
+
),
|
|
395
429
|
div({ id: "copilotinteractions" }, runInteractions),
|
|
396
430
|
input_form,
|
|
397
431
|
style(
|
|
@@ -416,6 +450,9 @@ const run = async (
|
|
|
416
450
|
left: 0.1rem;
|
|
417
451
|
cursor: pointer;
|
|
418
452
|
}
|
|
453
|
+
.session-open-sessions, .open-prev-runs {
|
|
454
|
+
cursor: pointer;
|
|
455
|
+
}
|
|
419
456
|
.copilot-entry span.attach_agent_image_wrap {
|
|
420
457
|
position: relative;
|
|
421
458
|
top: -1.8rem;
|
|
@@ -426,6 +463,9 @@ const run = async (
|
|
|
426
463
|
top: -1.2rem;
|
|
427
464
|
display: block;
|
|
428
465
|
}
|
|
466
|
+
.col-0 {
|
|
467
|
+
width: 0%
|
|
468
|
+
}
|
|
429
469
|
.copilot-entry {margin-bottom: -1.25rem; margin-top: 1rem;}
|
|
430
470
|
p.prevrun_content {
|
|
431
471
|
white-space: nowrap;
|
|
@@ -434,7 +474,17 @@ const run = async (
|
|
|
434
474
|
display: block;
|
|
435
475
|
text-overflow: ellipsis;}`
|
|
436
476
|
),
|
|
437
|
-
script(
|
|
477
|
+
script(
|
|
478
|
+
`
|
|
479
|
+
function close_session_list() {
|
|
480
|
+
$("div.prev-runs-list").hide().parents(".col-3").removeClass("col-3").addClass("was-col-3").parent().children(".col-9").removeClass("col-9").addClass("col-12")
|
|
481
|
+
$("div.open-prev-runs").show()
|
|
482
|
+
}
|
|
483
|
+
function open_session_list() {
|
|
484
|
+
$("div.prev-runs-list").show().parents(".was-col-3").removeClass(["was-col-3","col-0","d-none"]).addClass("col-3").parent().children(".col-12").removeClass("col-12").addClass("col-9")
|
|
485
|
+
$("div.open-prev-runs").hide()
|
|
486
|
+
}
|
|
487
|
+
function processCopilotResponse(res) {
|
|
438
488
|
const hadFile = $("input#attach_agent_image").val();
|
|
439
489
|
$("span.filename-label").text("");
|
|
440
490
|
$("input#attach_agent_image").val(null);
|
|
@@ -506,17 +556,20 @@ const run = async (
|
|
|
506
556
|
document.getElementById("inputuserinput").addEventListener("keydown", submitOnEnter);
|
|
507
557
|
function spin_send_button() {
|
|
508
558
|
$("#sendbuttonicon").attr("class","fas fa-spinner fa-spin");
|
|
509
|
-
}
|
|
510
|
-
|
|
559
|
+
};`,
|
|
560
|
+
initial_q && domReady("$('form.copilot').submit()")
|
|
561
|
+
)
|
|
511
562
|
)
|
|
512
563
|
);
|
|
513
564
|
return show_prev_runs
|
|
514
565
|
? {
|
|
515
|
-
widths: [3, 9],
|
|
566
|
+
widths: prev_runs_closed ? [0, 12] : [3, 9],
|
|
567
|
+
colClasses: prev_runs_closed ? ["was-col-3 d-none"] : undefined,
|
|
516
568
|
gx: 3,
|
|
517
569
|
besides: [
|
|
518
570
|
{
|
|
519
571
|
type: "container",
|
|
572
|
+
customClass: "prev-runs-list",
|
|
520
573
|
contents: prev_runs_side_bar,
|
|
521
574
|
},
|
|
522
575
|
{
|
|
@@ -530,6 +583,8 @@ const run = async (
|
|
|
530
583
|
|
|
531
584
|
const interact = async (table_id, viewname, config, body, { req, res }) => {
|
|
532
585
|
const { userinput, run_id, triggering_row_id } = body;
|
|
586
|
+
const action = await Trigger.findOne({ id: config.action_id });
|
|
587
|
+
|
|
533
588
|
let run;
|
|
534
589
|
let triggering_row;
|
|
535
590
|
if (table_id && triggering_row_id) {
|
|
@@ -537,19 +592,24 @@ const interact = async (table_id, viewname, config, body, { req, res }) => {
|
|
|
537
592
|
const pk = table?.pk_name;
|
|
538
593
|
if (table) triggering_row = await table.getRow({ [pk]: triggering_row_id });
|
|
539
594
|
}
|
|
540
|
-
if (!run_id || run_id === "undefined")
|
|
595
|
+
if (!run_id || run_id === "undefined") {
|
|
596
|
+
const ini_interacts = await get_initial_interactions(
|
|
597
|
+
action.configuration,
|
|
598
|
+
req.user,
|
|
599
|
+
triggering_row
|
|
600
|
+
);
|
|
541
601
|
run = await WorkflowRun.create({
|
|
542
602
|
status: "Running",
|
|
543
603
|
started_by: req.user?.id,
|
|
544
604
|
trigger_id: config.action_id,
|
|
545
605
|
context: {
|
|
546
606
|
implemented_fcall_ids: [],
|
|
547
|
-
interactions: [{ role: "user", content: userinput }],
|
|
607
|
+
interactions: [...ini_interacts, { role: "user", content: userinput }],
|
|
548
608
|
funcalls: {},
|
|
549
609
|
triggering_row_id,
|
|
550
610
|
},
|
|
551
611
|
});
|
|
552
|
-
else {
|
|
612
|
+
} else {
|
|
553
613
|
run = await WorkflowRun.findOne({ id: +run_id });
|
|
554
614
|
await addToContext(run, {
|
|
555
615
|
interactions: [{ role: "user", content: userinput }],
|
|
@@ -590,7 +650,6 @@ const interact = async (table_id, viewname, config, body, { req, res }) => {
|
|
|
590
650
|
],
|
|
591
651
|
});
|
|
592
652
|
}
|
|
593
|
-
const action = await Trigger.findOne({ id: config.action_id });
|
|
594
653
|
|
|
595
654
|
return await process_interaction(
|
|
596
655
|
run,
|
package/common.js
CHANGED
|
@@ -79,6 +79,16 @@ const find_image_tool = (config) => {
|
|
|
79
79
|
}
|
|
80
80
|
};
|
|
81
81
|
|
|
82
|
+
const get_initial_interactions = async (config, user, triggering_row) => {
|
|
83
|
+
const interacts = [];
|
|
84
|
+
const skills = get_skill_instances(config);
|
|
85
|
+
for (const skill of skills) {
|
|
86
|
+
const its = await skill.initialInteractions?.({ user, triggering_row });
|
|
87
|
+
if (its) interacts.push(...its);
|
|
88
|
+
}
|
|
89
|
+
return interacts;
|
|
90
|
+
};
|
|
91
|
+
|
|
82
92
|
const getCompletionArguments = async (config, user, triggering_row) => {
|
|
83
93
|
let tools = [];
|
|
84
94
|
|
|
@@ -359,4 +369,6 @@ module.exports = {
|
|
|
359
369
|
process_interaction,
|
|
360
370
|
find_image_tool,
|
|
361
371
|
is_debug_mode,
|
|
372
|
+
get_initial_interactions,
|
|
373
|
+
nubBy,
|
|
362
374
|
};
|
package/locales/de.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "Sessions": "Sitzungen" }
|
package/package.json
CHANGED
package/skills/FTSRetrieval.js
CHANGED
|
@@ -6,6 +6,7 @@ const View = require("@saltcorn/data/models/view");
|
|
|
6
6
|
const { getState } = require("@saltcorn/data/db/state");
|
|
7
7
|
const db = require("@saltcorn/data/db");
|
|
8
8
|
const { interpolate } = require("@saltcorn/data/utils");
|
|
9
|
+
const { nubBy } = require("../common");
|
|
9
10
|
|
|
10
11
|
class RetrievalByFullTextSearch {
|
|
11
12
|
static skill_name = "Retrieval by full-text search";
|
|
@@ -105,30 +106,45 @@ class RetrievalByFullTextSearch {
|
|
|
105
106
|
const table = Table.findOne(this.table_name);
|
|
106
107
|
return {
|
|
107
108
|
type: "function",
|
|
108
|
-
process: async (
|
|
109
|
+
process: async (arg, { req }) => {
|
|
109
110
|
const scState = getState();
|
|
110
111
|
const language = scState.pg_ts_config;
|
|
111
112
|
const use_websearch = scState.getConfig("search_use_websearch", false);
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
113
|
+
let rows = [];
|
|
114
|
+
const phrases =
|
|
115
|
+
arg.query?.phrases ||
|
|
116
|
+
arg.phrases ||
|
|
117
|
+
(arg.phrase
|
|
118
|
+
? [arg.phrase]
|
|
119
|
+
: arg.query?.phrase
|
|
120
|
+
? [arg.query?.phrase]
|
|
121
|
+
: []);
|
|
122
|
+
for (const phrase of phrases) {
|
|
123
|
+
const my_rows = await table.getRows({
|
|
124
|
+
_fts: {
|
|
125
|
+
fields: table.fields,
|
|
126
|
+
searchTerm: phrase,
|
|
127
|
+
language,
|
|
128
|
+
use_websearch,
|
|
129
|
+
table: table.name,
|
|
130
|
+
schema: db.isSQLite ? undefined : db.getTenantSchema(),
|
|
131
|
+
},
|
|
130
132
|
});
|
|
133
|
+
if (this.hidden_fields) {
|
|
134
|
+
const hidden_fields = this.hidden_fields
|
|
135
|
+
.split(",")
|
|
136
|
+
.map((s) => s.trim());
|
|
137
|
+
my_rows.forEach((r) => {
|
|
138
|
+
hidden_fields.forEach((k) => {
|
|
139
|
+
delete r[k];
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
rows.push(...my_rows);
|
|
131
144
|
}
|
|
145
|
+
const pk = table.pk_name;
|
|
146
|
+
rows = nubBy((r) => r[pk], rows);
|
|
147
|
+
|
|
132
148
|
if (rows.length)
|
|
133
149
|
if (!this.doc_format) return { rows };
|
|
134
150
|
else {
|
|
@@ -139,7 +155,8 @@ class RetrievalByFullTextSearch {
|
|
|
139
155
|
}
|
|
140
156
|
else
|
|
141
157
|
return {
|
|
142
|
-
responseText:
|
|
158
|
+
responseText:
|
|
159
|
+
"There are no rows related to: " + phrases.join(" or "),
|
|
143
160
|
};
|
|
144
161
|
},
|
|
145
162
|
/*renderToolCall({ phrase }, { req }) {
|
|
@@ -163,15 +180,41 @@ class RetrievalByFullTextSearch {
|
|
|
163
180
|
name: this.toolName,
|
|
164
181
|
description: `Search the ${this.table_name} database table${
|
|
165
182
|
table.description ? ` (${table.description})` : ""
|
|
166
|
-
} by
|
|
183
|
+
} by one or several search phrase or multiple search phrases matched against all fields in the table with full text search. The retrieved rows will be returned. If you want to search for documents matching any of several phrases, call this tool once with the phrases argument and give all the phrases you want to search for in one tool call.`,
|
|
167
184
|
parameters: {
|
|
168
185
|
type: "object",
|
|
169
|
-
required: ["
|
|
186
|
+
required: ["query"],
|
|
170
187
|
properties: {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
188
|
+
query: {
|
|
189
|
+
anyOf: [
|
|
190
|
+
{
|
|
191
|
+
type: "object",
|
|
192
|
+
required: ["phrase"],
|
|
193
|
+
properties: {
|
|
194
|
+
phrase: {
|
|
195
|
+
type: "string",
|
|
196
|
+
description:
|
|
197
|
+
"The phrase to search the table with. The search phrase is the synatx used by web search engines: use double quotes for exact match, unquoted text for words in any order, dash (minus sign) to exclude a word. Do not use SQL or any other formal query language.",
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
type: "object",
|
|
203
|
+
required: ["phrases"],
|
|
204
|
+
description:
|
|
205
|
+
"Search the table by any of a number of phrases. This will return any document that matches one or the other of the phrases",
|
|
206
|
+
properties: {
|
|
207
|
+
phrases: {
|
|
208
|
+
type: "array",
|
|
209
|
+
description:
|
|
210
|
+
"A phrase to search the table with. The search phrase is the synatx used by web search engines: use double quotes for exact match, unquoted text for words in any order, dash (minus sign) to exclude a word. Do not use SQL or any other formal query language.",
|
|
211
|
+
items: {
|
|
212
|
+
type: "string",
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
],
|
|
175
218
|
},
|
|
176
219
|
},
|
|
177
220
|
},
|
package/skills/PreloadData.js
CHANGED
|
@@ -2,11 +2,15 @@ const { div, pre } = require("@saltcorn/markup/tags");
|
|
|
2
2
|
const Workflow = require("@saltcorn/data/models/workflow");
|
|
3
3
|
const Form = require("@saltcorn/data/models/form");
|
|
4
4
|
const Table = require("@saltcorn/data/models/table");
|
|
5
|
+
const File = require("@saltcorn/data/models/file");
|
|
6
|
+
const Trigger = require("@saltcorn/data/models/trigger");
|
|
7
|
+
const User = require("@saltcorn/data/models/user");
|
|
5
8
|
const View = require("@saltcorn/data/models/view");
|
|
6
9
|
const { getState } = require("@saltcorn/data/db/state");
|
|
7
10
|
const db = require("@saltcorn/data/db");
|
|
8
11
|
const { eval_expression } = require("@saltcorn/data/models/expression");
|
|
9
12
|
const { interpolate } = require("@saltcorn/data/utils");
|
|
13
|
+
const vm = require("vm");
|
|
10
14
|
|
|
11
15
|
class PreloadData {
|
|
12
16
|
static skill_name = "Preload Data";
|
|
@@ -19,28 +23,69 @@ class PreloadData {
|
|
|
19
23
|
Object.assign(this, cfg);
|
|
20
24
|
}
|
|
21
25
|
|
|
22
|
-
async
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
{},
|
|
26
|
+
async run_the_code({ user, triggering_row }) {
|
|
27
|
+
const sysState = getState();
|
|
28
|
+
const f = vm.runInNewContext(`async () => {${this.code}\n}`, {
|
|
29
|
+
Table,
|
|
30
|
+
row: triggering_row,
|
|
31
|
+
context: triggering_row,
|
|
29
32
|
user,
|
|
30
|
-
|
|
31
|
-
|
|
33
|
+
User,
|
|
34
|
+
File,
|
|
35
|
+
Buffer,
|
|
36
|
+
Trigger,
|
|
37
|
+
setTimeout,
|
|
38
|
+
interpolate,
|
|
39
|
+
require,
|
|
40
|
+
getConfig: (k) =>
|
|
41
|
+
sysState.isFixedConfig(k) ? undefined : sysState.getConfig(k),
|
|
42
|
+
...(triggering_row || {}),
|
|
43
|
+
...sysState.eval_context,
|
|
44
|
+
});
|
|
45
|
+
return await f();
|
|
46
|
+
}
|
|
32
47
|
|
|
33
|
-
|
|
34
|
-
if (this.
|
|
35
|
-
|
|
36
|
-
|
|
48
|
+
async initialInteractions({ user, triggering_row }) {
|
|
49
|
+
if (this._stashed_initial_interactions)
|
|
50
|
+
return this._stashed_initial_interactions;
|
|
51
|
+
if (this.data_source === "Code") {
|
|
52
|
+
const result = await this.run_the_code({ user, triggering_row });
|
|
53
|
+
return result?.interactions;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async systemPrompt({ user, triggering_row }) {
|
|
58
|
+
const prompts = [];
|
|
59
|
+
if (this.data_source === "Code") {
|
|
60
|
+
const result = await this.run_the_code({ user, triggering_row });
|
|
61
|
+
if (typeof result === "string") return result;
|
|
62
|
+
if (result?.interactions)
|
|
63
|
+
this._stashed_initial_interactions = result?.interactions;
|
|
64
|
+
if (result?.systemPrompt) return result.systemPrompt;
|
|
37
65
|
} else {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
|
|
66
|
+
if (this.add_sys_prompt) prompts.push(this.add_sys_prompt);
|
|
67
|
+
const table = Table.findOne(this.table_name);
|
|
68
|
+
const q = eval_expression(
|
|
69
|
+
this.preload_query,
|
|
70
|
+
{},
|
|
71
|
+
user,
|
|
72
|
+
"PreloadData query"
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
const rows = await table.getRows(q);
|
|
76
|
+
if (this.contents_expr) {
|
|
77
|
+
for (const row of rows)
|
|
78
|
+
prompts.push(interpolate(this.contents_expr, row, user));
|
|
79
|
+
} else {
|
|
80
|
+
const hidden_fields = this.hidden_fields
|
|
81
|
+
.split(",")
|
|
82
|
+
.map((s) => s.trim());
|
|
83
|
+
for (const row of rows) {
|
|
84
|
+
hidden_fields.forEach((k) => {
|
|
85
|
+
delete row[k];
|
|
86
|
+
});
|
|
87
|
+
prompts.push(JSON.stringify(row));
|
|
88
|
+
}
|
|
44
89
|
}
|
|
45
90
|
}
|
|
46
91
|
return prompts.join("\n");
|
|
@@ -50,6 +95,34 @@ class PreloadData {
|
|
|
50
95
|
const allTables = await Table.find();
|
|
51
96
|
|
|
52
97
|
return [
|
|
98
|
+
{
|
|
99
|
+
name: "data_source",
|
|
100
|
+
label: "Data source",
|
|
101
|
+
type: "String",
|
|
102
|
+
required: true,
|
|
103
|
+
attributes: { options: ["Table", "Code"] },
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: "code",
|
|
107
|
+
label: "Code",
|
|
108
|
+
input_type: "code",
|
|
109
|
+
attributes: { mode: "application/javascript" },
|
|
110
|
+
showIf: { data_source: "Code" },
|
|
111
|
+
class: "validate-statements",
|
|
112
|
+
sublabel:
|
|
113
|
+
"Return string or object <code>{systemPrompt: string, interactions: Interaction[]}</code>",
|
|
114
|
+
validator(s) {
|
|
115
|
+
try {
|
|
116
|
+
let AsyncFunction = Object.getPrototypeOf(
|
|
117
|
+
async function () {}
|
|
118
|
+
).constructor;
|
|
119
|
+
AsyncFunction(s);
|
|
120
|
+
return true;
|
|
121
|
+
} catch (e) {
|
|
122
|
+
return e.message;
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
},
|
|
53
126
|
{
|
|
54
127
|
name: "table_name",
|
|
55
128
|
label: "Table",
|
|
@@ -57,17 +130,20 @@ class PreloadData {
|
|
|
57
130
|
type: "String",
|
|
58
131
|
required: true,
|
|
59
132
|
attributes: { options: allTables.map((t) => t.name) },
|
|
133
|
+
showIf: { data_source: "Table" },
|
|
60
134
|
},
|
|
61
135
|
{
|
|
62
136
|
name: "preload_query",
|
|
63
137
|
label: "Query",
|
|
64
138
|
type: "String",
|
|
65
139
|
class: "validate-expression",
|
|
140
|
+
showIf: { data_source: "Table" },
|
|
66
141
|
},
|
|
67
142
|
{
|
|
68
143
|
name: "add_sys_prompt",
|
|
69
144
|
label: "Additional prompt",
|
|
70
145
|
type: "String",
|
|
146
|
+
showIf: { data_source: "Table" },
|
|
71
147
|
fieldview: "textarea",
|
|
72
148
|
},
|
|
73
149
|
{
|
|
@@ -75,6 +151,7 @@ class PreloadData {
|
|
|
75
151
|
label: "Contents string",
|
|
76
152
|
type: "String",
|
|
77
153
|
fieldview: "textarea",
|
|
154
|
+
showIf: { data_source: "Table" },
|
|
78
155
|
sublabel:
|
|
79
156
|
"Use handlebars (<code>{{ }}</code>) to access fields in each retrieved row",
|
|
80
157
|
},
|
|
@@ -82,6 +159,7 @@ class PreloadData {
|
|
|
82
159
|
name: "hidden_fields",
|
|
83
160
|
label: "Hide fields",
|
|
84
161
|
type: "String",
|
|
162
|
+
showIf: { data_source: "Table" },
|
|
85
163
|
sublabel:
|
|
86
164
|
"Comma-separated list of fields to hide from the prompt, if not using the contents string",
|
|
87
165
|
},
|