mlx-code 0.0.8__tar.gz → 0.0.9__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.
Files changed (37) hide show
  1. mlx_code-0.0.9/PKG-INFO +222 -0
  2. mlx_code-0.0.9/README.md +193 -0
  3. mlx_code-0.0.9/mlx_code/__init__.py +0 -0
  4. mlx_code-0.0.9/mlx_code/apis.py +1133 -0
  5. mlx_code-0.0.9/mlx_code/gits.py +252 -0
  6. mlx_code-0.0.9/mlx_code/lsp_tool.py +882 -0
  7. {mlx_code-0.0.8 → mlx_code-0.0.9}/mlx_code/main.py +792 -745
  8. mlx_code-0.0.9/mlx_code/mcb.py +243 -0
  9. mlx_code-0.0.9/mlx_code/mcb_tool.py +73 -0
  10. mlx_code-0.0.9/mlx_code/repl.py +764 -0
  11. mlx_code-0.0.9/mlx_code/stream_log.py +59 -0
  12. mlx_code-0.0.9/mlx_code/tools.py +503 -0
  13. mlx_code-0.0.9/mlx_code/util.py +49 -0
  14. mlx_code-0.0.9/mlx_code/view_git.py +951 -0
  15. mlx_code-0.0.8/mlx_code/log.py → mlx_code-0.0.9/mlx_code/view_log.py +235 -218
  16. mlx_code-0.0.9/mlx_code.egg-info/PKG-INFO +222 -0
  17. mlx_code-0.0.9/mlx_code.egg-info/SOURCES.txt +24 -0
  18. mlx_code-0.0.9/mlx_code.egg-info/entry_points.txt +5 -0
  19. mlx_code-0.0.9/mlx_code.egg-info/requires.txt +9 -0
  20. {mlx_code-0.0.8 → mlx_code-0.0.9}/mlx_code.egg-info/top_level.txt +1 -0
  21. mlx_code-0.0.9/setup.py +34 -0
  22. mlx_code-0.0.9/tests/__init__.py +0 -0
  23. mlx_code-0.0.9/tests/test.py +75 -0
  24. mlx_code-0.0.8/PKG-INFO +0 -557
  25. mlx_code-0.0.8/README.md +0 -528
  26. mlx_code-0.0.8/mlx_code/__init__.py +0 -4
  27. mlx_code-0.0.8/mlx_code/ledger.py +0 -192
  28. mlx_code-0.0.8/mlx_code/pie.py +0 -2105
  29. mlx_code-0.0.8/mlx_code/symgraph.py +0 -483
  30. mlx_code-0.0.8/mlx_code.egg-info/PKG-INFO +0 -557
  31. mlx_code-0.0.8/mlx_code.egg-info/SOURCES.txt +0 -15
  32. mlx_code-0.0.8/mlx_code.egg-info/entry_points.txt +0 -4
  33. mlx_code-0.0.8/mlx_code.egg-info/requires.txt +0 -7
  34. mlx_code-0.0.8/setup.py +0 -21
  35. {mlx_code-0.0.8 → mlx_code-0.0.9}/LICENSE +0 -0
  36. {mlx_code-0.0.8 → mlx_code-0.0.9}/mlx_code.egg-info/dependency_links.txt +0 -0
  37. {mlx_code-0.0.8 → mlx_code-0.0.9}/setup.cfg +0 -0
