pro-craft 0.1.37__py3-none-any.whl → 0.1.38__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.

@@ -25,14 +25,14 @@ from datetime import datetime, timedelta
25
25
  from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine, async_sessionmaker
26
26
  from sqlalchemy import select, and_ # 引入 select 和 and_
27
27
  from sqlalchemy.orm import class_mapper # 用于检查对象是否是持久化的
28
- import tqdm
28
+
29
29
  from tqdm.asyncio import tqdm
30
30
  import pandas as pd
31
31
  import plotly.graph_objects as go
32
32
  from pro_craft import super_log
33
33
 
34
34
  BATCH_SIZE = int(os.getenv("DATABASE_SYNC_BATCH_SIZE",100))
35
-
35
+ print(12)
36
36
 
37
37
  def fix_broken_json_string(broken_json_str):
38
38
  # 移除 BOM
@@ -642,7 +642,7 @@ class AsyncIntel():
642
642
  使用以下正则检出
643
643
  "```json([\s\S]*?)```"
644
644
  使用以下方式验证
645
- """
645
+ """
646
646
  if OutputFormat:
647
647
  output_format = base_format_prompt + "\n".join([inspect.getsource(outputformat) for outputformat in ExtraFormats]) + inspect.getsource(OutputFormat)
648
648
  else:
@@ -740,10 +740,12 @@ class AsyncIntel():
740
740
  async def intellect_format_eval(self,
741
741
  OutputFormat: object,
742
742
  prompt_id: str,
743
+ database_url = None,
743
744
  ExtraFormats: list[object] = [],
744
745
  version: str = None,
745
746
  MIN_SUCCESS_RATE = 80.0,
746
747
  ConTent_Function = None,
748
+ AConTent_Function = None,
747
749
  ):
748
750
  """
749
751
  ConTent_Function:
@@ -751,20 +753,32 @@ class AsyncIntel():
751
753
  # TODO llm 评价 eval
752
754
  """
753
755
  async with create_async_session(self.engine) as session:
754
- use_cases = await self.get_use_case(target_prompt_id=prompt_id,session=session)
755
756
  prompt_result = await self.get_prompt_safe(prompt_id=prompt_id,
756
757
  session=session)
757
758
  if prompt_result is None:
758
759
  raise IntellectRemoveError("不存在的prompt_id")
759
760
  if prompt_result.action_type != "inference":
760
761
  raise IntellectRemoveError("请在inference模式下使用次类")
761
-
762
+
763
+ if database_url:
764
+ eval_engine = create_async_engine(database_url, echo=False,
765
+ pool_size=10, # 连接池中保持的连接数
766
+ max_overflow=20, # 当pool_size不够时,允许临时创建的额外连接数
767
+ pool_recycle=3600, # 每小时回收一次连接
768
+ pool_pre_ping=True, # 使用前检查连接活性
769
+ pool_timeout=30 # 等待连接池中连接的最长时间(秒)
770
+ )
771
+ else:
772
+ eval_engine = self.engine
773
+ async with create_async_session(eval_engine) as eval_session:
774
+ use_cases = await self.get_use_case(target_prompt_id=prompt_id,session=eval_session)
762
775
 
763
776
  total_assertions = len(use_cases)
764
777
  result_cases = []
765
778
 
766
779
  async def evals_func(use_case,prompt_id,OutputFormat,ExtraFormats,version):
767
780
  try:
781
+
768
782
  # 这里将参数传入
769
783
  ai_result = await self.intellect_format(
770
784
  input_data = use_case.use_case,
@@ -775,16 +789,25 @@ class AsyncIntel():
775
789
  inference_save_case = False,
776
790
  )
777
791
  if ConTent_Function:
778
- ConTent_Function()
792
+ ConTent_Function(ai_result)
793
+
794
+ if AConTent_Function:
795
+ await AConTent_Function(ai_result)
796
+
779
797
  result_cases.append({"type":"Successful","case":use_case.use_case,"reply":f"pass"})
780
- use_case.output = ai_result
798
+ use_case.output = json.dumps(ai_result,ensure_ascii=False,indent=4)
799
+
800
+
781
801
  except IntellectRemoveFormatError as e:
