mlx-code 0.0.26__tar.gz → 0.0.27__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 (28) hide show
  1. {mlx_code-0.0.26 → mlx_code-0.0.27}/PKG-INFO +21 -21
  2. {mlx_code-0.0.26 → mlx_code-0.0.27}/README.md +20 -20
  3. {mlx_code-0.0.26 → mlx_code-0.0.27}/mlx_code/repl.py +36 -9
  4. {mlx_code-0.0.26 → mlx_code-0.0.27}/mlx_code.egg-info/PKG-INFO +21 -21
  5. {mlx_code-0.0.26 → mlx_code-0.0.27}/setup.py +1 -1
  6. {mlx_code-0.0.26 → mlx_code-0.0.27}/LICENSE +0 -0
  7. {mlx_code-0.0.26 → mlx_code-0.0.27}/mlx_code/__init__.py +0 -0
  8. {mlx_code-0.0.26 → mlx_code-0.0.27}/mlx_code/apis.py +0 -0
  9. {mlx_code-0.0.26 → mlx_code-0.0.27}/mlx_code/bare.py +0 -0
  10. {mlx_code-0.0.26 → mlx_code-0.0.27}/mlx_code/bats.py +0 -0
  11. {mlx_code-0.0.26 → mlx_code-0.0.27}/mlx_code/gits.py +0 -0
  12. {mlx_code-0.0.26 → mlx_code-0.0.27}/mlx_code/lsp_tool.py +0 -0
  13. {mlx_code-0.0.26 → mlx_code-0.0.27}/mlx_code/main.py +0 -0
  14. {mlx_code-0.0.26 → mlx_code-0.0.27}/mlx_code/mcb.py +0 -0
  15. {mlx_code-0.0.26 → mlx_code-0.0.27}/mlx_code/mcb_tool.py +0 -0
  16. {mlx_code-0.0.26 → mlx_code-0.0.27}/mlx_code/stream_log.py +0 -0
  17. {mlx_code-0.0.26 → mlx_code-0.0.27}/mlx_code/tools.py +0 -0
  18. {mlx_code-0.0.26 → mlx_code-0.0.27}/mlx_code/util.py +0 -0
  19. {mlx_code-0.0.26 → mlx_code-0.0.27}/mlx_code/view_git.py +0 -0
  20. {mlx_code-0.0.26 → mlx_code-0.0.27}/mlx_code/view_log.py +0 -0
  21. {mlx_code-0.0.26 → mlx_code-0.0.27}/mlx_code.egg-info/SOURCES.txt +0 -0
  22. {mlx_code-0.0.26 → mlx_code-0.0.27}/mlx_code.egg-info/dependency_links.txt +0 -0
  23. {mlx_code-0.0.26 → mlx_code-0.0.27}/mlx_code.egg-info/entry_points.txt +0 -0
  24. {mlx_code-0.0.26 → mlx_code-0.0.27}/mlx_code.egg-info/requires.txt +0 -0
  25. {mlx_code-0.0.26 → mlx_code-0.0.27}/mlx_code.egg-info/top_level.txt +0 -0
  26. {mlx_code-0.0.26 → mlx_code-0.0.27}/setup.cfg +0 -0
  27. {mlx_code-0.0.26 → mlx_code-0.0.27}/tests/__init__.py +0 -0
  28. {mlx_code-0.0.26 → mlx_code-0.0.27}/tests/test.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mlx-code
3
- Version: 0.0.26
3
+ Version: 0.0.27
4
4
  Summary: Coding Agent for Mac
5
5
  Home-page: https://josefalbers.github.io/mlx-code/
6
6
  Author: J Joe
@@ -47,9 +47,9 @@ A Git-native coding agent that can run entirely on your Mac. No API keys, no clo
47
47
  ## Architecture
48
48
 
