mm-qa-mcp 3.0.1__tar.gz → 3.0.3__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.
- {mm_qa_mcp-3.0.1/mm_qa_mcp.egg-info → mm_qa_mcp-3.0.3}/PKG-INFO +2 -1
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/minimax_qa_mcp/server.py +27 -3
- mm_qa_mcp-3.0.3/minimax_qa_mcp/src/auto_case/case_write.py +182 -0
- mm_qa_mcp-3.0.3/minimax_qa_mcp/src/auto_case/pdf_jiexi.py +28 -0
- mm_qa_mcp-3.0.3/minimax_qa_mcp/utils/__init__.py +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3/mm_qa_mcp.egg-info}/PKG-INFO +2 -1
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/mm_qa_mcp.egg-info/SOURCES.txt +3 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/mm_qa_mcp.egg-info/requires.txt +1 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/pyproject.toml +3 -2
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/MANIFEST.in +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/README.md +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/minimax_qa_mcp/__init__.py +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/minimax_qa_mcp/conf/__init__.py +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/minimax_qa_mcp/conf/conf.ini +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/minimax_qa_mcp/src/__init__.py +0 -0
- {mm_qa_mcp-3.0.1/minimax_qa_mcp/src/gateway_case → mm_qa_mcp-3.0.3/minimax_qa_mcp/src/auto_case}/__init__.py +0 -0
- {mm_qa_mcp-3.0.1/minimax_qa_mcp/src/grafana → mm_qa_mcp-3.0.3/minimax_qa_mcp/src/gateway_case}/__init__.py +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/minimax_qa_mcp/src/gateway_case/get_case.py +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/minimax_qa_mcp/src/generator_case/__init__.py +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/minimax_qa_mcp/src/generator_case/generator_case.py +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/minimax_qa_mcp/src/generator_case/generator_case_langchain.py +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/minimax_qa_mcp/src/get_full_api_call_chain/__init__.py +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/minimax_qa_mcp/src/get_full_api_call_chain/get_full_api_call_chain.py +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/minimax_qa_mcp/src/get_weaviate_info/__init__.py +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/minimax_qa_mcp/src/get_weaviate_info/get_weaviate_info.py +0 -0
- {mm_qa_mcp-3.0.1/minimax_qa_mcp/utils → mm_qa_mcp-3.0.3/minimax_qa_mcp/src/grafana}/__init__.py +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/minimax_qa_mcp/src/grafana/service.py +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/minimax_qa_mcp/src/query_segments/__init__.py +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/minimax_qa_mcp/src/query_segments/query_segments.py +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/minimax_qa_mcp/src/xmind2markdown/__init__.py +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/minimax_qa_mcp/src/xmind2markdown/xmind_to_markdown.py +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/minimax_qa_mcp/utils/logger.py +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/minimax_qa_mcp/utils/mysql_op.py +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/minimax_qa_mcp/utils/utils.py +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/mm_qa_mcp.egg-info/dependency_links.txt +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/mm_qa_mcp.egg-info/entry_points.txt +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/mm_qa_mcp.egg-info/top_level.txt +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/setup.cfg +0 -0
- {mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/setup.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: mm_qa_mcp
|
3
|
-
Version: 3.0.
|
3
|
+
Version: 3.0.3
|
4
4
|
Summary: QA agent service 集合
|
5
5
|
Author-email: xingyun <xingyun@minimaxi.com>
|
6
6
|
License-Expression: MIT
|
@@ -60,6 +60,7 @@ Requires-Dist: validators<1.0.0,>=0.21.2
|
|
60
60
|
Requires-Dist: wcwidth>=0.2.13
|
61
61
|
Requires-Dist: weaviate-client<4.0.0,>=3.25.0
|
62
62
|
Requires-Dist: zstandard>=0.23.0
|
63
|
+
Requires-Dist: pdfplumber>=0.11.6
|
63
64
|
Provides-Extra: dev
|
64
65
|
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
65
66
|
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
@@ -2,6 +2,7 @@
|
|
2
2
|
import asyncio
|
3
3
|
import sys
|
4
4
|
import os
|
5
|
+
import json
|
5
6
|
|
6
7
|
# 将项目根目录添加到Python路径中
|
7
8
|
current_dir = os.path.dirname(os.path.abspath(__file__))
|
@@ -18,7 +19,9 @@ from minimax_qa_mcp.src.generator_case.generator_case import GeneratorCase
|
|
18
19
|
from minimax_qa_mcp.src.get_weaviate_info.get_weaviate_info import GetWeaviateInfo
|
19
20
|
from minimax_qa_mcp.src.grafana.service import GetFromGrafana, GetApiFromGrafana
|
20
21
|
from minimax_qa_mcp.src.gateway_case.get_case import CaseGrafanaService
|
21
|
-
from minimax_qa_mcp.src.query_segments.query_segments import query_main, TYPE_API, TYPE_FUNC, TYPE_CODE, TYPE_ANY,
|
22
|
+
from minimax_qa_mcp.src.query_segments.query_segments import query_main, TYPE_API, TYPE_FUNC, TYPE_CODE, TYPE_ANY, \
|
23
|
+
TYPE_FUNC_DETAIL
|
24
|
+
from minimax_qa_mcp.src.auto_case.case_write import PDFWeaviateInfo
|
22
25
|
from minimax_qa_mcp.src.get_full_api_call_chain.get_full_api_call_chain import GetFullApiCallChain
|
23
26
|
|
24
27
|
# Initialize FastMCP server
|
@@ -162,6 +165,24 @@ async def get_weaviate_info(input_data: str) -> dict:
|
|
162
165
|
return result
|
163
166
|
|
164
167
|
|
168
|
+
@mcp.tool()
|
169
|
+
async def get_auto_case(file_path: str, ref_case_name: str, use_moxing: bool = True) -> dict:
|
170
|
+
"""
|
171
|
+
根据给定的文件路径和参考case名称,自动生成case
|
172
|
+
|
173
|
+
Args:
|
174
|
+
file_path: 需要处理的文件路径
|
175
|
+
ref_case_name: 参考的case名称
|
176
|
+
use_moxing: 是否使用模型,开关默认开启
|
177
|
+
Returns:
|
178
|
+
包含自动生成case的相关信息的字典
|
179
|
+
"""
|
180
|
+
# 调用 PDFWeaviateInfo.get_pdf_and_weaviate_info 方法
|
181
|
+
prd_case = PDFWeaviateInfo(file_path, ref_case_name, use_moxing=use_moxing)
|
182
|
+
case_response = prd_case.get_pdf_and_weaviate_info()
|
183
|
+
return case_response
|
184
|
+
|
185
|
+
|
165
186
|
@mcp.tool()
|
166
187
|
async def get_full_api_call_chain(api_path: str) -> dict:
|
167
188
|
"""
|
@@ -171,6 +192,9 @@ async def get_full_api_call_chain(api_path: str) -> dict:
|
|
171
192
|
Return:
|
172
193
|
API调用链信息
|
173
194
|
"""
|
195
|
+
# 判断api_path是不是'/'开头 不是的话 拼接
|
196
|
+
if not api_path.startswith('/'):
|
197
|
+
api_path = '/' + api_path
|
174
198
|
logger.info(f"===== The input params is :{api_path}")
|
175
199
|
|
176
200
|
api_call_chain = GetFullApiCallChain(api_path)
|
@@ -190,10 +214,10 @@ def run_server():
|
|
190
214
|
# 确保当前工作目录在sys.path中
|
191
215
|
if os.getcwd() not in sys.path:
|
192
216
|
sys.path.insert(0, os.getcwd())
|
193
|
-
|
217
|
+
|
194
218
|
# 输出启动信息
|
195
219
|
print("Starting Minimax QA MCP server from CLI")
|
196
|
-
|
220
|
+
|
197
221
|
# 调用主函数
|
198
222
|
main()
|
199
223
|
|
@@ -0,0 +1,182 @@
|
|
1
|
+
import functools
|
2
|
+
import re
|
3
|
+
from minimax_qa_mcp.src.get_weaviate_info.get_weaviate_info import GetWeaviateInfo
|
4
|
+
from minimax_qa_mcp.src.auto_case.pdf_jiexi import read_pdf_text
|
5
|
+
import logging
|
6
|
+
import requests
|
7
|
+
import json
|
8
|
+
import time
|
9
|
+
|
10
|
+
# 设置日志
|
11
|
+
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
12
|
+
logger = logging.getLogger('生成日志case')
|
13
|
+
|
14
|
+
|
15
|
+
def retry(max_attempts=3, wait=2):
|
16
|
+
def decorator(func):
|
17
|
+
@functools.wraps(func)
|
18
|
+
def wrapper(*args, **kwargs):
|
19
|
+
last_exception = None
|
20
|
+
for attempt in range(1, max_attempts + 1):
|
21
|
+
try:
|
22
|
+
return func(*args, **kwargs)
|
23
|
+
except Exception as e:
|
24
|
+
logger.warning(f"第{attempt}次请求异常:{e}")
|
25
|
+
last_exception = e
|
26
|
+
if attempt < max_attempts:
|
27
|
+
time.sleep(wait)
|
28
|
+
logger.error(f"请求失败,已重试{max_attempts}次。")
|
29
|
+
return f"请求失败,已重试{max_attempts}次,最后异常:{last_exception}"
|
30
|
+
|
31
|
+
return wrapper
|
32
|
+
|
33
|
+
return decorator
|
34
|
+
|
35
|
+
|
36
|
+
class PDFWeaviateInfo(GetWeaviateInfo):
|
37
|
+
def __init__(self, prd_path, input_question,use_moxing, is_need_module=False):
|
38
|
+
super().__init__(input_question, is_need_module)
|
39
|
+
self.prd_path = prd_path
|
40
|
+
self.timeout = 120
|
41
|
+
self.use_moxing = use_moxing
|
42
|
+
|
43
|
+
def get_pdf_and_weaviate_info(self):
|
44
|
+
# 解析PDF内容
|
45
|
+
pdf_text = read_pdf_text(self.prd_path)
|
46
|
+
# 获取Weaviate信息
|
47
|
+
weaviate_info = self.get_knowledge()
|
48
|
+
# 拼接结果
|
49
|
+
result = {
|
50
|
+
'pdf_text': pdf_text,
|
51
|
+
'weaviate_info': weaviate_info
|
52
|
+
}
|
53
|
+
|
54
|
+
case_response = self.call_model(result)
|
55
|
+
return case_response
|
56
|
+
|
57
|
+
def call_model(self, prd_content, max_attempts=5, wait=6):
|
58
|
+
"""
|
59
|
+
调用模型,给出参考case
|
60
|
+
Args:
|
61
|
+
prd_content: prd信息+参考case
|
62
|
+
max_attempts: 最大重试次数
|
63
|
+
wait: 重试等待时间(秒)
|
64
|
+
|
65
|
+
Returns:
|
66
|
+
content内容拼接后的字符串,或错误信息
|
67
|
+
"""
|
68
|
+
prd_case = prd_content.get("pdf_text", "")
|
69
|
+
prompt = f"需求内容:{prd_case}"
|
70
|
+
cankao_case = prd_content.get("weaviate_info", {}).get("results", [])
|
71
|
+
for i, content in enumerate(cankao_case):
|
72
|
+
case_content = content.get('content', '').strip()
|
73
|
+
case_content_clean = re.sub(r'\s+', ' ', case_content)
|
74
|
+
prompt += f"参考用例{i + 1}、用例名称:{content.get('title', 'N/A')}、用例内容:{case_content_clean}\n\n"
|
75
|
+
break
|
76
|
+
|
77
|
+
prompt += " 帮我写一份测试用例,参考用例若与本次需求相关可借鉴其设计思路和细节,不相关则忽略,用例设计需覆盖功能、边界、异常、安全、兼容性、性能、数据一致性、UI等多个维度,每个测试用例需包含:用例名称、用例编号、前置条件、测试步骤、预期结果、测试环境,用例内容要具体、细致,测试步骤要可操作,预期结果要明确"
|
78
|
+
# prompt += "帮我写一份测试用例,参考用例若与本次需求相关可借鉴其设计思路和细节,不相关则忽略"
|
79
|
+
clean_params = prompt.replace('\\"', "'")
|
80
|
+
prd_prompt = clean_params.replace("\n", " ").strip()
|
81
|
+
|
82
|
+
if not self.use_moxing:
|
83
|
+
return prd_prompt
|
84
|
+
|
85
|
+
payload = {
|
86
|
+
"scene": "qa_agent",
|
87
|
+
"params": {
|
88
|
+
"user_content": prd_prompt
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
logger.info(f"==== 发送请求调用模型 ======")
|
93
|
+
# print(payload)
|
94
|
+
last_exception = None
|
95
|
+
for attempt in range(1, max_attempts + 1):
|
96
|
+
try:
|
97
|
+
response = requests.post(
|
98
|
+
self.api_url,
|
99
|
+
json=payload,
|
100
|
+
headers={'Content-Type': 'application/json'},
|
101
|
+
verify=False,
|
102
|
+
timeout=self.timeout
|
103
|
+
)
|
104
|
+
|
105
|
+
# logger.info(f"API响应状态码: {response.status_code}")
|
106
|
+
# logger.info(f"API响应内容: {response.text}")
|
107
|
+
|
108
|
+
if response.status_code != 200:
|
109
|
+
logger.error(f"API请求失败,状态码: {response.status_code}")
|
110
|
+
raise Exception(f"API请求失败,状态码: {response.status_code}")
|
111
|
+
|
112
|
+
try:
|
113
|
+
resp_json = response.json()
|
114
|
+
if 'response' in resp_json:
|
115
|
+
try:
|
116
|
+
model_response = json.loads(resp_json['response'])
|
117
|
+
if 'choices' in model_response and isinstance(model_response['choices'], list):
|
118
|
+
# 兼容OpenAI/Claude等大模型返回结构
|
119
|
+
for choice in model_response['choices']:
|
120
|
+
message = choice.get('message', {})
|
121
|
+
content = message.get('content')
|
122
|
+
if content:
|
123
|
+
content += "\n- 需求内容" + f"{prd_case}"
|
124
|
+
return content
|
125
|
+
# 如果没找到content,兜底返回整个choices
|
126
|
+
return str(model_response['choices'])
|
127
|
+
elif 'content' in model_response and isinstance(model_response['content'], list):
|
128
|
+
# 兼容content直接在顶层的情况
|
129
|
+
text_content = ""
|
130
|
+
for item in model_response['content']:
|
131
|
+
if item.get('type') == 'text':
|
132
|
+
text_content += item.get('text', '')
|
133
|
+
text_content += "\n- 需求内容" + f"{prd_case}"
|
134
|
+
return text_content
|
135
|
+
else:
|
136
|
+
return str(model_response)
|
137
|
+
except json.JSONDecodeError as json_e:
|
138
|
+
logger.error(f"解析二层JSON失败: {json_e}")
|
139
|
+
# 抛出异常,触发重试机制
|
140
|
+
raise Exception(f"解析二层JSON失败: {json_e}")
|
141
|
+
except Exception as e:
|
142
|
+
logger.error(f"处理二层JSON时发生未知错误: {e}")
|
143
|
+
# 抛出异常,触发重试机制
|
144
|
+
raise Exception(f"处理二层JSON时发生未知错误: {e}")
|
145
|
+
|
146
|
+
# 如果没有response字段,直接返回原始响应
|
147
|
+
return response.text
|
148
|
+
|
149
|
+
except json.JSONDecodeError as json_e:
|
150
|
+
logger.error(f"解析一层JSON失败: {json_e}")
|
151
|
+
# 抛出异常,触发重试机制
|
152
|
+
raise Exception(f"解析一层JSON失败: {json_e}")
|
153
|
+
except Exception as e:
|
154
|
+
logger.error(f"处理响应时发生未知错误: {e}")
|
155
|
+
# 抛出异常,触发重试机制
|
156
|
+
raise Exception(f"处理响应时发生未知错误: {e}")
|
157
|
+
|
158
|
+
except requests.RequestException as e:
|
159
|
+
logger.warning(f"第{attempt}次网络请求异常:{e}")
|
160
|
+
last_exception = e
|
161
|
+
if attempt < max_attempts:
|
162
|
+
time.sleep(wait)
|
163
|
+
continue
|
164
|
+
else:
|
165
|
+
break
|
166
|
+
except Exception as e:
|
167
|
+
logger.warning(f"第{attempt}次请求处理异常:{e}")
|
168
|
+
last_exception = e
|
169
|
+
if attempt < max_attempts:
|
170
|
+
time.sleep(wait)
|
171
|
+
continue
|
172
|
+
else:
|
173
|
+
break
|
174
|
+
|
175
|
+
logger.error(f"请求失败,已重试{max_attempts}次。最后异常:{last_exception}")
|
176
|
+
return f"请求失败,已重试{max_attempts}次,最后异常:{last_exception}"
|
177
|
+
|
178
|
+
|
179
|
+
if __name__ == '__main__':
|
180
|
+
a = PDFWeaviateInfo(prd_path="支持搜索用户功能.pdf", input_question="星野支持搜索用户功能的相关用例")
|
181
|
+
print(a.get_pdf_and_weaviate_info())
|
182
|
+
# read_pdf_text(prd_path = "注销流程优化.pdf")
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import pdfplumber
|
2
|
+
import warnings
|
3
|
+
import re
|
4
|
+
warnings.filterwarnings("ignore")
|
5
|
+
def read_pdf_text(pdf_path):
|
6
|
+
"""
|
7
|
+
读取指定路径的PDF文件内容,返回所有文本内容的字符串。
|
8
|
+
:param pdf_path: PDF文件的本地路径
|
9
|
+
:return: PDF中的全部文本内容
|
10
|
+
"""
|
11
|
+
all_text = ""
|
12
|
+
with pdfplumber.open(pdf_path) as pdf:
|
13
|
+
for page in pdf.pages:
|
14
|
+
all_text += page.extract_text() or ""
|
15
|
+
# 清除特殊不可见字符
|
16
|
+
all_text = re.sub(r'[\x00-\x1F\x7F]', '', all_text)
|
17
|
+
# all_text = clean_encoding(all_text)
|
18
|
+
return all_text
|
19
|
+
|
20
|
+
# def clean_encoding(text):
|
21
|
+
# # 先转换为bytes,再解码回字符串
|
22
|
+
# text_bytes = text.encode('utf-8', errors='ignore')
|
23
|
+
# cleaned_text = text_bytes.decode('utf-8')
|
24
|
+
# return cleaned_text
|
25
|
+
if __name__ == "__main__":
|
26
|
+
pdf_path = "创作输入框改版.pdf"
|
27
|
+
text = read_pdf_text(pdf_path)
|
28
|
+
print(text)
|
File without changes
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: mm_qa_mcp
|
3
|
-
Version: 3.0.
|
3
|
+
Version: 3.0.3
|
4
4
|
Summary: QA agent service 集合
|
5
5
|
Author-email: xingyun <xingyun@minimaxi.com>
|
6
6
|
License-Expression: MIT
|
@@ -60,6 +60,7 @@ Requires-Dist: validators<1.0.0,>=0.21.2
|
|
60
60
|
Requires-Dist: wcwidth>=0.2.13
|
61
61
|
Requires-Dist: weaviate-client<4.0.0,>=3.25.0
|
62
62
|
Requires-Dist: zstandard>=0.23.0
|
63
|
+
Requires-Dist: pdfplumber>=0.11.6
|
63
64
|
Provides-Extra: dev
|
64
65
|
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
65
66
|
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
@@ -7,6 +7,9 @@ minimax_qa_mcp/server.py
|
|
7
7
|
minimax_qa_mcp/conf/__init__.py
|
8
8
|
minimax_qa_mcp/conf/conf.ini
|
9
9
|
minimax_qa_mcp/src/__init__.py
|
10
|
+
minimax_qa_mcp/src/auto_case/__init__.py
|
11
|
+
minimax_qa_mcp/src/auto_case/case_write.py
|
12
|
+
minimax_qa_mcp/src/auto_case/pdf_jiexi.py
|
10
13
|
minimax_qa_mcp/src/gateway_case/__init__.py
|
11
14
|
minimax_qa_mcp/src/gateway_case/get_case.py
|
12
15
|
minimax_qa_mcp/src/generator_case/__init__.py
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "mm_qa_mcp"
|
7
|
-
version = "3.0.
|
7
|
+
version = "3.0.3"
|
8
8
|
description = "QA agent service 集合"
|
9
9
|
readme = "README.md"
|
10
10
|
requires-python = ">=3.10"
|
@@ -68,7 +68,8 @@ dependencies = [
|
|
68
68
|
"validators>=0.21.2,<1.0.0",
|
69
69
|
"wcwidth>=0.2.13",
|
70
70
|
"weaviate-client>=3.25.0,<4.0.0",
|
71
|
-
"zstandard>=0.23.0"
|
71
|
+
"zstandard>=0.23.0",
|
72
|
+
"pdfplumber>=0.11.6"
|
72
73
|
]
|
73
74
|
|
74
75
|
[project.optional-dependencies]
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/minimax_qa_mcp/src/generator_case/generator_case_langchain.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{mm_qa_mcp-3.0.1 → mm_qa_mcp-3.0.3}/minimax_qa_mcp/src/get_weaviate_info/get_weaviate_info.py
RENAMED
File without changes
|
{mm_qa_mcp-3.0.1/minimax_qa_mcp/utils → mm_qa_mcp-3.0.3/minimax_qa_mcp/src/grafana}/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|