pro-craft 0.1.56__tar.gz → 0.2.58__tar.gz
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-0.1.56 → pro_craft-0.2.58}/PKG-INFO +7 -1
- {pro_craft-0.1.56 → pro_craft-0.2.58}/README.md +4 -0
- {pro_craft-0.1.56 → pro_craft-0.2.58}/pyproject.toml +2 -2
- {pro_craft-0.1.56 → pro_craft-0.2.58}/src/pro_craft/__init__.py +2 -10
- pro_craft-0.2.58/src/pro_craft/code_helper/agent.py +90 -0
- pro_craft-0.2.58/src/pro_craft/code_helper/codermanager.py +143 -0
- pro_craft-0.2.58/src/pro_craft/code_helper/database.py +36 -0
- pro_craft-0.2.58/src/pro_craft/code_helper/paper_program.py +183 -0
- pro_craft-0.2.58/src/pro_craft/code_helper/template_extract.py +134 -0
- pro_craft-0.2.58/src/pro_craft/code_helper/tools.py +113 -0
- pro_craft-0.2.58/src/pro_craft/code_helper/vectorstore.py +81 -0
- pro_craft-0.2.58/src/pro_craft/code_helper/write_code.py +61 -0
- {pro_craft-0.1.56 → pro_craft-0.2.58}/src/pro_craft/database.py +30 -90
- pro_craft-0.2.58/src/pro_craft/log.py +112 -0
- {pro_craft-0.1.56 → pro_craft-0.2.58}/src/pro_craft/prompt_craft/async_.py +190 -401
- pro_craft-0.2.58/src/pro_craft/server/router/__init__.py +0 -0
- {pro_craft-0.1.56 → pro_craft-0.2.58}/src/pro_craft/server/router/prompt.py +19 -0
- {pro_craft-0.1.56 → pro_craft-0.2.58}/src/pro_craft/utils.py +1 -1
- {pro_craft-0.1.56 → pro_craft-0.2.58}/src/pro_craft.egg-info/PKG-INFO +7 -1
- {pro_craft-0.1.56 → pro_craft-0.2.58}/src/pro_craft.egg-info/SOURCES.txt +10 -2
- {pro_craft-0.1.56 → pro_craft-0.2.58}/src/pro_craft.egg-info/requires.txt +2 -0
- pro_craft-0.2.58/tests/test_code.py +7 -0
- {pro_craft-0.1.56 → pro_craft-0.2.58}/tests/test_coder.py +2 -2
- pro_craft-0.1.56/src/pro_craft/code_helper/coder.py +0 -660
- pro_craft-0.1.56/src/pro_craft/code_helper/designer.py +0 -115
- pro_craft-0.1.56/src/pro_craft/log.py +0 -82
- {pro_craft-0.1.56 → pro_craft-0.2.58}/setup.cfg +0 -0
- {pro_craft-0.1.56/src/pro_craft/server/router → pro_craft-0.2.58/src/pro_craft/code_helper}/__init__.py +0 -0
- {pro_craft-0.1.56 → pro_craft-0.2.58}/src/pro_craft/file_manager.py +0 -0
- {pro_craft-0.1.56 → pro_craft-0.2.58}/src/pro_craft/prompt_craft/__init__.py +0 -0
- {pro_craft-0.1.56 → pro_craft-0.2.58}/src/pro_craft/prompt_craft/new.py +0 -0
- {pro_craft-0.1.56 → pro_craft-0.2.58}/src/pro_craft/prompt_craft/sync.py +0 -0
- {pro_craft-0.1.56 → pro_craft-0.2.58}/src/pro_craft/server/mcp/__init__.py +0 -0
- {pro_craft-0.1.56 → pro_craft-0.2.58}/src/pro_craft/server/mcp/models.py +0 -0
- {pro_craft-0.1.56 → pro_craft-0.2.58}/src/pro_craft/server/mcp/prompt.py +0 -0
- {pro_craft-0.1.56 → pro_craft-0.2.58}/src/pro_craft/server/router/models.py +0 -0
- {pro_craft-0.1.56 → pro_craft-0.2.58}/src/pro_craft.egg-info/dependency_links.txt +0 -0
- {pro_craft-0.1.56 → pro_craft-0.2.58}/src/pro_craft.egg-info/top_level.txt +0 -0
- {pro_craft-0.1.56 → pro_craft-0.2.58}/tests/test22.py +0 -0
- {pro_craft-0.1.56 → pro_craft-0.2.58}/tests/test_11.py +0 -0
- {pro_craft-0.1.56 → pro_craft-0.2.58}/tests/test_designer.py +0 -0
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pro-craft
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.58
|
|
4
4
|
Summary: Add your description here
|
|
5
5
|
Requires-Python: >=3.12
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
7
7
|
Requires-Dist: aiomysql>=0.2.0
|
|
8
8
|
Requires-Dist: anyio>=4.11.0
|
|
9
9
|
Requires-Dist: db-help>=0.2.2
|
|
10
|
+
Requires-Dist: deepagents>=0.2.4
|
|
10
11
|
Requires-Dist: fastapi>=0.119.0
|
|
12
|
+
Requires-Dist: langchain-openai>=1.0.2
|
|
11
13
|
Requires-Dist: llmada>=1.1.11
|
|
12
14
|
Requires-Dist: mcp[cli]>=1.19.0
|
|
13
15
|
Requires-Dist: modusched==0.1.5
|
|
@@ -51,3 +53,7 @@ await ctx.elicit(message, schema) - Request additional information from user wit
|
|
|
51
53
|
```
|
|
52
54
|
|
|
53
55
|
|
|
56
|
+
|
|
57
|
+
## 做到prompt_writing_herper 中 目标是, 无论什么, 随便扔进去, 然后取的时候直接取即可
|
|
58
|
+
|
|
59
|
+
## 然后做code自动化编写的coder 写完之后写豆包语音智能体的链接, mcp协议 然后重构一些, obsidian 的SDK
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "pro-craft"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.2.58"
|
|
4
4
|
description = "Add your description here"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12"
|
|
7
|
-
dependencies = [ "aiomysql>=0.2.0", "anyio>=4.11.0", "db-help>=0.2.2", "fastapi>=0.119.0", "llmada>=1.1.11", "mcp[cli]>=1.19.0", "modusched==0.1.5", "plotly>=6.3.1", "pyyaml>=6.0.3", "toml>=0.10.2", "utils-tool==0.1.3", "uvicorn>=0.38.0",]
|
|
7
|
+
dependencies = [ "aiomysql>=0.2.0", "anyio>=4.11.0", "db-help>=0.2.2", "deepagents>=0.2.4", "fastapi>=0.119.0", "langchain-openai>=1.0.2", "llmada>=1.1.11", "mcp[cli]>=1.19.0", "modusched==0.1.5", "plotly>=6.3.1", "pyyaml>=6.0.3", "toml>=0.10.2", "utils-tool==0.1.3", "uvicorn>=0.38.0",]
|
|
8
8
|
|
|
9
9
|
[tool.setuptools.package-data]
|
|
10
10
|
pro_craft = [ "config.yaml",]
|
|
@@ -1,18 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
1
|
from dotenv import load_dotenv, find_dotenv
|
|
5
|
-
|
|
6
2
|
dotenv_path = find_dotenv()
|
|
7
3
|
load_dotenv(".env", override=True)
|
|
8
|
-
|
|
9
|
-
from .log import Log
|
|
10
4
|
import logging
|
|
11
|
-
|
|
5
|
+
from .log import Log
|
|
6
|
+
Log_ = Log(console_level = logging.WARNING, # 显示控制台的等级 WARNING
|
|
12
7
|
log_file_name="app.log")
|
|
13
8
|
logger = Log_.logger
|
|
14
|
-
Log_.set_super_log(logger.critical) # 控制superlog 打印的等级 默认是最高级单独存储一个文件
|
|
15
|
-
super_log = Log_.super_log # 调试工具
|
|
16
|
-
inference_save_case = False
|
|
17
9
|
|
|
18
10
|
from .prompt_craft import AsyncIntel, Intel, IntelNew
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# LLM1
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from typing import Literal
|
|
5
|
+
# from tavily import TavilyClient
|
|
6
|
+
from deepagents import create_deep_agent
|
|
7
|
+
from .tools import search_template_by_text, get_template_details, ask_user_for_clarification, generate_request_file
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# System prompt to steer the agent to be an expert researcher
|
|
11
|
+
research_instructions = """你是一个高级代码生成助手 Agent,你的主要职责是帮助用户通过模板快速生成代码。
|
|
12
|
+
|
|
13
|
+
**你的目标是:**
|
|
14
|
+
1. **精确理解用户对代码功能和结构的自然语言描述。**
|
|
15
|
+
2. **在现有模板库中,智能地找到最符合用户需求的模板。**
|
|
16
|
+
3. **如果找不到高匹配度的模板,引导用户创建新模板。**
|
|
17
|
+
4. **基于选定的模板和用户需求,生成一个结构化、可执行的 `REQUEST_START/END` 指令文件,用于后续的代码生成。**
|
|
18
|
+
5. **在必要时与用户进行交互,澄清需求或提供建议。**
|
|
19
|
+
|
|
20
|
+
**你的可用工具:**
|
|
21
|
+
|
|
22
|
+
1. **`search_template_by_text(query: str, top_k: int = 5) -> List[Dict[str, Any]]`**
|
|
23
|
+
* **描述:** 根据自然语言查询在模板库中进行语义搜索(使用 Qdrant 向量检索),返回最相关的 `top_k` 个模板的摘要信息。
|
|
24
|
+
* **返回字段示例:** `[{'template_id': 'uuid', 'template_name': 'str', 'description': 'str', 'match_score': 'float'}]`
|
|
25
|
+
* **何时使用:** 当你需要根据用户需求找到合适的代码模板时。
|
|
26
|
+
|
|
27
|
+
2. **`get_template_details(template_id: str) -> Dict[str, Any]`**
|
|
28
|
+
* **描述:** 根据 `template_id` 从数据库中获取模板的完整详细信息,包括模板代码、推断出的命名约定和使用建议。
|
|
29
|
+
* **返回字段示例:** `{'template_id': 'uuid', 'template_name': 'str', 'template_code': 'str', 'suggested_naming_conventions': 'json', 'usage_guidance': 'str'}`
|
|
30
|
+
* **何时使用:** 当你已经选择了一个模板,需要其详细内容来生成指令时。
|
|
31
|
+
|
|
32
|
+
3. **`generate_request_file(template_code: str, user_request_details: Dict[str, Any], naming_conventions: Dict[str, Any]) -> str`**
|
|
33
|
+
* **描述:** 根据选定的模板代码、解析后的用户需求(结构化形式)和模板的命名约定,生成符合 `REQUEST_START/END` 格式的指令文件。
|
|
34
|
+
* **何时使用:** 当你已经确定了模板,并且充分理解了用户需求的所有细节,准备生成最终指令时。
|
|
35
|
+
|
|
36
|
+
4. **`ask_user_for_clarification(question: str) -> str`**
|
|
37
|
+
* **描述:** 当你对用户需求有疑问,或需要用户做选择(例如在多个匹配模板中选择一个)时,使用此工具向用户提问。
|
|
38
|
+
* **返回:** 用户的回答。
|
|
39
|
+
* **何时使用:** 任何需要用户输入或确认的场景。
|
|
40
|
+
|
|
41
|
+
**你的工作流程:**
|
|
42
|
+
|
|
43
|
+
1. **接收用户需求:** 用户会提供一个自然语言描述。
|
|
44
|
+
2. **初步理解与模板搜索:**
|
|
45
|
+
* 首先使用 `search_template_by_text` 工具,以用户需求的概要作为 `query`,找到 `top_k` 个最相关的模板。
|
|
46
|
+
* 分析搜索结果中的 `match_score` 和 `description`,评估匹配度。
|
|
47
|
+
3. **决策点 - 模板匹配:**
|
|
48
|
+
* **高匹配度:** 如果存在一个或少数几个模板的 `match_score` 显著高,且 `description` 与用户需求高度吻合:
|
|
49
|
+
* 使用 `get_template_details` 获取该模板的完整信息。
|
|
50
|
+
* 进入 **需求细化与指令生成** 阶段。
|
|
51
|
+
* **中等匹配度 / 多个相似匹配:** 如果有多个模板得分接近,或没有一个模板完美匹配:
|
|
52
|
+
* 使用 `ask_user_for_clarification` 工具,向用户展示这些模板的 `template_name` 和 `description`,并询问用户希望选择哪一个,或者是否希望在此基础上进行调整。
|
|
53
|
+
* 根据用户反馈,决定是选择一个模板还是引导用户创建新模板。
|
|
54
|
+
* **低匹配度 / 无匹配:** 如果没有找到任何合适的模板(例如,所有 `match_score` 都很低):
|
|
55
|
+
* 使用 `ask_user_for_clarification` 工具,告知用户未能找到合适的模板,并询问用户是否希望提供多个示例代码,以便使用 LLM 0 创建一个新的模板。
|
|
56
|
+
* 如果用户同意,引导用户进入 LLM 0 的流程。
|
|
57
|
+
4. **需求细化与指令生成 (基于选定模板):**
|
|
58
|
+
* 一旦确定了模板,仔细解析用户需求的每个细节,并将其映射到选定模板中的 `BLOCK` 和 `PLACEHOLDER`。
|
|
59
|
+
* 考虑模板的 `suggested_naming_conventions`,并尝试将其整合到生成的指令中。
|
|
60
|
+
* 如果用户需求与模板的某个 `BLOCK` 或 `PLACEHOLDER` 不兼容,或用户没有提供足够的细节来填充某个区域,使用 `ask_user_for_clarification` 向用户提问。
|
|
61
|
+
* 当所有必要信息都已获取且明确无误时,使用 `generate_request_file` 工具生成最终的 `REQUEST_START/END` 指令文件。
|
|
62
|
+
5. **输出最终指令:** 将 `generate_request_file` 的输出返回给系统,以便进行下一步的代码生成。
|
|
63
|
+
|
|
64
|
+
**交互约束:**
|
|
65
|
+
* 除非使用 `ask_user_for_clarification` 工具,否则不要直接与用户对话。
|
|
66
|
+
* 始终以使用工具作为首选行动。
|
|
67
|
+
* 保持你的回复简洁、直接,聚焦于完成任务。
|
|
68
|
+
|
|
69
|
+
**示例用户需求:**
|
|
70
|
+
"我需要一个API来发送用户消息。路径是 `/send`,POST 方法。输入模型叫 `SendMessageRequest`,包含 `user_id` (UUID格式) 和 `message_content` (字符串,最大500字)。输出模型叫 `SendMessageResponse`,继承 `CommonResponseModel`,额外包含 `message_id`。它会调用 `message_service_manager.send_message(user_id, content)`。如果 `user_id` 无效,应该返回 400 错误。"
|
|
71
|
+
"""
|
|
72
|
+
from langchain.chat_models import init_chat_model
|
|
73
|
+
|
|
74
|
+
model = init_chat_model(
|
|
75
|
+
model="openai:gemini-2.5-flash-preview-05-20-nothinking",
|
|
76
|
+
api_key=os.getenv("BIANXIE_API_KEY"),
|
|
77
|
+
base_url=os.getenv("BIANXIE_BASE"),
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
agent = create_deep_agent(
|
|
81
|
+
model=model,
|
|
82
|
+
tools=[search_template_by_text, get_template_details, ask_user_for_clarification, generate_request_file],
|
|
83
|
+
system_prompt=research_instructions
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
if __name__ == "__main__":
|
|
88
|
+
result = agent.invoke({"messages": [{"role": "user", "content": "hello"}]})
|
|
89
|
+
|
|
90
|
+
print(result["messages"][-1].content)
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
|
|
2
|
+
from sqlalchemy import create_engine
|
|
3
|
+
import os
|
|
4
|
+
from typing import List
|
|
5
|
+
from .database import Base, CodeTemplate
|
|
6
|
+
from .vectorstore import VolcanoEmbedding
|
|
7
|
+
QDRANT_COLLECTION_NAME = "template_collection" # 你的 Qdrant collection 名称
|
|
8
|
+
from pro_craft.utils import create_session
|
|
9
|
+
from qdrant_client import QdrantClient, models
|
|
10
|
+
from uuid import uuid4
|
|
11
|
+
from .template_extract import extract_template
|
|
12
|
+
from qdrant_client import QdrantClient
|
|
13
|
+
from qdrant_client.models import Filter, FieldCondition, MatchValue, PointStruct, CollectionStatus, Distance, VectorParams
|
|
14
|
+
|
|
15
|
+
class CoderTemplateManager():
|
|
16
|
+
def __init__(self,
|
|
17
|
+
database_url = "mysql+pymysql://zxf_root:Zhf4233613%40@rm-2ze0793c6548pxs028o.mysql.rds.aliyuncs.com:3306/serverz",
|
|
18
|
+
model_name = "",
|
|
19
|
+
logger = None,
|
|
20
|
+
):
|
|
21
|
+
database_url = database_url or os.getenv("database_url")
|
|
22
|
+
assert database_url
|
|
23
|
+
self.engine = create_engine(database_url, echo=False, # echo=True 仍然会打印所有执行的 SQL 语句
|
|
24
|
+
pool_size=10, # 连接池中保持的连接数
|
|
25
|
+
max_overflow=20, # 当pool_size不够时,允许临时创建的额外连接数
|
|
26
|
+
pool_recycle=3600, # 每小时回收一次连接
|
|
27
|
+
pool_pre_ping=True, # 使用前检查连接活性
|
|
28
|
+
pool_timeout=30 # 等待连接池中连接的最长时间(秒)
|
|
29
|
+
)
|
|
30
|
+
self.embedding_model = VolcanoEmbedding(
|
|
31
|
+
model_name = "doubao-embedding-text-240715",
|
|
32
|
+
api_key = "39ad310a-c6f7-4d66-962e-1fbfa7e6edf1"
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
Base.metadata.create_all(self.engine)
|
|
37
|
+
|
|
38
|
+
self.connection = QdrantClient(host="127.0.0.1", port=6333)
|
|
39
|
+
|
|
40
|
+
self.connection.recreate_collection(
|
|
41
|
+
collection_name=QDRANT_COLLECTION_NAME,
|
|
42
|
+
vectors_config=models.VectorParams(size=2560, distance=models.Distance.COSINE),
|
|
43
|
+
)
|
|
44
|
+
self.logger = logger
|
|
45
|
+
|
|
46
|
+
# if model_name in ["gemini-2.5-flash-preview-05-20-nothinking",]:
|
|
47
|
+
# self.llm = BianXieAdapter(model_name = model_name)
|
|
48
|
+
# elif model_name in ["doubao-1-5-pro-256k-250115","doubao-1-5-pro-32k-250115"]:
|
|
49
|
+
# self.llm = ArkAdapter(model_name = model_name)
|
|
50
|
+
# else:
|
|
51
|
+
# raise Exception("error llm name")
|
|
52
|
+
|
|
53
|
+
def get_embedding(self,text: str) -> List[float]:
|
|
54
|
+
return self.embedding_model._get_text_embedding(text)
|
|
55
|
+
|
|
56
|
+
def add_template(self,
|
|
57
|
+
use_case: str,
|
|
58
|
+
template_id: str,
|
|
59
|
+
description: str,):
|
|
60
|
+
template = extract_template(use_case)
|
|
61
|
+
embedding_vector = self.get_embedding(description)
|
|
62
|
+
points = [
|
|
63
|
+
models.PointStruct(
|
|
64
|
+
id = str(uuid4()),
|
|
65
|
+
vector=embedding_vector,
|
|
66
|
+
payload={
|
|
67
|
+
"template_id": template_id,
|
|
68
|
+
"description": description,
|
|
69
|
+
"use_case": use_case,
|
|
70
|
+
"template": template,
|
|
71
|
+
}
|
|
72
|
+
)
|
|
73
|
+
]
|
|
74
|
+
self.connection.upsert(
|
|
75
|
+
collection_name=QDRANT_COLLECTION_NAME,
|
|
76
|
+
wait=True,
|
|
77
|
+
points=points
|
|
78
|
+
)
|
|
79
|
+
# 数据库
|
|
80
|
+
with create_session(self.engine) as session:
|
|
81
|
+
new_template = CodeTemplate(
|
|
82
|
+
template_id=template_id,
|
|
83
|
+
version=1,
|
|
84
|
+
description=description,
|
|
85
|
+
template_code=template,
|
|
86
|
+
)
|
|
87
|
+
session.add(new_template)
|
|
88
|
+
session.commit()
|
|
89
|
+
session.refresh(new_template)
|
|
90
|
+
return "success"
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def delete_template(self, template_id: str) -> bool:
|
|
94
|
+
"""
|
|
95
|
+
逻辑删除指定的代码模板。
|
|
96
|
+
"""
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
# 3. 使用属性删除点
|
|
100
|
+
# 目标:删除所有 'color' 属性为 'red' 的点
|
|
101
|
+
|
|
102
|
+
# 定义一个过滤器
|
|
103
|
+
# 这个过滤器会匹配所有 payload 中 'color' 字段值为 'red' 的点
|
|
104
|
+
_filter = Filter(
|
|
105
|
+
must=[
|
|
106
|
+
FieldCondition(
|
|
107
|
+
key="template_id",
|
|
108
|
+
match=MatchValue(value=template_id)
|
|
109
|
+
)
|
|
110
|
+
]
|
|
111
|
+
)
|
|
112
|
+
self.connection.delete(
|
|
113
|
+
collection_name=QDRANT_COLLECTION_NAME,
|
|
114
|
+
points_selector=_filter,
|
|
115
|
+
wait=True
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
with create_session(self.engine) as session:
|
|
120
|
+
template = session.query(CodeTemplate).filter_by(template_id=template_id).first()
|
|
121
|
+
if template:
|
|
122
|
+
session.delete(template)
|
|
123
|
+
session.commit()
|
|
124
|
+
return True
|
|
125
|
+
return False
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def search(self, text , limit , query_filter=None):
|
|
129
|
+
query_vector = self.get_embedding(text)
|
|
130
|
+
results = self.connection.search(
|
|
131
|
+
collection_name=QDRANT_COLLECTION_NAME,
|
|
132
|
+
query_vector=query_vector,
|
|
133
|
+
limit=limit,
|
|
134
|
+
query_filter=query_filter
|
|
135
|
+
)
|
|
136
|
+
return results
|
|
137
|
+
|
|
138
|
+
def get_template_obj(self, template_id: str):
|
|
139
|
+
# 模拟从数据库获取模板详情
|
|
140
|
+
# 实际使用时,你需要根据你的数据库 setup 来实现
|
|
141
|
+
with create_session(self.engine) as session:
|
|
142
|
+
template = session.query(CodeTemplate).filter_by(template_id = template_id).first()
|
|
143
|
+
return template
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from sqlalchemy import Column, Integer, String, Text, DateTime, text, UniqueConstraint, Boolean, func, Float, Double
|
|
2
|
+
from sqlalchemy.orm import declarative_base
|
|
3
|
+
|
|
4
|
+
from datetime import datetime, timedelta
|
|
5
|
+
|
|
6
|
+
FileBase = declarative_base()
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# template_id (PK)
|
|
10
|
+
# template_name (e.g., "FastAPI Router Endpoint")
|
|
11
|
+
# description (e.g., "FastAPI服务路由器中的单个API端点,包含Pydantic校验、异步调用、Try-Except错误处理和日志记录。")
|
|
12
|
+
# template_code (实际的模板代码字符串)
|
|
13
|
+
# suggested_naming_conventions (JSONB 或文本)
|
|
14
|
+
# usage_guidance (文本)
|
|
15
|
+
# language (e.g., "Python")
|
|
16
|
+
# framework (e.g., "FastAPI")
|
|
17
|
+
# version
|
|
18
|
+
# created_by
|
|
19
|
+
# created_at
|
|
20
|
+
# last_updated_at
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
from sqlalchemy import Column, Integer, String, Text, DateTime, text, UniqueConstraint, Boolean, func, Float, Double
|
|
24
|
+
from sqlalchemy.orm import declarative_base
|
|
25
|
+
|
|
26
|
+
from datetime import datetime, timedelta
|
|
27
|
+
|
|
28
|
+
Base = declarative_base()
|
|
29
|
+
|
|
30
|
+
class CodeTemplate(Base):
|
|
31
|
+
__tablename__ = 'code_template'
|
|
32
|
+
template_id = Column(String(255), primary_key=True, nullable=False, comment="自增")
|
|
33
|
+
description = Column(Text, nullable=False, comment="Detailed description of the template")
|
|
34
|
+
template_code = Column(Text, nullable=False, comment="The actual code of the template")
|
|
35
|
+
version = Column(Integer, nullable=True, comment="Template version")
|
|
36
|
+
# UniqueConstraint('template_name', name='uq_template_name') # 如果 template_name 应该是唯一的
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
from pro_craft import Intel
|
|
2
|
+
from pro_craft.log import Log
|
|
3
|
+
from pro_craft.utils import extract_
|
|
4
|
+
from typing import List, Dict, Any
|
|
5
|
+
from llmada.core import BianXieAdapter
|
|
6
|
+
import re
|
|
7
|
+
import json
|
|
8
|
+
|
|
9
|
+
logger = Log.logger
|
|
10
|
+
|
|
11
|
+
intel = Intel(model_name="doubao-1-5-pro-256k-250115")
|
|
12
|
+
|
|
13
|
+
class CoderHelper():
|
|
14
|
+
def __init__(self):
|
|
15
|
+
self.bx = BianXieAdapter()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@intel.intellect_remove_warp(prompt_id ="代码修改-最小化改动001")
|
|
19
|
+
def minedit_prompt(self,input:dict):
|
|
20
|
+
# 可以做pydantic 的校验
|
|
21
|
+
input = extract_(input, pattern_key = r"python")
|
|
22
|
+
return input
|
|
23
|
+
|
|
24
|
+
@intel.intellect_remove_warp(prompt_id ="高定制化自由函数修改_001")
|
|
25
|
+
def free_function_prompt(self,input:dict,kwargs):
|
|
26
|
+
# 可以做pydantic 的校验
|
|
27
|
+
result_ = extract_(input, pattern_key = r"python")
|
|
28
|
+
if not result_:
|
|
29
|
+
return None
|
|
30
|
+
|
|
31
|
+
complet_code = result_ + "\n" + f'result = Function(**{kwargs})'
|
|
32
|
+
|
|
33
|
+
rut = {"result": ""}
|
|
34
|
+
# 使用exec执行代码,并捕获可能的错误
|
|
35
|
+
try:
|
|
36
|
+
exec(
|
|
37
|
+
complet_code, globals(), rut
|
|
38
|
+
) # 将globals()作为全局作用域,避免依赖外部locals()
|
|
39
|
+
except Exception as e:
|
|
40
|
+
logger.error(f"执行动态生成的代码时发生错误: {e}")
|
|
41
|
+
return None # 返回None或抛出异常
|
|
42
|
+
|
|
43
|
+
return rut.get("result")
|
|
44
|
+
|
|
45
|
+
def min_edit(self,code:str, edit_demand:str):
|
|
46
|
+
input_ = {"源码":code,
|
|
47
|
+
"功能需求":edit_demand
|
|
48
|
+
}
|
|
49
|
+
data = self.minedit_prompt(input = input_)
|
|
50
|
+
return data
|
|
51
|
+
|
|
52
|
+
def free_function(self,function: str ="帮我将 日期 2025/12/03 向前回退12天",
|
|
53
|
+
**kwargs):
|
|
54
|
+
# params = locals()
|
|
55
|
+
prompt_user_part = f"{function}"
|
|
56
|
+
if kwargs:
|
|
57
|
+
prompt_user_part += "入参 : \n"
|
|
58
|
+
prompt_user_part += json.dumps(kwargs,ensure_ascii=False)
|
|
59
|
+
|
|
60
|
+
exec_result = self.free_function_prompt(input = prompt_user_part,kwargs = kwargs)
|
|
61
|
+
|
|
62
|
+
return exec_result
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def free_function_advanced(self):
|
|
66
|
+
pass
|
|
67
|
+
|
|
68
|
+
class Paper():
|
|
69
|
+
def __init__(self,content):
|
|
70
|
+
self.content = content
|
|
71
|
+
|
|
72
|
+
@intel.intellect_remove_warp(prompt_id ="白板编辑-修改画板001")
|
|
73
|
+
def system_prompt(self,data):
|
|
74
|
+
return data
|
|
75
|
+
|
|
76
|
+
def talk(self,prompt:str):
|
|
77
|
+
data = {"data":self.content+ prompt}
|
|
78
|
+
result = self.system_prompt(data = data)
|
|
79
|
+
# result = bx.product(system_prompt+ self.content+ prompt)
|
|
80
|
+
print(result,'result')
|
|
81
|
+
result_json = json.loads(extract_(result,pattern_key = r"json"))
|
|
82
|
+
print(result_json,'result_json')
|
|
83
|
+
for ops in result_json:
|
|
84
|
+
self.deal(ops.get('type'), ops.get('operations'))
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def deal(self, type_, operations:str):
|
|
88
|
+
if type_ == "add":
|
|
89
|
+
self.add(operations)
|
|
90
|
+
elif type_ == "delete":
|
|
91
|
+
self.delete(operations)
|
|
92
|
+
else:
|
|
93
|
+
print('error')
|
|
94
|
+
|
|
95
|
+
def add(self, operations:str):
|
|
96
|
+
print('add running')
|
|
97
|
+
match_tips = re.search(r'<mark>(.*?)</mark>', operations, re.DOTALL)
|
|
98
|
+
positon_ = operations.replace(f"<mark>{match_tips.group(1)}</mark>","")
|
|
99
|
+
# 锁定原文
|
|
100
|
+
positon_frist = operations.replace('<mark>',"").replace('</mark>',"")
|
|
101
|
+
print(positon_frist,'positon_frist')
|
|
102
|
+
print('==========')
|
|
103
|
+
print(positon_,'positon__')
|
|
104
|
+
self.content = self.content.replace(positon_,positon_frist)
|
|
105
|
+
|
|
106
|
+
def delete(self, operations:str):
|
|
107
|
+
# 制定替换内容
|
|
108
|
+
print('delete running')
|
|
109
|
+
match_tips = re.search(r'<mark>(.*?)</mark>', operations, re.DOTALL)
|
|
110
|
+
positon_ = operations.replace(f"<mark>{match_tips.group(1)}</mark>","")
|
|
111
|
+
# 锁定原文
|
|
112
|
+
positon_frist = operations.replace('<mark>',"").replace('</mark>',"")
|
|
113
|
+
print(positon_frist,'positon_frist')
|
|
114
|
+
assert positon_frist in self.content
|
|
115
|
+
print('==========')
|
|
116
|
+
print(positon_,'positon__')
|
|
117
|
+
|
|
118
|
+
self.content = self.content.replace(positon_frist,positon_)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
mermaid_format = """
|
|
123
|
+
```mermaid
|
|
124
|
+
{result}
|
|
125
|
+
```"""
|
|
126
|
+
|
|
127
|
+
class ProgramChart():
|
|
128
|
+
'''
|
|
129
|
+
# ## 有一个原始的程序框图, -> 可以通过需求来调整程序框图 -> 结合数据库来调度程序框图
|
|
130
|
+
# 一个新的任务, => 基本需求, -> 根据需求调取之前的程序框图, -> 融合程序框图 -> 调整程序框图到完成满意,-> 由程序框图实现代码, 并拉取出待实现函数
|
|
131
|
+
# -> 用知识库中获取代码与对应的测试, 整合到待实现函数中, -> 剩余的使用封装好的包进行补充, -> 创新的补充, -> ...
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
inputs = """
|
|
135
|
+
帮我实现一个文件读取的逻辑
|
|
136
|
+
"""
|
|
137
|
+
program_chart = init_program_chart_mermaid(inputs) # TODO 类图另做吧
|
|
138
|
+
# 一直循环, 直到满意
|
|
139
|
+
program_chart = finetune_program_chart(program_chart + "如果文件不存在, 就创建")
|
|
140
|
+
codes = fill_code_frame_program_chart(program_chart) #TODO 可以尝试配置对应的pytest
|
|
141
|
+
|
|
142
|
+
'''
|
|
143
|
+
|
|
144
|
+
# TODO 数据用例等, 只是保存, 真正做统计的时候可以导出选择合适的数据
|
|
145
|
+
|
|
146
|
+
@intel.intellect_remove_warp(prompt_id="程序框图-根据需求创建")
|
|
147
|
+
def init_program_chart_mermaid(self,input_data:str,
|
|
148
|
+
output_format:str):
|
|
149
|
+
result = extract_(input_data,r"mermaid")
|
|
150
|
+
input_ = mermaid_format.format(result = result)
|
|
151
|
+
|
|
152
|
+
with open("/Users/zhaoxuefeng/GitHub/obsidian/工作/TODO/1根据需求创建.md",'w') as f:
|
|
153
|
+
f.write(input_)
|
|
154
|
+
return input_
|
|
155
|
+
|
|
156
|
+
@intel.intellect_remove_warp(prompt_id="程序框图-白板微调")
|
|
157
|
+
def finetune_program_chart(self,input_data:str,
|
|
158
|
+
output_format:str):
|
|
159
|
+
print(input_data,'input_datainput_datainput_data')
|
|
160
|
+
result = extract_(input_data,r"mermaid")
|
|
161
|
+
input_ = mermaid_format.format(result = result)
|
|
162
|
+
with open("/Users/zhaoxuefeng/GitHub/obsidian/工作/TODO/1根据需求创建.md",'w') as f:
|
|
163
|
+
f.write(input_)
|
|
164
|
+
return input_
|
|
165
|
+
|
|
166
|
+
@intel.intellect_remove_warp(prompt_id="程序框图-框架实现")
|
|
167
|
+
def fill_code_frame_program_chart(self,input:dict):
|
|
168
|
+
# result = extract_(input.get("program_chart"),r"python")
|
|
169
|
+
code = input.get("program_chart")
|
|
170
|
+
|
|
171
|
+
with open("/Users/zhaoxuefeng/GitHub/obsidian/工作/TODO/3框架实现.md",'w') as f:
|
|
172
|
+
f.write(code)
|
|
173
|
+
return code
|
|
174
|
+
|
|
175
|
+
def pc_work(self,chat,fill = False):
|
|
176
|
+
self.init_program_chart_mermaid(chat)
|
|
177
|
+
|
|
178
|
+
program_chart = self.finetune_program_chart
|
|
179
|
+
|
|
180
|
+
code = self.fill_code_frame_program_chart(input = {
|
|
181
|
+
"program_chart":program_chart
|
|
182
|
+
})
|
|
183
|
+
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
LLM0 = """
|
|
2
|
+
|
|
3
|
+
你是一个高级代码分析和模板工程师AI。你的任务是根据用户提供的多个编程示例和场景描述,提炼出一个高质量、通用且符合约定格式的代码模板。
|
|
4
|
+
|
|
5
|
+
**输入格式:**
|
|
6
|
+
用户将以以下结构向你提供信息:
|
|
7
|
+
|
|
8
|
+
--- SCENARIO_DESCRIPTION_START ---
|
|
9
|
+
[用户提供的场景描述]
|
|
10
|
+
--- SCENARIO_DESCRIPTION_END ---
|
|
11
|
+
|
|
12
|
+
--- CODE_EXAMPLE_START: [文件名1] ---
|
|
13
|
+
[第一个示例代码内容]
|
|
14
|
+
--- CODE_EXAMPLE_END: [文件名1] ---
|
|
15
|
+
|
|
16
|
+
--- CODE_EXAMPLE_START: [文件名2] ---
|
|
17
|
+
[第二个示例代码内容]
|
|
18
|
+
--- CODE_EXAMPLE_END: [文件名2] ---
|
|
19
|
+
...
|
|
20
|
+
[用户可能提供3到5个或更多示例]
|
|
21
|
+
...
|
|
22
|
+
--- CODE_EXAMPLE_START: [文件名N] ---
|
|
23
|
+
[第N个示例代码内容]
|
|
24
|
+
--- CODE_EXAMPLE_END: [文件名N] ---
|
|
25
|
+
|
|
26
|
+
**你的任务和提炼原则:**
|
|
27
|
+
|
|
28
|
+
1. **理解场景:** 仔细阅读 SCENARIO_DESCRIPTION,理解所有示例代码的共同目的和核心业务逻辑。
|
|
29
|
+
2. **分析共性:**
|
|
30
|
+
* 识别所有示例中重复出现或结构上高度相似的代码段(例如:导入语句、类/函数定义、错误处理结构、Pydantic模型定义模式)。这些构成模板的**固定部分**。
|
|
31
|
+
* 识别在所有示例中都出现,但内容可能有所差异的通用常量、变量名、类名、函数名或方法名。这些是潜在的**命名约定**。
|
|
32
|
+
3. **识别差异和可变性:**
|
|
33
|
+
* 找出在不同示例中有所不同、需要根据具体需求调整的部分(例如:API路径、Pydantic模型的具体字段、业务逻辑调用的函数名及其参数、错误处理中的特定异常类型、日志消息内容)。这些构成模板的**可变部分**。
|
|
34
|
+
4. **生成模板代码:**
|
|
35
|
+
* 使用提供的示例代码中最具代表性的一个作为基础,或者综合多个示例的特点来构建模板。
|
|
36
|
+
* **固定部分:** 直接保留在模板中,不加特殊标记。
|
|
37
|
+
* **可变部分:** 使用我们约定的标记进行替换或封装:
|
|
38
|
+
* **`<!-- BLOCK_START: [块名称] -->` / `<!-- BLOCK_END: [块名称] -->`:** 用于封装较大的、多行的可变代码逻辑块(例如Pydantic模型定义块、API端点实现块)。在 `BLOCK_START` 之后紧跟一行注释 `AI: [该块的预期用途和示例]`。
|
|
39
|
+
* **`<!-- PLACEHOLDER: [占位符名称] -->` / `<!-- END_PLACEHOLDER: [占位符名称] -->`:** 用于封装较小的、行内或短代码片段的可变内容(例如特定导入、单个配置项、特定函数参数)。在 `PLACEHOLDER` 之后紧跟一行注释 `AI: [该占位符的预期用途和示例]`。
|
|
40
|
+
* 如果某个小块的代码在示例中是固定的,但你判断它未来很可能会根据用户需求变化,也可以将其封装为 `PLACEHOLDER` 或 `BLOCK`。
|
|
41
|
+
* **注释编写:** 为每个 `BLOCK` 和 `PLACEHOLDER` 添加清晰、简洁的注释,解释该区域的用途和预期的输入类型/内容。这些注释应直接跟在 `BLOCK_START` 或 `PLACEHOLDER` 标记之后。
|
|
42
|
+
* **Docstrings/常规注释:** 保留示例代码中原有的 Docstrings 和常规注释,除非它们是示例特有的、不具通用性的。
|
|
43
|
+
5. **推断命名约定:**
|
|
44
|
+
* 根据示例代码中的命名模式(例如类名前缀、变量名风格、通用服务/管理器名称),推断并列出建议的命名约定。
|
|
45
|
+
* 这些命名约定应以我们约定的格式呈现。
|
|
46
|
+
6. **撰写模板使用建议:**
|
|
47
|
+
* 提供简要的文本说明,总结该模板最适合解决哪类问题,以及用户在使用时应重点关注哪些 `BLOCK` 或 `PLACEHOLDER`。
|
|
48
|
+
|
|
49
|
+
**输出格式 (严格遵守):**
|
|
50
|
+
|
|
51
|
+
你的输出必须包含以下三个部分,每个部分之间用 `---` 分隔:
|
|
52
|
+
|
|
53
|
+
**第一部分:模板代码**
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
# [文件名称,例如: template_service.py]
|
|
57
|
+
|
|
58
|
+
[提炼出的模板代码,包含 BLOCK_START/END 和 PLACEHOLDER/END_PLACEHOLDER 标记,以及必要的注释]
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**第二部分:推断出的命名约定**
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
--- NAMING_CONVENTIONS_START ---
|
|
65
|
+
**命名约定:**
|
|
66
|
+
* [推断出的命名约定1]
|
|
67
|
+
* [推断出的命名约定2]
|
|
68
|
+
...
|
|
69
|
+
--- NAMING_CONVENTIONS_END ---
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**第三部分:模板使用建议**
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
--- USAGE_SUGGESTIONS_START ---
|
|
76
|
+
**模板使用建议:**
|
|
77
|
+
[简要说明该模板的适用场景和使用重点]
|
|
78
|
+
--- USAGE_SUGGESTIONS_END ---
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**重要提示:**
|
|
82
|
+
* 请务必保持输出格式的完整性和准确性,尤其是各种标记的匹配。
|
|
83
|
+
* 力求模板的通用性,同时通过详细的注释指导未来的使用。
|
|
84
|
+
* 如果示例代码中有非常具体且不具通用性的部分,即使它重复出现,也要考虑是否将其作为可变部分处理。
|
|
85
|
+
|
|
86
|
+
现在,请等待用户提供多个代码示例和场景描述。
|
|
87
|
+
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
## 用户输入格式示例
|
|
92
|
+
'''
|
|
93
|
+
--- SCENARIO_DESCRIPTION_START ---
|
|
94
|
+
这是一个Python脚本系列,它们都用于处理用户数据。
|
|
95
|
+
基本流程是:从某个地方(文件、API等)加载原始用户数据,
|
|
96
|
+
对数据进行清洗和标准化(例如,去除重复项,格式化地址),
|
|
97
|
+
然后将处理后的数据保存到另一个位置(文件、数据库)。
|
|
98
|
+
目标是提炼一个通用模板,以便后续可以快速生成处理不同数据源和目标的代码。
|
|
99
|
+
--- SCENARIO_DESCRIPTION_END ---
|
|
100
|
+
|
|
101
|
+
--- CODE_EXAMPLE_START: example1.py ---
|
|
102
|
+
# 第一个示例代码内容
|
|
103
|
+
# ...
|
|
104
|
+
--- CODE_EXAMPLE_END: example1.py ---
|
|
105
|
+
|
|
106
|
+
--- CODE_EXAMPLE_START: example2.py ---
|
|
107
|
+
# 第二个示例代码内容
|
|
108
|
+
# ...
|
|
109
|
+
--- CODE_EXAMPLE_END: example2.py ---
|
|
110
|
+
|
|
111
|
+
--- CODE_EXAMPLE_START: example3.py ---
|
|
112
|
+
# 第三个示例代码内容
|
|
113
|
+
# ...
|
|
114
|
+
--- CODE_EXAMPLE_END: example3.py ---
|
|
115
|
+
|
|
116
|
+
--- CODE_EXAMPLE_START: example4.py ---
|
|
117
|
+
# 第四个示例代码内容
|
|
118
|
+
# ...
|
|
119
|
+
--- CODE_EXAMPLE_END: example4.py ---
|
|
120
|
+
|
|
121
|
+
--- CODE_EXAMPLE_START: example5.py ---
|
|
122
|
+
# 第五个示例代码内容
|
|
123
|
+
# ...
|
|
124
|
+
--- CODE_EXAMPLE_END: example5.py ---'''
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
from modusched.core import BianXieAdapter
|
|
128
|
+
|
|
129
|
+
def extract_template(User_Input):
|
|
130
|
+
"""
|
|
131
|
+
"""
|
|
132
|
+
bx = BianXieAdapter()
|
|
133
|
+
result = bx.product(LLM0 + User_Input)
|
|
134
|
+
return result
|