agent从app下移到server,更新readme

This commit is contained in:
ruotongyu
2024-07-09 22:53:32 +08:00
parent 7de7ef711b
commit d93a8e01d2
7 changed files with 89 additions and 110 deletions

View File

@@ -3,7 +3,7 @@
<img src="./resources/logo.png" width="120" height="120" alt="autoMate logo">
<h1>autoMate</h1>
一个 AgentRPA 开发平台
一个开源的Agent+RPA开发平台
[![][issues-helper-image]][issues-helper-url] [![Issues need help][help-wanted-image]][help-wanted-url]

View File

@@ -36,7 +36,7 @@ export default function Chat(props: {id: number, revalidator: () => void, search
}
request={async (messages) => {
const response = await getResponse(messages, id, revalidator, proChatRef.current)
const response = await getResponse(messages, id, revalidator)
return new Response(response.content)// 支持流式和非流式
}}
/>

View File

@@ -1,54 +0,0 @@
export const requireAlignmentPrompt=()=>`# 上下文 #
你是一位资深的自动化产品经理,你不懂代码,与用户对齐需求,根据用户的需求编写自动化用例。
#############
# 目标 #
我希望你能分析用户的需求,与用户进行对齐,你记忆非常短暂,容易忘输出内容,因此做事情前要先说一下你在做什么,请一步一步执行下面的过程,不要跳过任何一个步骤。
1. 确认用户需求【可省略】:如果需求明确可以省略这一步,如果用户需求中如果有不清楚的地方请不要自己猜测,而是要向用户询问清楚,比如用户说打开桌面文件,你要问清楚是哪一个桌面文件;
2. 生成自动化用例根据用户需求按【步骤】生成自动化用例这是口语化的用例不要出现代码比如1. 获取桌面路径 2. 打开桌面文件a.text
3. 如果用例生成完毕,请在内容最开始加上“【自动化方案】”。
#############
# 风格 #
严谨认真
#############
# 语气 #
与用户对需求时要保持尊重
#############
# 受众 #
有自动化需求,想让你给一个自动化方案
#############
# 回复 #
【自动化方案】
1. 【步骤1】
2. 【步骤2】
3. 【步骤3】。
#############
`
export const programmerPrompt=(code:string='')=>`# 上下文 #
你是一位高级python程序员根据产品经理的需求编写python代码。
#############
# 目标 #
我希望你够根据产品经理的自动化需求返回可执行的python代码。你返回的所有内容会直接传递到exec()的参数。
你可以直接使用以下封装好的【函数】
${code}
#############
# 风格 #
请你编写python代码时要遵循PEP8规范代码简单易懂每一行代码都要用#编写注释并且在关键地方用#给出修改建议。
#############
# 语气 #
只有代码,不要有任何其他信息
#############
# 受众 #
会写python但是不太熟悉
#############
# 约束 #
代码中的函数一定是python内置函数或我提供的【函数】不要使用其他函数。
############
# 回复格式 #
只回复python代码
#############
# 例子 #
1. print("abc")
2. c = [i in range(10)]\nprint(c)
#############
`

View File

@@ -2,43 +2,57 @@ import { useStore } from "@renderer/store/useStore";
import { requireAlignmentPrompt, programmerPrompt } from "./prompt";
import useOpenai from "./useOpenai";
import { ProChatInstance } from "@ant-design/pro-chat";
import { localServerBaseUrl } from "@renderer/config";
export default () => {
const setIsCodeLoading = useStore(state => state.setIsCodeLoading)
const getResponse = async (chat_messages: Array<any>, id: number, revalidator: () => void, proChatRef: ProChatInstance|undefined) => {
const getResponse = async (chat_messages: Array<any>, id: number, revalidator: () => void) => {
const response = useOpenai(requireAlignmentPrompt(), chat_messages)
response.then(async (res) => {
if (res.content.includes("【自动化方案】")) {
const chat_id = Date.now().toString()
proChatRef!.pushChat({
id: chat_id,
createAt: new Date(),
updateAt: new Date(),
role: "assistant",
content: "根据自动化方案生成代码中,请稍等..."
})
setIsCodeLoading(true)
const programmerResponse = await useOpenai(programmerPrompt(), [{
role: "user",
content: res.content
}])
const code = programmerResponse.content.replace(/^```python/, "").replace(/^```/, "").replace(/```python$/, "").replace(/```$/, "").trim()
proChatRef!.setMessageContent(
chat_id,
"根据测试方案生成的python代码如下\n```python\n" + code + "\n```"
)
window.api.sql('update contents set content = @content where id = @id',
'update',
{ content: code, id})
// 更新数据
revalidator()
// 关闭loading
setIsCodeLoading(false)
// response.then(async (res) => {
// if (res.content.includes("【自动化方案】")) {
// const chat_id = Date.now().toString()
// proChatRef!.pushChat({
// id: chat_id,
// createAt: new Date(),
// updateAt: new Date(),
// role: "assistant",
// content: "根据自动化方案生成代码中,请稍等..."
// })
// setIsCodeLoading(true)
// const programmerResponse = await useOpenai(programmerPrompt(), [{
// role: "user",
// content: res.content
// }])
// const code = programmerResponse.content.replace(/^```python/, "").replace(/^```/, "").replace(/```python$/, "").replace(/```$/, "").trim()
// proChatRef!.setMessageContent(
// chat_id,
// "根据测试方案生成的python代码如下\n```python\n" + code + "\n```"
// )
// window.api.sql('update contents set content = @content where id = @id',
// 'update',
// { content: code, id})
// // 更新数据
// revalidator()
// // 关闭loading
// setIsCodeLoading(false)
// }
// })
const messages = chat_messages.map((m) => {
return {
role: m.role,
content: m.content
}
})
return response
})
const response = await fetch(localServerBaseUrl + "/llm", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({messages, isStream: false })
})
return response.json()
}

View File

@@ -0,0 +1,6 @@
from agent.agent_base import AgentBase
class CodeAgent(AgentBase):
def run(self):
pass

25
server/agent/prompt.py Normal file
View File

@@ -0,0 +1,25 @@
import string
code_prompt=string.Template("""# 背景 #
你是一位资深的python程序员根据用户的需求编写python代码。
#############
# 目标 #
你需要根据用户需求编写新的代码,如果对话的上下文中有代码,你需要在已有的代码之上进行修改。生成代码时请一定要遵守以下规则否则会出错!
1. 代码中只能使用官方内置库和以下依赖库:
selenium、python-docx、requests
2. 以下是我封装好的函数如果有需要可以直接在代码中使用无需import
暂无
#############
# 风格 #
遵循PEP8规范每一行代码都要用编写注释并且在关键地方给出修改建议。
############
# 回复格式 #
只回复python代码
#############
# 返回例子 #
1. print("abc")
2. c = [i in range(10)]\nprint(c)
#############
""")

View File

@@ -1,36 +1,24 @@
from flask import Blueprint, Response
from flask import request
from flask import Blueprint, Response, request
from litellm import completion
from utils.sql_util import get_config
from agent.prompt import code_prompt
import json
home_bp = Blueprint('llm', __name__)
@home_bp.route('/llm', methods=["POST"])
def llm():
messages = request.get_json()["messages"]
isStream = request.get_json().get("isStream", False)
llm_config = request.get_json().get("llm_config", None)
if llm_config:
config = json.loads(llm_config)
else:
config = json.loads(get_config())["llm"]
data = request.get_json()
messages = data["messages"]
isStream = data.get("isStream", False)
config = json.loads(data.get("llm_config", get_config()))["llm"]
messages = [{"role": "system", "content": code_prompt}] + messages
if isStream:
def generate():
response = completion(
messages=messages,
stream=True,
**config
)
response = completion(messages=messages, stream=True, **config)
for part in response:
yield part.choices[0].delta.content or ""
return Response(generate(), mimetype='text/event-stream')
else:
res = completion(
messages=messages,
**config
)
return {
"content": res.choices[0].message.content
}
res = completion(messages=messages, **config)
return {"content": res.choices[0].message.content}