49
49
  ```
50
- Conversation tree (nodes = git commits with embedded chat history)
50
+ Worktrees:
51
51
 
52
- main ──●──●──●──●──●──●──●──●──●──●──●──●──●──●
52
+ main ──●──●──●──●──●──●──●──●──●──●──●──●──●──●───────────► Node = git commit + chat history
53
53
  │ │
54
54
  │ └── branch-1 ──●──●──●
55
55
  │ │ ┌────────────┐
@@ -58,7 +58,7 @@ Conversation tree (nodes = git commits with embedded chat history)
58
58
  └── branch-0 ──●──●──● │
59
59
 
60
60
 
61
- REPL tabs (each tab = a git branch + agent) │
61
+ Tabs: ├────────────► Tab = git branch + Agent
62
62
 
63
63
 
64
64
  ┌──────────────────────────────────────────────┼─────────┐
@@ -68,20 +68,20 @@ REPL tabs (each tab = a git branch + agent) │
68
68
  │ └──────┘ └────┬─────┘ └──────────┘ └────────────┘ │
69
69
  └─────────────────┼──────────────────────────────────────┘
70
70
 
71
- ├─────────────────────────────────────────► Each tab is an independent Agent
71
+ Agents: ├─────────────────────────────────────────► Each tab runs its own Agent
72
72
 
73
73
  ┌────┴─────────────────────────────────────┐
74
74
  │ Agent │
75
75
  │ ┌────────────────┐ ┌────────────────┐ │
76
76
  │ │ API: │ │ Tools: │ │
77
77
  │ │ Local (mlx-lm) │ │ Read Write │ │
78
- │ │ Claude │ │ Edit Bash │ │
79
- │ │ Gemini │ │ Grep Find │ │
80
- │ │ OpenAI │ │ Ls Skill │ │
81
- └────────────────┘ │ Agent ─────────┼──┼───► Spawns child Agent
82
- └────────────────┘ │ (each with own tools + worktree + etc)
83
- │ Git worktree │
84
- │ (isolation + session state) │
78
+ │ │ Gemini │ │ Edit Bash │ │
79
+ │ │ Claude │ │ Grep Find │ │
80
+ │ │ Codex │ │ Ls Skill │ │
81
+ │ DeepSeek │ │ Agent ─────────┼──┼───► Recursively spawns sub-Agents
82
+ └────────────────┘ └────────────────┘
83
+ │ Git worktree │
84
+ │ (isolation + session state) │
85
85
  └──────────────────────────────────────────┘
86
86
  ```
87
87
 
@@ -97,6 +97,15 @@ result = await agent.run('refactor utils.py to use dataclasses')
97
97
 
98
98
  ---
99
99
 
100
+ ## Core ideas
101
+
102
+ - **Git is the state machine.** Every file-changing agent step is committed with the conversation that produced it, so you can inspect, resume, and branch from any checkpoint.
103
+ - **Branches are alternative futures.** A branch is not just a Git branch; it is a different reasoning path with its own worktree and session state.
104
+ - **Agents are the primitive.** Tabs, branches, and delegated subtasks are all instances of the same `Agent` abstraction.
105
+ - **Worktrees provide isolation.** The agent edits in a separate worktree, so your main checkout stays clean and recoverable.
106
+
107
+ ---
108
+
100
109
  ## Quick start
101
110
 
102
111
  ```bash
@@ -115,15 +124,6 @@ That's it. The first run starts a local inference server and drops you into the
115
124
 
116
125
  ---
117
126
 
118
- ## Core ideas
119
-
120
- - **Git is the state machine.** Every file-changing agent step is committed with the conversation that produced it, so you can inspect, resume, and branch from any checkpoint.
121
- - **Branches are alternative futures.** A branch is not just a Git branch; it is a different reasoning path with its own worktree and session state.
122
- - **Agents are the primitive.** Tabs, branches, and delegated subtasks are all instances of the same `Agent` abstraction.
123
- - **Worktrees provide isolation.** The agent edits in a separate worktree, so your main checkout stays clean and recoverable.
124
-
125
- ---
126
-
127
127
  ## Why mlx-code
128
128
 
129
129
  **Agents as reusable workflow atoms.** Tabs, branches, and tasks are all managed within instances of `Agent`. Each one gets its own conversation, its own tools, and its own worktree. Agents can spawn sub-agents to delegate subtasks, and each child is a full agent with its own scoped tool set.
@@ -9,9 +9,9 @@ A Git-native coding agent that can run entirely on your Mac. No API keys, no clo
9
9
  ## Architecture
10
10
 
11
11
  ```
