maque 0.2.1__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.
Files changed (143) hide show
  1. maque/__init__.py +30 -0
  2. maque/__main__.py +926 -0
  3. maque/ai_platform/__init__.py +0 -0
  4. maque/ai_platform/crawl.py +45 -0
  5. maque/ai_platform/metrics.py +258 -0
  6. maque/ai_platform/nlp_preprocess.py +67 -0
  7. maque/ai_platform/webpage_screen_shot.py +195 -0
  8. maque/algorithms/__init__.py +78 -0
  9. maque/algorithms/bezier.py +15 -0
  10. maque/algorithms/bktree.py +117 -0
  11. maque/algorithms/core.py +104 -0
  12. maque/algorithms/hilbert.py +16 -0
  13. maque/algorithms/rate_function.py +92 -0
  14. maque/algorithms/transform.py +27 -0
  15. maque/algorithms/trie.py +272 -0
  16. maque/algorithms/utils.py +63 -0
  17. maque/algorithms/video.py +587 -0
  18. maque/api/__init__.py +1 -0
  19. maque/api/common.py +110 -0
  20. maque/api/fetch.py +26 -0
  21. maque/api/static/icon.png +0 -0
  22. maque/api/static/redoc.standalone.js +1782 -0
  23. maque/api/static/swagger-ui-bundle.js +3 -0
  24. maque/api/static/swagger-ui.css +3 -0
  25. maque/cli/__init__.py +1 -0
  26. maque/cli/clean_invisible_chars.py +324 -0
  27. maque/cli/core.py +34 -0
  28. maque/cli/groups/__init__.py +26 -0
  29. maque/cli/groups/config.py +205 -0
  30. maque/cli/groups/data.py +615 -0
  31. maque/cli/groups/doctor.py +259 -0
  32. maque/cli/groups/embedding.py +222 -0
  33. maque/cli/groups/git.py +29 -0
  34. maque/cli/groups/help.py +410 -0
  35. maque/cli/groups/llm.py +223 -0
  36. maque/cli/groups/mcp.py +241 -0
  37. maque/cli/groups/mllm.py +1795 -0
  38. maque/cli/groups/mllm_simple.py +60 -0
  39. maque/cli/groups/quant.py +210 -0
  40. maque/cli/groups/service.py +490 -0
  41. maque/cli/groups/system.py +570 -0
  42. maque/cli/mllm_run.py +1451 -0
  43. maque/cli/script.py +52 -0
  44. maque/cli/tree.py +49 -0
  45. maque/clustering/__init__.py +52 -0
  46. maque/clustering/analyzer.py +347 -0
  47. maque/clustering/clusterers.py +464 -0
  48. maque/clustering/sampler.py +134 -0
  49. maque/clustering/visualizer.py +205 -0
  50. maque/constant.py +13 -0
  51. maque/core.py +133 -0
  52. maque/cv/__init__.py +1 -0
  53. maque/cv/image.py +219 -0
  54. maque/cv/utils.py +68 -0
  55. maque/cv/video/__init__.py +3 -0
  56. maque/cv/video/keyframe_extractor.py +368 -0
  57. maque/embedding/__init__.py +43 -0
  58. maque/embedding/base.py +56 -0
  59. maque/embedding/multimodal.py +308 -0
  60. maque/embedding/server.py +523 -0
  61. maque/embedding/text.py +311 -0
  62. maque/git/__init__.py +24 -0
  63. maque/git/pure_git.py +912 -0
  64. maque/io/__init__.py +29 -0
  65. maque/io/core.py +38 -0
  66. maque/io/ops.py +194 -0
  67. maque/llm/__init__.py +111 -0
  68. maque/llm/backend.py +416 -0
  69. maque/llm/base.py +411 -0
  70. maque/llm/server.py +366 -0
  71. maque/mcp_server.py +1096 -0
  72. maque/mllm_data_processor_pipeline/__init__.py +17 -0
  73. maque/mllm_data_processor_pipeline/core.py +341 -0
  74. maque/mllm_data_processor_pipeline/example.py +291 -0
  75. maque/mllm_data_processor_pipeline/steps/__init__.py +56 -0
  76. maque/mllm_data_processor_pipeline/steps/data_alignment.py +267 -0
  77. maque/mllm_data_processor_pipeline/steps/data_loader.py +172 -0
  78. maque/mllm_data_processor_pipeline/steps/data_validation.py +304 -0
  79. maque/mllm_data_processor_pipeline/steps/format_conversion.py +411 -0
  80. maque/mllm_data_processor_pipeline/steps/mllm_annotation.py +331 -0
  81. maque/mllm_data_processor_pipeline/steps/mllm_refinement.py +446 -0
  82. maque/mllm_data_processor_pipeline/steps/result_validation.py +501 -0
  83. maque/mllm_data_processor_pipeline/web_app.py +317 -0
  84. maque/nlp/__init__.py +14 -0
  85. maque/nlp/ngram.py +9 -0
  86. maque/nlp/parser.py +63 -0
  87. maque/nlp/risk_matcher.py +543 -0
  88. maque/nlp/sentence_splitter.py +202 -0
  89. maque/nlp/simple_tradition_cvt.py +31 -0
  90. maque/performance/__init__.py +21 -0
  91. maque/performance/_measure_time.py +70 -0
  92. maque/performance/_profiler.py +367 -0
  93. maque/performance/_stat_memory.py +51 -0
  94. maque/pipelines/__init__.py +15 -0
  95. maque/pipelines/clustering.py +252 -0
  96. maque/quantization/__init__.py +42 -0
  97. maque/quantization/auto_round.py +120 -0
  98. maque/quantization/base.py +145 -0
  99. maque/quantization/bitsandbytes.py +127 -0
  100. maque/quantization/llm_compressor.py +102 -0
  101. maque/retriever/__init__.py +35 -0
  102. maque/retriever/chroma.py +654 -0
  103. maque/retriever/document.py +140 -0
  104. maque/retriever/milvus.py +1140 -0
  105. maque/table_ops/__init__.py +1 -0
  106. maque/table_ops/core.py +133 -0
  107. maque/table_viewer/__init__.py +4 -0
  108. maque/table_viewer/download_assets.py +57 -0
  109. maque/table_viewer/server.py +698 -0
  110. maque/table_viewer/static/element-plus-icons.js +5791 -0
  111. maque/table_viewer/static/element-plus.css +1 -0
  112. maque/table_viewer/static/element-plus.js +65236 -0
  113. maque/table_viewer/static/main.css +268 -0
  114. maque/table_viewer/static/main.js +669 -0
  115. maque/table_viewer/static/vue.global.js +18227 -0
  116. maque/table_viewer/templates/index.html +401 -0
  117. maque/utils/__init__.py +56 -0
  118. maque/utils/color.py +68 -0
  119. maque/utils/color_string.py +45 -0
  120. maque/utils/compress.py +66 -0
  121. maque/utils/constant.py +183 -0
  122. maque/utils/core.py +261 -0
  123. maque/utils/cursor.py +143 -0
  124. maque/utils/distance.py +58 -0
  125. maque/utils/docker.py +96 -0
  126. maque/utils/downloads.py +51 -0
  127. maque/utils/excel_helper.py +542 -0
  128. maque/utils/helper_metrics.py +121 -0
  129. maque/utils/helper_parser.py +168 -0
  130. maque/utils/net.py +64 -0
  131. maque/utils/nvidia_stat.py +140 -0
  132. maque/utils/ops.py +53 -0
  133. maque/utils/packages.py +31 -0
  134. maque/utils/path.py +57 -0
  135. maque/utils/tar.py +260 -0
  136. maque/utils/untar.py +129 -0
  137. maque/web/__init__.py +0 -0
  138. maque/web/image_downloader.py +1410 -0
  139. maque-0.2.1.dist-info/METADATA +450 -0
  140. maque-0.2.1.dist-info/RECORD +143 -0
  141. maque-0.2.1.dist-info/WHEEL +4 -0
  142. maque-0.2.1.dist-info/entry_points.txt +3 -0
  143. maque-0.2.1.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,259 @@
