mlx-code 0.0.4__tar.gz → 0.0.5__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.
@@ -0,0 +1,274 @@
1
+ Metadata-Version: 2.4
2
+ Name: mlx-code
3
+ Version: 0.0.5
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
13
+ Requires-Dist: numpy
14
+ Requires-Dist: httpx
15
+ Requires-Dist: pydantic
16
+ Dynamic: author
17
+ Dynamic: author-email
18
+ Dynamic: description
19
+ Dynamic: description-content-type
20
+ Dynamic: home-page
21
+ Dynamic: license
22
+ Dynamic: license-file
23
+ Dynamic: requires-dist
24
+ Dynamic: requires-python
25
+ Dynamic: summary
26
+
27
+ # mlx-code
28
+
29
+ [![Link](https://raw.githubusercontent.com/JosefAlbers/mlx-code/main/assets/mlx-code.gif)](https://youtu.be/bizPhrHL1_w)
30
+
31
+ A lightweight, powerful Coding Agent for Mac. Built on top of Apple's MLX framework, `mlx-code` provides fast, local inference with built-in prompt caching and robust tool-calling capabilities.
32
+
33
+ ### Features
34
+
35
+ * **Multi-Provider Compatibility**: Seamlessly translates and handles requests formatted for **Claude**, **Gemini**, **Codex**, and **DeepSeek**.
36
+ * **Built-in REPL & Tools**: Comes with `pie`, a fully-featured REPL with tool execution and reasoning token support.
37
+ * **Server Mode**: Easily spin up a local LLM server.
38
+
39
+ ### Quick Start
40
+
41
+ Install via pip and launch the agent immediately:
42
+
43
+ ```bash
44
+ pip install mlx-code
45
+ mc
46
+ ```
47
+
48
+ ### Command Line Interfaces
49
+
50
+ The package installs three primary command-line tools:
51
+ - mc (Main/Server): Launches the local LLM API server (defaults to 127.0.0.1:8000).
52
+ - me (TUI/Harness): Runs the interactive pie chat REPL.
53
+
54
+ ### Options
55
+
56
+ You can customize the model, server, and behavior using command-line flags.
57
+
58
+ ```bash
59
+ # Use Gemini CLI as the harness
60
+ mc --harness gemini
61
+
62
+ # Use a custom local LLM backend
63
+ mc --model mlx-community/Qwen3.5-4B-OptiQ-4bit
64
+
65
+ # Use DeepSeek V4 Flash API
66
+ me --deepseek
67
+
68
+ # Run the server only
69
+ mc --nocc
70
+
71
+ # General shell piping and chaining works too
72
+ echo "explain symgraph.py" | mc -d | cat - PLAN.md | mc
73
+ ```
74
+ *(For a full list of mc server arguments, run mc --help)*
75
+
76
+ ### Credits
77
+
78
+ - `main.py`: Built on [MLX](https://github.com/ml-explore/mlx) and [MLX LM](https://github.com/ml-explore/mlx-lm) by Apple.
79
+ - `pie.py`: Adapted from [pi](https://github.com/badlogic/pi-mono) by Mario Zechner (MIT License).
80
+
81
+ ### Licence
82
+
83
+ Apache License 2.0 — see LICENSE for details.
84
+
85
+ <details><summary>...</summary><pre>
86
+
87
+ ~/D/tmp> mc
88
+ pie REPL • type /help for commands, Ctrl-D or 'exit' to quit.
89
+
90
+ ≫ explain symgraph.py
91
+ π The user wants me to explain symgraph.py. I should first look at the file to understand its contents. Let me use the ReadAST function to inspect this file.
92
+
93
+ ReadAST {"path": "symgraph.py"} This looks like a Python file that defines a graph-based system for analyzing code. Let me get more details about the main components by looking up the key symbols.
94
+
95
+ ReadAST {"path": "symgraph.py", "symbols": "[\"Edge\", \"Graph\", \"DefCollector\", \"TypeInfo\", \"TypeInferrer\", \"EdgeEmitte This is a comprehensive Python file that builds a symbolic graph representation of Python code. Let me provide a clear explanation of what this file does.
96
+
97
+ ## Overview
98
+
99
+ `symgraph.py` is a **symbolic graph builder** for Python code that constructs a directed graph representation of Python modules, classes, functions, and their relationships. It uses Python's `ast` (Abstract Syntax Tree) module to analyze code and build a graph where nodes are symbols and edges represent relationships like calls and references.
100
+
101
+ ## Key Components
102
+
103
+ ### 1. **Edge** (47-60)
104
+ Represents relationships between symbols:
105
+ - `src`, `dst`: source and destination symbols
106
+ - `kind`: "call" or "ref" (call or reference)
107
+ - `via`: optional alias/variable name for indirect references
108
+
109
+ ### 2. **Graph** (67-167)
110
+ The main graph structure that stores:
111
+ - `symbols`: list of all discovered symbols
112
+ - `edges`: list of all relationships
113
+ - Internal indexes for efficient lookup (`_sym_by_qname`, `_uses`, `_used_by`)
114
+
115
+ ### 3. **DefCollector** (186-238)
116
+ First pass visitor that collects all definitions:
117
+ - Classes, functions, methods, module-level variables
118
+ - Tracks scope (class/function nesting)
119
+ - No type inference, just definition collection
120
+
121
+ ### 4. **TypeInferrer** (253-464)
122
+ Second pass that infers types using **fixpoint iteration**:
123
+ - Tracks local variable types per scope
124
+ - Resolves return types from annotations
125
+ - Handles class instances and method calls
126
+ - Uses `ast.NodeVisitor` with proper scope tracking
127
+
128
+ ### 5. **EdgeEmitter** (471-700)
129
+ Third pass that emits edges based on type information:
130
+ - Emits "call" edges for function/method calls
131
+ - Emits "ref" edges for variable references
132
+ - Handles `__call__` for class instances
133
+ - Tracks live local variable environments
134
+
135
+ ### 6. **build()** (730-755)
136
+ Main entry point that orchestrates the three passes:
137
+ 1. Collect definitions
138
+ 2. Infer types (fixpoint)
139
+ 3. Emit edges
140
+
141
+ ### 7. **main()** (762-776)
142
+ CLI interface:
143
+ - `symgraph.py <path>` → outputs all edges as JSON
144
+ - `symgraph.py <path> <query>` → queries for symbols matching a name
145
+
146
+ ## How It Works
147
+
148
+ ```
149
+ ┌─────────────────────────────────────────────────────────────┐
150
+ │ Pass 1: DefCollector │
151
+ │ └─ Collects all symbols (classes, functions, variables) │
152
+ └─────────────────────────────────────────────────────────────┘
153
+
154
+ ┌─────────────────────────────────────────────────────────────┐
155
+ │ Pass 2: TypeInferrer (fixpoint) │
156
+ │ └─ Infers types, return types, class instances │
157
+ └─────────────────────────────────────────────────────────────┘
158
+
159
+ ┌─────────────────────────────────────────────────────────────┐
160
+ │ Pass 3: EdgeEmitter │
161
+ │ └─ Emits call/ref edges based on type info │
162
+ └─────────────────────────────────────────────────────────────┘
163
+ ```
164
+
165
+ ## Use Cases
166
+
167
+ This tool is useful for:
168
+ - **Dependency analysis** - understand call graphs and dependencies
169
+ - **Code navigation** - find where symbols are used
170
+ - **Refactoring** - understand impact of changes
171
+ - **Static analysis** - detect unused code, circular dependencies
172
+
173
+ The graph can be queried to find all uses of a symbol, all callers, or all references within a module.
174
+ ≫ Add a method to Graph called clear_edges() that resets edges, _edge_keys, _uses, and _used_by to empty.
175
+ π The user wants me to add a `clear_edges()` method to the `Graph` class that resets the edges and related internal structures. I need to:1. Add the method to the Graph class2. Reset `self.edges`, `self._edge_keys`, `self._uses`, and `self._used_by` to emptyLet me first read the Graph class to see its current structure, then add the method.
176
+
177
+ Edit {"path": "symgraph.py", "old_text": "# \u2500\u2500 query \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u The edit was successful. Let me verify the change by reading the updated section of the file to confirm the method was added correctly.
178
+
179
+ ReadAST {"path": "symgraph.py", "symbols": "[\"Graph\"]"} The edit was successful. The `clear_edges()` method has been added to the `Graph` class. It resets:- `self.edges` - the list of edges- `self._edge_keys` - the set of edge keys (to prevent duplicate edges)- `self._uses` - the dictionary tracking which symbols use which edges- `self._used_by` - the dictionary tracking which symbols are used by which edgesThe symbols list is NOT cleared, which makes sense since we want to keep the symbol definitions but just clear the edges.Let me provide a summary of what was added.
180
+
181
+ Done! I've added the `clear_edges()` method to the `Graph` class. Here's what it does:
182
+
183
+ ```python
184
+ def clear_edges(self) -> None:
185
+ """Reset all edges and related internal structures."""
186
+ self.edges.clear()
187
+ self._edge_keys.clear()
188
+ self._uses.clear()
189
+ self._used_by.clear()
190
+ ```
191
+
192
+ This method:
193
+ - Clears all edges from the graph
194
+ - Resets the edge key set (prevents duplicate edges)
195
+ - Clears the `_uses` mapping (which symbols use which edges)
196
+ - Clears the `_used_by` mapping (which symbols are used by which edges)
197
+
198
+ **Note:** It does NOT clear `self.symbols` or `self._sym_by_qname`, so symbol definitions are preserved while only the edge relationships are reset. This is useful for:
199
+ - Re-running edge emission on the same symbols
200
+ - Building multiple graphs from the same codebase
201
+ - Resetting the graph state without losing collected definitions
202
+ ≫ exit
203
+ Bye!
204
+ ~/D/tmp> gg *.py
205
+ staging: log.py
206
+ exists
207
+ staging: main.py
208
+ exists
209
+ staging: pie.py
210
+ exists
211
+ staging: symgraph.py
212
+ exists
213
+
214
+ Diff preview:
215
+ Users/jjms/Downloads/tmp/symgraph.py | 7 +++++++
216
+ 1 file changed, 7 insertions(+)
217
+
218
+ Show per-file diffs? [s=skip]: s
219
+
220
+ read> symgraph edit by mlx-code
221
+ Saved snapshot 09529bc9bcbc6d1ff761618c982ece9a290f50fb
222
+
223
+ ~/D/tmp> md
224
+
225
+ ┌─ logs ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐┌─ detail ──────────────────────────────────────────────────────────────────────────┐
226
+ │ TIME LVL FILE FUNC MESSAGE …││ time : 2026-05-05T20:55:26.707364+00:00 │
227
+ │ 20:55:21 INFO main.py main args=Namespace(model='mlx-community/Qwen3.5-4B-OptiQ-4bit', api='de…││ level : INFO │
228
+ │ 20:55:26 INFO pie.py _repl explain symgraph.py ││ logger : root │
229
+ │ 20:55:26 INFO main.py do_POST self.path='/v1/chat/completions' { "model": "jj", "max_tokens": 819…││ file : tmp/main.py │
230
+ │ 20:55:26 DEBUG main.py translate messages=[Message(role='system', content='You are a helpful assista…││ function : do_POST │
231
+ │ 20:55:26 INFO main.py encode ckpts=[742] <|im_start|>system # Tools You have access to the follo…││ line : 1432 │
232
+ │ 20:55:26 INFO main.py __call__ ckpts=[742] len(prompt)=753 len(self.hx)=0 cl=0 ││ id : bdedc2c5-00a5-49od-9bj9-890a6e2a89b1 │
233
+ │ 20:55:26 DEBUG main.py load cache/mlxcommunityQwen354BOptiQ4bit_742_3bb19df63c78dde8.safetensor…││ │
234
+ │ 20:55:27 DEBUG main.py generate pmt Processed 753 input tokens in 0 seconds (4684 tokens per second…││ ── message ── │
235
+ │ 20:55:27 INFO main.py generate gen The user wants me to explain symgraph.py. I should first look a…││ self.path='/v1/chat/completions' │
236
+ │ 20:55:27 DEBUG pie.py _loop AssistantMessage(content=[ThinkingContent(thinking='The user wants …││ { │
237
+ │ 20:55:27 DEBUG pie.py on_event symgraph.py ─────────────── [C] Symbol (32-43) [C] Edge (47-60) [C…││ "model": "jj", │
238
+ │ 20:55:28 INFO main.py do_POST self.path='/v1/chat/completions' { "model": "jj", "max_tokens": 819…││ "max_tokens": 8192, │
239
+ │ 20:55:28 DEBUG main.py translate messages=[Message(role='system', content='You are a helpful assista…││ "messages": [ │
240
+ │ 20:55:28 INFO main.py encode ckpts=[742] <|im_start|>system # Tools You have access to the follo…││ { │
241
+ │ 20:55:28 INFO main.py __call__ ckpts=[742] len(prompt)=1015 len(self.hx)=818 cl=818 ││ "role": "system", │
242
+ │ 20:55:28 DEBUG main.py __call__ cont ││ "content": "You are a helpful assistant." │
243
+ │ 20:55:28 DEBUG main.py generate pmt Processed 1015 input tokens in 1 seconds (1761 tokens per secon…││ }, │
244
+ │ 20:55:30 INFO main.py generate gen This looks like a Python file that defines a graph-based system…││ { │
245
+ │ 20:55:30 DEBUG pie.py _loop AssistantMessage(content=[ThinkingContent(thinking='This looks like…││ "role": "user", │
246
+ │ 20:55:30 DEBUG pie.py on_event # DEF class symgraph.Edge /private/var/folders/_5/vz_p3mls23l5rtlhj…││ "content": "explain symgraph.py" │
247
+ │ 20:55:30 INFO main.py do_POST self.path='/v1/chat/completions' { "model": "jj", "max_tokens": 819…││ } │
248
+ │ 20:55:30 DEBUG main.py translate messages=[Message(role='system', content='You are a helpful assista…││ ], │
249
+ │ 20:55:30 INFO main.py encode ckpts=[742] <|im_start|>system # Tools You have access to the follo…││ "stream": true, │
250
+ │ 20:55:30 INFO main.py __call__ ckpts=[742] len(prompt)=12781 len(self.hx)=1117 cl=1117 ││ "tools": [ │
251
+ │ 20:55:30 DEBUG main.py __call__ cont ││ { │
252
+ │ 20:55:58 DEBUG main.py generate pmt Processed 12781 input tokens in 28 seconds (454 tokens per seco…││ "type": "function", │
253
+ │ 20:56:11 INFO main.py generate gen This is a comprehensive Python file that builds a symbolic grap…││ "function": { │
254
+ │ 20:56:11 DEBUG pie.py _loop AssistantMessage(content=[ThinkingContent(thinking='This is a compr…││ "name": "Read", │
255
+ │ 20:56:25 INFO pie.py _repl Add a method to Graph called clear_edges() that resets edges, _edge…││ "description": "Read a file. Use offset/limit for large files instead of │
256
+ │ 20:56:25 INFO main.py do_POST self.path='/v1/chat/completions' { "model": "jj", "max_tokens": 819…││ reading the whole thing.", │
257
+ │ 20:56:25 DEBUG main.py translate messages=[Message(role='system', content='You are a helpful assista…││ "parameters": { │
258
+ │ 20:56:25 INFO main.py encode ckpts=[742, 13481] <|im_start|>system # Tools You have access to th…││ "type": "object", │
259
+ │ 20:56:25 INFO main.py __call__ ckpts=[13481, 742] len(prompt)=13515 len(self.hx)=13586 cl=751 ││ "properties": { │
260
+ │ 20:56:25 DEBUG main.py load cache/mlxcommunityQwen354BOptiQ4bit_742_3bb19df63c78dde8.safetensor…││ "path": { │
261
+ │ 20:56:25 DEBUG main.py generate save_fn 13481 ││ "description": "File path to read (relative to cwd)", │
262
+ │ 20:56:56 DEBUG main.py generate pmt Processed 13515 input tokens in 31 seconds (438 tokens per seco…││ "title": "Path", │
263
+ │ 20:57:00 INFO main.py generate gen The user wants me to add a `clear_edges()` method to the `Graph…││ "type": "string" │
264
+ │ 20:57:00 DEBUG pie.py _loop AssistantMessage(content=[ThinkingContent(thinking='The user wants …││ }, │
265
+ │ 20:57:00 DEBUG pie.py on_event edited symgraph.py: replaced 3 line(s) with 10 line(s) ││ "offset": { │
266
+ │ 20:57:00 INFO main.py do_POST self.path='/v1/chat/completions' { "model": "jj", "max_tokens": 819…││ "anyOf": [ │
267
+ │ 20:57:00 DEBUG main.py translate messages=[Message(role='system', content='You are a helpful assista…││ { │
268
+ │ 20:57:00 INFO main.py encode ckpts=[742, 13481] <|im_start|>system # Tools You have access to th…││ "type": "integer" │
269
+ │ 20:57:00 INFO main.py __call__ ckpts=[13481, 742] len(prompt)=13801 len(self.hx)=13768 cl=13768 ││ }, │
270
+ │ 20:57:00 DEBUG main.py __call__ cont ││ { │
271
+ └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘└───────────────────────────────────────────────────────────────────────────────────┘
272
+ All bdedc2c5-0 8j7j3o1e-6
273
+ log.json │ 3/58 (of 172) filter: lvl:10;file:main,pie │ ↑/k ↓/j · PgUp/PgDn · g/G · n/N · * highlight · o open · ; filter · h/l tabs · q quit
274
+ </pre></details><br>
@@ -0,0 +1,248 @@
1
+ # mlx-code
2
+
3
+ [![Link](https://raw.githubusercontent.com/JosefAlbers/mlx-code/main/assets/mlx-code.gif)](https://youtu.be/bizPhrHL1_w)
4
+
5
+ A lightweight, powerful Coding Agent for Mac. Built on top of Apple's MLX framework, `mlx-code` provides fast, local inference with built-in prompt caching and robust tool-calling capabilities.
6
+
7
+ ### Features
8
+
9
+ * **Multi-Provider Compatibility**: Seamlessly translates and handles requests formatted for **Claude**, **Gemini**, **Codex**, and **DeepSeek**.
10
+ * **Built-in REPL & Tools**: Comes with `pie`, a fully-featured REPL with tool execution and reasoning token support.
11
+ * **Server Mode**: Easily spin up a local LLM server.
12
+
13
+ ### Quick Start
14
+
15
+ Install via pip and launch the agent immediately:
16
+
17
+ ```bash
18
+ pip install mlx-code
19
+ mc
20
+ ```
21
+
22
+ ### Command Line Interfaces
23
+
24
+ The package installs three primary command-line tools:
25
+ - mc (Main/Server): Launches the local LLM API server (defaults to 127.0.0.1:8000).
26
+ - me (TUI/Harness): Runs the interactive pie chat REPL.
27
+
28
+ ### Options
29
+
30
+ You can customize the model, server, and behavior using command-line flags.
31
+
32
+ ```bash
33
+ # Use Gemini CLI as the harness
34
+ mc --harness gemini
35
+
36
+ # Use a custom local LLM backend
37
+ mc --model mlx-community/Qwen3.5-4B-OptiQ-4bit
38
+
39
+ # Use DeepSeek V4 Flash API
40
+ me --deepseek
41
+
42
+ # Run the server only
43
+ mc --nocc
44
+
45
+ # General shell piping and chaining works too
46
+ echo "explain symgraph.py" | mc -d | cat - PLAN.md | mc
47
+ ```
48
+ *(For a full list of mc server arguments, run mc --help)*
49
+
50
+ ### Credits
51
+
52
+ - `main.py`: Built on [MLX](https://github.com/ml-explore/mlx) and [MLX LM](https://github.com/ml-explore/mlx-lm) by Apple.
53
+ - `pie.py`: Adapted from [pi](https://github.com/badlogic/pi-mono) by Mario Zechner (MIT License).
54
+
55
+ ### Licence
56
+
57
+ Apache License 2.0 — see LICENSE for details.
58
+
59
+ <details><summary>...</summary><pre>
60
+
61
+ ~/D/tmp> mc
62
+ pie REPL • type /help for commands, Ctrl-D or 'exit' to quit.
63
+
64
+ ≫ explain symgraph.py
65
+ π The user wants me to explain symgraph.py. I should first look at the file to understand its contents. Let me use the ReadAST function to inspect this file.
66
+
67
+ ReadAST {"path": "symgraph.py"} This looks like a Python file that defines a graph-based system for analyzing code. Let me get more details about the main components by looking up the key symbols.
68
+
69
+ ReadAST {"path": "symgraph.py", "symbols": "[\"Edge\", \"Graph\", \"DefCollector\", \"TypeInfo\", \"TypeInferrer\", \"EdgeEmitte This is a comprehensive Python file that builds a symbolic graph representation of Python code. Let me provide a clear explanation of what this file does.
70
+
71
+ ## Overview
72
+
73
+ `symgraph.py` is a **symbolic graph builder** for Python code that constructs a directed graph representation of Python modules, classes, functions, and their relationships. It uses Python's `ast` (Abstract Syntax Tree) module to analyze code and build a graph where nodes are symbols and edges represent relationships like calls and references.
74
+
75
+ ## Key Components
76
+
77
+ ### 1. **Edge** (47-60)
78
+ Represents relationships between symbols:
79
+ - `src`, `dst`: source and destination symbols
80
+ - `kind`: "call" or "ref" (call or reference)
81
+ - `via`: optional alias/variable name for indirect references
82
+
83
+ ### 2. **Graph** (67-167)
84
+ The main graph structure that stores:
85
+ - `symbols`: list of all discovered symbols
86
+ - `edges`: list of all relationships
87
+ - Internal indexes for efficient lookup (`_sym_by_qname`, `_uses`, `_used_by`)
88
+
89
+ ### 3. **DefCollector** (186-238)
90
+ First pass visitor that collects all definitions:
91
+ - Classes, functions, methods, module-level variables
92
+ - Tracks scope (class/function nesting)
93
+ - No type inference, just definition collection
94
+
95
+ ### 4. **TypeInferrer** (253-464)
96
+ Second pass that infers types using **fixpoint iteration**:
97
+ - Tracks local variable types per scope
98
+ - Resolves return types from annotations
99
+ - Handles class instances and method calls
100
+ - Uses `ast.NodeVisitor` with proper scope tracking
101
+
102
+ ### 5. **EdgeEmitter** (471-700)
103
+ Third pass that emits edges based on type information:
104
+ - Emits "call" edges for function/method calls
105
+ - Emits "ref" edges for variable references
106
+ - Handles `__call__` for class instances
107
+ - Tracks live local variable environments
108
+
109
+ ### 6. **build()** (730-755)
110
+ Main entry point that orchestrates the three passes:
111
+ 1. Collect definitions
112
+ 2. Infer types (fixpoint)
113
+ 3. Emit edges
114
+
115
+ ### 7. **main()** (762-776)
116
+ CLI interface:
117
+ - `symgraph.py <path>` → outputs all edges as JSON
118
+ - `symgraph.py <path> <query>` → queries for symbols matching a name
119
+
120
+ ## How It Works
121
+
122
+ ```
123
+ ┌─────────────────────────────────────────────────────────────┐
124
+ │ Pass 1: DefCollector │
125
+ │ └─ Collects all symbols (classes, functions, variables) │
126
+ └─────────────────────────────────────────────────────────────┘
127
+
128
+ ┌─────────────────────────────────────────────────────────────┐
129
+ │ Pass 2: TypeInferrer (fixpoint) │
130
+ │ └─ Infers types, return types, class instances │
131
+ └─────────────────────────────────────────────────────────────┘
132
+
133
+ ┌─────────────────────────────────────────────────────────────┐
134
+ │ Pass 3: EdgeEmitter │
135
+ │ └─ Emits call/ref edges based on type info │
136
+ └─────────────────────────────────────────────────────────────┘
137
+ ```
138
+
139
+ ## Use Cases
140
+
141
+ This tool is useful for:
142
+ - **Dependency analysis** - understand call graphs and dependencies
143
+ - **Code navigation** - find where symbols are used
144
+ - **Refactoring** - understand impact of changes
145
+ - **Static analysis** - detect unused code, circular dependencies
146
+
147
+ The graph can be queried to find all uses of a symbol, all callers, or all references within a module.
148
+ ≫ Add a method to Graph called clear_edges() that resets edges, _edge_keys, _uses, and _used_by to empty.
149
+ π The user wants me to add a `clear_edges()` method to the `Graph` class that resets the edges and related internal structures. I need to:1. Add the method to the Graph class2. Reset `self.edges`, `self._edge_keys`, `self._uses`, and `self._used_by` to emptyLet me first read the Graph class to see its current structure, then add the method.
150
+
151
+ Edit {"path": "symgraph.py", "old_text": "# \u2500\u2500 query \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u The edit was successful. Let me verify the change by reading the updated section of the file to confirm the method was added correctly.
152
+
153
+ ReadAST {"path": "symgraph.py", "symbols": "[\"Graph\"]"} The edit was successful. The `clear_edges()` method has been added to the `Graph` class. It resets:- `self.edges` - the list of edges- `self._edge_keys` - the set of edge keys (to prevent duplicate edges)- `self._uses` - the dictionary tracking which symbols use which edges- `self._used_by` - the dictionary tracking which symbols are used by which edgesThe symbols list is NOT cleared, which makes sense since we want to keep the symbol definitions but just clear the edges.Let me provide a summary of what was added.
154
+
155
+ Done! I've added the `clear_edges()` method to the `Graph` class. Here's what it does:
156
+
157
+ ```python
158
+ def clear_edges(self) -> None:
159
+ """Reset all edges and related internal structures."""
160
+ self.edges.clear()
161
+ self._edge_keys.clear()
162
+ self._uses.clear()
163
+ self._used_by.clear()
164
+ ```
165
+
166
+ This method:
167
+ - Clears all edges from the graph
168
+ - Resets the edge key set (prevents duplicate edges)
169
+ - Clears the `_uses` mapping (which symbols use which edges)
170
+ - Clears the `_used_by` mapping (which symbols are used by which edges)
171
+
172
+ **Note:** It does NOT clear `self.symbols` or `self._sym_by_qname`, so symbol definitions are preserved while only the edge relationships are reset. This is useful for:
173
+ - Re-running edge emission on the same symbols
174
+ - Building multiple graphs from the same codebase
175
+ - Resetting the graph state without losing collected definitions
176
+ ≫ exit
177
+ Bye!
178
+ ~/D/tmp> gg *.py
179
+ staging: log.py
180
+ exists
181
+ staging: main.py
182
+ exists
183
+ staging: pie.py
184
+ exists
185
+ staging: symgraph.py
186
+ exists
187
+
188
+ Diff preview:
189
+ Users/jjms/Downloads/tmp/symgraph.py | 7 +++++++
190
+ 1 file changed, 7 insertions(+)
191
+
192
+ Show per-file diffs? [s=skip]: s
193
+
194
+ read> symgraph edit by mlx-code
195
+ Saved snapshot 09529bc9bcbc6d1ff761618c982ece9a290f50fb
196
+
197
+ ~/D/tmp> md
198
+
199
+ ┌─ logs ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐┌─ detail ──────────────────────────────────────────────────────────────────────────┐
200
+ │ TIME LVL FILE FUNC MESSAGE …││ time : 2026-05-05T20:55:26.707364+00:00 │
201
+ │ 20:55:21 INFO main.py main args=Namespace(model='mlx-community/Qwen3.5-4B-OptiQ-4bit', api='de…││ level : INFO │
202
+ │ 20:55:26 INFO pie.py _repl explain symgraph.py ││ logger : root │
203
+ │ 20:55:26 INFO main.py do_POST self.path='/v1/chat/completions' { "model": "jj", "max_tokens": 819…││ file : tmp/main.py │
204
+ │ 20:55:26 DEBUG main.py translate messages=[Message(role='system', content='You are a helpful assista…││ function : do_POST │
205
+ │ 20:55:26 INFO main.py encode ckpts=[742] <|im_start|>system # Tools You have access to the follo…││ line : 1432 │
206
+ │ 20:55:26 INFO main.py __call__ ckpts=[742] len(prompt)=753 len(self.hx)=0 cl=0 ││ id : bdedc2c5-00a5-49od-9bj9-890a6e2a89b1 │
207
+ │ 20:55:26 DEBUG main.py load cache/mlxcommunityQwen354BOptiQ4bit_742_3bb19df63c78dde8.safetensor…││ │
208
+ │ 20:55:27 DEBUG main.py generate pmt Processed 753 input tokens in 0 seconds (4684 tokens per second…││ ── message ── │
209
+ │ 20:55:27 INFO main.py generate gen The user wants me to explain symgraph.py. I should first look a…││ self.path='/v1/chat/completions' │
210
+ │ 20:55:27 DEBUG pie.py _loop AssistantMessage(content=[ThinkingContent(thinking='The user wants …││ { │
211
+ │ 20:55:27 DEBUG pie.py on_event symgraph.py ─────────────── [C] Symbol (32-43) [C] Edge (47-60) [C…││ "model": "jj", │
212
+ │ 20:55:28 INFO main.py do_POST self.path='/v1/chat/completions' { "model": "jj", "max_tokens": 819…││ "max_tokens": 8192, │
213
+ │ 20:55:28 DEBUG main.py translate messages=[Message(role='system', content='You are a helpful assista…││ "messages": [ │
214
+ │ 20:55:28 INFO main.py encode ckpts=[742] <|im_start|>system # Tools You have access to the follo…││ { │
215
+ │ 20:55:28 INFO main.py __call__ ckpts=[742] len(prompt)=1015 len(self.hx)=818 cl=818 ││ "role": "system", │
216
+ │ 20:55:28 DEBUG main.py __call__ cont ││ "content": "You are a helpful assistant." │
217
+ │ 20:55:28 DEBUG main.py generate pmt Processed 1015 input tokens in 1 seconds (1761 tokens per secon…││ }, │
218
+ │ 20:55:30 INFO main.py generate gen This looks like a Python file that defines a graph-based system…││ { │
219
+ │ 20:55:30 DEBUG pie.py _loop AssistantMessage(content=[ThinkingContent(thinking='This looks like…││ "role": "user", │
220
+ │ 20:55:30 DEBUG pie.py on_event # DEF class symgraph.Edge /private/var/folders/_5/vz_p3mls23l5rtlhj…││ "content": "explain symgraph.py" │
221
+ │ 20:55:30 INFO main.py do_POST self.path='/v1/chat/completions' { "model": "jj", "max_tokens": 819…││ } │
222
+ │ 20:55:30 DEBUG main.py translate messages=[Message(role='system', content='You are a helpful assista…││ ], │
223
+ │ 20:55:30 INFO main.py encode ckpts=[742] <|im_start|>system # Tools You have access to the follo…││ "stream": true, │
224
+ │ 20:55:30 INFO main.py __call__ ckpts=[742] len(prompt)=12781 len(self.hx)=1117 cl=1117 ││ "tools": [ │
225
+ │ 20:55:30 DEBUG main.py __call__ cont ││ { │
226
+ │ 20:55:58 DEBUG main.py generate pmt Processed 12781 input tokens in 28 seconds (454 tokens per seco…││ "type": "function", │
227
+ │ 20:56:11 INFO main.py generate gen This is a comprehensive Python file that builds a symbolic grap…││ "function": { │
228
+ │ 20:56:11 DEBUG pie.py _loop AssistantMessage(content=[ThinkingContent(thinking='This is a compr…││ "name": "Read", │
229
+ │ 20:56:25 INFO pie.py _repl Add a method to Graph called clear_edges() that resets edges, _edge…││ "description": "Read a file. Use offset/limit for large files instead of │
230
+ │ 20:56:25 INFO main.py do_POST self.path='/v1/chat/completions' { "model": "jj", "max_tokens": 819…││ reading the whole thing.", │
231
+ │ 20:56:25 DEBUG main.py translate messages=[Message(role='system', content='You are a helpful assista…││ "parameters": { │
232
+ │ 20:56:25 INFO main.py encode ckpts=[742, 13481] <|im_start|>system # Tools You have access to th…││ "type": "object", │
233
+ │ 20:56:25 INFO main.py __call__ ckpts=[13481, 742] len(prompt)=13515 len(self.hx)=13586 cl=751 ││ "properties": { │
234
+ │ 20:56:25 DEBUG main.py load cache/mlxcommunityQwen354BOptiQ4bit_742_3bb19df63c78dde8.safetensor…││ "path": { │
235
+ │ 20:56:25 DEBUG main.py generate save_fn 13481 ││ "description": "File path to read (relative to cwd)", │
236
+ │ 20:56:56 DEBUG main.py generate pmt Processed 13515 input tokens in 31 seconds (438 tokens per seco…││ "title": "Path", │
237
+ │ 20:57:00 INFO main.py generate gen The user wants me to add a `clear_edges()` method to the `Graph…││ "type": "string" │
238
+ │ 20:57:00 DEBUG pie.py _loop AssistantMessage(content=[ThinkingContent(thinking='The user wants …││ }, │
239
+ │ 20:57:00 DEBUG pie.py on_event edited symgraph.py: replaced 3 line(s) with 10 line(s) ││ "offset": { │
240
+ │ 20:57:00 INFO main.py do_POST self.path='/v1/chat/completions' { "model": "jj", "max_tokens": 819…││ "anyOf": [ │
241
+ │ 20:57:00 DEBUG main.py translate messages=[Message(role='system', content='You are a helpful assista…││ { │
242
+ │ 20:57:00 INFO main.py encode ckpts=[742, 13481] <|im_start|>system # Tools You have access to th…││ "type": "integer" │
243
+ │ 20:57:00 INFO main.py __call__ ckpts=[13481, 742] len(prompt)=13801 len(self.hx)=13768 cl=13768 ││ }, │
244
+ │ 20:57:00 DEBUG main.py __call__ cont ││ { │
245
+ └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘└───────────────────────────────────────────────────────────────────────────────────┘
246
+ All bdedc2c5-0 8j7j3o1e-6
247
+ log.json │ 3/58 (of 172) filter: lvl:10;file:main,pie │ ↑/k ↓/j · PgUp/PgDn · g/G · n/N · * highlight · o open · ; filter · h/l tabs · q quit
248
+ </pre></details><br>