12
- Conversation tree (nodes = git commits with embedded chat history)
12
+ Worktrees:
13
13
 
14
- main ──●──●──●──●──●──●──●──●──●──●──●──●──●──●
14
+ main ──●──●──●──●──●──●──●──●──●──●──●──●──●──●───────────► Node = git commit + chat history
15
15
  │ │
16
16
  │ └── branch-1 ──●──●──●
17
17
  │ │ ┌────────────┐
@@ -20,7 +20,7 @@ Conversation tree (nodes = git commits with embedded chat history)
20
20
  └── branch-0 ──●──●──● │
21
21
 
22
22
 
23
- REPL tabs (each tab = a git branch + agent) │
23
+ Tabs: ├────────────► Tab = git branch + Agent
24
24
 
25
25
 
26
26
  ┌──────────────────────────────────────────────┼─────────┐
@@ -30,20 +30,20 @@ REPL tabs (each tab = a git branch + agent) │
30
30
  │ └──────┘ └────┬─────┘ └──────────┘ └────────────┘ │
31
31
  └─────────────────┼──────────────────────────────────────┘
32
32
 
33
- ├─────────────────────────────────────────► Each tab is an independent Agent
33
+ Agents: ├─────────────────────────────────────────► Each tab runs its own Agent
34
34
 
35
35
  ┌────┴─────────────────────────────────────┐
36
36
  │ Agent │
37
37
  │ ┌────────────────┐ ┌────────────────┐ │
38
38
  │ │ API: │ │ Tools: │ │
39
39
  │ │ Local (mlx-lm) │ │ Read Write │ │
40
- │ │ Claude │ │ Edit Bash │ │
41
- │ │ Gemini │ │ Grep Find │ │
42
- │ │ OpenAI │ │ Ls Skill │ │
43
- └────────────────┘ │ Agent ─────────┼──┼───► Spawns child Agent
44
- └────────────────┘ │ (each with own tools + worktree + etc)
45
- │ Git worktree │
46
- │ (isolation + session state) │
40
+ │ │ Gemini │ │ Edit Bash │ │
41
+ │ │ Claude │ │ Grep Find │ │
42
+ │ │ Codex │ │ Ls Skill │ │
43
+ │ DeepSeek │ │ Agent ─────────┼──┼───► Recursively spawns sub-Agents
44
+ └────────────────┘ └────────────────┘
45
+ │ Git worktree │
46
+ │ (isolation + session state) │
47
47
  └──────────────────────────────────────────┘
48
48
  ```
49
49
 
@@ -59,6 +59,15 @@ result = await agent.run('refactor utils.py to use dataclasses')
59
59
 
60
60
  ---
61
61
 
62
+ ## Core ideas
63
+
64
+ - **Git is the state machine.** Every file-changing agent step is committed with the conversation that produced it, so you can inspect, resume, and branch from any checkpoint.
65
+ - **Branches are alternative futures.** A branch is not just a Git branch; it is a different reasoning path with its own worktree and session state.
66
+ - **Agents are the primitive.** Tabs, branches, and delegated subtasks are all instances of the same `Agent` abstraction.
67
+ - **Worktrees provide isolation.** The agent edits in a separate worktree, so your main checkout stays clean and recoverable.
68
+
69
+ ---
70
+
62
71
  ## Quick start
63
72
 
64
73
  ```bash
@@ -77,15 +86,6 @@ That's it. The first run starts a local inference server and drops you into the
77
86
 
78
87
  ---
79
88
 
80
- ## Core ideas
81
-
82
- - **Git is the state machine.** Every file-changing agent step is committed with the conversation that produced it, so you can inspect, resume, and branch from any checkpoint.
83
- - **Branches are alternative futures.** A branch is not just a Git branch; it is a different reasoning path with its own worktree and session state.
84
- - **Agents are the primitive.** Tabs, branches, and delegated subtasks are all instances of the same `Agent` abstraction.
85
- - **Worktrees provide isolation.** The agent edits in a separate worktree, so your main checkout stays clean and recoverable.
86
-
87
- ---
88
-
89
89
  ## Why mlx-code
