mirror of
https://github.com/yuruotong1/autoMate.git
synced 2026-03-22 13:07:17 +08:00
🚀 部署:更新代码和配置文件并引入新的功能,为应用程序添加Python代码编辑器,支持多行代码高亮显示和执行功能。更新了系统提示信息模板,增加了对process.env.PORT环境变量的支持。更新了LLM工具类,允许根据用户输入调用tools中的execute函数来执行Python代码。修复了测试用例,修改了测试数据。
This commit is contained in:
32
agent/prompt.py
Normal file
32
agent/prompt.py
Normal file
@@ -0,0 +1,32 @@
|
||||
from string import Template
|
||||
system_prompt=Template("""### 目标 ###
|
||||
你是一个高级程序员,请调用tools中的execute函数完成用户提出的目标,execute 的code由你来编写,遇到不清楚的信息向用户咨询,最终一定要调用tools中的execute函数。
|
||||
### 在代码中你可以使用以下函数 ###
|
||||
word_action
|
||||
|
||||
如果你需要引用下面代码记得导入并初始化 WordAction。
|
||||
```python
|
||||
$python_code
|
||||
```
|
||||
"""
|
||||
)
|
||||
|
||||
tools = [
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "execute",
|
||||
"description": "execute python code",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string",
|
||||
"description": "python code",
|
||||
},
|
||||
},
|
||||
"required": ["code"],
|
||||
|
||||
},
|
||||
},
|
||||
}]
|
||||
@@ -1,35 +0,0 @@
|
||||
from string import Template
|
||||
system_prompt=Template("""
|
||||
You are Open Interpreter, a world-class programmer that can complete any goal by executing code.
|
||||
First, write a plan. **Always recap the plan between each code block** (you have extreme short-term memory loss, so you need to recap the plan between each message block to retain it).
|
||||
When you execute code, it will be executed **on the user's machine**. The user has given you **full and complete permission** to execute any code necessary to complete the task. Execute the code.
|
||||
If you want to send data between programming languages, save the data to a txt or json.
|
||||
You can access the internet. Run **any code** to achieve the goal, and if at first you don't succeed, try again and again.
|
||||
You can install new packages.
|
||||
When a user refers to a filename, they're likely referring to an existing file in the directory you're currently executing code in.
|
||||
Write messages to the user in Markdown.
|
||||
In general, try to **make plans** with as few steps as possible. As for actually executing code to carry out that plan, for *stateful* languages (like python, javascript, shell, but NOT for html which starts from 0 every time) **it's critical not to try to do everything in one code block.** You should try something, print information about it, then continue from there in tiny, informed steps. You will never get it on the first try, and attempting it in one go will often lead to errors you cant see.
|
||||
You are capable of **any** task.
|
||||
|
||||
# THE COMPUTER API
|
||||
|
||||
A python `word_action` module is ALREADY IMPORTED, and can be used for many tasks:
|
||||
|
||||
```python
|
||||
$python_code
|
||||
```
|
||||
|
||||
Do not import the computer module, or any of its sub-modules. They are already imported.
|
||||
|
||||
User Info\{\{import getpass
|
||||
import os
|
||||
import platform
|
||||
|
||||
print(f"Name: {getpass.getuser()}")
|
||||
print(f"CWD: {os.getcwd()}")
|
||||
print(f"SHELL: {os.environ.get('SHELL')}")
|
||||
print(f"OS: {platform.system()}")
|
||||
\}\}
|
||||
|
||||
"""
|
||||
)
|
||||
@@ -1,5 +1,5 @@
|
||||
from actions.action_util import ActionUtil
|
||||
from agent.system_prompt import system_prompt
|
||||
from agent.prompt import system_prompt
|
||||
from utils.llm_util import LLM_Util
|
||||
|
||||
|
||||
@@ -11,11 +11,14 @@ class WorkerAgent:
|
||||
action_descriptions += action.package_actions_description() + "\n"
|
||||
self.messages = [{"content": system_prompt.substitute(python_code=action_descriptions), "role": "system"}]
|
||||
|
||||
|
||||
def run(self, question):
|
||||
self.messages.append({"content": question, "role": "user"})
|
||||
res = LLM_Util().invoke(self.messages)
|
||||
self.messages.append({"content": res, "role": "assistant"})
|
||||
# self.messages.append({"content": res, "role": "assistant"})
|
||||
return res
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
import json
|
||||
import traceback
|
||||
from PyQt6 import QtWidgets, QtCore
|
||||
from PyQt6.QtCore import QThread, pyqtSignal, QEvent, Qt
|
||||
from PyQt6.QtGui import QPixmap, QIcon
|
||||
from PyQt6.QtWidgets import QApplication, QSystemTrayIcon, QMainWindow, QLabel, QTextEdit, QListWidgetItem, QSpacerItem, QSizePolicy, QAbstractItemView, QListWidget, QMenu
|
||||
from pygments import highlight
|
||||
from actions.action_util import ActionUtil
|
||||
from agent.woker_agent import WorkerAgent
|
||||
from pages.config_page import ConfigPage
|
||||
from pages.plugin_page import PluginPage
|
||||
from utils.global_keyboard_listen import GlobalKeyboardListen
|
||||
from utils.qt_util import QtUtil
|
||||
from utils.window_util import WindowUtil
|
||||
from pygments.lexers import PythonLexer
|
||||
from pygments.formatters import HtmlFormatter
|
||||
|
||||
class ActionItems(QListWidgetItem):
|
||||
def __init__(self, action, chat_page):
|
||||
@@ -93,7 +96,7 @@ class ChatList(QListWidget):
|
||||
self.chat_page.action_list.set_visibility(False)
|
||||
|
||||
class WorkerThread(QThread):
|
||||
finished_signal = pyqtSignal(str)
|
||||
finished_signal = pyqtSignal(object)
|
||||
|
||||
def __init__(self, text):
|
||||
QThread.__init__(self)
|
||||
@@ -127,12 +130,25 @@ class ChatInput(QTextEdit):
|
||||
# 清空输入框
|
||||
self.clear()
|
||||
# 连接线程的 finished 信号到槽函数,增加对话UI
|
||||
self.worker_thread.finished_signal.connect(lambda res: self.chat_page.new_conversation(f"{res}", "system"))
|
||||
self.worker_thread.finished_signal.connect(self.render_llm_response)
|
||||
self.worker_thread.start()
|
||||
event.accept()
|
||||
|
||||
else:
|
||||
super().keyPressEvent(event)
|
||||
|
||||
def render_llm_response(self, llm_res):
|
||||
text = ""
|
||||
if llm_res.get("tool_calls"):
|
||||
print(llm_res.get("tool_calls"))
|
||||
raw_arguments = llm_res["tool_calls"][0]["function"]["arguments"]
|
||||
arguments = json.loads(raw_arguments)
|
||||
self.chat_page.new_conversation(arguments["code"], "system", type="code")
|
||||
elif llm_res.get("content"):
|
||||
text = llm_res["content"]
|
||||
self.chat_page.new_conversation(text, "system", type="text")
|
||||
|
||||
|
||||
def on_text_changed(self):
|
||||
current_text = self.toPlainText()
|
||||
# 当输入中文不选择具体的文字时,也会进入到这里
|
||||
@@ -226,9 +242,9 @@ class ChatPage(QMainWindow, interface_ui):
|
||||
|
||||
def mousePressEvent(self, event):
|
||||
self.action_list.setVisible(False)
|
||||
|
||||
def new_conversation(self, text, role):
|
||||
text = text.replace("\n", "<br>")
|
||||
|
||||
# type 为 text 时,显示文本,为 code 时,显示代码
|
||||
def new_conversation(self, text, role, type="text"):
|
||||
widget = QtWidgets.QWidget()
|
||||
widget.setGeometry(QtCore.QRect(110, 100, 160, 80))
|
||||
v_box = QtWidgets.QVBoxLayout(widget)
|
||||
@@ -238,7 +254,7 @@ class ChatPage(QMainWindow, interface_ui):
|
||||
role_name = "智子"
|
||||
else:
|
||||
role_pic = QtUtil.get_icon("vip.png")
|
||||
role_name = "VIP用户"
|
||||
role_name = "我"
|
||||
# 创建 QPixmap 对象并加图片
|
||||
pixmap = QPixmap(role_pic)
|
||||
pixmap = pixmap.scaled(30, 30, QtCore.Qt.AspectRatioMode.KeepAspectRatio)
|
||||
@@ -267,7 +283,11 @@ class ChatPage(QMainWindow, interface_ui):
|
||||
background-color: white;
|
||||
border-radius: 10px;
|
||||
""")
|
||||
text_edit.setHtml(text)
|
||||
if type == "code":
|
||||
text = highlight(text, PythonLexer(), HtmlFormatter())
|
||||
text_edit.setHtml(text)
|
||||
else:
|
||||
text_edit.setHtml(text)
|
||||
v_box.addWidget(text_edit)
|
||||
item = QListWidgetItem()
|
||||
# 连接文档大小改变的信号
|
||||
|
||||
360
pages/python_code_edit.py
Normal file
360
pages/python_code_edit.py
Normal file
@@ -0,0 +1,360 @@
|
||||
import uuid
|
||||
from pydantic import BaseModel, Field
|
||||
from actions.action_base import ActionBase
|
||||
from PyQt6.QtCore import Qt
|
||||
from PyQt6.QtWidgets import QTextEdit
|
||||
from PyQt6.QtCore import QRect
|
||||
from PyQt6.QtGui import QFont, QColor, QPainter, QTextFormat
|
||||
from PyQt6.QtWidgets import QWidget, QPlainTextEdit, QTextEdit
|
||||
from PyQt6 import QtGui, QtCore
|
||||
class PythonExecutorInput(BaseModel):
|
||||
code: str = Field(description="python代码", title="pytho代码", default="")
|
||||
|
||||
|
||||
class PythonExecutorActoin(ActionBase):
|
||||
name: str = "执行python代码"
|
||||
description: str = "执行python代码"
|
||||
args: PythonExecutorInput
|
||||
output_save_name:str = "python_output"
|
||||
|
||||
def config_page_ui(self):
|
||||
code_editor = QCodeEditor(display_line_numbers=True,
|
||||
highlight_current_line=True,
|
||||
syntax_high_lighter=PythonHighlighter)
|
||||
self._config_ui.config_list.addWidget(code_editor)
|
||||
self._ui_name_and_line_edit["code"] = code_editor
|
||||
code_editor.setPlainText('# 保存输出结果\n' + self.output_save_name + " = ''")
|
||||
|
||||
|
||||
# 执行python代码
|
||||
def run(self, code):
|
||||
environent = {}
|
||||
exec(code, environent)
|
||||
return environent[self.output_save_name]
|
||||
|
||||
|
||||
|
||||
class LineNumberArea(QWidget):
|
||||
def __init__(self, editor):
|
||||
QWidget.__init__(self, editor)
|
||||
self.editor = editor
|
||||
self.editor.blockCountChanged.connect(self.update_width)
|
||||
self.editor.updateRequest.connect(self.update_contents)
|
||||
self.font = QFont()
|
||||
self.numberBarColor = QColor("#e8e8e8")
|
||||
|
||||
def paintEvent(self, event):
|
||||
# Override paintEvent to draw the line numbers
|
||||
painter = QPainter(self)
|
||||
painter.fillRect(event.rect(), self.numberBarColor)
|
||||
|
||||
block = self.editor.firstVisibleBlock()
|
||||
|
||||
# Iterate over all visible text blocks in the document.
|
||||
while block.isValid():
|
||||
block_number = block.blockNumber()
|
||||
block_top = self.editor.blockBoundingGeometry(block).translated(self.editor.contentOffset()).top()
|
||||
|
||||
# Check if the position of the block is outside the visible area.
|
||||
if not block.isVisible() or block_top >= event.rect().bottom():
|
||||
break
|
||||
|
||||
# We want the line number for the selected line to be bold.
|
||||
if block_number == self.editor.textCursor().blockNumber():
|
||||
self.font.setBold(True)
|
||||
painter.setPen(QColor("#000000"))
|
||||
else:
|
||||
self.font.setBold(False)
|
||||
painter.setPen(QColor("#717171"))
|
||||
painter.setFont(self.font)
|
||||
|
||||
# Draw the line number right justified at the position of the line.
|
||||
paint_rect = QRect(0, int(block_top), self.width(), self.editor.fontMetrics().height())
|
||||
painter.drawText(paint_rect, Qt.AlignmentFlag.AlignRight, str(block_number + 1))
|
||||
|
||||
block = block.next()
|
||||
|
||||
painter.end()
|
||||
|
||||
QWidget.paintEvent(self, event)
|
||||
|
||||
# 根据文档的总行数来计算宽度
|
||||
def get_width(self):
|
||||
count = self.editor.blockCount()
|
||||
# width = self.fontMetrics().width(str(count)) + 10
|
||||
width = self.fontMetrics().horizontalAdvance(str(count)) + 5
|
||||
|
||||
return width
|
||||
|
||||
# 设置宽度
|
||||
def update_width(self):
|
||||
width = self.get_width()
|
||||
if self.width() != width:
|
||||
self.setFixedWidth(width)
|
||||
self.editor.setViewportMargins(width, 0, 0, 0);
|
||||
|
||||
# 更行内容
|
||||
def update_contents(self, rect, scroll):
|
||||
if scroll:
|
||||
self.scroll(0, scroll)
|
||||
else:
|
||||
self.update(0, rect.y(), self.width(), rect.height())
|
||||
|
||||
if rect.contains(self.editor.viewport().rect()):
|
||||
font_size = self.editor.currentCharFormat().font().pointSize()
|
||||
self.font.setPointSize(font_size)
|
||||
self.font.setStyle(QFont.Style.StyleNormal)
|
||||
self.update_width()
|
||||
|
||||
class QCodeEditor(QPlainTextEdit):
|
||||
def __init__(self, display_line_numbers=True, highlight_current_line=True,
|
||||
syntax_high_lighter=None, *args):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
display_line_numbers : bool
|
||||
switch on/off the presence of the lines number bar
|
||||
highlight_current_line : bool
|
||||
switch on/off the current line highlighting
|
||||
syntax_high_lighter : QSyntaxHighlighter
|
||||
should be inherited from QSyntaxHighlighter
|
||||
|
||||
"""
|
||||
super(QCodeEditor, self).__init__()
|
||||
|
||||
self.setFont(QFont("Microsoft YaHei UI Light", 11))
|
||||
self.setLineWrapMode(QPlainTextEdit.LineWrapMode.NoWrap)
|
||||
|
||||
self.DISPLAY_LINE_NUMBERS = display_line_numbers
|
||||
|
||||
if display_line_numbers:
|
||||
self.number_bar = LineNumberArea(self)
|
||||
|
||||
if highlight_current_line:
|
||||
self.currentLineNumber = None
|
||||
self.currentLineColor = self.palette().alternateBase()
|
||||
self.cursorPositionChanged.connect(self.highlight_current_line)
|
||||
|
||||
if syntax_high_lighter is not None: # add highlighter to text document
|
||||
self.highlighter = syntax_high_lighter(self.document())
|
||||
# 默认选中第一行
|
||||
cursor = self.textCursor()
|
||||
cursor.movePosition(QtGui.QTextCursor.MoveOperation.Start)
|
||||
self.setTextCursor(cursor)
|
||||
self.highlight_current_line() # 确保第一行高亮
|
||||
|
||||
def resizeEvent(self, *e):
|
||||
"""overload resizeEvent handler"""
|
||||
|
||||
if self.DISPLAY_LINE_NUMBERS: # resize LineNumberArea widget
|
||||
cr = self.contentsRect()
|
||||
rec = QRect(cr.left(), cr.top(), self.number_bar.get_width(), cr.height())
|
||||
self.number_bar.setGeometry(rec)
|
||||
|
||||
QPlainTextEdit.resizeEvent(self, *e)
|
||||
|
||||
# 获取代码
|
||||
def text(self):
|
||||
return self.toPlainText()
|
||||
|
||||
def highlight_current_line(self):
|
||||
new_current_line_number = self.textCursor().blockNumber()
|
||||
if new_current_line_number != self.currentLineNumber:
|
||||
self.currentLineNumber = new_current_line_number
|
||||
hi_selection = QTextEdit.ExtraSelection()
|
||||
hi_selection.format.setBackground(self.currentLineColor)
|
||||
hi_selection.format.setProperty(QTextFormat.Property.FullWidthSelection, True)
|
||||
hi_selection.cursor = self.textCursor()
|
||||
hi_selection.cursor.clearSelection()
|
||||
self.setExtraSelections([hi_selection])
|
||||
|
||||
|
||||
def format_syn(color, style=''):
|
||||
"""Return a QTextCharFormat with the given attributes.
|
||||
"""
|
||||
_color = QtGui.QColor()
|
||||
_color.setNamedColor(color)
|
||||
|
||||
_format = QtGui.QTextCharFormat()
|
||||
_format.setForeground(_color)
|
||||
if 'bold' in style:
|
||||
# QtGui.QFont.setBold(True)
|
||||
_format.setFontWeight(QtGui.QFont.bold.__sizeof__())
|
||||
if 'italic' in style:
|
||||
_format.setFontItalic(True)
|
||||
|
||||
return _format
|
||||
|
||||
|
||||
# Syntax styles that can be shared by all languages
|
||||
STYLES = {
|
||||
'keyword': format_syn('blue'),
|
||||
'operator': format_syn('red'),
|
||||
'brace': format_syn('darkGray'),
|
||||
'defclass': format_syn('black', 'bold'),
|
||||
'string': format_syn('magenta'),
|
||||
'string2': format_syn('darkMagenta'),
|
||||
'comment': format_syn('darkGreen', 'italic'),
|
||||
'self': format_syn('black', 'italic'),
|
||||
'numbers': format_syn('brown'),
|
||||
}
|
||||
|
||||
|
||||
class PythonHighlighter(QtGui.QSyntaxHighlighter):
|
||||
"""Syntax highlighter for the Python language.
|
||||
"""
|
||||
# Python keywords
|
||||
keywords = [
|
||||
'and', 'assert', 'break', 'class', 'continue', 'def',
|
||||
'del', 'elif', 'else', 'except', 'exec', 'finally',
|
||||
'for', 'from', 'global', 'if', 'import', 'in',
|
||||
'is', 'lambda', 'not', 'or', 'pass', 'print',
|
||||
'raise', 'return', 'try', 'while', 'yield',
|
||||
'None', 'True', 'False',
|
||||
]
|
||||
|
||||
# Python operators
|
||||
operators = [
|
||||
r'=',
|
||||
# Comparison
|
||||
r'==', r'!=', r'<', r'<=', r'>', r'>=',
|
||||
# Arithmetic
|
||||
r'\+', r'-', r'\*', r'/', r'//', r'\%', r'\*\*',
|
||||
# In-place
|
||||
r'\+=', r'-=', r'\*=', r'/=', r'\%=',
|
||||
# Bitwise
|
||||
r'\^', r'\|', r'\&', r'\~', r'>>', r'<<',
|
||||
]
|
||||
|
||||
# Python braces
|
||||
braces = [
|
||||
r'\{', r'\}', r'\(', r'\)', r'\[', r'\]',
|
||||
]
|
||||
|
||||
def __init__(self, parent: QtGui.QTextDocument) -> None:
|
||||
super().__init__(parent)
|
||||
|
||||
# Multi-line strings (expression, flag, style)
|
||||
self.tri_single = (QtCore.QRegularExpression("'''"), 1, STYLES['string2'])
|
||||
self.tri_double = (QtCore.QRegularExpression('"""'), 2, STYLES['string2'])
|
||||
|
||||
rules = []
|
||||
|
||||
# Keyword, operator, and brace rules
|
||||
rules += [(r'\b%s\b' % w, 0, STYLES['keyword'])
|
||||
for w in PythonHighlighter.keywords]
|
||||
rules += [(r'%s' % o, 0, STYLES['operator'])
|
||||
for o in PythonHighlighter.operators]
|
||||
rules += [(r'%s' % b, 0, STYLES['brace'])
|
||||
for b in PythonHighlighter.braces]
|
||||
|
||||
# All other rules
|
||||
rules += [
|
||||
# 'self'
|
||||
(r'\bself\b', 0, STYLES['self']),
|
||||
|
||||
# 'def' followed by an identifier
|
||||
(r"\bdef\b\s*(\w+)", 1, STYLES['defclass']),
|
||||
# 'class' followed by an identifier
|
||||
(r'\bclass\b\s*(\w+)', 1, STYLES['defclass']),
|
||||
|
||||
# Numeric literals
|
||||
(r'\b[+-]?[0-9]+[lL]?\b', 0, STYLES['numbers']),
|
||||
(r'\b[+-]?0[xX][0-9A-Fa-f]+[lL]?\b', 0, STYLES['numbers']),
|
||||
(r'\b[+-]?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\b', 0, STYLES['numbers']),
|
||||
|
||||
# Double-quoted string, possibly containing escape sequences
|
||||
(r'"[^"\\]*(\\.[^"\\]*)*"', 0, STYLES['string']),
|
||||
# Single-quoted string, possibly containing escape sequences
|
||||
(r"'[^'\\]*(\\.[^'\\]*)*'", 0, STYLES['string']),
|
||||
|
||||
# From '#' until a newline
|
||||
(r'#[^\n]*', 0, STYLES['comment']),
|
||||
]
|
||||
|
||||
# Build a QRegExp for each pattern
|
||||
self.rules = [(QtCore.QRegularExpression(pat), index, fmt)
|
||||
for (pat, index, fmt) in rules]
|
||||
|
||||
def highlightBlock(self, text):
|
||||
"""Apply syntax highlighting to the given block of text.
|
||||
"""
|
||||
self.tripleQuoutesWithinStrings = []
|
||||
# Do other syntax formatting
|
||||
for expression, nth, format in self.rules:
|
||||
index = expression.match(text, 0).capturedStart(0)
|
||||
if index >= 0:
|
||||
# if there is a string we check
|
||||
# if there are some triple quotes within the string
|
||||
# they will be ignored if they are matched again
|
||||
if expression.pattern() in [r'"[^"\\]*(\\.[^"\\]*)*"', r"'[^'\\]*(\\.[^'\\]*)*'"]:
|
||||
# 匹配到三个引号
|
||||
innerIndex = self.tri_single[0].match(text, index + 1).capturedStart(0)
|
||||
if innerIndex == -1:
|
||||
innerIndex = self.tri_double[0].match(text, index + 1).capturedStart(0)
|
||||
|
||||
if innerIndex != -1:
|
||||
tripleQuoteIndexes = range(innerIndex, innerIndex + 3)
|
||||
self.tripleQuoutesWithinStrings.extend(tripleQuoteIndexes)
|
||||
|
||||
while index >= 0:
|
||||
# 跳过三引号
|
||||
if index in self.tripleQuoutesWithinStrings:
|
||||
index += 1
|
||||
continue
|
||||
|
||||
# We actually want the index of the nth match
|
||||
index = expression.match(text, index).capturedStart(nth)
|
||||
length = expression.match(text, index).capturedLength(nth)
|
||||
self.setFormat(index, length, format)
|
||||
index = expression.match(text, index + length).capturedStart(0)
|
||||
|
||||
|
||||
self.setCurrentBlockState(0)
|
||||
|
||||
# Do multi-line strings
|
||||
in_multiline = self.match_multiline(text, *self.tri_single)
|
||||
if not in_multiline:
|
||||
in_multiline = self.match_multiline(text, *self.tri_double)
|
||||
|
||||
def match_multiline(self, text, delimiter, in_state, style):
|
||||
"""Do highlight of multi-line strings. ``delimiter`` should be a
|
||||
``QRegExp`` for triple-single-quotes or triple-double-quotes, and
|
||||
``in_state`` should be a unique integer to represent the corresponding
|
||||
state changes when inside those strings. Returns True if we're still
|
||||
inside a multi-line string when this function is finished.
|
||||
"""
|
||||
# If inside triple-single quotes, start at 0
|
||||
if self.previousBlockState() == in_state:
|
||||
start = 0
|
||||
add = 0
|
||||
# Otherwise, look for the delimiter on this line
|
||||
else:
|
||||
start = delimiter.match(text).capturedStart(0)
|
||||
# skipping triple quotes within strings
|
||||
if start in self.tripleQuoutesWithinStrings:
|
||||
return False
|
||||
# Move past this match
|
||||
add = delimiter.match(text).capturedLength()
|
||||
|
||||
# As long as there's a delimiter match on this line...
|
||||
while start >= 0: # Look for the ending delimiter
|
||||
end = delimiter.match(text, start + add).capturedStart(0)
|
||||
# Ending delimiter on this line?
|
||||
if end >= add:
|
||||
length = end - start + add + delimiter.match(text).capturedLength()
|
||||
self.setCurrentBlockState(0)
|
||||
# No; multi-line string
|
||||
else:
|
||||
self.setCurrentBlockState(in_state)
|
||||
length = len(text) - start + add
|
||||
# Apply formatting
|
||||
self.setFormat(start, length, style)
|
||||
# Look for the next match
|
||||
start = delimiter.match(text, start + length).capturedStart()
|
||||
|
||||
# Return True if still inside a multi-line string, False otherwise
|
||||
if self.currentBlockState() == in_state:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
@@ -11,19 +11,15 @@ PyYAML = "6.0.1"
|
||||
requests = "2.31.0"
|
||||
selenium = "4.16.0"
|
||||
webdriver-manager = "4.0.1"
|
||||
langchain = "0.1.7"
|
||||
langchain-openai = "0.0.6"
|
||||
pytest = "^8.0.1"
|
||||
pyqt6 = "^6.6.1"
|
||||
leancloud = "^2.9.12"
|
||||
pyautogui = "^0.9.54"
|
||||
langchainhub = "^0.1.15"
|
||||
pyinstaller = "^6.5.0"
|
||||
pygments = "^2.17.2"
|
||||
python-docx = "^1.1.2"
|
||||
global-hotkeys = "^0.1.7"
|
||||
pynput = "^1.7.7"
|
||||
litellm = "^1.38.12"
|
||||
open-interpreter = "^0.2.5"
|
||||
|
||||
|
||||
[build-system]
|
||||
|
||||
@@ -2,7 +2,7 @@ from interpreter import interpreter
|
||||
|
||||
class OpenInterpreter:
|
||||
def test_api(self):
|
||||
interpreter.chat("电脑桌面有什么文件?")
|
||||
interpreter.chat("显示桌面所有文件")
|
||||
|
||||
if __name__ == "__main__":
|
||||
interpreter.llm.api_key = "sk-i6ClcJAogigoWxI9271b80E978374e8dAbC1167d3b6d8eA3" # LiteLLM, which we use to talk to LM Studio, requires this
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
|
||||
from utils.config import Config
|
||||
from litellm import completion
|
||||
from agent.prompt import tools
|
||||
|
||||
class LLM_Util:
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.config = Config()
|
||||
@@ -10,16 +12,9 @@ class LLM_Util:
|
||||
self.base_url = self.config.get_config_from_component("llm", "api_url")
|
||||
self.model = self.config.get_config_from_component("llm", "model")
|
||||
|
||||
def llm(self):
|
||||
from langchain_openai import ChatOpenAI
|
||||
return ChatOpenAI(temperature=0, model_name=self.model, openai_api_key=self.api_key,
|
||||
openai_api_base=self.base_url)
|
||||
|
||||
# messages = [{ "content": message, "role": "user"}]
|
||||
def invoke(self, messages):
|
||||
if self.base_url == "":
|
||||
response = completion(model=self.model, api_key=self.api_key, messages=messages)
|
||||
else:
|
||||
response = completion(model=self.model, base_url=self.base_url, api_key=self.api_key, messages=messages)
|
||||
response = completion(model=self.model, base_url=self.base_url, api_key=self.api_key,
|
||||
messages=messages, tools=tools, tool_choice={"type": "function", "function": {"name": "execute"}})
|
||||
|
||||
return response.choices[0].message.content
|
||||
return response.json()["choices"][0]["message"]
|
||||
Reference in New Issue
Block a user