1
+ """环境检查和诊断命令组"""
2
+ import os
3
+ import sys
4
+ import subprocess
5
+ import importlib
6
+ from pathlib import Path
7
+ from rich.console import Console
8
+ from rich.table import Table
9
+ from rich import print
10
+
11
+
12
+ class DoctorGroup:
13
+ """环境检查和诊断命令组"""
14
+
15
+ def __init__(self, cli_instance):
16
+ self.cli = cli_instance
17
+ self.console = Console()
18
+
19
+ def check(self, verbose: bool = False):
20
+ """检查环境和依赖"""
21
+ print("[bold blue]Sparrow 环境诊断[/bold blue]\n")
22
+
23
+ issues = []
24
+
25
+ # 检查Python版本
26
+ issues.extend(self._check_python_version(verbose))
27
+
28
+ # 检查核心依赖
29
+ issues.extend(self._check_core_dependencies(verbose))
30
+
31
+ # 检查可选依赖
32
+ issues.extend(self._check_optional_dependencies(verbose))
33
+
34
+ # 检查配置文件
35
+ issues.extend(self._check_config_files(verbose))
36
+
37
+ # 检查服务连接
38
+ issues.extend(self._check_services(verbose))
39
+
40
+ # 汇总结果
41
+ print("\n" + "="*50)
42
+ if issues:
43
+ print(f"[yellow]发现 {len(issues)} 个问题:[/yellow]")
44
+ for i, issue in enumerate(issues, 1):
45
+ print(f"{i}. [yellow]{issue}[/yellow]")
46
+
47
+ print(f"\n[bold cyan]建议运行 'maque doctor fix' 来自动修复部分问题[/bold cyan]")
48
+ else:
49
+ print("[green]✓ 环境检查完成,未发现问题[/green]")
50
+
51
+ return len(issues) == 0
52
+
53
+ def _check_python_version(self, verbose):
54
+ """检查Python版本"""
55
+ issues = []
56
+ python_version = sys.version_info
57
+
58
+ if verbose or python_version < (3, 8):
59
+ print(f"Python 版本: {python_version.major}.{python_version.minor}.{python_version.micro}")
60
+
61
+ if python_version < (3, 8):
62
+ issues.append("Python版本过低,建议使用Python 3.8+")
63
+ elif verbose:
64
+ print("[green]✓[/green] Python版本符合要求")
65
+
66
+ return issues
67
+
68
+ def _check_core_dependencies(self, verbose):
69
+ """检查核心依赖"""
70
+ core_deps = [
71
+ 'fire',
72
+ 'rich',
73
+ 'pyyaml',
74
+ 'requests',
75
+ 'pathlib' # 标准库,但检查兼容性
76
+ ]
77
+
78
+ issues = []
79
+
80
+ if verbose:
81
+ print("\n[bold]核心依赖检查:[/bold]")
82
+
83
+ for dep in core_deps:
84
+ try:
85
+ importlib.import_module(dep.replace('-', '_'))
86
+ if verbose:
87
+ print(f"[green]✓[/green] {dep}")
88
+ except ImportError:
89
+ issues.append(f"缺少核心依赖: {dep}")
90
+ if verbose:
91
+ print(f"[red]✗[/red] {dep} - 未安装")
92
+
93
+ return issues
94
+
95
+ def _check_optional_dependencies(self, verbose):
96
+ """检查可选依赖"""
97
+ optional_deps = {
98
+ 'cv2': 'opencv-python (视频处理)',
99
+ 'torch': 'torch (深度学习)',
100
+ 'pandas': 'pandas (数据处理)',
101
+ 'numpy': 'numpy (数值计算)',
102
+ 'PIL': 'pillow (图像处理)',
103
+ 'httpx': 'httpx (异步HTTP客户端)',
104
+ 'uvicorn': 'uvicorn (Web服务器)'
105
+ }
106
+
107
+ issues = []
108
+ missing_optional = []
109
+
110
+ if verbose:
111
+ print("\n[bold]可选依赖检查:[/bold]")
112
+
113
+ for dep, description in optional_deps.items():
114
+ try:
115
+ importlib.import_module(dep)
116
+ if verbose:
117
+ print(f"[green]✓[/green] {dep} - {description}")
118
+ except ImportError:
119
+ missing_optional.append(f"{dep} ({description})")
120
+ if verbose:
121
+ print(f"[yellow]○[/yellow] {dep} - {description} (未安装)")
122
+
123
+ if missing_optional and not verbose:
124
+ # 非详细模式下只提示有多少个可选依赖未安装
125
+ print(f"[yellow]提示: {len(missing_optional)} 个可选依赖未安装,某些功能可能不可用[/yellow]")
126
+
127
+ return issues
128
+
129
+ def _check_config_files(self, verbose):
130
+ """检查配置文件"""
131
+ issues = []
132
+
133
+ if verbose:
134
+ print("\n[bold]配置文件检查:[/bold]")
135
+
136
+ config_paths = self.cli._get_config_search_paths()
137
+ found_config = False
138
+
139
+ for path in config_paths:
140
+ if path.exists():
141
+ found_config = True
142
+ try:
143
+ # 验证配置文件
144
+ config = self.cli._load_maque_config()
145
+ if verbose:
146
+ print(f"[green]✓[/green] 配置文件: {path}")
147
+ break
148
+ except Exception as e:
149
+ issues.append(f"配置文件错误: {path} - {e}")
150
+ if verbose:
151
+ print(f"[red]✗[/red] 配置文件: {path} - 错误: {e}")
152
+
153
+ if not found_config:
154
+ if verbose:
155
+ print("[yellow]○[/yellow] 未找到配置文件,将使用默认配置")
156
+
157
+ return issues
158
+
159
+ def _check_services(self, verbose):
160
+ """检查服务连接"""
161
+ issues = []
162
+
163
+ if verbose:
164
+ print("\n[bold]服务连接检查:[/bold]")
165
+
166
+ # 检查MLLM服务
167
+ mllm_config = self.cli.maque_config.get('mllm', {})
168
+ base_url = mllm_config.get('base_url')
169
+
170
+ if base_url:
171
+ try:
172
+ import requests
173
+ # 简单的连接测试
174
+ response = requests.get(f"{base_url.rstrip('/')}/models", timeout=5)
175
+ if response.status_code == 200:
176
+ if verbose:
177
+ print(f"[green]✓[/green] MLLM服务: {base_url}")
178
+ else:
179
+ issues.append(f"MLLM服务响应异常: {base_url} (状态码: {response.status_code})")
180
+ except requests.RequestException as e:
181
+ issues.append(f"无法连接MLLM服务: {base_url}")
182
+ if verbose:
183
+ print(f"[red]✗[/red] MLLM服务: {base_url} - {e}")
184
+ except ImportError:
185
+ pass # requests未安装,已在依赖检查中处理
186
+
187
+ return issues
188
+
189
+ def fix(self, auto: bool = False):
190
+ """自动修复常见问题
191
+
192
+ Args:
193
+ auto: 自动修复而不询问
194
+ """
195
+ print("[bold blue]自动修复工具[/bold blue]\n")
196
+
197
+ fixes_applied = 0
198
+
199
+ # 检查并创建配置文件
200
+ config_paths = self.cli._get_config_search_paths()
201
+ has_config = any(p.exists() for p in config_paths)
202
+
203
+ if not has_config:
204
+ if auto or self._confirm("创建默认配置文件?"):
205
+ self.cli.init_config()
206
+ print("[green]✓[/green] 已创建默认配置文件")
207
+ fixes_applied += 1
208
+
209
+ # 可以添加更多自动修复逻辑...
210
+
211
+ if fixes_applied > 0:
212
+ print(f"\n[green]已应用 {fixes_applied} 个修复[/green]")
213
+ else:
214
+ print("[yellow]未发现可自动修复的问题[/yellow]")
215
+
216
+ def _confirm(self, message):
217
+ """确认对话"""
218
+ response = input(f"{message} (y/N): ")
219
+ return response.lower() == 'y'
220
+
221
+ def version(self, full: bool = False):
222
+ """显示版本信息
223
+
224
+ Args:
225
+ full: 显示详细版本信息
226
+ """
227
+ from maque import __version__
228
+
229
+ if not full:
230
+ print(f"maque {__version__}")
231
+ return
232
+
233
+ # 详细版本信息
234
+ print(f"[bold blue]Sparrow v{__version__}[/bold blue]\n")
235
+
236
+ # Python信息
237
+ print(f"Python: {sys.version}")
238
+ print(f"平台: {sys.platform}")
239
+
240
+ # 安装位置
241
+ maque_path = Path(__file__).parent.parent.parent
242
+ print(f"安装路径: {maque_path}")
243
+
244
+ # 依赖版本
245
+ deps_info = []
246
+ key_deps = ['fire', 'rich', 'requests', 'pyyaml']
247
+
248
+ for dep in key_deps:
249
+ try:
250
+ mod = importlib.import_module(dep)
251
+ version = getattr(mod, '__version__', 'unknown')
252
+ deps_info.append(f"{dep}: {version}")
253
+ except ImportError:
254
+ deps_info.append(f"{dep}: 未安装")
255
+
256
+ if deps_info:
257
+ print(f"\n依赖版本:")
258
+ for info in deps_info:
259
+ print(f" {info}")
@@ -0,0 +1,222 @@
1
+ """Embedding 服务命令组"""
2
+ from typing import List, Optional
3
+ from rich import print
4
+ from rich.console import Console
5
+
6
+
7
+ class EmbeddingGroup:
8
+ """Embedding 服务命令组
9
+
10
+ 提供 embedding 模型服务的启动、管理功能,
11
+ 支持 jina-embeddings-v3 等模型的 task 类型。
12
+ """
13
+
14
+ def __init__(self, cli_instance):
15
+ self.cli = cli_instance
16
+ self.console = Console()
17
+
18
+ def serve(
19
+ self,
20
+ model: str = "jinaai/jina-embeddings-v3",
21
+ host: str = "0.0.0.0",
22
+ port: int = 8000,
23
+ device: str = None,
24
+ workers: int = 1,
25
+ local_dir: str = None,
26
+ dtype: str = None,
27
+ attn: str = None,
28
+ ):
29
+ """启动 Embedding API 服务
30
+
31
+ 启动兼容 OpenAI/vLLM 的 Embedding API 服务,
32
+ 支持 jina-embeddings-v3 的 task 类型扩展。
33
+
34
+ Args:
35
+ model: 模型名称或路径,默认 jinaai/jina-embeddings-v3
36
+ host: 监听地址,默认 0.0.0.0
37
+ port: 监听端口,默认 8000
38
+ device: 设备类型 (cuda/cpu),默认自动检测
39
+ workers: worker 数量,默认 1
40
+ local_dir: 本地模型目录
41
+ dtype: 数据类型 (float16/bfloat16/float32),默认自动选择
42
+ attn: 注意力实现 (eager/sdpa/flash_attention_2),默认自动选择
43
+
44
+ Examples:
45
+ maque embedding serve
46
+ maque embedding serve --model=BAAI/bge-m3 --port=8001
47
+ maque embedding serve --dtype=float32 --attn=eager
48
+ """
49
+ try:
50
+ from maque.embedding.server import create_server
51
+ except ImportError as e:
52
+ print(f"[red]无法导入 embedding 服务模块: {e}[/red]")
53
+ print("请确保已安装依赖: pip install sentence-transformers fastapi uvicorn")
54
+ return
55
+
56
+ print(f"[bold blue]启动 Embedding 服务[/bold blue]")
57
+ print(f" 模型: [cyan]{model}[/cyan]")
58
+ print(f" 地址: [green]http://{host}:{port}[/green]")
59
+ print(f" 设备: [yellow]{device or 'auto'}[/yellow]")
60
+ print(f" 精度: [yellow]{dtype or 'auto'}[/yellow]")
61
+ print(f" 注意力: [yellow]{attn or 'auto'}[/yellow]")
62
+ if local_dir:
63
+ print(f" 本地目录: [magenta]{local_dir}[/magenta]")
64
+ print()
65
+
66
+ # 处理多模型
67
+ models = [m.strip() for m in model.split(",")] if "," in model else [model]
68
+
69
+ server = create_server(
70
+ models=models,
71
+ device=device,
72
+ local_dir=local_dir,
73
+ dtype=dtype,
74
+ attn=attn,
75
+ )
76
+ server.run(host=host, port=port, workers=workers)
77
+
78
+ def test(
79
+ self,
80
+ url: str = "http://localhost:8000",
81
+ model: str = "jinaai/jina-embeddings-v3",
82
+ text: str = "Hello, world!",
83
+ task: str = None,
84
+ ):
85
+ """测试 Embedding 服务
86
+
87
+ Args:
88
+ url: 服务 URL
89
+ model: 模型名称
90
+ text: 测试文本
91
+ task: 任务类型 (text-matching/retrieval.query/retrieval.passage/classification/separation)
92
+
93
+ Examples:
94
+ maque embedding test
95
+ maque embedding test --task=retrieval.query
96
+ maque embedding test --url=http://localhost:8000
97
+ """
98
+ import requests
99
+ import json
100
+
101
+ endpoint = f"{url.rstrip('/')}/v1/embeddings"
102
+
103
+ payload = {
104
+ "model": model,
105
+ "input": text,
106
+ }
107
+ if task:
108
+ payload["task"] = task
109
+
110
+ print(f"[blue]测试 Embedding 服务[/blue]")
111
+ print(f" URL: {endpoint}")
112
+ print(f" 模型: {model}")
113
+ print(f" 文本: {text[:50]}{'...' if len(text) > 50 else ''}")
114
+ if task:
115
+ print(f" Task: {task}")
116
+ print()
117
+
118
+ try:
119
+ response = requests.post(
120
+ endpoint,
121
+ json=payload,
122
+ headers={"Content-Type": "application/json"},
123
+ timeout=60,
124
+ )
125
+ response.raise_for_status()
126
+ data = response.json()
127
+
128
+ if "data" in data and len(data["data"]) > 0:
129
+ embedding = data["data"][0]["embedding"]
130
+ print(f"[green]成功![/green]")
131
+ print(f" 向量维度: {len(embedding)}")
132
+ print(f" 向量前5维: {embedding[:5]}")
133
+ print(f" Token 使用: {data.get('usage', {})}")
134
+ else:
135
+ print(f"[yellow]响应异常: {data}[/yellow]")
136
+
137
+ except requests.exceptions.ConnectionError:
138
+ print(f"[red]无法连接到服务: {endpoint}[/red]")
139
+ print("请确保服务已启动")
140
+ except Exception as e:
141
+ print(f"[red]测试失败: {e}[/red]")
142
+
143
+ def tasks(self):
144
+ """显示支持的 task 类型
145
+
146
+ 显示 jina-embeddings-v3 支持的所有 task 类型及其用途。
147
+ """
148
+ from rich.table import Table
149
+
150
+ print("[bold blue]jina-embeddings-v3 支持的 Task 类型[/bold blue]\n")
151
+
152
+ table = Table(show_header=True, header_style="bold magenta")
153
+ table.add_column("Task", style="cyan")
154
+ table.add_column("用途", style="green")
155
+ table.add_column("适用场景", style="yellow")
156
+
157
+ tasks = [
158
+ ("text-matching", "语义相似度匹配", "对称检索、句子相似度计算"),
159
+ ("retrieval.query", "检索查询编码", "非对称检索的查询端"),
160
+ ("retrieval.passage", "检索文档编码", "非对称检索的文档/段落端"),
161
+ ("classification", "文本分类", "分类任务的特征提取"),
162
+ ("separation", "聚类/重排", "聚类分析、重排序任务"),
163
+ ]
164
+
165
+ for task, desc, usage in tasks:
166
+ table.add_row(task, desc, usage)
167
+
168
+ self.console.print(table)
169
+
170
+ print("\n[dim]使用示例:[/dim]")
171
+ print(' curl -X POST http://localhost:8000/v1/embeddings \\')
172
+ print(' -H "Content-Type: application/json" \\')
173
+ print(' -d \'{"model": "jinaai/jina-embeddings-v3", "input": "text", "task": "retrieval.query"}\'')
174
+
175
+ def client(
176
+ self,
177
+ url: str = "http://localhost:8000",
178
+ model: str = "jinaai/jina-embeddings-v3",
179
+ ):
180
+ """创建 Embedding 客户端 (交互模式)
181
+
182
+ Args:
183
+ url: 服务 URL
184
+ model: 模型名称
185
+
186
+ Examples:
187
+ maque embedding client
188
+ maque embedding client --url=http://localhost:8000
189
+ """
190
+ from maque.embedding import TextEmbedding
191
+
192
+ print("[bold blue]Embedding 客户端 (交互模式)[/bold blue]")
193
+ print(f" URL: {url}")
194
+ print(f" 模型: {model}")
195
+ print("\n输入文本进行编码,输入 'quit' 退出")
196
+ print("可选: 输入 'task:<type>' 切换任务类型\n")
197
+
198
+ client = TextEmbedding(base_url=url, model=model)
199
+ current_task = None
200
+
201
+ while True:
202
+ try:
203
+ text = input(f"[{current_task or 'default'}] > ").strip()
204
+
205
+ if not text:
206
+ continue
207
+ if text.lower() == "quit":
208
+ break
209
+ if text.startswith("task:"):
210
+ current_task = text[5:].strip() or None
211
+ print(f" 切换到 task: {current_task or 'default'}")
212
+ continue
213
+
214
+ embeddings = client.embed(text, task=current_task)
215
+ print(f" 维度: {len(embeddings[0])}, 前5维: {embeddings[0][:5]}")
216
+
217
+ except KeyboardInterrupt:
218
+ break
219
+ except Exception as e:
220
+ print(f" [red]错误: {e}[/red]")
221
+
222
+ print("\n[yellow]已退出[/yellow]")
@@ -0,0 +1,29 @@
1
+ """Git 命令组 - 代理到 Dulwich CLI
2
+
3
+ 直接调用 dulwich CLI,支持所有 git 命令。
4
+ 注意:实际的 git 命令在 __main__.py 中直接处理,绕过 fire。
5
+
6
+ Usage:
7
+ spr git <command> [args...]
8
+
9
+ Examples:
10
+ spr git status
11
+ spr git add .
12
+ spr git commit -m "message"
13
+ spr git log
14
+ spr git rebase main
15
+ spr git stash push
16
+ spr git cherry-pick <commit>
17
+ spr git config -l
18
+ """
19
+
20
+
21
+ class GitGroup:
22
+ """Git 命令组 - 代理到 Dulwich CLI
23
+
24
+ 注意:此类仅作为占位符,实际的 git 命令处理在 __main__.py 中,
25
+ 直接调用 dulwich CLI 以避免 fire 参数解析问题。
26
+ """
27
+
28
+ def __init__(self, cli_instance):
29
+ self.cli = cli_instance