782
802
  result_cases.append({"type":"FAILED","case":use_case.use_case,"reply":f"{e}"})
783
803
  use_case.output = f"{"FAILED"}-{e}"
804
+ use_case.faired_time +=1
805
+
784
806
  except Exception as e: # 捕获其他可能的错误
785
807
  result_cases.append({"type":"FAILED","case":use_case.use_case,"reply":f"Exp {e}"})
786
808
  use_case.output = f"{"FAILED"}-{e}"
787
- await session.commit()
809
+ use_case.faired_time +=1
810
+
788
811
 
789
812
  tasks = []
790
813
  for use_case in use_cases:
@@ -800,6 +823,7 @@ class AsyncIntel():
800
823
  await tqdm.gather(*tasks,total=len(tasks))
801
824
  # await asyncio.gather(*tasks, return_exceptions=False)
802
825
 
826
+ await eval_session.commit()
803
827
 
804
828
  successful_assertions = 0
805
829
  bad_case = []
@@ -818,7 +842,7 @@ class AsyncIntel():
818
842
 
819
843
 
820
844
 
821
- def draw_data(self):
845
+ def draw_data(self,save_html_path):
822
846
  df = self.eval_df
823
847
  # --- 可视化部分 ---
824
848
  fig = go.Figure()
@@ -899,18 +923,20 @@ class AsyncIntel():
899
923
  )
900
924
 
901
925
  fig.show()
902
- pass
926
+ if save_html_path:
927
+ fig.write_html(save_html_path)
903
928
 
904
- async def _evals(self,prompt_id, OutputFormat, ExtraFormats_list = [],**kwargs):
929
+ async def _evals(self,prompt_id, OutputFormat, ExtraFormats_list = [],database_url = None,**kwargs):
905
930
 
906
931
  status,score, total, bad_case = await self.intellect_format_eval(
907
932
  prompt_id=prompt_id,
908
933
  OutputFormat = OutputFormat,
909
934
  ExtraFormats = ExtraFormats_list,
910
935
  version = None,
936
+ database_url = database_url,
911
937
  **kwargs
912
938
  )