90
90
 
91
91
  **Agents as reusable workflow atoms.** Tabs, branches, and tasks are all managed within instances of `Agent`. Each one gets its own conversation, its own tools, and its own worktree. Agents can spawn sub-agents to delegate subtasks, and each child is a full agent with its own scoped tool set.
@@ -30,6 +30,7 @@ from rich.markup import escape
30
30
  from rich.markdown import Markdown
31
31
  from rich.cells import cell_len
32
32
  from rich.syntax import Syntax
33
+ VERBOSE = False
33
34
 
34
35
  def load_agent_config(path: str) -> dict:
35
36
  path = os.path.expanduser(path)
@@ -231,12 +232,16 @@ def append_to_history_table(tbl: Table, messages: list[dict]) -> None:
231
232
  prefix, style = ('◌', 'dim italic')
232
233
  elif role == 'toolResult':
233
234
  prefix, style = ('→', 'dim yellow')
235
+ if not VERBOSE:
236
+ text = ''
234
237
  elif b_type == 'toolCall':
235
238
  prefix, style = ('⚙', 'yellow')
236
- args = block.get('arguments', {})
237
- if isinstance(args, dict):
238
- args = json.dumps(args, ensure_ascii=False)
239
- text = block.get('name', '') + ' ' + str(args)
239
+ text = block.get('name', '')
240
+ if VERBOSE:
241
+ args = block.get('arguments', {})
242
+ if isinstance(args, dict):
243
+ args = json.dumps(args, ensure_ascii=False)
244
+ text += ' ' + str(args)
240
245
  elif role == 'assistant':
241
246
  prefix, style = ('○', '')
242
247
  text = re.sub('\\s*<tool_call>.*?</tool_call>\\s*', '', text, flags=re.DOTALL).strip()
@@ -333,21 +338,36 @@ class Tab(Vertical):
333
338
  payload = event.get('payload', {})
334
339
  if et == 'agent_start':
335
340
  self.status = 'running'
341
+ self._tool_call_buf = ''
336
342
  self._stream_blocks = []
337
343
  self._command_blocks = []
338
344
  self.refresh_cache()
339
345
  self.refresh_stream()
340
346
  elif et == 'turn_start':
347
+ self._tool_call_buf = ''
341
348
  self._stream_blocks = []
342
349
  self._command_blocks = []
343
350
  self.refresh_stream()
344
351
  elif et == 'text_delta':
345
352
  delta = payload.get('delta', '')
346
353
  if delta:
347
- if self._stream_blocks and self._stream_blocks[-1].get('type') == 'text' and (not self._stream_blocks[-1].get('is_error')):
348
- self._stream_blocks[-1]['text'] += delta
354
+ if not VERBOSE:
355
+ self._tool_call_buf = getattr(self, '_tool_call_buf', '') + delta
356
+ cleaned = re.sub('<tool_call>.*?</tool_call>', '', self._tool_call_buf, flags=re.DOTALL)
357
+ if '<tool_call>' in cleaned:
358
+ cut = cleaned.index('<tool_call>')
359
+ emit = cleaned[:cut]
360
+ self._tool_call_buf = cleaned[cut:]
361
+ else:
362
+ emit = cleaned
363
+ self._tool_call_buf = ''
349
364
  else:
350
- self._stream_blocks.append({'type': 'text', 'text': delta})
365
+ emit = delta
366
+ if emit:
367
+ if self._stream_blocks and self._stream_blocks[-1].get('type') == 'text' and (not self._stream_blocks[-1].get('is_error')):
368
+ self._stream_blocks[-1]['text'] += emit
369
+ else:
370
+ self._stream_blocks.append({'type': 'text', 'text': emit})
351
371
  self.refresh_stream()
352
372
  elif et == 'thinking_delta':
353
373
  delta = payload.get('delta', '')
@@ -875,6 +895,11 @@ class ReplApp(App[None]):
875
895
  self._refresh_chrome()
876
896
  except OSError as exc:
