@saltcorn/large-language-model 0.3.7 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/function-insert-action.js +150 -0
- package/index.js +7 -0
- package/model.js +6 -0
- package/package.json +1 -1
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
const Workflow = require("@saltcorn/data/models/workflow");
|
|
2
|
+
const Form = require("@saltcorn/data/models/form");
|
|
3
|
+
const FieldRepeat = require("@saltcorn/data/models/fieldrepeat");
|
|
4
|
+
const Field = require("@saltcorn/data/models/field");
|
|
5
|
+
const Table = require("@saltcorn/data/models/table");
|
|
6
|
+
const { getState } = require("@saltcorn/data/db/state");
|
|
7
|
+
const { interpolate } = require("@saltcorn/data/utils");
|
|
8
|
+
const { getCompletion, getEmbedding } = require("./generate");
|
|
9
|
+
const { eval_expression } = require("@saltcorn/data/models/expression");
|
|
10
|
+
|
|
11
|
+
const noSpaces = (s) => s.replaceAll(" ", "");
|
|
12
|
+
module.exports = (config) => ({
|
|
13
|
+
description: "Use LLM function call to insert rows in tables",
|
|
14
|
+
requireRow: true,
|
|
15
|
+
configFields: async ({ table }) => {
|
|
16
|
+
const tables = await Table.find();
|
|
17
|
+
return [
|
|
18
|
+
{
|
|
19
|
+
name: "prompt_template",
|
|
20
|
+
label: "Prompt",
|
|
21
|
+
type: "String",
|
|
22
|
+
fieldview: "textarea",
|
|
23
|
+
sublabel: `Use interpolations {{ }} to access variables in ${table.name} table.`,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: "function_name",
|
|
27
|
+
label: "Function name",
|
|
28
|
+
type: "String",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: "function_description",
|
|
32
|
+
label: "Function description",
|
|
33
|
+
sublabel: "Describe what you are trying to achieve in general terms",
|
|
34
|
+
type: "String",
|
|
35
|
+
},
|
|
36
|
+
new FieldRepeat({
|
|
37
|
+
name: "columns",
|
|
38
|
+
fields: [
|
|
39
|
+
{
|
|
40
|
+
name: "target_table",
|
|
41
|
+
label: "Target table",
|
|
42
|
+
type: "String",
|
|
43
|
+
required: true,
|
|
44
|
+
attributes: { options: tables.map((t) => t.name) },
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
label: "Fixed values",
|
|
48
|
+
name: "fixed_values",
|
|
49
|
+
type: "String",
|
|
50
|
+
fieldview: "textarea",
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: "cardinality",
|
|
54
|
+
label: "Cardinality",
|
|
55
|
+
type: "String",
|
|
56
|
+
required: true,
|
|
57
|
+
attributes: {
|
|
58
|
+
options: ["One", /*"Zero or one",*/ "Zero to many"],
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
}),
|
|
63
|
+
];
|
|
64
|
+
},
|
|
65
|
+
run: async ({
|
|
66
|
+
row,
|
|
67
|
+
table,
|
|
68
|
+
configuration: {
|
|
69
|
+
prompt_template,
|
|
70
|
+
columns,
|
|
71
|
+
function_description,
|
|
72
|
+
function_name,
|
|
73
|
+
},
|
|
74
|
+
user,
|
|
75
|
+
}) => {
|
|
76
|
+
const prompt = interpolate(prompt_template, row, user);
|
|
77
|
+
let args = {};
|
|
78
|
+
const json_type = (ty) => {
|
|
79
|
+
if (ty?.js_type) return ty?.js_type;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
for (const col of columns) {
|
|
83
|
+
const target_table = Table.findOne({ name: col.target_table });
|
|
84
|
+
const tableArgs = {};
|
|
85
|
+
const fixed = eval_expression(
|
|
86
|
+
col.fixed_values,
|
|
87
|
+
row,
|
|
88
|
+
user,
|
|
89
|
+
"llm_function_call fixed values"
|
|
90
|
+
);
|
|
91
|
+
for (const field of target_table.fields) {
|
|
92
|
+
if (field.primary_key) continue;
|
|
93
|
+
if (typeof fixed[field.name] !== "undefined") continue;
|
|
94
|
+
tableArgs[field.name] = {
|
|
95
|
+
type: json_type(field.type),
|
|
96
|
+
description: field.description,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
const argObj = { type: "object", properties: tableArgs };
|
|
100
|
+
args[noSpaces(target_table.name)] =
|
|
101
|
+
col.cardinality == "One" ? argObj : { type: "array", items: argObj };
|
|
102
|
+
}
|
|
103
|
+
if (columns.length === 1) {
|
|
104
|
+
//args = args[Object]
|
|
105
|
+
}
|
|
106
|
+
const expert_function = {
|
|
107
|
+
type: "function",
|
|
108
|
+
function: {
|
|
109
|
+
name: function_name,
|
|
110
|
+
description: function_description,
|
|
111
|
+
parameters: {
|
|
112
|
+
type: "object",
|
|
113
|
+
properties: args,
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
const toolargs = {
|
|
118
|
+
tools: [expert_function],
|
|
119
|
+
tool_choice: { type: "function", function: { name: function_name } },
|
|
120
|
+
};
|
|
121
|
+
//console.log(JSON.stringify(expert_function, null, 2));
|
|
122
|
+
const compl = await getCompletion(config, { prompt, ...toolargs });
|
|
123
|
+
|
|
124
|
+
const response = JSON.parse(compl.tool_calls[0].function.arguments);
|
|
125
|
+
//console.log("response: ", JSON.stringify(response, null, 2));
|
|
126
|
+
for (const col of columns) {
|
|
127
|
+
const target_table = Table.findOne({ name: col.target_table });
|
|
128
|
+
const fixed = eval_expression(
|
|
129
|
+
col.fixed_values,
|
|
130
|
+
row,
|
|
131
|
+
user,
|
|
132
|
+
"llm_function_call fixed values"
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
if (col.cardinality == "One") {
|
|
136
|
+
const row = {
|
|
137
|
+
...(response[noSpaces(target_table.name)] || {}),
|
|
138
|
+
...fixed,
|
|
139
|
+
};
|
|
140
|
+
await target_table.insertRow(row, user);
|
|
141
|
+
} else {
|
|
142
|
+
for (const resp of response[noSpaces(target_table.name)] || []) {
|
|
143
|
+
const row = { ...resp, ...fixed };
|
|
144
|
+
await target_table.insertRow(row, user);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return {};
|
|
149
|
+
},
|
|
150
|
+
});
|
package/index.js
CHANGED
|
@@ -58,10 +58,14 @@ const configuration_workflow = () =>
|
|
|
58
58
|
options: [
|
|
59
59
|
"gpt-3.5-turbo",
|
|
60
60
|
"gpt-3.5-turbo-16k",
|
|
61
|
+
"gpt-3.5-turbo-1106",
|
|
62
|
+
"gpt-3.5-turbo-0125",
|
|
61
63
|
"gpt-4",
|
|
62
64
|
"gpt-4-32k",
|
|
63
65
|
"gpt-4-turbo-preview",
|
|
64
66
|
"gpt-4-1106-preview",
|
|
67
|
+
"gpt-4-0125-preview",
|
|
68
|
+
"gpt-4-turbo",
|
|
65
69
|
],
|
|
66
70
|
},
|
|
67
71
|
},
|
|
@@ -136,4 +140,7 @@ module.exports = {
|
|
|
136
140
|
configuration_workflow,
|
|
137
141
|
functions,
|
|
138
142
|
modelpatterns: require("./model.js"),
|
|
143
|
+
actions: (config) => ({
|
|
144
|
+
llm_function_call: require("./function-insert-action.js")(config),
|
|
145
|
+
}),
|
|
139
146
|
};
|
package/model.js
CHANGED
|
@@ -35,8 +35,14 @@ const configuration_workflow = (config) => (req) =>
|
|
|
35
35
|
models = [
|
|
36
36
|
"gpt-3.5-turbo",
|
|
37
37
|
"gpt-3.5-turbo-16k",
|
|
38
|
+
"gpt-3.5-turbo-1106",
|
|
39
|
+
"gpt-3.5-turbo-0125",
|
|
38
40
|
"gpt-4",
|
|
39
41
|
"gpt-4-32k",
|
|
42
|
+
"gpt-4-turbo-preview",
|
|
43
|
+
"gpt-4-1106-preview",
|
|
44
|
+
"gpt-4-0125-preview",
|
|
45
|
+
"gpt-4-turbo",
|
|
40
46
|
];
|
|
41
47
|
}
|
|
42
48
|
return new Form({
|