pyminicode 0.1.0__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.
@@ -0,0 +1,265 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyminicode
3
+ Version: 0.1.0
4
+ Summary: Terminal-native AI coding assistant (Python)
5
+ Author: Wangzheng Yuan
6
+ License: MIT
7
+ Classifier: Development Status :: 3 - Alpha
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
15
+ Requires-Python: >=3.10
16
+ Description-Content-Type: text/markdown
17
+ Requires-Dist: pydantic>=2.6
18
+ Requires-Dist: httpx>=0.27
19
+ Requires-Dist: anyio>=4.3
20
+ Requires-Dist: PyYAML>=6.0
21
+ Provides-Extra: dev
22
+ Requires-Dist: pytest>=8.0; extra == "dev"
23
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
24
+ Requires-Dist: ruff>=0.4; extra == "dev"
25
+
26
+ # minicode
27
+
28
+ Terminal-native AI coding assistant, implemented in Python.
29
+
30
+ > **当前状态**:已完成**工具层**([v0])和**模型层**([v1])。能加载 LLM、切换 provider、流式测试连通性。
31
+ > 下一版([v2])会接入 ReAct 循环(输入 → LLM → 工具调用 → 回灌 → 循环)。
32
+
33
+ ## Quick start
34
+
35
+ ```bash
36
+ # 1. install
37
+ pip install -e .
38
+
39
+ # 2. 跑起来(首次会自动建 .minicode/)
40
+ minicode
41
+
42
+ # 一次性命令
43
+ minicode --version
44
+ minicode --paths
45
+ minicode --print-tools # 列工具
46
+ minicode --print-models # 列 model provider
47
+ ```
48
+
49
+ ## Layout
50
+
51
+ ```
52
+ minicode/
53
+ ├── pyproject.toml
54
+ ├── README.md
55
+ ├── .minicode/ # per-project config dir
56
+ │ ├── skills/ # skill files
57
+ │ │ ├── code-review/SKILL.md
58
+ │ │ ├── refactor/SKILL.md
59
+ │ │ └── test-gen/SKILL.md
60
+ │ ├── mcp.json # MCP server config (stdio / http)
61
+ │ └── config.yaml # LLM provider 配置
62
+ ├── minicode/ # source
63
+ │ ├── __init__.py
64
+ │ ├── __main__.py
65
+ │ ├── paths.py # .minicode 路径解析
66
+ │ ├── config.py # config.yaml 加载
67
+ │ ├── tool/ # 工具层
68
+ │ │ ├── base.py # Tool 抽象基类 + ToolContext + ToolResult
69
+ │ │ ├── registry.py # ToolRegistry
70
+ │ │ ├── skill.py # SkillLoader
71
+ │ │ ├── mcp.py # McpClient + McpToolAdapter
72
+ │ │ └── builtin/ # 7 个内置工具
73
+ │ ├── model/ # 模型层
74
+ │ │ ├── base.py # Model 抽象基类 + ModelResponse/Event
75
+ │ │ ├── message.py # Message / Part / ToolSchema
76
+ │ │ ├── openai_compat.py # OpenAI Chat Completions (覆盖 ollama/vllm/DeepSeek/OpenAI)
77
+ │ │ ├── anthropic.py # Anthropic Messages API
78
+ │ │ ├── demo.py # 假 provider(echo),无需 apikey
79
+ │ │ └── registry.py # ModelRegistry
80
+ │ └── cli/
81
+ │ └── app.py # REPL + /tools /skills /mcp /models /model /call
82
+ └── tests/ # 单测 + 端到端冒烟
83
+ ├── test_base.py
84
+ ├── test_skill_loader.py
85
+ ├── test_registry.py # 工具层端到端
86
+ ├── test_config.py # config.yaml 加载
87
+ ├── test_model_registry.py # ModelRegistry
88
+ ├── test_openai_compat.py # 用 httpx MockTransport 模拟 SSE
89
+ ├── test_anthropic.py
90
+ ├── test_demo.py
91
+ ├── demo_mcp_server.py
92
+ └── test_e2e_mcp.py
93
+ ```
94
+
95
+ ## config.yaml 格式
96
+
97
+ `.minicode/config.yaml`:
98
+
99
+ ```yaml
100
+ default: openai # 可选:默认 provider id
101
+
102
+ providers:
103
+ openai:
104
+ type: openai-compat # openai-compat | anthropic | demo
105
+ api_key: ${OPENAI_API_KEY} # ${ENV_VAR} 自动展开
106
+ base_url: https://api.openai.com/v1
107
+ model: gpt-4o
108
+ extra: # 透传给 provider
109
+ timeout: 60
110
+ temperature: 0.7
111
+ max_tokens: 4096
112
+
113
+ anthropic:
114
+ type: anthropic
115
+ api_key: ${ANTHROPIC_API_KEY}
116
+ base_url: https://api.anthropic.com
117
+ model: claude-3-5-sonnet-20241022
118
+ extra:
119
+ max_tokens: 4096
120
+
121
+ demo: # 假 provider(开箱即用)
122
+ type: demo
123
+ base_url: "(in-process)"
124
+ model: demo-echo
125
+ ```
126
+
127
+ `type` 字段:
128
+ - `openai-compat` — 任何实现 OpenAI Chat Completions 的服务(OpenAI/DeepSeek/Moonshot/ollama/vllm/...)
129
+ - `anthropic` — Anthropic Messages API
130
+ - `demo` — 进程内回显,无需网络
131
+
132
+ `extra` 字段透传给 provider 实现(OpenAI:`temperature`/`top_p`/`presence_penalty`;Anthropic:`max_tokens` 必填/`temperature`/`top_k`)。
133
+
134
+ ## CLI 命令
135
+
136
+ | 命令 | 作用 |
137
+ | --- | --- |
138
+ | `/tools` | 列出所有工具(builtin + skill + mcp) |
139
+ | `/skills` | 列出 skill |
140
+ | `/mcp` | 列出 MCP server + 工具 |
141
+ | `/models` | 列出 `config.yaml` 中所有 LLM provider,标 current |
142
+ | `/model` | 显示当前 model 详情 |
143
+ | `/model <id>` | 切换到指定 provider |
144
+ | `/model test` | 流式发 "ping" 测试当前 model 的连通性 |
145
+ | `/paths` | 路径解析 |
146
+ | `/call <id> [json]` | 手动调用一个工具 |
147
+ | `/reload` | 重新 build registry |
148
+ | `/help` | 帮助 |
149
+ | `/exit` | 退出 |
150
+
151
+ ## 工具协议
152
+
153
+ 所有工具实现同一接口([minicode/tool/base.py](minicode/tool/base.py)):
154
+
155
+ ```python
156
+ class Tool(ABC):
157
+ kind: ToolKind = ToolKind.BUILTIN
158
+
159
+ @property
160
+ def id(self) -> str: ...
161
+ @property
162
+ def description(self) -> str: ...
163
+ @property
164
+ def parameters(self) -> type[BaseModel]: ...
165
+ @abstractmethod
166
+ async def execute(self, args: BaseModel, ctx: ToolContext) -> ToolResult: ...
167
+ ```
168
+
169
+ - `parameters` 是 Pydantic BaseModel,自动生成 JSON Schema 给 LLM
170
+ - `ToolKind`: BUILTIN / SKILL / MCP / CUSTOM
171
+
172
+ ## Model 协议
173
+
174
+ 所有 Model 实现同一接口([minicode/model/base.py](minicode/model/base.py)):
175
+
176
+ ```python
177
+ class Model(ABC):
178
+ @property
179
+ def info(self) -> ModelInfo: ... # id / type / base_url / model
180
+ @property
181
+ def api_key(self) -> str: ...
182
+ @property
183
+ def extra(self) -> dict: ...
184
+
185
+ @abstractmethod
186
+ async def stream(
187
+ self,
188
+ messages: List[Message],
189
+ tools: Optional[List[ToolSchema]] = None,
190
+ system: Optional[str] = None,
191
+ ) -> AsyncIterator[ModelEvent]: ... # 流式产出 text_delta / tool_call_delta / usage / finish / error
192
+
193
+ async def complete(...) -> ModelResponse: # 基类默认实现:把 stream 攒起来
194
+ ...
195
+ ```
196
+
197
+ - 协议不感知 Tool/MCP,只接收 `ToolSchema`(与 `ToolDef` 解耦)
198
+ - HTTP 错误用 `yield ModelEvent(type="error", error=...)` 表达,不抛
199
+
200
+ ## 架构
201
+
202
+ ```
203
+ .minicode/skills/ .minicode/mcp.json .minicode/config.yaml
204
+ │ │ │
205
+ scan ▼ load ▼ load ▼
206
+ ┌─────────────┐ ┌─────────────────┐ ┌─────────────────┐
207
+ │SkillLoader │ │ McpClient │ │ ModelRegistry │
208
+ │ │ │ (stdio+http) │ │ (openai/anthropic/demo) │
209
+ └──────┬──────┘ └────────┬────────┘ └────────┬────────┘
210
+ │ │ │
211
+ │ inject │ tools/list │ build
212
+ ▼ ▼ ▼
213
+ ┌─────────────┐ ┌─────────────────┐ ┌─────────────────┐
214
+ │ SkillTool │ │ McpToolAdapter │ │ OpenAICompat │
215
+ │ (builtin) │ │ (kind=MCP) │ │ Anthropic │
216
+ └─────────────┘ └─────────────────┘ │ Demo │
217
+ └─────────────────┘
218
+ │ │ │
219
+ │ ┌────────────────────┴────────────────────────┐ │
220
+ └───────▶│ ToolRegistry │ │
221
+ │ id → ToolDef (all kinds) │ │
222
+ └────────────────────┬────────────────────────┘ │
223
+ │ │
224
+ │ tools │ model
225
+ ▼ ▼
226
+ ┌──────────────────────────┐ ┌────────────────┐
227
+ │ ReAct 循环(v2 待做) │ │ /model test │
228
+ └──────────────────────────┘ └────────────────┘
229
+ ```
230
+
231
+ ## 与原 mimo code 的差异
232
+
233
+ | 维度 | mimo code (TS) | minicode (Py) |
234
+ | --- | --- | --- |
235
+ | 语言 | TypeScript + Effect | Python 3.10+ + Pydantic |
236
+ | 异步模型 | Effect.gen | async/await |
237
+ | 工具 schema | zod | Pydantic BaseModel |
238
+ | MCP SDK | 官方 @modelcontextprotocol/sdk | 自研最小 JSON-RPC over stdio/http |
239
+ | 内置工具数 | 21 | 7(保留核心) |
240
+ | Skill 协议 | 完整(嵌套 + 外部目录 + 远程拉取) | 简化(`<name>/SKILL.md` + frontmatter) |
241
+ | Model 协议 | Vercel AI SDK | 自研(`stream()` + `complete()`) |
242
+ | provider | 11 种 | 2 种(openai-compat + anthropic)+ 1 demo |
243
+ | LLM 循环 | 接好 | **未接**(v2) |
244
+
245
+ ## 下一步
246
+
247
+ 1. **ReAct 循环**(v2):把 `ToolRegistry` 的工具转成 `ToolSchema` 给 LLM,处理 `tool_call_delta` → 调 `ToolRegistry.execute` → 灌回 `Message.tool_result` → 下一轮
248
+ 2. **权限系统**:完善 `ctx.ask` 的实际行为(allow/deny/ask)
249
+ 3. **truncate 服务**:超过阈值的输出写入临时文件,原始位置放占位
250
+ 4. **plugin / hooks**:参照 mimo code 的 plugin system
251
+ 5. **Google provider**(v3):Gemini generateContent
252
+
253
+ ## 测试
254
+
255
+ ```bash
256
+ pip install pytest pytest-asyncio
257
+ python -m pytest tests/ -v
258
+ ```
259
+
260
+ 应该看到 39 个测试全过。
261
+
262
+ ## 已知问题
263
+
264
+ - Windows 终端默认 GBK 编码会乱码。在自己的终端跑前请先 `chcp 65001` 或换 Windows Terminal + Cascadia Code。
265
+ - v2 才接 LLM 循环。/model test 用来单点测试连通性。
@@ -0,0 +1,5 @@
1
+ pyminicode-0.1.0.dist-info/METADATA,sha256=SIN0ly5X6rcwawI7DvEo2YZGROMCgamSHrN-vZ-sWbI,12057
2
+ pyminicode-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
3
+ pyminicode-0.1.0.dist-info/entry_points.txt,sha256=v3_Je4n7ZldtI8ImTTNoCHt49HatKrHdQQn1w5AN3Ms,51
4
+ pyminicode-0.1.0.dist-info/top_level.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
5
+ pyminicode-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ minicode = minicode.cli.app:main
@@ -0,0 +1 @@
1
+