pro-craft 0.1.38__py3-none-any.whl → 0.1.40__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/database.py CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- from sqlalchemy import Column, Integer, String, Text, DateTime, text, UniqueConstraint, Boolean, func
2
+ from sqlalchemy import Column, Integer, String, Text, DateTime, text, UniqueConstraint, Boolean, func, Float
3
3
  from sqlalchemy.orm import declarative_base
4
4
 
5
5
  from datetime import datetime, timedelta
@@ -248,3 +248,72 @@ class UseCase(PromptBase):
248
248
  f"is_deleted='{self.is_deleted}...'>")
249
249
 
250
250
 
251
+ class EvalsInfo(PromptBase):
252
+ __tablename__ = 'ai_evals' # 数据库中的表名,你可以改成你希望的名字
253
+
254
+ # __table_args__ = (
255
+ # UniqueConstraint('prompt_id', 'use_case', name='_prompt_id_version_uc'),
256
+ # # 'name' 参数是可选的,用于给数据库中的约束指定一个名称,方便管理和调试
257
+ # )
258
+
259
+ # id (int, primary_key=True, autoincrement=True)
260
+ # 你的属性表中 id 为 int, true (not null), true (primary key), 0 (length), ASC (key order), true (auto increment)
261
+ id = Column(
262
+ Integer,
263
+ primary_key=True,
264
+ autoincrement=True, # 自动递增
265
+ nullable=False, # 不能为空
266
+ comment="Primary key ID"
267
+ )
268
+
269
+ # prompt_id (varchar 255, not null, unique)
270
+ # 你的属性表中 prompt_id 为 varchar, 255 (length), true (not null)
271
+ prompt_id = Column(
272
+ String(255), # VARCHAR 类型,长度 255
273
+ nullable=False, # 不能为空 # 必须是唯一的,这会创建唯一索引
274
+ comment="Unique identifier for the prompt"
275
+ )
276
+ status = Column(
277
+ String(255), # VARCHAR 类型,长度 255
278
+ nullable=False, # 不能为空 # 必须是唯一的,这会创建唯一索引
279
+ comment="通过/未通过"
280
+ )
281
+
282
+ score = Column(
283
+ Float,
284
+ nullable=False, # 不能为空
285
+ comment="失败次数"
286
+ )
287
+
288
+ total = Column(
289
+ Integer,
290
+ nullable=False, # 不能为空
291
+ comment="失败次数"
292
+ )
293
+
294
+ # prompt (text, not null)
295
+ # 你的属性表中 prompt 为 text, true (not null)
296
+ bad_case = Column(
297
+ Text, # TEXT 类型,适用于长文本
298
+ nullable=False, # 不能为空
299
+ comment="用例"
300
+ )
301
+
302
+ timestamp = Column(
303
+ DateTime,
304
+ nullable=False, # 不能为空
305
+ server_default=text('CURRENT_TIMESTAMP'),
306
+ onupdate=text('CURRENT_TIMESTAMP'),
307
+ comment="时间戳"
308
+ )
309
+
310
+
311
+ is_deleted = Column(Boolean, default=False, server_default=text('0'))
312
+
313
+ # 定义 __repr__ 方法以便打印对象时有清晰的表示
314
+ def __repr__(self):
315
+ return (f"<Prompt(id={self.id}, prompt_id='{self.prompt_id}', "
316
+ f"status='{self.status}...', score='{self.score}')>"
317
+ f"total='{self.total}...', score='{self.score}')>"
318
+ f"is_deleted='{self.is_deleted}...'>")
319
+
@@ -421,6 +421,10 @@ class AsyncIntel():
421
421
  inference_save_case = True,
422
422
  change_case = False,
423
423
  ):
424
+ """
425
+ 自定自动化执行命令的方法,
426
+ 不涉及严格的校验, 主要职能在自动化的修改提示词, 或者管理提示词上
427
+ """
424
428
  if isinstance(input_data,dict):
425
429
  input_ = json.dumps(input_data,ensure_ascii=False)
426
430
  elif isinstance(input_data,str):
@@ -634,7 +638,16 @@ class AsyncIntel():
634
638
  ExtraFormats: list[object] = [],
635
639
  version: str = None,
636
640
  inference_save_case = True,
641
+ ConTent_Function = None,
642
+ AConTent_Function = None,
637
643
  ):
