pro-craft 0.1.2__py3-none-any.whl → 0.1.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pro-craft might be problematic. Click here for more details.
- pro_craft/code_helper/coder.py +660 -0
- pro_craft/database.py +233 -0
- pro_craft/designer.py +115 -0
- pro_craft/evals.py +68 -0
- pro_craft/file_manager.py +118 -0
- pro_craft/prompt_helper.py +538 -0
- pro_craft/prompt_helper_async.py +566 -0
- pro_craft/server/__main__.py +77 -83
- pro_craft/server/models.py +6 -0
- pro_craft/server/router/recommended.py +283 -0
- pro_craft/utils.py +161 -1
- pro_craft-0.1.4.dist-info/METADATA +52 -0
- pro_craft-0.1.4.dist-info/RECORD +23 -0
- pro_craft/core.py +0 -1
- pro_craft/server/__init__.py +0 -0
- pro_craft/server/models/__init__.py +0 -0
- pro_craft/server/models/models.py +0 -48
- pro_craft/server/routers/__init__.py +0 -2
- pro_craft/server/routers/admin.py +0 -42
- pro_craft/server/routers/user.py +0 -24
- pro_craft/server/utils/__init__.py +0 -3
- pro_craft/server/utils/auth_backends.py +0 -15
- pro_craft/server/utils/database.py +0 -27
- pro_craft/server/utils/user_manager.py +0 -87
- pro_craft-0.1.2.dist-info/METADATA +0 -14
- pro_craft-0.1.2.dist-info/RECORD +0 -25
- {pro_craft-0.1.2.dist-info → pro_craft-0.1.4.dist-info}/WHEEL +0 -0
- {pro_craft-0.1.2.dist-info → pro_craft-0.1.4.dist-info}/top_level.txt +0 -0
pro_craft/database.py
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
|
|
2
|
+
from sqlalchemy import Column, Integer, String, Text, DateTime, text, UniqueConstraint, Boolean, func
|
|
3
|
+
from sqlalchemy.orm import declarative_base
|
|
4
|
+
|
|
5
|
+
from datetime import datetime, timedelta
|
|
6
|
+
|
|
7
|
+
FileBase = declarative_base()
|
|
8
|
+
|
|
9
|
+
class Content(FileBase):
|
|
10
|
+
__tablename__ = 'content' # 数据库中的表名,你可以改成你希望的名字
|
|
11
|
+
|
|
12
|
+
# id (int, primary_key=True, autoincrement=True)
|
|
13
|
+
# 你的属性表中 id 为 int, true (not null), true (primary key), 0 (length), ASC (key order), true (auto increment)
|
|
14
|
+
id = Column(
|
|
15
|
+
Integer,
|
|
16
|
+
primary_key=True,
|
|
17
|
+
autoincrement=True, # 自动递增
|
|
18
|
+
nullable=False, # 不能为空
|
|
19
|
+
comment="自增"
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
# prompt_id (varchar 255, not null, unique)
|
|
23
|
+
# 你的属性表中 prompt_id 为 varchar, 255 (length), true (not null)
|
|
24
|
+
embed_name_id = Column(
|
|
25
|
+
String(255), # VARCHAR 类型,长度 255
|
|
26
|
+
nullable=False, # 不能为空 # 必须是唯一的,这会创建唯一索引
|
|
27
|
+
comment="Unique identifier for the prompt"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# version (varchar 50, not null)
|
|
31
|
+
# 你的属性表中 version 为 varchar, 50 (length), true (not null)
|
|
32
|
+
name = Column(
|
|
33
|
+
String(255), # VARCHAR 类型,长度 50
|
|
34
|
+
nullable=False, # 不能为空
|
|
35
|
+
comment="Version of the prompt"
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
# version (varchar 50, not null)
|
|
39
|
+
# 你的属性表中 version 为 varchar, 50 (length), true (not null)
|
|
40
|
+
version = Column(
|
|
41
|
+
String(50), # VARCHAR 类型,长度 50
|
|
42
|
+
nullable=False, # 不能为空
|
|
43
|
+
comment="版本"
|
|
44
|
+
)
|
|
45
|
+
timestamp = Column(
|
|
46
|
+
DateTime,
|
|
47
|
+
nullable=False, # 不能为空
|
|
48
|
+
server_default=text('CURRENT_TIMESTAMP'),
|
|
49
|
+
onupdate=text('CURRENT_TIMESTAMP'),
|
|
50
|
+
comment="时间戳"
|
|
51
|
+
)
|
|
52
|
+
content = Column(
|
|
53
|
+
Text, # TEXT 类型,适用于长文本
|
|
54
|
+
nullable=False, # 不能为空
|
|
55
|
+
comment="内容"
|
|
56
|
+
)
|
|
57
|
+
type = Column(
|
|
58
|
+
Integer,
|
|
59
|
+
nullable=True, # 可以为空 (因为你的表格中 Not Null 为 false)
|
|
60
|
+
comment="类型" # 列注释
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
# 定义 __repr__ 方法以便打印对象时有清晰的表示
|
|
64
|
+
def __repr__(self):
|
|
65
|
+
return (f"<Prompt(id={self.id}, prompt_id='{self.prompt_id}', "
|
|
66
|
+
f"version='{self.version}', timestamp='{self.timestamp}', "
|
|
67
|
+
f"prompt='{self.prompt[:50]}...', use_case='{self.use_case}')>")
|
|
68
|
+
|
|
69
|
+
PromptBase = declarative_base()
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class SyncMetadata(PromptBase):
|
|
74
|
+
"""用于存储同步元数据的表模型"""
|
|
75
|
+
__tablename__ = "sync_metadata"
|
|
76
|
+
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
77
|
+
last_sync_time = Column(DateTime, default=datetime(1970, 1, 1))
|
|
78
|
+
table_name = Column(String(255), unique=True)
|
|
79
|
+
|
|
80
|
+
def __repr__(self):
|
|
81
|
+
return f"<SyncMetadata(table_name='{self.table_name}', last_sync_time='{self.last_sync_time}')>"
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class Prompt(PromptBase):
|
|
85
|
+
__tablename__ = 'prompts_table' # 数据库中的表名,你可以改成你希望的名字
|
|
86
|
+
# __tablename__ = 'llm_prompt' # 数据库中的表名,你可以改成你希望的名字
|
|
87
|
+
|
|
88
|
+
# 定义联合唯一约束
|
|
89
|
+
# 这是一个元组,包含你希望应用于表的额外定义,例如索引或约束
|
|
90
|
+
__table_args__ = (
|
|
91
|
+
UniqueConstraint('prompt_id', 'version', name='_prompt_id_version_uc'),
|
|
92
|
+
# 'name' 参数是可选的,用于给数据库中的约束指定一个名称,方便管理和调试
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
# id (int, primary_key=True, autoincrement=True)
|
|
96
|
+
# 你的属性表中 id 为 int, true (not null), true (primary key), 0 (length), ASC (key order), true (auto increment)
|
|
97
|
+
id = Column(
|
|
98
|
+
Integer,
|
|
99
|
+
primary_key=True,
|
|
100
|
+
autoincrement=True, # 自动递增
|
|
101
|
+
nullable=False, # 不能为空
|
|
102
|
+
comment="Primary key ID"
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
# prompt_id (varchar 255, not null, unique)
|
|
106
|
+
# 你的属性表中 prompt_id 为 varchar, 255 (length), true (not null)
|
|
107
|
+
prompt_id = Column(
|
|
108
|
+
String(255), # VARCHAR 类型,长度 255
|
|
109
|
+
nullable=False, # 不能为空 # 必须是唯一的,这会创建唯一索引
|
|
110
|
+
comment="Unique identifier for the prompt"
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
# version (varchar 50, not null)
|
|
114
|
+
# 你的属性表中 version 为 varchar, 50 (length), true (not null)
|
|
115
|
+
version = Column(
|
|
116
|
+
String(50), # VARCHAR 类型,长度 50
|
|
117
|
+
nullable=False, # 不能为空
|
|
118
|
+
comment="Version of the prompt"
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
# timestamp (datetime, not null, default current_timestamp, on update current_timestamp)
|
|
122
|
+
# 你的属性表中 timestamp 为 datetime, true (not null), false (default value), true (generated always on update current_timestamp)
|
|
123
|
+
timestamp = Column(
|
|
124
|
+
DateTime,
|
|
125
|
+
nullable=False, # 不能为空
|
|
126
|
+
# MySQL 的 DEFAULT CURRENT_TIMESTAMP
|
|
127
|
+
server_default=text('CURRENT_TIMESTAMP'),
|
|
128
|
+
# MySQL 的 ON UPDATE CURRENT_TIMESTAMP
|
|
129
|
+
onupdate=text('CURRENT_TIMESTAMP'),
|
|
130
|
+
comment="Timestamp of creation or last update"
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
# prompt (text, not null)
|
|
134
|
+
# 你的属性表中 prompt 为 text, true (not null)
|
|
135
|
+
prompt = Column(
|
|
136
|
+
Text, # TEXT 类型,适用于长文本
|
|
137
|
+
nullable=False, # 不能为空
|
|
138
|
+
comment="The actual prompt text content"
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
# use_case (text, nullable)
|
|
142
|
+
# 你的属性表中 use_case 为 text, false (not null, 即 nullable=True), NULL (default value), '用例' (comment)
|
|
143
|
+
use_case = Column(
|
|
144
|
+
Text,
|
|
145
|
+
nullable=True, # 可以为空 (因为你的表格中 Not Null 为 false)
|
|
146
|
+
comment="用例" # 列注释
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
# 执行类型
|
|
150
|
+
action_type = Column(
|
|
151
|
+
String(255), # VARCHAR 类型,长度 255
|
|
152
|
+
nullable=False, # 不能为空 # 必须是唯一的,这会创建唯一索引
|
|
153
|
+
comment="type train inference summary"
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
demand = Column(
|
|
157
|
+
Text,
|
|
158
|
+
nullable=True, # 可以为空 (因为你的表格中 Not Null 为 false)
|
|
159
|
+
comment="提示词改动需求" # 列注释
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
score = Column(
|
|
163
|
+
Integer,
|
|
164
|
+
nullable=False, # 不能为空
|
|
165
|
+
comment="分数"
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
is_deleted = Column(Boolean, default=False, server_default=text('0'))
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
# 定义 __repr__ 方法以便打印对象时有清晰的表示
|
|
172
|
+
def __repr__(self):
|
|
173
|
+
return (f"<Prompt(id={self.id}, prompt_id='{self.prompt_id}', "
|
|
174
|
+
f"version='{self.version}', timestamp='{self.timestamp}', "
|
|
175
|
+
f"prompt='{self.prompt[:50]}...', use_case='{self.use_case}')>"
|
|
176
|
+
f"action_type='{self.action_type}...', demand='{self.demand[:30]}')>"
|
|
177
|
+
f"is_deleted='{self.is_deleted}...'>"
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
class UseCase(PromptBase):
|
|
182
|
+
__tablename__ = 'usecase' # 数据库中的表名,你可以改成你希望的名字
|
|
183
|
+
|
|
184
|
+
# id (int, primary_key=True, autoincrement=True)
|
|
185
|
+
# 你的属性表中 id 为 int, true (not null), true (primary key), 0 (length), ASC (key order), true (auto increment)
|
|
186
|
+
id = Column(
|
|
187
|
+
Integer,
|
|
188
|
+
primary_key=True,
|
|
189
|
+
autoincrement=True, # 自动递增
|
|
190
|
+
nullable=False, # 不能为空
|
|
191
|
+
comment="Primary key ID"
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
# prompt_id (varchar 255, not null, unique)
|
|
195
|
+
# 你的属性表中 prompt_id 为 varchar, 255 (length), true (not null)
|
|
196
|
+
prompt_id = Column(
|
|
197
|
+
String(255), # VARCHAR 类型,长度 255
|
|
198
|
+
nullable=False, # 不能为空 # 必须是唯一的,这会创建唯一索引
|
|
199
|
+
comment="Unique identifier for the prompt"
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
# prompt (text, not null)
|
|
204
|
+
# 你的属性表中 prompt 为 text, true (not null)
|
|
205
|
+
use_case = Column(
|
|
206
|
+
Text, # TEXT 类型,适用于长文本
|
|
207
|
+
nullable=False, # 不能为空
|
|
208
|
+
comment="用例"
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
output = Column(
|
|
212
|
+
Text, # TEXT 类型,适用于长文本
|
|
213
|
+
nullable=False, # 不能为空
|
|
214
|
+
comment="AI输出"
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
# use_case (text, nullable)
|
|
218
|
+
# 你的属性表中 use_case 为 text, false (not null, 即 nullable=True), NULL (default value), '用例' (comment)
|
|
219
|
+
solution = Column(
|
|
220
|
+
Text,
|
|
221
|
+
nullable=True, # 可以为空 (因为你的表格中 Not Null 为 false)
|
|
222
|
+
comment="理想结果" # 列注释
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
is_deleted = Column(Boolean, default=False, server_default=text('0'))
|
|
226
|
+
|
|
227
|
+
# 定义 __repr__ 方法以便打印对象时有清晰的表示
|
|
228
|
+
def __repr__(self):
|
|
229
|
+
return (f"<Prompt(id={self.id}, prompt_id='{self.prompt_id}', "
|
|
230
|
+
f"use_case='{self.use_case[:50]}...', solution='{self.solution}')>"
|
|
231
|
+
f"is_deleted='{self.is_deleted}...'>")
|
|
232
|
+
|
|
233
|
+
|
pro_craft/designer.py
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## 分析编码习惯
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class MeetingMessageHistory:
|
|
8
|
+
def __init__(self):
|
|
9
|
+
self._messages: List[Dict[str, Any]] = []
|
|
10
|
+
|
|
11
|
+
def add_message(self, role: str, content: str, speaker_name: str = None):
|
|
12
|
+
"""添加一条消息到历史记录。"""
|
|
13
|
+
message = {"role": role, "content": content}
|
|
14
|
+
if speaker_name:
|
|
15
|
+
message["speaker"] = speaker_name # 添加发言者元信息
|
|
16
|
+
self._messages.append(message)
|
|
17
|
+
|
|
18
|
+
def get_messages(self) -> List[Dict[str, Any]]:
|
|
19
|
+
"""获取当前完整的消息历史。"""
|
|
20
|
+
return self._messages
|
|
21
|
+
|
|
22
|
+
def clear(self):
|
|
23
|
+
"""清空消息历史。"""
|
|
24
|
+
self._messages = []
|
|
25
|
+
|
|
26
|
+
def __str__(self) -> str:
|
|
27
|
+
return "\n".join([f"[{msg.get('speaker', msg['role'])}] {msg['content']}" for msg in self._messages])
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# 模拟一个外部 LLM 调用函数,以便在框架中演示
|
|
31
|
+
def simulate_external_llm_call(messages: List[Dict[str, Any]], model_name: str = "default") -> str:
|
|
32
|
+
"""模拟调用外部 LLM 函数."""
|
|
33
|
+
print(messages[0].get('speaker'),'messages')
|
|
34
|
+
print(model_name,'model_name')
|
|
35
|
+
|
|
36
|
+
bx = BianXieAdapter()
|
|
37
|
+
bx.set_model(model_name)
|
|
38
|
+
result = bx.chat(messages)
|
|
39
|
+
simulated_response = f"[{model_name}] Responding to '{result}"
|
|
40
|
+
return simulated_response
|
|
41
|
+
|
|
42
|
+
class MeetingOrganizer:
|
|
43
|
+
def __init__(self):
|
|
44
|
+
# 存储参会者信息:名称和使用的模型
|
|
45
|
+
self._participants: List[Dict[str, str]] = []
|
|
46
|
+
self._history = MeetingMessageHistory()
|
|
47
|
+
self._topic: str = ""
|
|
48
|
+
self._background: str = ""
|
|
49
|
+
# TODO: 在实际使用时,这里应该引用您真实的 LLM 调用函数
|
|
50
|
+
self._llm_caller = simulate_external_llm_call # 指向您外部的 LLM 调用函数
|
|
51
|
+
|
|
52
|
+
def set_llm_caller(self, caller_func):
|
|
53
|
+
"""设置外部的 LLM 调用函数."""
|
|
54
|
+
self._llm_caller = caller_func
|
|
55
|
+
print("External LLM caller function set.")
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def add_participant(self, name: str, model_name: str = "default"):
|
|
59
|
+
"""添加一个参会者 (LLM) 到会议中。"""
|
|
60
|
+
participant_info = {"name": name, "model": model_name}
|
|
61
|
+
self._participants.append(participant_info)
|
|
62
|
+
print(f"Added participant: {name} (using model: {model_name})")
|
|
63
|
+
|
|
64
|
+
def set_topic(self, topic: str, background: str = ""):
|
|
65
|
+
"""设置会议主题和背景。"""
|
|
66
|
+
self._topic = topic
|
|
67
|
+
self._background = background
|
|
68
|
+
initial_message = f"Meeting Topic: {topic}\nBackground: {background}"
|
|
69
|
+
# 可以将主题和背景作为用户输入的第一条消息,或者 system 消息
|
|
70
|
+
self._history.add_message("user", initial_message, speaker_name="Meeting Host")
|
|
71
|
+
print(f"Meeting topic set: {topic}")
|
|
72
|
+
|
|
73
|
+
def run_simple_round(self):
|
|
74
|
+
"""执行一轮简单的会议:每个参会 LLM 基于当前历史回复一次。"""
|
|
75
|
+
if not self._participants:
|
|
76
|
+
print("No participants in the meeting.")
|
|
77
|
+
return
|
|
78
|
+
|
|
79
|
+
print("\n--- Running a Simple Meeting Round ---")
|
|
80
|
+
current_history = self._history.get_messages()
|
|
81
|
+
|
|
82
|
+
for participant in self._participants:
|
|
83
|
+
participant_name = participant["name"]
|
|
84
|
+
model_to_use = participant["model"]
|
|
85
|
+
try:
|
|
86
|
+
# 调用外部 LLM 函数
|
|
87
|
+
print(current_history,'current_history')
|
|
88
|
+
response_content = self._llm_caller(current_history, model_name=model_to_use)
|
|
89
|
+
# 将回复添加到历史中,并标记发言者
|
|
90
|
+
self._history.add_message("assistant", response_content, speaker_name=participant_name)
|
|
91
|
+
print(f"'{participant_name}' responded.")
|
|
92
|
+
except Exception as e:
|
|
93
|
+
print(f"Error during '{participant_name}' participation: {e}")
|
|
94
|
+
# 在框架阶段,简单的错误打印即可
|
|
95
|
+
|
|
96
|
+
def get_discussion_history(self) -> List[Dict[str, Any]]:
|
|
97
|
+
"""获取完整的讨论消息历史。"""
|
|
98
|
+
return self._history.get_messages()
|
|
99
|
+
|
|
100
|
+
def get_simple_summary(self) -> str:
|
|
101
|
+
"""获取简单的讨论摘要(第一阶段:拼接所有 LLM 发言)。"""
|
|
102
|
+
print("\n--- Generating Simple Summary ---")
|
|
103
|
+
summary_parts = []
|
|
104
|
+
for message in self._history.get_messages():
|
|
105
|
+
# 提取 assistant 角色的发言作为摘要内容
|
|
106
|
+
if message.get("role") == "assistant":
|
|
107
|
+
speaker = message.get("speaker", "Unknown Assistant")
|
|
108
|
+
summary_parts.append(f"[{speaker}]: {message['content']}")
|
|
109
|
+
|
|
110
|
+
return "\n\n".join(summary_parts)
|
|
111
|
+
|
|
112
|
+
def display_history(self):
|
|
113
|
+
"""打印格式化的讨论历史。"""
|
|
114
|
+
print("\n--- Full Discussion History ---")
|
|
115
|
+
print(self._history)
|
pro_craft/evals.py
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
|
|
2
|
+
import json
|
|
3
|
+
|
|
4
|
+
from pro_craft.log import Log
|
|
5
|
+
logger = Log.logger
|
|
6
|
+
editing_log = logger.debug
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
############evals##############
|
|
13
|
+
|
|
14
|
+
# 异步
|
|
15
|
+
class Base_Evals():
|
|
16
|
+
def __init__(self):
|
|
17
|
+
"""
|
|
18
|
+
# TODO 2 自动优化prompt 并提升稳定性, 并测试
|
|
19
|
+
通过重写继承来使用它
|
|
20
|
+
"""
|
|
21
|
+
self.MIN_SUCCESS_RATE = 00.0 # 这里定义通过阈值, 高于该比例则通过
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
async def _assert_eval_function(self,params):
|
|
25
|
+
#这里定义函数的评价体系
|
|
26
|
+
print(params,'params')
|
|
27
|
+
|
|
28
|
+
async def get_success_rate(self,test_cases:list[tuple]):
|
|
29
|
+
"""
|
|
30
|
+
# 这里定义数据
|
|
31
|
+
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
successful_assertions = 0
|
|
35
|
+
total_assertions = len(test_cases)
|
|
36
|
+
result_cases = []
|
|
37
|
+
|
|
38
|
+
for i, params in enumerate(test_cases):
|
|
39
|
+
try:
|
|
40
|
+
# 这里将参数传入
|
|
41
|
+
await self._assert_eval_function(params)
|
|
42
|
+
successful_assertions += 1
|
|
43
|
+
result_cases.append({"type":"Successful","--input--":params,"evaluate_info":f"满足要求"})
|
|
44
|
+
except AssertionError as e:
|
|
45
|
+
result_cases.append({"type":"FAILED","--input--":params,"evaluate_info":f"ERROR {e}"})
|
|
46
|
+
except Exception as e: # 捕获其他可能的错误
|
|
47
|
+
result_cases.append({"type":"FAILED","--input--":params,"evaluate_info":f"ERROR {e}"})
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
success_rate = (successful_assertions / total_assertions) * 100
|
|
51
|
+
print(f"\n--- Aggregated Results ---")
|
|
52
|
+
print(f"Total test cases: {total_assertions}")
|
|
53
|
+
print(f"Successful cases: {successful_assertions}")
|
|
54
|
+
print(f"Success Rate: {success_rate:.2f}%")
|
|
55
|
+
|
|
56
|
+
if success_rate >= self.MIN_SUCCESS_RATE:
|
|
57
|
+
return "通过", json.dumps(result_cases,ensure_ascii=False)
|
|
58
|
+
else:
|
|
59
|
+
return "未通过",json.dumps(result_cases,ensure_ascii=False)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def global_evals():
|
|
63
|
+
pass
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# from db_help.mysql import MySQLManagerWithVersionControler
|
|
2
|
+
from db_help.qdrant import QdrantManager
|
|
3
|
+
from pydantic import BaseModel
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from pro_craft.utils import get_adler32_hash, embedding_inputs
|
|
6
|
+
from pro_craft.prompt_helper import Intel, IntellectType
|
|
7
|
+
from pro_craft.utils import extract_
|
|
8
|
+
from enum import Enum
|
|
9
|
+
import json
|
|
10
|
+
|
|
11
|
+
from pro_craft.database import Base, Prompt
|
|
12
|
+
from sqlalchemy import create_engine, Column, Integer, String
|
|
13
|
+
from sqlalchemy.orm import sessionmaker, declarative_base
|
|
14
|
+
from pro_craft.utils import create_session
|
|
15
|
+
from pro_craft.database import Content
|
|
16
|
+
|
|
17
|
+
import os
|
|
18
|
+
intel = Intel(database_url = os.getenv("database_url"))
|
|
19
|
+
|
|
20
|
+
class TextType(Enum):
|
|
21
|
+
Code = 0
|
|
22
|
+
Prompt = 1
|
|
23
|
+
Tips = 2
|
|
24
|
+
Experience = 3
|
|
25
|
+
|
|
26
|
+
class ContentManager():
|
|
27
|
+
def __init__(self):
|
|
28
|
+
"""
|
|
29
|
+
"""
|
|
30
|
+
self.table_name = "content"
|
|
31
|
+
self.qdrant = QdrantManager(host = "localhost")
|
|
32
|
+
self.neo = None
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@intel.intellect_2(IntellectType.inference,
|
|
36
|
+
prompt_id = "db_help_001",
|
|
37
|
+
demand="""
|
|
38
|
+
name 后面加一个4位随机数字防止重复
|
|
39
|
+
""")
|
|
40
|
+
def diverter(self,input:dict):
|
|
41
|
+
# 根据需求修改程序框图
|
|
42
|
+
input = json.loads(extract_(input,pattern_key=r"json"))
|
|
43
|
+
|
|
44
|
+
class Output(BaseModel):
|
|
45
|
+
name : str
|
|
46
|
+
type : int
|
|
47
|
+
note : str
|
|
48
|
+
|
|
49
|
+
Output(**input)
|
|
50
|
+
return input
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def save_content_auto(self,text:str):
|
|
54
|
+
|
|
55
|
+
output = self.diverter(input = {"text":text})
|
|
56
|
+
print(output,'output')
|
|
57
|
+
self.save_content(text = text,
|
|
58
|
+
name = output.get("name"),
|
|
59
|
+
type = output.get("type"),
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def save_content(self,text:str,name:str,type:int | TextType)->str:
|
|
65
|
+
# 数据库维护版本, 而向量库只保持最新
|
|
66
|
+
|
|
67
|
+
# 1 存入到数据库中
|
|
68
|
+
embed_name_id = get_adler32_hash(name)
|
|
69
|
+
|
|
70
|
+
vector_list = embedding_inputs([text])
|
|
71
|
+
if isinstance(type,TextType):
|
|
72
|
+
type = type.value
|
|
73
|
+
|
|
74
|
+
with create_session(intel.engine) as session:
|
|
75
|
+
cont = Content(name = name,
|
|
76
|
+
embed_name_id = embed_name_id,
|
|
77
|
+
timestamp = datetime.now(),
|
|
78
|
+
content = text,
|
|
79
|
+
type = type,
|
|
80
|
+
)
|
|
81
|
+
session.add(cont)
|
|
82
|
+
session.commit() # 提交事务,将数据写入数据库
|
|
83
|
+
|
|
84
|
+
# 2 存入到qdrant中
|
|
85
|
+
self.qdrant.update(self.table_name,
|
|
86
|
+
data_list =[
|
|
87
|
+
{
|
|
88
|
+
"id":embed_name_id,
|
|
89
|
+
"vector":vector_list[0],
|
|
90
|
+
"payload":{
|
|
91
|
+
"name": name,
|
|
92
|
+
'timestamp': datetime.now(),
|
|
93
|
+
"content": text,
|
|
94
|
+
"type":type}
|
|
95
|
+
}
|
|
96
|
+
])
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
# 考虑使用知识图 + 增加因果联系
|
|
100
|
+
|
|
101
|
+
def save_to(self):
|
|
102
|
+
#TODO 尝试另存为
|
|
103
|
+
pass
|
|
104
|
+
|
|
105
|
+
def search(self,name:str,version = None):
|
|
106
|
+
with create_session(intel.engine) as session:
|
|
107
|
+
target_content = session.query(Content).filter_by(name = name,
|
|
108
|
+
version = version).frist()
|
|
109
|
+
result = target_content.content
|
|
110
|
+
return result
|
|
111
|
+
|
|
112
|
+
def similarity(self,content: str,limit: int =2):
|
|
113
|
+
vector = embedding_inputs([content])[0]
|
|
114
|
+
result = self.qdrant.select_by_vector(query_vector = vector,
|
|
115
|
+
collection_name = self.table_name,
|
|
116
|
+
limit = limit)
|
|
117
|
+
return result
|
|
118
|
+
|