913
- self.df.loc[len(self.df)] = {"name":prompt_id,
939
+ self.eval_df.loc[len(self.eval_df)] = {"name":prompt_id,
914
940
  'status':status,"score":score,
915
941
  "total":total,"bad_case":bad_case}
916
942
 
@@ -0,0 +1,35 @@
1
+ from typing import Dict, Any, Optional, List
2
+ from pydantic import BaseModel, Field, model_validator, field_validator, RootModel
3
+ import re
4
+
5
+ class PushOrderRequest(BaseModel):
6
+ demand: str = Field(None, description="信息")
7
+ prompt_id: str = Field(..., description="提示词id")
8
+ action_type: str = Field(..., description="执行动作",min_length=1, max_length=10)
9
+
10
+ @field_validator('action_type')
11
+ @classmethod
12
+ def validate_action_type(cls, v: str) -> str:
13
+ if v in ['train','inference','summary','finetune','patch']:
14
+ return v
15
+ else:
16
+ raise ValueError(f"无效action_type: {v}")
17
+
18
+ class GetPromptRequest(BaseModel):
19
+ prompt_id: str = Field(..., description="提示词id")
20
+
21
+ class UpdatePromptRequest(BaseModel):
22
+ prompt_id: str = Field(..., description="提示词id")
23
+ prompt: str = Field(..., description="新的提示词")
24
+
25
+ class RollBackPromptRequest(BaseModel):
26
+ prompt_id: str = Field(..., description="提示词id")
27
+ version: str = Field(..., description="版本号")
28
+
29
+ class SyncDataBaseRequest(BaseModel):
30
+ slave_database_url: str = Field(None, description="从属数据库url")
31
+
32
+
33
+ class PromptResponse(BaseModel):
34
+ msg: str = Field(..., description="信息")
35
+ content: str = None
@@ -3,6 +3,7 @@
3
3
  from fastapi import APIRouter
4
4
  from pro_craft import Intel,AsyncIntel
5
5
  from pro_craft.utils import create_async_session
6
+ from .models import *
6
7
 
7
8
  def create_router(database_url: str,
8
9
  slave_database_url: str,
@@ -32,49 +33,100 @@ def create_router(database_url: str,
32
33
  tags=["prompt"] # 这里使用 Depends 确保每次请求都验证
33
34
  )
34
35
 
35
- @router.get("/push_order",
36
- description="可选 train,inference,summary,finetune,patch",)
37
- async def push_order(demand: str, prompt_id: str, action_type: str = "train"):
36
+ # 自动修改
37
+ @router.post("/push_order",
38
+ description="可选 train,inference,summary,finetune,patch",
39
+ response_model=PromptResponse,
40
+ )
41
+ async def push_order(request: PushOrderRequest):
38
42
  result = await intels.push_action_order(
39
- demand=demand,
40
- prompt_id=prompt_id,
41
- action_type=action_type
43
+ demand=request.demand,
44
+ prompt_id=request.prompt_id,
45
+ action_type=request.action_type
42
46
  )
43
- return {"message": "success", "result": result}
47
+ return PromptResponse(msg = "success",content=result)
44
48
 
45
- @router.get("/get_latest_prompt")
46
- async def get_latest_prompt(prompt_id: str):
49
+ # 人为干预
50
+
51
+ @router.get("/registered_prompt",
52
+ description="获取以注册的提示词",
53
+ response_model=PromptResponse)
54
+ async def get_prompt():
55
+ result = ["memorycard-format",
56
+ "memorycard-polish",
57
+ "memorycard-merge",
58
+ "memorycard-score",
59
+ "memorycard-generate-content",
60
+ "user-overview",
61
+ "user-relationship-extraction",
62
+ "avatar-brief",
63
+ "avatar-personality-extraction",
64
+ "avatar-desensitization",
65
+ "biograph-free-writer",
66
+ "biograph-paid-title",
67
+ "biograph-outline",
68
+ "biograph-brief",
69
+ "biograph-extract-person-name",
70
+ "biograph-extract-place",
71
+ "biograph-extract-material",
72
+ "biograph-writer"]
73
+
74
+ return PromptResponse(msg = "success",content=result)
75
+
76
+ @router.post("/get_prompt",
77
+ description="获得现行提示词",
78
+ response_model=PromptResponse)
79
+ async def get_prompt(request: GetPromptRequest):
47
80
  async with create_async_session(intels.engine) as session:
48
- result = await intels.get_prompts_from_sql(
49
- prompt_id=prompt_id,
81
+ result = await intels.get_prompt_safe(
82
+ prompt_id=request.prompt_id,
50
83
  session=session
51
84
  )
52
- return {"message": "success", "result": result}
53
-
54
- @router.get("/sync_database")
55
- async def sync_database():
56
- result = await intels.sync_prompt_data_to_database(slave_database_url)
57
- return {"message": "success","result":result}
85
+ return PromptResponse(msg = "success",content=result)
58
86
 
87
+ @router.post("/update_prompt",
88
+ description="更新现行提示词",
89
+ response_model=PromptResponse)
90
+ async def update_prompt(request: UpdatePromptRequest):
91
+ async with create_async_session(intels.engine) as session:
92
+ await intels.save_prompt(
93
+ prompt_id = request.prompt_id,
94
+ new_prompt = request.prompt,
95
+ use_case = "",
96
+ action_type = "inference",
97
+ demand = "上传",
98
+ score = 70,
99
+ session = session)
100
+ return PromptResponse(msg = "success",content=None)
59
101
 
60
- @router.get("/roll_back")
61
- async def roll_back(prompt_id:str,version:str):
102
+ @router.post("/rollback_prompt",
103
+ description="回滚现行提示词",
104
+ response_model=PromptResponse)
105
+ async def roll_back(request: RollBackPromptRequest):
62
106
  async with create_async_session(intels.engine) as session:
63
- result = await intels.get_prompts_from_sql(
64
- prompt_id=prompt_id,
65
- version = version,
107
+ result = await intels.get_prompt_safe(
108
+ prompt_id=request.prompt_id,
109
+ version = request.version,
66
110
  session=session
67
111
  )
68
- assert result.version == version
69
- await intels.save_prompt_increment_version(
70
- prompt_id = prompt_id,
112
+ assert result.version == request.version
113
+ await intels.save_prompt(
114
+ prompt_id = request.prompt_id,
71
115
  new_prompt = result.prompt,
72
116
  use_case = result.use_case,
73
117
  action_type = "inference",
74
118
  demand = "",
75
119
  score = 61,
76
120
  session = session)
77
- return {"message": "success"}
121
+ return PromptResponse(msg = "success",content=None)
122
+
123
+ #系统级别服务
78
124
 
125
+ @router.post("/sync_database")
126
+ async def sync_database(request: SyncDataBaseRequest):
127
+ slave_database_url = request.slave_database_url or slave_database_url
128
+ result = await intels.sync_production_database(slave_database_url)
129
+ return PromptResponse(msg = "success",content=result)
130
+
79
131
  return router
80
132
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pro-craft
3
- Version: 0.1.37
3
+ Version: 0.1.38
4
4
  Summary: Add your description here
5
5
  Requires-Python: >=3.12
6
6
  Description-Content-Type: text/markdown
@@ -6,14 +6,15 @@ pro_craft/utils.py,sha256=R1DFkS4dsm5dIhg8lLTgBBvItvIYyyojROdh-ykqiYk,5250
6
6
  pro_craft/code_helper/coder.py,sha256=L6pRQr0pYRIHrMFZ4-pO_tZf1koxgGgF3L7Vl-GIyjM,24687
7
7
  pro_craft/code_helper/designer.py,sha256=3gyCqrjcw61sHzDjUPKhL1LOAE8xWLLbNT8NlK2mFLc,4739
8
8
  pro_craft/prompt_craft/__init__.py,sha256=83ruWO1Oci-DWvdVhPqcQrgdZTNfbmK72VQCkWASk7A,80
9
- pro_craft/prompt_craft/async_.py,sha256=orxKDtxZSrx3uqHCOijqFcX2-436Cz2eakG03m33C9M,40426
9
+ pro_craft/prompt_craft/async_.py,sha256=bPQNottHtgfvUSPTBS7rw0Gvy3d0XQT1ffNiLPgWNDw,41653
10
10
  pro_craft/prompt_craft/new.py,sha256=ULjGGl95vmHrOs7XECJGlaqj1NE9BypE5WnFYhGugRY,25903
11
11
  pro_craft/prompt_craft/sync.py,sha256=4bms8Qvzq5QqgwHWwiyjrcl7hdkSqE7Kne5s3Ex8bBU,26217
12
12
  pro_craft/server/mcp/__init__.py,sha256=4dbl-lFcm0r2tkOP04OxqiZG2jR-rqF181qi2AfU6UA,123
13
13
  pro_craft/server/mcp/prompt.py,sha256=OZrsyUfSQMOY_KX7dWthW209adz5JfELsQ0ODfuQR44,1245
14
14
  pro_craft/server/router/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
- pro_craft/server/router/prompt.py,sha256=Wa4FfYRL6oeyA3F-79pmPeIH0Vo8wSEv7RH1lP6jXck,2907
16
- pro_craft-0.1.37.dist-info/METADATA,sha256=r2xyJiA_x6zoAv-GhhXVi6IG-V-Vt_YOJkpuN7Du-l0,1718
17
- pro_craft-0.1.37.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
18
- pro_craft-0.1.37.dist-info/top_level.txt,sha256=yqYDHArnYMWpeCxkmGRwlL6sJtxiOUnYylLDx9EOgFg,10
19
- pro_craft-0.1.37.dist-info/RECORD,,
15
+ pro_craft/server/router/models.py,sha256=0QlohI7aSVjYjMdXK9Rq19Dp7b2LnjLKIiArDzI1ufg,1272
16
+ pro_craft/server/router/prompt.py,sha256=muayKf9oHsFQpNE_ZBPflACv4QQhKbiS5vIREmeV-lg,4952
17
+ pro_craft-0.1.38.dist-info/METADATA,sha256=IMRCNvx1yYSjx1Mb-glmdiAH8Z-OOVgsSdKaIHPaZnI,1718
18
+ pro_craft-0.1.38.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
19
+ pro_craft-0.1.38.dist-info/top_level.txt,sha256=yqYDHArnYMWpeCxkmGRwlL6sJtxiOUnYylLDx9EOgFg,10
20
+ pro_craft-0.1.38.dist-info/RECORD,,