@@ -0,0 +1,222 @@
1
+ Metadata-Version: 2.4
2
+ Name: mlx-code
3
+ Version: 0.0.9
4
+ Summary: Coding Agent for Mac
5
+ Home-page: https://github.com/JosefAlbers/mlx-code
6
+ Author: J Joe
7
+ Author-email: albersj66@gmail.com
8
+ License: Apache-2.0
9
+ Requires-Python: >=3.12.8
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Requires-Dist: mlx-lm>=0.31.3; platform_system == "Darwin"
13
+ Requires-Dist: httpx
14
+ Requires-Dist: pydantic
15
+ Requires-Dist: GitPython
16
+ Provides-Extra: all
17
+ Requires-Dist: python-lsp-server[all]; extra == "all"
18
+ Dynamic: author
19
+ Dynamic: author-email
20
+ Dynamic: description
21
+ Dynamic: description-content-type
22
+ Dynamic: home-page
23
+ Dynamic: license
24
+ Dynamic: license-file
25
+ Dynamic: provides-extra
26
+ Dynamic: requires-dist
27
+ Dynamic: requires-python
28
+ Dynamic: summary
29
+
30
+ # mlx-code
31
+
32
+ A lightweight coding agent built on Apple's MLX framework.
33
+
34
+ ![demo](https://raw.githubusercontent.com/JosefAlbers/mlx-code/main/assets/mlx-code.gif)
35
+
36
+ ---
37
+
38
+ ## Features
39
+
40
+ - **Composable by design**: `Agent`, `Tool`, and the REPL are separate pieces you can import and wire together however you like
41
+ - **Swappable backends**: point the harness at the local MLX server, a remote provider, or any OpenAI-compatible endpoint without changing anything else
42
+ - **Git worktree isolation**: every session gets a fresh worktree so the agent can't silently corrupt your working tree
43
+ - **9 built-in tools**: `Read`, `Write`, `Edit`, `Bash`, `Grep`, `Find`, `Ls`, `Skill`, `Agent`
44
+ - **Interactive REPL commands**: `/clear`, `/history`, `/tools`, `/branch`, `/abort`
45
+
46
+ ---
47
+
48
+ ## Quick Start
49
+
50
+ ```bash
51
+ pip install mlx-code[all]
52
+ mlxc
53
+ ```
54
+
55
+ ---
56
+
57
+ ## Command Line
58
+
59
+ ### `mlxc`: local server + harness
60
+
61
+ Starts the MLX inference server and launches a harness against it.
62
+
63
+ ```bash
64
+ # Default: local MLX server + built-in REPL harness
65
+ mlxc
66
+
67
+ # Use a different harness (routes traffic through the local server)
68
+ mlxc --leash claude
69
+ mlxc --leash gemini
70
+ mlxc --leash codex
71
+
72
+ # Server only, no harness
73
+ mlxc --leash none
74
+
75
+ # Specify a model
76
+ mlxc --model mlx-community/Qwen3.5-4B-OptiQ-4bit
77
+
78
+ # Restrict the tools available to the agent
79
+ mlxc --tools Read Write Bash
80
+
81
+ # Custom system prompt
82
+ mlxc --system "You are a helpful assistant."
83
+
84
+ # Load skills from a directory (scans recursively for SKILL.md files)
85
+ mlxc --skill ./my-skills
86
+
87
+ # Resume a previous session from a git commit hash
88
+ mlxc --resume <commit-hash>
89
+
90
+ # Because `mlxc` reads from stdin when it isn't a TTY, it composes naturally with shell pipes:
91
+ echo "explain lsp.py" | mlxc -d | cat - PLAN.md | mlxc
92
+ ```
93
+
94
+ ### `mlxc-run`: harness only
95
+
96
+ Runs the agent harness against an already-running server or a remote provider.
97
+
98
+ ```bash
99
+ # Connect to a local server at 127.0.0.1:8000 (default)
100
+ mlxc-run
101
+
102
+ # Remote providers
103
+ mlxc-run --api claude
104
+ mlxc-run --api gemini
105
+ mlxc-run --api deepseek --model deepseek-v4-pro
106
+ mlxc-run --api codex
107
+
108
+ # Custom endpoint
109
+ mlxc-run --url http://localhost:9000
110
+
111
+ # With skills
112
+ mlxc-run --skill ./my-skills
113
+ ```
114
+
115
+ ---
116
+
117
+ ## Using as a Library
118
+
119
+ Import the pieces you need to build background workers, scheduled jobs, or event-triggered handlers.
120
+
121
+ ### Spawn an agent from Python
122
+
123
+ ```python
124
+ import asyncio
125
+ from mlx_code.repl import Agent
126
+
127
+ async def main():
128
+ agent = Agent(system="You are a concise technical writer.")
129
+ await agent.run("Summarise all *.py files changed in the last 7 days. Save to digest.md.")
130
+
131
+ asyncio.run(main())
132
+ ```
133
+
134
+ ### Multi-agent pipeline
135
+
136
+ ```python
137
+ import asyncio
138
+ from mlx_code.repl import Agent
139
+
140
+ async def main():
141
+ researcher = Agent(system="You are a research assistant.")
142
+ await researcher.run("Research PBFT consensus. Save a structured summary to kb/draft.md.")
143
+
144
+ reviewer = Agent(system="You are a critical reviewer.")
145
+ await reviewer.run(
146
+ "Read kb/draft.md. Write a one-paragraph critique to kb/critique.md. "
147
+ "Use only information in that file."
148
+ )
149
+
150
+ asyncio.run(main())
151
+ ```
152
+
153
+ ### Parallel workers with `asyncio.gather`
154
+
155
+ ```python
156
+ import asyncio
157
+ from mlx_code.repl import Agent
158
+
159
+ async def main():
160
+ topics = ["history", "algorithms", "industry_usage"]
161
+ agents = [Agent() for _ in topics]
162
+ await asyncio.gather(*[
163
+ a.run(f"Research the {t} of Byzantine Fault Tolerance. Save to kb/{t}.md.")
164
+ for a, t in zip(agents, topics)
165
+ ])
166
+ reducer = Agent()
167
+ await reducer.run("Read all files in kb/. Synthesise into final_report.md.")
168
+
169
+ asyncio.run(main())
170
+ ```
171
+
172
+ ### Resume a session from a git commit
173
+
174
+ mlx-code stores the full conversation as JSON in each commit message, so you can restore both the workspace state and the agent's memory from any checkpoint.
175
+
176
+ ```python
177
+ import asyncio
178
+ from mlx_code.gits import resume_worktree
179
+ from mlx_code.repl import Agent, repl
180
+
181
+ async def main():
182
+ gwt, messages = resume_worktree(".", "abc1234")
183
+ agent = Agent(ctx={"gwt": gwt})
184
+ agent.messages = messages
185
+ await repl(agent)
186
+
187
+ asyncio.run(main())
188
+ ```
189
+
190
+ ### Custom tools
191
+
192
+ Subclass `Tool`, define a Pydantic schema, and pass the class at instantiation.
193
+
194
+ ```python
195
+ from mlx_code.tools import Tool
196
+ from mlx_code.repl import Agent
197
+ from pydantic import BaseModel, Field
198
+
199
+ class QueryParams(BaseModel):
200
+ query: str = Field(description="SQL query to run")
201
+
202
+ class LiveDBTool(Tool):
203
+ name = "QueryDB"
204
+ description = "Execute a query against the dev database"
205
+ parameters = QueryParams
206
+
207
+ async def execute(self, params: QueryParams, signal=None) -> dict:
208
+ result = run_query(params.query) # your logic here
209
+ return {"content": [{"type": "text", "text": result}], "is_error": False}
210
+
211
+ agent = Agent(extra_tool_classes=[LiveDBTool], tool_names=["QueryDB"])
212
+ ```
213
+
214
+ ---
215
+
216
+ ## Credits
217
+
218
+ Built on [mlx](https://github.com/ml-explore/mlx) and [mlx-lm](https://github.com/ml-explore/mlx-lm). Inspired by Mario Zechner's [pi](https://github.com/badlogic/pi-mono).
219
+
220
+ ## License
221
+
222
+ Apache License 2.0: see [LICENSE](LICENSE) for details.
@@ -0,0 +1,193 @@
1
+ # mlx-code
2
+
3
+ A lightweight coding agent built on Apple's MLX framework.
4
+
5
+ ![demo](https://raw.githubusercontent.com/JosefAlbers/mlx-code/main/assets/mlx-code.gif)
6
+
7
+ ---
8
+
9
+ ## Features
10
+
11
+ - **Composable by design**: `Agent`, `Tool`, and the REPL are separate pieces you can import and wire together however you like
12
+ - **Swappable backends**: point the harness at the local MLX server, a remote provider, or any OpenAI-compatible endpoint without changing anything else
13
+ - **Git worktree isolation**: every session gets a fresh worktree so the agent can't silently corrupt your working tree
14
+ - **9 built-in tools**: `Read`, `Write`, `Edit`, `Bash`, `Grep`, `Find`, `Ls`, `Skill`, `Agent`
15
+ - **Interactive REPL commands**: `/clear`, `/history`, `/tools`, `/branch`, `/abort`
16
+
17
+ ---
18
+
19
+ ## Quick Start
20
+
21
+ ```bash
22
+ pip install mlx-code[all]
23
+ mlxc
24
+ ```
25
+
26
+ ---
27
+
28
+ ## Command Line
29
+
30
+ ### `mlxc`: local server + harness
31
+
32
+ Starts the MLX inference server and launches a harness against it.
33
+
34
+ ```bash
35
+ # Default: local MLX server + built-in REPL harness
36
+ mlxc
37
+
38
+ # Use a different harness (routes traffic through the local server)
39
+ mlxc --leash claude
40
+ mlxc --leash gemini
41
+ mlxc --leash codex
42
+
43
+ # Server only, no harness
44
+ mlxc --leash none
45
+
46
+ # Specify a model
47
+ mlxc --model mlx-community/Qwen3.5-4B-OptiQ-4bit
48
+
49
+ # Restrict the tools available to the agent
50
+ mlxc --tools Read Write Bash
51
+
52
+ # Custom system prompt
53
+ mlxc --system "You are a helpful assistant."
54
+
55
+ # Load skills from a directory (scans recursively for SKILL.md files)
56
+ mlxc --skill ./my-skills
57
+
58
+ # Resume a previous session from a git commit hash
59
+ mlxc --resume <commit-hash>
60
+
61
+ # Because `mlxc` reads from stdin when it isn't a TTY, it composes naturally with shell pipes:
62
+ echo "explain lsp.py" | mlxc -d | cat - PLAN.md | mlxc
63
+ ```
64
+
65
+ ### `mlxc-run`: harness only
66
+
67
+ Runs the agent harness against an already-running server or a remote provider.
68
+
69
+ ```bash
70
+ # Connect to a local server at 127.0.0.1:8000 (default)
71
+ mlxc-run
72
+
73
+ # Remote providers
74
+ mlxc-run --api claude
75
+ mlxc-run --api gemini
76
+ mlxc-run --api deepseek --model deepseek-v4-pro
77
+ mlxc-run --api codex
78
+
79
+ # Custom endpoint
80
+ mlxc-run --url http://localhost:9000
81
+
82
+ # With skills
83
+ mlxc-run --skill ./my-skills
84
+ ```
85
+
86
+ ---
87
+
88
+ ## Using as a Library
89
+
90
+ Import the pieces you need to build background workers, scheduled jobs, or event-triggered handlers.
91
+
92
+ ### Spawn an agent from Python
93
+
94
+ ```python
95
+ import asyncio
96
+ from mlx_code.repl import Agent
97
+
98
+ async def main():
99
+ agent = Agent(system="You are a concise technical writer.")
100
+ await agent.run("Summarise all *.py files changed in the last 7 days. Save to digest.md.")
101
+
102
+ asyncio.run(main())
103
+ ```
104
+
105
+ ### Multi-agent pipeline
106
+
107
+ ```python
108
+ import asyncio
109
+ from mlx_code.repl import Agent
110
+
111
+ async def main():
112
+ researcher = Agent(system="You are a research assistant.")
113
+ await researcher.run("Research PBFT consensus. Save a structured summary to kb/draft.md.")
114
+
115
+ reviewer = Agent(system="You are a critical reviewer.")
116
+ await reviewer.run(
117
+ "Read kb/draft.md. Write a one-paragraph critique to kb/critique.md. "
118
+ "Use only information in that file."
119
+ )
120
+
121
+ asyncio.run(main())
122
+ ```
123
+
124
+ ### Parallel workers with `asyncio.gather`
125
+
126
+ ```python
127
+ import asyncio
128
+ from mlx_code.repl import Agent
129
+
130
+ async def main():
131
+ topics = ["history", "algorithms", "industry_usage"]
132
+ agents = [Agent() for _ in topics]
133
+ await asyncio.gather(*[
134
+ a.run(f"Research the {t} of Byzantine Fault Tolerance. Save to kb/{t}.md.")
135
+ for a, t in zip(agents, topics)
136
+ ])
137
+ reducer = Agent()
138
+ await reducer.run("Read all files in kb/. Synthesise into final_report.md.")
139
+
140
+ asyncio.run(main())
141
+ ```
142
+
143
+ ### Resume a session from a git commit
144
+
145
+ mlx-code stores the full conversation as JSON in each commit message, so you can restore both the workspace state and the agent's memory from any checkpoint.
146
+
147
+ ```python
148
+ import asyncio
149
+ from mlx_code.gits import resume_worktree
150
+ from mlx_code.repl import Agent, repl
151
+
152
+ async def main():
153
+ gwt, messages = resume_worktree(".", "abc1234")
154
+ agent = Agent(ctx={"gwt": gwt})
155
+ agent.messages = messages
156
+ await repl(agent)
157
+
158
+ asyncio.run(main())
159
+ ```
160
+
161
+ ### Custom tools
162
+
163
+ Subclass `Tool`, define a Pydantic schema, and pass the class at instantiation.
164
+
165
+ ```python
166
+ from mlx_code.tools import Tool
167
+ from mlx_code.repl import Agent
168
+ from pydantic import BaseModel, Field
169
+
170
+ class QueryParams(BaseModel):
171
+ query: str = Field(description="SQL query to run")
172
+
173
+ class LiveDBTool(Tool):
174
+ name = "QueryDB"
175
+ description = "Execute a query against the dev database"
176
+ parameters = QueryParams
177
+
178
+ async def execute(self, params: QueryParams, signal=None) -> dict:
179
+ result = run_query(params.query) # your logic here
180
+ return {"content": [{"type": "text", "text": result}], "is_error": False}
181
+
182
+ agent = Agent(extra_tool_classes=[LiveDBTool], tool_names=["QueryDB"])
183
+ ```
184
+
185
+ ---
186
+
187
+ ## Credits
188
+
189
+ Built on [mlx](https://github.com/ml-explore/mlx) and [mlx-lm](https://github.com/ml-explore/mlx-lm). Inspired by Mario Zechner's [pi](https://github.com/badlogic/pi-mono).
190
+
191
+ ## License
192
+
193
+ Apache License 2.0: see [LICENSE](LICENSE) for details.
File without changes