generator-begcode
Version:
Spring Boot + Angular/React/Vue in one handy generator
103 lines (102 loc) • 4.56 kB
JavaScript
import { AgentOutputType, ChatMessageBuilder, trimText } from '../agent-core/index.js';
import { AgentFunctionBase } from './utils/index.js';
export class WriteScriptFunction extends AgentFunctionBase {
static allowedLibs = ['fs', 'axios', 'util', 'path'];
name = 'writeScript';
description = 'Writes the function.';
parameters = {
type: 'object',
properties: {
namespace: {
type: 'string',
description: 'The namespace of the function, e.g. fs.readFile',
},
description: {
type: 'string',
description: 'The detailed description of the function.',
},
arguments: {
type: 'string',
description: "The arguments of the function. E.g. '{ path: string, encoding: string }'",
},
code: {
type: 'string',
description: 'The code of the function.',
},
},
required: ['namespace', 'description', 'arguments', 'code'],
additionalProperties: false,
};
buildExecutor({ context }) {
return async (params, rawParams) => {
if (params.namespace.startsWith('agent.')) {
return this.onErrorCannotCreateInAgentNamespace(this.name, params, rawParams, context.variables);
}
if (this.extractRequires(params.code).some(x => !WriteScriptFunction.allowedLibs.includes(x))) {
return this.onErrorCannotRequireLib(this.name, params, rawParams, context.variables);
}
await context.workspace.writeFile('index.js', params.code);
return this.onSuccess(params, rawParams, context.variables);
};
}
onSuccess(params, rawParams, variables) {
return {
outputs: [
{
type: AgentOutputType.Success,
title: `Wrote function '${params.namespace}'.`,
content: `Wrote the function ${params.namespace} to the workspace.`,
},
],
messages: [ChatMessageBuilder.functionCall(this.name, rawParams), ChatMessageBuilder.functionCallResult(this.name, 'Success.')],
};
}
onError(name, error, args) {
return `The function '${name}' failed, this is the error:\n\`\`\`\n${error && typeof error === 'string' ? trimText(error, 300) : 'Unknown error.'}\n\`\`\`\n\nArguments:\n\`\`\`\n${JSON.stringify(args, null, 2)}\n\`\`\``;
}
extractRequires = (code) => {
const regex = /\brequire\b\s*\(\s*["']([^"']+)["']\s*\)/g;
let match;
const libraries = [];
while ((match = regex.exec(code)) !== null) {
libraries.push(match[1]);
}
return libraries;
};
onErrorCannotCreateInAgentNamespace(functionName, params, rawParams, variables) {
return {
outputs: [
{
type: AgentOutputType.Error,
title: `Failed to write function '${params.namespace}'!`,
content: this.onError(functionName, `Cannot create a function with namespace ${params.namespace}. Namespaces starting with 'agent.' are reserved.`, params),
},
],
messages: [
ChatMessageBuilder.functionCall(functionName, rawParams),
ChatMessageBuilder.functionCallResult(functionName, `Failed writing the function.
Namespaces starting with 'agent.' are reserved.`),
],
};
}
onErrorCannotRequireLib(functionName, params, rawParams, variables) {
return {
outputs: [
{
type: AgentOutputType.Error,
title: `Failed to write function '${params.namespace}'!`,
content: this.onError(functionName, `Cannot require libraries other than ${WriteScriptFunction.allowedLibs.join(', ')}.`, params),
},
],
messages: [
ChatMessageBuilder.functionCall(functionName, rawParams),
ChatMessageBuilder.functionCallResult(functionName, `Cannot require libraries other than ${WriteScriptFunction.allowedLibs.join(', ')}.`),
],
};
}
static formatSupportedLibraries() {
const [last] = this.allowedLibs.slice(-1);
const others = this.allowedLibs.slice(0, -1);
return others.length ? `"${others.join('", "')}", and "${last}"` : `"${last}"`;
}
}