mindcode 0.5.1__tar.gz → 0.5.2__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 (99) hide show
  1. {mindcode-0.5.1 → mindcode-0.5.2}/PKG-INFO +1 -1
  2. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/_version.py +1 -1
  3. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/render.py +13 -4
  4. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode.egg-info/PKG-INFO +1 -1
  5. {mindcode-0.5.1 → mindcode-0.5.2}/pyproject.toml +1 -1
  6. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_render_exec.py +62 -0
  7. {mindcode-0.5.1 → mindcode-0.5.2}/README.md +0 -0
  8. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/__init__.py +0 -0
  9. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/__main__.py +0 -0
  10. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/acp_agent/__init__.py +0 -0
  11. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/acp_agent/__main__.py +0 -0
  12. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/acp_agent/agent.py +0 -0
  13. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/approval.py +0 -0
  14. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/bench/__init__.py +0 -0
  15. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/bench/adapters/__init__.py +0 -0
  16. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/bench/adapters/base.py +0 -0
  17. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/bench/adapters/mini_bfcl.py +0 -0
  18. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/bench/adapters/mini_gaia.py +0 -0
  19. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/bench/adapters/mini_terminal.py +0 -0
  20. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/bench/adapters/swe_bench.py +0 -0
  21. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/bench/adapters/terminal_bench.py +0 -0
  22. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/bench/fake_tools.py +0 -0
  23. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/bench/jsonutil.py +0 -0
  24. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/bench/paths.py +0 -0
  25. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/bench/predictions.py +0 -0
  26. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/bench/report.py +0 -0
  27. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/bench/runner.py +0 -0
  28. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/bench/schema.py +0 -0
  29. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/bench/scorers/base.py +0 -0
  30. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/bench/scorers/composite.py +0 -0
  31. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/bench/scorers/exact.py +0 -0
  32. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/bench/scorers/json_call.py +0 -0
  33. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/bench/scorers/swe.py +0 -0
  34. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/bench/scorers/terminal.py +0 -0
  35. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/bench/scorers/terminal_bench.py +0 -0
  36. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/bench/trace.py +0 -0
  37. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/bench/workspace.py +0 -0
  38. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/cli/__init__.py +0 -0
  39. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/cli/_shared.py +0 -0
  40. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/cli/commands/__init__.py +0 -0
  41. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/cli/commands/bench.py +0 -0
  42. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/cli/commands/chat.py +0 -0
  43. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/cli/commands/config_cmd.py +0 -0
  44. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/cli/commands/remote.py +0 -0
  45. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/cli/commands/shell.py +0 -0
  46. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/cli/commands/status.py +0 -0
  47. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/cli/commands/task.py +0 -0
  48. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/cli/commands/terminal.py +0 -0
  49. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/cli/shell/__init__.py +0 -0
  50. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/cli/shell/completion.py +0 -0
  51. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/cli/shell/input_pipeline.py +0 -0
  52. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/cli/shell/menu.py +0 -0
  53. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/cli/shell/repl.py +0 -0
  54. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/cli/shell/slash.py +0 -0
  55. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/cli/shell/startup.py +0 -0
  56. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/cli/shell/tui.py +0 -0
  57. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/config.py +0 -0
  58. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/mcp.py +0 -0
  59. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/policy.py +0 -0
  60. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/remote.py +0 -0
  61. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/runtime.py +0 -0
  62. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/skills.py +0 -0
  63. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/subagents.py +0 -0
  64. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/tasking.py +0 -0
  65. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/terminal/__init__.py +0 -0
  66. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/terminal/__main__.py +0 -0
  67. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode/terminal_core.py +0 -0
  68. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode.egg-info/SOURCES.txt +0 -0
  69. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode.egg-info/dependency_links.txt +0 -0
  70. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode.egg-info/entry_points.txt +0 -0
  71. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode.egg-info/requires.txt +0 -0
  72. {mindcode-0.5.1 → mindcode-0.5.2}/mindcode.egg-info/top_level.txt +0 -0
  73. {mindcode-0.5.1 → mindcode-0.5.2}/setup.cfg +0 -0
  74. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_acp_agent.py +0 -0
  75. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_approval.py +0 -0
  76. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_bench.py +0 -0
  77. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_cli_commands.py +0 -0
  78. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_config.py +0 -0
  79. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_diff_capture.py +0 -0
  80. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_exec_command_guard.py +0 -0
  81. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_external_file_approval.py +0 -0
  82. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_policy_choice.py +0 -0
  83. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_policy_timeout.py +0 -0
  84. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_provider_retry_defaults.py +0 -0
  85. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_reasoner_compat.py +0 -0
  86. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_remote.py +0 -0
  87. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_shell_channels.py +0 -0
  88. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_shell_completion.py +0 -0
  89. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_shell_interrupt.py +0 -0
  90. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_shell_session.py +0 -0
  91. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_shell_slash_priority.py +0 -0
  92. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_shell_tui.py +0 -0
  93. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_skills_mcp.py +0 -0
  94. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_slash_resume.py +0 -0
  95. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_subagents.py +0 -0
  96. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_system_prompt.py +0 -0
  97. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_task_resume.py +0 -0
  98. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_tasking.py +0 -0
  99. {mindcode-0.5.1 → mindcode-0.5.2}/tests/test_terminal.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mindcode