644
+ """
645
+ 这个format 是严格校验模式, 是interllect 的增强版, 会主动校验内容,并及时抛出异常(或者伺机修正)
646
+ ConTent_Function
647
+ AConTent_Function
648
+ 两种方式的传入方式, 内容未通过就抛出异常
649
+
650
+ """
638
651
 
639
652
  base_format_prompt = """
640
653
  按照一定格式输出, 以便可以通过如下校验
@@ -676,6 +689,12 @@ class AsyncIntel():
676
689
 
677
690
  except Exception as e:
678
691
  raise Exception(f"Error {prompt_id} : {e}") from e
692
+
693
+ if ConTent_Function:
694
+ ConTent_Function(ai_result)
695
+
696
+ if AConTent_Function:
697
+ await AConTent_Function(ai_result)
679
698
 
680
699
  return ai_result
681
700
 
@@ -686,6 +705,7 @@ class AsyncIntel():
686
705
  ExtraFormats: list[object] = [],
687
706
  version: str = None,
688
707
  inference_save_case = True,
708
+ **kwargs,
689
709
  ):
690
710
 
691
711
  async with create_async_session(self.engine) as session:
@@ -705,6 +725,7 @@ class AsyncIntel():
705
725
  ExtraFormats = ExtraFormats,
706
726
  version = version,
707
727
  inference_save_case = inference_save_case,
728
+ **kwargs,
708
729
  )
709
730
  )
710
731
  results = await asyncio.gather(*tasks, return_exceptions=False)
@@ -717,8 +738,7 @@ class AsyncIntel():
717
738
  # 修改逻辑
718
739
  assert kwargs.get('input_data') # 要求一定要有data入参
719
740
  input_data = kwargs.get('input_data')
720
- OutputFormat = kwargs.get('OutputFormat','')
721
-
741
+ kwargs.pop(input_data)
722
742
  if isinstance(input_data,dict):
723
743
  input_ = output_ = json.dumps(input_data,ensure_ascii=False)
724
744
  elif isinstance(input_data,str):
@@ -727,7 +747,8 @@ class AsyncIntel():
727
747
  output_ = await self.intellect_format(
728
748
  input_data = input_data,
729
749
  prompt_id = prompt_id,
730
- OutputFormat = OutputFormat,
750
+ **kwargs,
751
+
731
752
  )
732
753
 
733
754
  #######
@@ -787,12 +808,9 @@ class AsyncIntel():
787
808
  ExtraFormats = ExtraFormats,
788
809
  version = version,
789
810
  inference_save_case = False,
811
+ ConTent_Function = ConTent_Function,
812
+ AConTent_Function = AConTent_Function,
790
813
  )
791
- if ConTent_Function:
792
- ConTent_Function(ai_result)
793
-
794
- if AConTent_Function:
795
- await AConTent_Function(ai_result)
796
814
 
797
815
  result_cases.append({"type":"Successful","case":use_case.use_case,"reply":f"pass"})
798
816
  use_case.output = json.dumps(ai_result,ensure_ascii=False,indent=4)
@@ -835,13 +853,22 @@ class AsyncIntel():
835
853
 
836
854
  success_rate = (successful_assertions / total_assertions) * 100
837
855
 
856
+
838
857
  if success_rate >= MIN_SUCCESS_RATE:
858
+ self.eval_df.loc[len(self.eval_df)] = {"name":prompt_id,
859
+ 'status':"通过",
860
+ "score":success_rate,
861
+ "total":str(total_assertions),
862
+ "bad_case":json.dumps(bad_case,ensure_ascii=False)}
839
863
  return "通过", success_rate, str(total_assertions), json.dumps(bad_case,ensure_ascii=False),
840
864
  else:
865
+ self.eval_df.loc[len(self.eval_df)] = {"name":prompt_id,
866
+ 'status':"未通过",
867
+ "score":success_rate,
868
+ "total":str(total_assertions),
869
+ "bad_case":json.dumps(bad_case,ensure_ascii=False)}
841
870
  return "未通过",success_rate, str(total_assertions), json.dumps(bad_case,ensure_ascii=False),
842
871
 
843
-
844
-
845
872
  def draw_data(self,save_html_path):
846
873
  df = self.eval_df
847
874
  # --- 可视化部分 ---
@@ -926,18 +953,5 @@ class AsyncIntel():
926
953
  if save_html_path:
927
954
  fig.write_html(save_html_path)
928
955
 
929
- async def _evals(self,prompt_id, OutputFormat, ExtraFormats_list = [],database_url = None,**kwargs):
930
-
931
- status,score, total, bad_case = await self.intellect_format_eval(
932
- prompt_id=prompt_id,
933
- OutputFormat = OutputFormat,
934
- ExtraFormats = ExtraFormats_list,
935
- version = None,
936
- database_url = database_url,
937
- **kwargs
938
- )
939
- self.eval_df.loc[len(self.eval_df)] = {"name":prompt_id,
940
- 'status':status,"score":score,
941
- "total":total,"bad_case":bad_case}
942
956
 
943
957
  # 整体测试d, 测试未通过d, 大模型调整再测试, 依旧不通过, 大模型裂变, 仍不通过, 互换人力
@@ -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
@@ -1,44 +1,77 @@
1
1
  from mcp.server.fastmcp import FastMCP
2
2
 
3
- from pro_craft import Intel
3
+ from pro_craft import Intel,AsyncIntel
4
+ from .models import *
4
5
 
5
6
  def create_mcp(database_url: str,
6
7
  slave_database_url: str,
7
- model_name: str):
8
+ model_name: str,
9
+ logger = None):
8
10
  # region MCP Weather
9
- mcp = FastMCP("PromptManager")
11
+ mcp = FastMCP("Prompt")
10
12
 
11
- intels = Intel(
13
+ intels = AsyncIntel(
12
14
  database_url=database_url,
13
- model_name=model_name
15
+ model_name=model_name,
16
+ logger=logger
14
17
  )
15
18
 
16
19
  @mcp.tool()
17
- def push_order(demand: str, prompt_id: str, action_type: str = "train") -> str:
18
- result = intels.push_action_order(
19
- demand=demand,
20
- prompt_id=prompt_id,
21
- action_type=action_type
22
- )
23
- return {"message": "success", "result": result}
24
-
25
- @mcp.tool()
26
- def get_latest_prompt(prompt_id: str) -> str:
27
- with create_session(intels.engine) as session:
28
- result = intels.get_prompts_from_sql(
20
+ async def push_order(demand: str, prompt_id: str, action_type: str):
21
+ """
22
+ 希望大模型进行哪种模式的调整
23
+ demand: str = Field(None, description="信息")
24
+ prompt_id: str = Field(..., description="提示词id")
25
+ action_type: str = Field(..., description="执行动作",min_length=1, max_length=10)
26
+ """
27
+ try:
28
+ PushOrderRequest(demand=demand,prompt_id=prompt_id,action_type=action_type)
29
+ result = await intels.push_action_order(
30
+ demand=demand,
29
31
  prompt_id=prompt_id,
30
- session=session
32
+ action_type=action_type
31
33
  )
32
- return {"message": "success", "result": result}
34
+ return PromptResponse(msg = "success",content=result)
35
+ except Exception as e:
36
+ return f"Error : {e}"
37
+
38
+ @mcp.tool()
39
+ async def get_registered_prompt():
40
+ "获取以注册的可修改的提示词id"
41
+ try:
42
+ result = ["memorycard-format",
43
+ "memorycard-polish",
44
+ "memorycard-merge",
45
+ "memorycard-score",
46
+ "memorycard-generate-content",
47
+ "user-overview",
48
+ "user-relationship-extraction",
49
+ "avatar-brief",
50
+ "avatar-personality-extraction",
51
+ "avatar-desensitization",
52
+ "biograph-free-writer",
53
+ "biograph-paid-title",
54
+ "biograph-outline",
55
+ "biograph-brief",
56
+ "biograph-extract-person-name",
57
+ "biograph-extract-place",
58
+ "biograph-extract-material",
59
+ "biograph-writer"]
60
+
61
+ return PromptResponse(msg = "success",content=result)
62
+ except Exception as e:
63
+ return f"Error : {e}"
33
64
 
34
65
 
35
66
  @mcp.tool()
36
- def sync_database() -> str:
37
- result = intels.sync_prompt_data_to_database(slave_database_url)
38
- return {"message": "success","result":result}
39
-
40
- return mcp
67
+ async def sync_database():
68
+ try:
69
+ result = await intels.sync_production_database(slave_database_url)
70
+ return PromptResponse(msg = "success",content=result)
71
+ except Exception as e:
72
+ return f"Error : {e}"
41
73
 
74
+ return mcp
42
75
 
43
76
  if __name__ == "__main__":
44
77
  mcp = create_mcp()
@@ -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 fastapi import FastAPI, HTTPException
6
7
  from .models import *
7
8
 
8
9
  def create_router(database_url: str,
@@ -39,12 +40,17 @@ def create_router(database_url: str,
39
40
  response_model=PromptResponse,
40
41
  )
41
42
  async def push_order(request: PushOrderRequest):
42
- result = await intels.push_action_order(
43
- demand=request.demand,
44
- prompt_id=request.prompt_id,
45
- action_type=request.action_type
46
- )
47
- return PromptResponse(msg = "success",content=result)
43
+ try:
44
+ result = await intels.push_action_order(
45
+ demand=request.demand,
46
+ prompt_id=request.prompt_id,
47
+ action_type=request.action_type
48
+ )
49
+ return PromptResponse(msg = "success",content=result)
50
+ except Exception as e:
51
+ raise HTTPException(
52
+ status_code=500, detail=f"{e}"
53
+ )
48
54
 
49
55
  # 人为干预
50
56
 
@@ -52,81 +58,106 @@ def create_router(database_url: str,
52
58
  description="获取以注册的提示词",
53
59
  response_model=PromptResponse)
54
60
  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)
61
+ try:
62
+ result = ["memorycard-format",
63
+ "memorycard-polish",
64
+ "memorycard-merge",
65
+ "memorycard-score",
66
+ "memorycard-generate-content",
67
+ "user-overview",
68
+ "user-relationship-extraction",
69
+ "avatar-brief",
70
+ "avatar-personality-extraction",
71
+ "avatar-desensitization",
72
+ "biograph-free-writer",
73
+ "biograph-paid-title",
74
+ "biograph-outline",
75
+ "biograph-brief",
76
+ "biograph-extract-person-name",
77
+ "biograph-extract-place",
78
+ "biograph-extract-material",
79
+ "biograph-writer"]
75
80
 
81
+ return PromptResponse(msg = "success",content='\n'.join(result))
82
+ except Exception as e:
83
+ raise HTTPException(
84
+ status_code=500, detail=f"{e}"
85
+ )
76
86
  @router.post("/get_prompt",
77
87
  description="获得现行提示词",
78
88
  response_model=PromptResponse)
79
89
  async def get_prompt(request: GetPromptRequest):
80
- async with create_async_session(intels.engine) as session:
81
- result = await intels.get_prompt_safe(
82
- prompt_id=request.prompt_id,
83
- session=session
84
- )
85
- return PromptResponse(msg = "success",content=result)
90
+ try:
91
+ async with create_async_session(intels.engine) as session:
92
+ result = await intels.get_prompt_safe(
93
+ prompt_id=request.prompt_id,
94
+ session=session
95
+ )
96
+ return PromptResponse(msg = "success",content=result)
86
97
 
98
+ except Exception as e:
99
+ raise HTTPException(
100
+ status_code=500, detail=f"{e}"
101
+ )
102
+
87
103
  @router.post("/update_prompt",
88
104
  description="更新现行提示词",
89
105
  response_model=PromptResponse)
90
106
  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)
107
+ try:
108
+ async with create_async_session(intels.engine) as session:
109
+ await intels.save_prompt(
110
+ prompt_id = request.prompt_id,
111
+ new_prompt = request.prompt,
112
+ use_case = "",
113
+ action_type = "inference",
114
+ demand = "上传",
115
+ score = 70,
116
+ session = session)
117
+ return PromptResponse(msg = "success",content=None)
118
+ except Exception as e:
119
+ raise HTTPException(
120
+ status_code=500, detail=f"{e}"
121
+ )
101
122
 
102
123
  @router.post("/rollback_prompt",
103
124
  description="回滚现行提示词",
104
125
  response_model=PromptResponse)
105
126
  async def roll_back(request: RollBackPromptRequest):
106
- async with create_async_session(intels.engine) as session:
107
- result = await intels.get_prompt_safe(
108
- prompt_id=request.prompt_id,
109
- version = request.version,
110
- session=session
127
+ try:
128
+ async with create_async_session(intels.engine) as session:
129
+ result = await intels.get_prompt_safe(
130
+ prompt_id=request.prompt_id,
131
+ version = request.version,
132
+ session=session
133
+ )
134
+ assert result.version == request.version
135
+ await intels.save_prompt(
136
+ prompt_id = request.prompt_id,
137
+ new_prompt = result.prompt,
138
+ use_case = result.use_case,
139
+ action_type = "inference",
140
+ demand = "",
141
+ score = 61,
142
+ session = session)
143
+ return PromptResponse(msg = "success",content=None)
144
+ except Exception as e:
145
+ raise HTTPException(
146
+ status_code=500, detail=f"{e}"
111
147
  )
112
- assert result.version == request.version
113
- await intels.save_prompt(
114
- prompt_id = request.prompt_id,
115
- new_prompt = result.prompt,
116
- use_case = result.use_case,
117
- action_type = "inference",
118
- demand = "",
119
- score = 61,
120
- session = session)
121
- return PromptResponse(msg = "success",content=None)
148
+
122
149
 
123
150
  #系统级别服务
124
151
 
125
152
  @router.post("/sync_database")
126
153
  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
-
154
+ try:
155
+ slave_database_url = request.slave_database_url or slave_database_url
156
+ result = await intels.sync_production_database(slave_database_url)
157
+ return PromptResponse(msg = "success",content=result)
158
+ except Exception as e:
159
+ raise HTTPException(
160
+ status_code=500, detail=f"{e}"
161
+ )
131
162
  return router
132
163
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pro-craft
3
- Version: 0.1.38
3
+ Version: 0.1.40
4
4
  Summary: Add your description here
5
5
  Requires-Python: >=3.12
6
6
  Description-Content-Type: text/markdown
@@ -9,6 +9,7 @@ Requires-Dist: anyio>=4.11.0
9
9
  Requires-Dist: db-help>=0.2.2
10
10
  Requires-Dist: fastapi>=0.119.0
11
11
  Requires-Dist: llmada>=1.1.11
12
+ Requires-Dist: mcp[cli]>=1.19.0
12
13
  Requires-Dist: plotly>=6.3.1
13
14
  Requires-Dist: pyyaml>=6.0.3
14
15
  Requires-Dist: toml>=0.10.2
@@ -1,20 +1,21 @@
1
1
  pro_craft/__init__.py,sha256=CkERhdDQyrPWpOb5nArMt2UCcX8STJLF7JC2x7yTBYM,515
2
- pro_craft/database.py,sha256=cbUcy4_e9RgcDVBNMvERNmTv_pZWgd4ox4a4drBWS6w,9310
2
+ pro_craft/database.py,sha256=qA9MP5oNOPp7YmZPg6GQwohitNdt2PwvYBFlYH_jX-A,11737
3
3
  pro_craft/file_manager.py,sha256=abVAlJ07_egWNuTj4JiP4me8NloQrsXGNd-SP63ab94,3738
4
4
  pro_craft/log.py,sha256=Ft5pKvdmNeXg7BPtc1H8vBi5r6p0vyKP5X_HVEEwE8U,3261
5
5
  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=bPQNottHtgfvUSPTBS7rw0Gvy3d0XQT1ffNiLPgWNDw,41653
9
+ pro_craft/prompt_craft/async_.py,sha256=bDcXQ3rfLOFOD_d5ImsBkP6FeWj-n69w6KfFIUE-5P4,42529
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
- pro_craft/server/mcp/prompt.py,sha256=OZrsyUfSQMOY_KX7dWthW209adz5JfELsQ0ODfuQR44,1245
13
+ pro_craft/server/mcp/models.py,sha256=0QlohI7aSVjYjMdXK9Rq19Dp7b2LnjLKIiArDzI1ufg,1272
14
+ pro_craft/server/mcp/prompt.py,sha256=zZ58zb422vhwoL_uYCVBdOwOR-xy69MLQ5tyVfbpBlU,2505
14
15
  pro_craft/server/router/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
16
  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,,
17
+ pro_craft/server/router/prompt.py,sha256=oaFUfBmOtQYYD1CeSXLv1zwRID1gZ7oZgMITjX67A-o,6086
18
+ pro_craft-0.1.40.dist-info/METADATA,sha256=wpwBOFs1LBZHNscFoi0Aa33Jai7XZqlWmRUeUp59Zx0,1750
19
+ pro_craft-0.1.40.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
20
+ pro_craft-0.1.40.dist-info/top_level.txt,sha256=yqYDHArnYMWpeCxkmGRwlL6sJtxiOUnYylLDx9EOgFg,10
21
+ pro_craft-0.1.40.dist-info/RECORD,,