877
897
  self.query_one('#helpbar', HelpBar).show_error(f'Export failed: {exc}')
898
+ elif cmd == '/verbose':
899
+ global VERBOSE
900
+ VERBOSE = not VERBOSE
901
+ state = 'on' if VERBOSE else 'off'
902
+ tab.show_command(text, f'Verbose mode {state}.')
878
903
  elif cmd in {'/exit', '/quit'}:
879
904
  if arg == '--all':
880
905
  self._exit_with_summary(tab)
@@ -1025,7 +1050,7 @@ _AGENT_ENV_ALLOWLIST: re.Pattern = re.compile('\n ^(\n # ── Execution
1025
1050
  def _make_agent_env(base: dict[str, str]) -> dict[str, str]:
1026
1051
  return {k: v for k, v in base.items() if _AGENT_ENV_ALLOWLIST.match(k)}
1027
1052
 
1028
- def run_repl(*, base_url=None, model=None, api: Literal['claude', 'codex', 'gemini', 'deepseek', 'noapi']='noapi', system='', sdir=None, skills=None, env=None, tool_names=None, extra_tool_classes=None, api_key=None, gwt=None, ctx=None, init_prompt=None, resume_messages=None, repo=None, resume=None, stream=None, verbose_transcript=False, bare=False):
1053
+ def run_repl(*, base_url=None, model=None, api: Literal['claude', 'codex', 'gemini', 'deepseek', 'noapi']='noapi', system='', sdir=None, skills=None, env=None, tool_names=None, extra_tool_classes=None, api_key=None, gwt=None, ctx=None, init_prompt=None, resume_messages=None, repo=None, resume=None, stream=None, bare=False):
1029
1054
  repo = os.path.abspath(repo or os.getcwd())
1030
1055
  with tempfile.TemporaryDirectory(dir=tempfile.gettempdir()) as _home:
1031
1056
  if gwt is None:
@@ -1102,11 +1127,13 @@ def main():
1102
1127
  parser.add_argument('--cwd', default=None, help='Working directory / git repo root')
1103
1128
  parser.add_argument('--key', default=None, help='API key')
1104
1129
  parser.add_argument('--stream', default=None, help='File to stream log into')
1105
- parser.add_argument('--verbose-transcript', action='store_true', help='Reserved; not yet implemented')
1130
+ parser.add_argument('--verbose', action='store_true', help='Show raw tool calls, args, and outputs')
1106
1131
  parser.add_argument('--bare', action='store_true', help='Use simple terminal REPL instead of TUI')
1107
1132
  args = parser.parse_args()
1108
1133
  logger.debug(args)
1109
1134
  url, model, tool_names, api_key = (args.url, args.model, args.tools, args.key)
1135
+ global VERBOSE
1136
+ VERBOSE = args.verbose
1110
1137
  if args.api == 'deepseek':
1111
1138
  api_key = os.environ.get('DEEPSEEK_API_KEY') if api_key is None else api_key
1112
1139
  url = 'https://api.deepseek.com' if api_key else url
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mlx-code
3
- Version: 0.0.26
3
+ Version: 0.0.27
4
4
  Summary: Coding Agent for Mac
5
5
  Home-page: https://josefalbers.github.io/mlx-code/
6
6
  Author: J Joe
@@ -47,9 +47,9 @@ A Git-native coding agent that can run entirely on your Mac. No API keys, no clo
47
47
  ## Architecture
48
48
 
49
49
  ```
50
- Conversation tree (nodes = git commits with embedded chat history)
50
+ Worktrees:
51
51
 
52
- main ──●──●──●──●──●──●──●──●──●──●──●──●──●──●
52
+ main ──●──●──●──●──●──●──●──●──●──●──●──●──●──●───────────► Node = git commit + chat history
53
53
  │ │
54
54
  │ └── branch-1 ──●──●──●
55
55
  │ │ ┌────────────┐
@@ -58,7 +58,7 @@ Conversation tree (nodes = git commits with embedded chat history)
58
58
  └── branch-0 ──●──●──● │
59
59
 
60
60
 
61
- REPL tabs (each tab = a git branch + agent) │
61
+ Tabs: ├────────────► Tab = git branch + Agent
62
62
 
63
63
 
64
64
  ┌──────────────────────────────────────────────┼─────────┐
@@ -68,20 +68,20 @@ REPL tabs (each tab = a git branch + agent) │
68
68
  │ └──────┘ └────┬─────┘ └──────────┘ └────────────┘ │
69
69
  └─────────────────┼──────────────────────────────────────┘
70
70
 
71
- ├─────────────────────────────────────────► Each tab is an independent Agent
71
+ Agents: ├─────────────────────────────────────────► Each tab runs its own Agent
72
72
 
73
73
  ┌────┴─────────────────────────────────────┐
74
74
  │ Agent │
75
75
  │ ┌────────────────┐ ┌────────────────┐ │
76
76
  │ │ API: │ │ Tools: │ │
77
77
  │ │ Local (mlx-lm) │ │ Read Write │ │
78
- │ │ Claude │ │ Edit Bash │ │
79
- │ │ Gemini │ │ Grep Find │ │
80
- │ │ OpenAI │ │ Ls Skill │ │
81
- └────────────────┘ │ Agent ─────────┼──┼───► Spawns child Agent
82
- └────────────────┘ │ (each with own tools + worktree + etc)
83
- │ Git worktree │
84
- │ (isolation + session state) │
78
+ │ │ Gemini │ │ Edit Bash │ │
79
+ │ │ Claude │ │ Grep Find │ │
80
+ │ │ Codex │ │ Ls Skill │ │
81
+ │ DeepSeek │ │ Agent ─────────┼──┼───► Recursively spawns sub-Agents
82
+ └────────────────┘ └────────────────┘
83
+ │ Git worktree │
84
+ │ (isolation + session state) │
85
85
  └──────────────────────────────────────────┘
86
86
  ```
87
87
 
@@ -97,6 +97,15 @@ result = await agent.run('refactor utils.py to use dataclasses')
97
97
 
98
98
  ---
99
99
 
100
+ ## Core ideas
101
+
102
+ - **Git is the state machine.** Every file-changing agent step is committed with the conversation that produced it, so you can inspect, resume, and branch from any checkpoint.
103
+ - **Branches are alternative futures.** A branch is not just a Git branch; it is a different reasoning path with its own worktree and session state.
104
+ - **Agents are the primitive.** Tabs, branches, and delegated subtasks are all instances of the same `Agent` abstraction.
105
+ - **Worktrees provide isolation.** The agent edits in a separate worktree, so your main checkout stays clean and recoverable.
106
+
107
+ ---
108
+
100
109
  ## Quick start
101
110
 
102
111
  ```bash
@@ -115,15 +124,6 @@ That's it. The first run starts a local inference server and drops you into the
115
124
 
116
125
  ---
117
126
 
118
- ## Core ideas
119
-
120
- - **Git is the state machine.** Every file-changing agent step is committed with the conversation that produced it, so you can inspect, resume, and branch from any checkpoint.
121
- - **Branches are alternative futures.** A branch is not just a Git branch; it is a different reasoning path with its own worktree and session state.
122
- - **Agents are the primitive.** Tabs, branches, and delegated subtasks are all instances of the same `Agent` abstraction.
123
- - **Worktrees provide isolation.** The agent edits in a separate worktree, so your main checkout stays clean and recoverable.
124
-
125
- ---
126
-
127
127
  ## Why mlx-code
128
128
 
129
129
  **Agents as reusable workflow atoms.** Tabs, branches, and tasks are all managed within instances of `Agent`. Each one gets its own conversation, its own tools, and its own worktree. Agents can spawn sub-agents to delegate subtasks, and each child is a full agent with its own scoped tool set.
@@ -11,7 +11,7 @@ setup(
11
11
  author_email="albersj66@gmail.com",
12
12
  author="J Joe",
13
13
  license="Apache-2.0",
14
- version="0.0.26",
14
+ version="0.0.27",
15
15
  readme="README.md",
16
16
  description="Coding Agent for Mac",
17
17
  long_description=open("README.md").read(),
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