new(gpt.gblib): GPT Tools and .gbdialog.

This commit is contained in:
Rodrigo Rodriguez 2024-03-13 20:26:13 -03:00
parent ce36ac476e
commit a0c3481c7d
3 changed files with 47 additions and 30 deletions

View file

@ -485,7 +485,7 @@ export class GBVMService extends GBService {
const jsfile: string = `${filename}.js`;
code = `
return (async () => {
module.exports = (async () => {
// Imports npm packages for this .gbdialog conversational application.
@ -725,7 +725,7 @@ export class GBVMService extends GBService {
public static getMetadata(mainName: string, propertiesText, description) {
let properties = {};
if (!propertiesText || !description) {
return {}
}
const getType = asClause => {
@ -773,7 +773,7 @@ export class GBVMService extends GBService {
type: "function",
function: {
name: `${mainName}`,
description: description ? description[1] : '',
description: description ? description : '',
parameters: zodToJsonSchema(z.object(properties))
}
}
@ -878,7 +878,7 @@ export class GBVMService extends GBService {
let endSystemPromptReg = endSystemPromptKeyword.exec(line);
if (endSystemPromptReg && systemPrompt) {
line = systemPrompt + '`})';
systemPrompt = null;
emmit = true;
}
@ -1079,24 +1079,31 @@ export class GBVMService extends GBService {
sandbox['channel'] = channel;
sandbox['today'] = await dk.getToday({ pid });
sandbox['now'] = await dk.getNow({ pid });
sandbox['returnValue'] = null;
let result;
try {
if (GBConfigService.get('GBVM') === 'false') {
const vm1 = new NodeVM({
allowAsync: true,
sandbox: sandbox,
console: 'inherit',
wrapper: 'commonjs',
require: {
builtin: ['stream', 'http', 'https', 'url', 'zlib', 'net', 'tls', 'crypto'],
root: ['./'],
external: true,
context: 'sandbox'
}
});
const s = new VMScript(code, { filename: scriptPath });
result = vm1.run(s);
return await (async () => {
return await new Promise(resolve => {
sandbox['resolve'] = resolve;
const vm1 = new NodeVM({
allowAsync: true,
sandbox: sandbox,
console: 'inherit',
wrapper: 'commonjs',
require: {
builtin: ['stream', 'http', 'https', 'url', 'zlib', 'net', 'tls', 'crypto'],
root: ['./'],
external: true,
context: 'sandbox'
}
});
const s = new VMScript(code, { filename: scriptPath });
result = vm1.run(s);
});
})();
} else {
const runnerPath = urlJoin(
process.cwd(),
@ -1127,7 +1134,6 @@ export class GBVMService extends GBService {
throw new Error(`BASIC RUNTIME ERR: ${error.message ? error.message : error}\n Stack:${error.stack}`);
}
return result;
}
public static createProcessInfo(user: GuaribasUser, min: GBMinInstance, channel: any, executable: string) {

View file

@ -241,6 +241,8 @@ export class KeywordsExpressions {
}
];
keywords[i++] = [/^\s*return +(.*)/gim, 'resolve($1);'];
keywords[i++] = [/^\s*else(?!{)/gim, '}\nelse {'];
keywords[i++] = [/^\s*select case +(.*)/gim, 'switch ($1) {'];

View file

@ -95,9 +95,8 @@ export class CustomLLMOutputParser extends BaseLLMOutputParser<ExpectedOutput> {
parsedOutput = llmOutputs[0].text;
}
this.documentChain.invoke(parsedOutput);
return this.documentChain.invoke(parsedOutput);
return ``;
}
}
@ -200,11 +199,14 @@ export class ChatServices {
{
func: async (output: object) =>{
const pid = 1;
const name = output['func'][0].function.name;
const args = JSON.parse(output['func'][0].function.arguments);
return await GBVMService.callVM(name, min, false, pid, false, args);
GBLog.info(`Running .gbdialog '${name}' as GPT tool...`);
const pid = GBVMService.createProcessInfo(null, min, 'gpt', null);
return await GBVMService.callVM(name, min, false, pid, false, args);
},
chat_history: async () => {
const { chat_history } = await memory.loadMemoryVariables({});
@ -229,8 +231,8 @@ export class ChatServices {
},
},
combineDocumentsPrompt,
modelWithTools,
model,
new StringOutputParser()
]);
const conversationalQaChain = RunnableSequence.from([
@ -285,12 +287,19 @@ export class ChatServices {
// Adds .gbdialog as functions if any to GPT Functions.
await CollectionUtil.asyncForEach(Object.keys(min.scriptMap), async (script) => {
const path = DialogKeywords.getGBAIPath(min.botId, "gbdialog", null);
const functionJSON = Path.join('work', path, `${script}.json`);
const jsonFile = Path.join('work', path, `${script}.json`);
if (Fs.existsSync(functionJSON)) {
const func = JSON.parse(Fs.readFileSync(functionJSON, 'utf8'));
func.schema = jsonSchemaToZod(func.properties, { module: "esm" });
functions.push(func);
if (Fs.existsSync(jsonFile)) {
const funcJSON = JSON.parse(Fs.readFileSync(jsonFile, 'utf8'));
const funcObj = funcJSON?.function;
if (funcObj){
// TODO: Use ajv.
funcObj.schema = eval(jsonSchemaToZod(funcObj.parameters));
functions.push(new DynamicStructuredTool(funcObj));
}
}
});