3
- Version: 0.5.1
3
+ Version: 0.5.2
4
4
  Summary: codex-style interactive coding agent on top of mindagent
5
5
  Author: mindcode
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  """mindcode 版本与品牌信息。"""
2
2
 
3
- __version__ = "0.5.1"
3
+ __version__ = "0.5.2"
4
4
 
5
5
  __logo__ = r"""
6
6
  [bold cyan] _ _[/bold cyan]
@@ -159,10 +159,11 @@ class RichRenderer:
159
159
  if _command_is_running(ok, result):
160
160
  session_id = result.get("session_id", "")
161
161
  preview = _first_line(_command_output(result))
162
- detail = f"running · {session_id}"
162
+ detail = f"{'running' if ok else 'timeout'} · {session_id}"
163
163
  if preview:
164
164
  detail += f" · {preview}"
165
- self.console.print(f" [yellow]…[/yellow] {detail}")
165
+ marker = "[yellow]…[/yellow]" if ok else "[red]✗[/red]"
166
+ self.console.print(f" {marker} {detail}")
166
167
  return
167
168
  exit_code, timed_out, succeeded, reason = _command_status(
168
169
  name, ok, result, error
@@ -298,6 +299,12 @@ class RichRenderer:
298
299
  session_id = result.get("session_id", "")
299
300
  if isinstance(session_id, str) and self._tui_action_tool is not None:
300
301
  self._tui_session_tools[session_id] = self._tui_action_tool
302
+ if not ok:
303
+ preview = _first_line(_command_output(result))
304
+ detail = f"timeout · {session_id}"
305
+ if preview:
306
+ detail += f" · {preview}"
307
+ self._finish_tui_tool(False, detail)
301
308
  return
302
309
  exit_code, timed_out, succeeded, reason = _command_status(
303
310
  name, ok, result, error
@@ -462,11 +469,13 @@ def _command_status(
462
469
 
463
470
 
464
471
  def _command_is_running(ok: bool, result: Any) -> bool:
472
+ del ok
465
473
  return (
466
- ok
467
- and isinstance(result, dict)
474
+ isinstance(result, dict)
468
475
  and result.get("ok") is True
469
476
  and result.get("state") == "running"
477
+ and isinstance(result.get("session_id"), str)
478
+ and bool(result.get("session_id"))
470
479
  )
471
480
 
472
481
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mindcode
3
- Version: 0.5.1
3
+ Version: 0.5.2
4
4
  Summary: codex-style interactive coding agent on top of mindagent
5
5
  Author: mindcode
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "mindcode"
7
- version = "0.5.1"
7
+ version = "0.5.2"
8
8
  description = "codex-style interactive coding agent on top of mindagent"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -8,6 +8,7 @@ import unittest
8
8
  from rich.console import Console
9
9
 
10
10
  from mindagent.core import AgentState, AgentEvent, EventType
11
+ from mindcode.cli.shell.tui import Transcript
11
12
  from mindcode.render import RichRenderer
12
13
 
13
14
 
@@ -163,6 +164,67 @@ class ExecRenderTest(unittest.TestCase):
163
164
 
164
165
  self.assertIn("running · s_live · epoch 2", out)
165
166
 
167
+ def test_action_timeout_renders_recoverable_session(self) -> None:
168
+ out = self._render(
169
+ _make_observation(
170
+ ok=False,
171
+ error="Action exceeded timeout",
172
+ result={
173
+ "ok": True,
174
+ "state": "running",
175
+ "session_id": "s_recoverable",
176
+ "pid": 123,
177
+ "exit_code": None,
178
+ "output": {"text": "still working\n"},
179
+ "error": None,
180
+ "meta": {},
181
+ },
182
+ )
183
+ )
184
+
185
+ self.assertIn("timeout · s_recoverable · still working", out)
186
+
187
+ def test_tui_action_timeout_card_shows_recoverable_session_id(self) -> None:
188
+ async def render() -> Transcript:
189
+ transcript = Transcript()
190
+ renderer = RichRenderer(console=Console(file=io.StringIO()))
191
+ renderer.attach_transcript(transcript)
192
+ await renderer(
193
+ _make_event(
194
+ "exec_command",
195
+ {"command": "python train.py"},
196
+ )
197
+ )
198
+ await renderer(
199
+ _make_observation(
200
+ ok=False,
201
+ error="Action exceeded timeout",
202
+ result={
203
+ "ok": True,
204
+ "state": "running",
205
+ "session_id": "s_recoverable",
206
+ "pid": 123,
207
+ "exit_code": None,
208
+ "output": {"text": "still working\n"},
209
+ "error": None,
210
+ "meta": {},
211
+ },
212
+ )
213
+ )
214
+ return transcript
215
+
216
+ import asyncio
217
+
218
+ transcript = asyncio.run(render())
219
+ tool_entries = [entry for entry in transcript.entries if entry.role == "tool"]
220
+
221
+ self.assertEqual(len(tool_entries), 1)
222
+ self.assertEqual(tool_entries[0].status, "error")
223
+ self.assertEqual(
224
+ tool_entries[0].content,
225
+ "timeout · s_recoverable · still working",
226
+ )
227
+
166
228
  def test_structured_runtime_error_uses_error_message(self) -> None:
167
229
  out = self._render(
168
230
  _make_observation(
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
File without changes
File without changes
File without changes
File without changes
File without changes