-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcommon.js
106 lines (99 loc) · 3.17 KB
/
common.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
const axios = require("axios");
const fsp = require("fs").promises;
const _ = require("underscore");
const path = require("path");
const Field = require("@saltcorn/data/models/field");
const Table = require("@saltcorn/data/models/table");
const Form = require("@saltcorn/data/models/form");
const View = require("@saltcorn/data/models/view");
const Trigger = require("@saltcorn/data/models/trigger");
const { getState } = require("@saltcorn/data/db/state");
const getPromptFromTemplate = async (tmplName, userPrompt, extraCtx = {}) => {
const tables = await Table.find({});
const context = {
Table,
tables,
View,
userTable: Table.findOne("users"),
scState: getState(),
userPrompt,
...extraCtx,
};
const fp = path.join(__dirname, "prompts", tmplName);
const fileBuf = await fsp.readFile(fp);
const tmpl = fileBuf.toString();
const template = _.template(tmpl, {
evaluate: /\{\{#(.+?)\}\}/g,
interpolate: /\{\{([^#].+?)\}\}/g,
});
const prompt = template(context);
console.log("Full prompt:\n", prompt);
return prompt;
};
const getCompletion = async (language, prompt) => {
return getState().functions.llm_generate.run(prompt, {
systemPrompt: `You are a helpful code assistant. Your language of choice is ${language}. Do not include any explanation, just generate the code block itself.`,
});
};
const incompleteCfgMsg = () => {
const plugin_cfgs = getState().plugin_cfgs;
if (
!plugin_cfgs["@saltcorn/large-language-model"] &&
!plugin_cfgs["large-language-model"]
) {
const modName = Object.keys(plugin_cfgs).find((m) =>
m.includes("large-language-model")
);
if (modName)
return `LLM module not configured. Please configure <a href="/plugins/configure/${encodeURIComponent(
modName
)}">here<a> before using copilot.`;
else
return `LLM module not configured. Please install and configure <a href="/plugins">here<a> before using copilot.`;
}
};
const toArrayOfStrings = (opts) => {
if (typeof opts === "string") return opts.split(",").map((s) => s.trim());
if (Array.isArray(opts))
return opts.map((o) => (typeof o === "string" ? o : o.value || o.name));
};
const fieldProperties = (field) => {
const props = {};
const typeName = field.type?.name || field.type || field.input_type;
if (field.isRepeat) {
props.type = "array";
const properties = {};
field.fields.map((f) => {
properties[f.name] = {
description: f.sublabel || f.label,
...fieldProperties(f),
};
});
props.items = {
type: "object",
properties,
};
}
switch (typeName) {
case "String":
props.type = "string";
if (field.attributes?.options)
props.enum = toArrayOfStrings(field.attributes.options);
break;
case "Bool":
props.type = "boolean";
break;
case "Integer":
props.type = "integer";
break;
case "Float":
props.type = "number";
break;
case "select":
props.type = "string";
if (field.options) props.enum = toArrayOfStrings(field.options);
break;
}
return props;
};
module.exports = { getCompletion, getPromptFromTemplate, incompleteCfgMsg, fieldProperties };