UNPKG

generator-begcode

Version:

Spring Boot + Angular/React/Vue in one handy generator

323 lines (322 loc) 8.43 kB
import path from 'path-browserify'; import { AgentOutputType, ChatMessageBuilder } from '../agent-core/index.js'; import { AgentFunctionBase } from './utils/index.js'; import { FUNCTION_CALL_SUCCESS_CONTENT, FUNCTION_CALL_FAILED } from '../agents/Scripter/utils.js'; export class InitPoetryFunction extends AgentFunctionBase { name = 'initPoetry'; description = 'Initialize a Python Poetry environment in the workspace.'; parameters = { type: 'object', properties: {} }; buildExecutor({ context }) { return async (params, rawParams) => { const result = await this.poetryInit(context.workspace); if (result.exitCode !== 0) { return this.onError(result.stderr, params, rawParams, context.variables); } return this.onSuccess(params, rawParams, context.variables); }; } onSuccess(params, rawParams, variables) { return { outputs: [ { type: AgentOutputType.Success, title: this.name, content: FUNCTION_CALL_SUCCESS_CONTENT(this.name, params, 'Initialized Poetry Environment.'), }, ], messages: [ ChatMessageBuilder.functionCall(this.name, rawParams), ChatMessageBuilder.functionCallResult(this.name, 'Initialized Python Poetry Environment. You can now execute `poetry run [command] [args]` in the shell.'), ], }; } onError(error, params, rawParams, variables) { return { outputs: [ { type: AgentOutputType.Error, title: 'Failed to initialize poetry environment', content: FUNCTION_CALL_FAILED(params, this.name, error ?? 'Unknown error'), }, ], messages: [ ChatMessageBuilder.functionCall(this.name, rawParams), ChatMessageBuilder.functionCallResult(this.name, `Failed to init poetry: ${error}.`), ], }; } async poetryInit(workspace) { await workspace.exec('poetry', ['init', '-n']); const dependencies = await this.getPythonDependencies(workspace, '/'); const alwaysAdd = ['pytest', 'pydantic']; const toAdd = Array.from(new Set(dependencies.concat(alwaysAdd))); return workspace.exec('poetry', ['add', ...toAdd]); } async getPythonDependencies(workspace, dir) { const pythonFiles = (await workspace.readdir(dir)).map(dirEntry => dirEntry.name).filter(file => file.endsWith('.py')); const imports = []; for (const file of pythonFiles) { const filePath = path.join(dir, file); const fileContent = await workspace.readFile(filePath); imports.push(...this.parsePythonImports(fileContent)); } const uniqueImports = Array.from(new Set(imports)); const externalImports = uniqueImports.filter(importName => { const maybeLocalPath = path.join(dir, `${importName}.py`); return !workspace.exists(maybeLocalPath) && !this.common_native_python_packages.has(importName); }); return externalImports; } parsePythonImports(fileContent) { const imports = []; const singleImportRegex = /^(?:import|from) ([a-zA-Z0-9_]+)(?: import [a-zA-Z0-9_*]+(?: as [a-zA-Z0-9_]+)?)?/gm; const multipleImportRegex = /^import ([a-zA-Z0-9_ ,]+)$/gm; const multipleFromImportRegex = /^from ([a-zA-Z0-9_]+) import (?:[a-zA-Z0-9_ ,]+)$/gm; let match; while ((match = singleImportRegex.exec(fileContent))) { imports.push(match[1]); } while ((match = multipleImportRegex.exec(fileContent))) { imports.push(...match[1].split(', ').map(item => item.trim())); } while ((match = multipleFromImportRegex.exec(fileContent))) { imports.push(match[1]); } return imports; } common_native_python_packages = new Set([ '_ast', '_bisect', '_blake2', '_codecs', '_collections', '_datetime', '_elementtree', '_functools', '_heapq', '_imp', '_io', '_json', '_locale', '_md5', '_operator', '_pickle', '_posixsubprocess', '_random', '_sha1', '_sha256', '_sha3', '_sha512', '_signal', '_sre', '_stat', '_string', '_struct', '_symtable', '_thread', '_tracemalloc', '_warnings', '_weakref', 'abc', 'argparse', 'array', 'ast', 'asynchat', 'asyncio', 'asyncore', 'atexit', 'audioop', 'base64', 'bdb', 'binascii', 'binhex', 'bisect', 'builtins', 'bz2', 'cProfile', 'calendar', 'cgi', 'cgitb', 'chunk', 'cmath', 'cmd', 'code', 'codecs', 'codeop', 'collections', 'colorsys', 'compileall', 'concurrent', 'configparser', 'contextlib', 'contextvars', 'copy', 'copyreg', 'crypt', 'csv', 'ctypes', 'curses', 'dataclasses', 'datetime', 'dbm', 'decimal', 'difflib', 'dis', 'distutils', 'doctest', 'email', 'encodings', 'ensurepip', 'enum', 'errno', 'faulthandler', 'fcntl', 'filecmp', 'fileinput', 'fnmatch', 'formatter', 'fractions', 'ftplib', 'functools', 'gc', 'getopt', 'getpass', 'gettext', 'glob', 'grp', 'gzip', 'hashlib', 'heapq', 'hmac', 'html', 'http', 'imaplib', 'imghdr', 'imp', 'importlib', 'inspect', 'io', 'ipaddress', 'itertools', 'json', 'keyword', 'lib2to3', 'linecache', 'locale', 'logging', 'lzma', 'mailbox', 'mailcap', 'marshal', 'math', 'mimetypes', 'mmap', 'modulefinder', 'msilib', 'msvcrt', 'multiprocessing', 'netrc', 'nntplib', 'nt', 'ntpath', 'opcode', 'operator', 'optparse', 'os', 'pathlib', 'pdb', 'pickle', 'pipes', 'pkgutil', 'platform', 'plistlib', 'poplib', 'posix', 'posixpath', 'pprint', 'profile', 'pstats', 'pty', 'pwd', 'py_compile', 'pyclbr', 'pydoc', 'queue', 'quopri', 'random', 're', 'readline', 'reprlib', 'resource', 'rlcompleter', 'runpy', 'sched', 'secrets', 'select', 'selectors', 'shelve', 'shlex', 'shutil', 'signal', 'site', 'smtpd', 'smtplib', 'sndhdr', 'socket', 'socketserver', 'spwd', 'sqlite3', 'sre_compile', 'sre_constants', 'sre_parse', 'ssl', 'stat', 'statistics', 'string', 'stringprep', 'struct', 'subprocess', 'sunau', 'symbol', 'symtable', 'sys', 'sysconfig', 'tabnanny', 'tarfile', 'telnetlib', 'tempfile', 'termios', 'textwrap', 'this', 'threading', 'time', 'timeit', 'token', 'tokenize', 'trace', 'traceback', 'tracemalloc', 'tty', 'turtle', 'types', 'typing', 'unicodedata', 'unittest', 'urllib', 'uu', 'uuid', 'venv', 'wave', 'weakref', 'webbrowser', 'wsgiref', 'xdrlib', 'xml', 'xmlrpc', 'zipapp', 'zipfile', 'zipimport', 'zoneinfo', 'zlib', ]); }