mindcode 0.2.0__py3-none-any.whl → 0.3.2__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.
- mindcode/_version.py +1 -1
- mindcode/approval.py +30 -5
- mindcode/bench/adapters/terminal_bench.py +6 -2
- mindcode/cli/__init__.py +14 -9
- mindcode/cli/commands/chat.py +2 -2
- mindcode/cli/commands/shell.py +16 -7
- mindcode/cli/shell/completion.py +2 -5
- mindcode/cli/shell/repl.py +284 -17
- mindcode/cli/shell/slash.py +199 -116
- mindcode/cli/shell/startup.py +2 -1
- mindcode/cli/shell/tui.py +37 -14
- mindcode/policy.py +100 -36
- mindcode/render.py +105 -52
- mindcode/runtime.py +68 -69
- mindcode-0.3.2.dist-info/METADATA +351 -0
- mindcode-0.3.2.dist-info/RECORD +63 -0
- mindcode/__pycache__/__init__.cpython-313.pyc +0 -0
- mindcode/__pycache__/__main__.cpython-313.pyc +0 -0
- mindcode/__pycache__/_version.cpython-313.pyc +0 -0
- mindcode/__pycache__/config.cpython-313.pyc +0 -0
- mindcode/__pycache__/policy.cpython-313.pyc +0 -0
- mindcode/__pycache__/remote.cpython-313.pyc +0 -0
- mindcode/__pycache__/render.cpython-313.pyc +0 -0
- mindcode/__pycache__/runtime.cpython-313.pyc +0 -0
- mindcode/__pycache__/tasking.cpython-313.pyc +0 -0
- mindcode/__pycache__/terminal_core.cpython-313.pyc +0 -0
- mindcode/bench/__pycache__/__init__.cpython-313.pyc +0 -0
- mindcode/bench/__pycache__/fake_tools.cpython-313.pyc +0 -0
- mindcode/bench/__pycache__/jsonutil.cpython-313.pyc +0 -0
- mindcode/bench/__pycache__/paths.cpython-313.pyc +0 -0
- mindcode/bench/__pycache__/predictions.cpython-313.pyc +0 -0
- mindcode/bench/__pycache__/report.cpython-313.pyc +0 -0
- mindcode/bench/__pycache__/runner.cpython-313.pyc +0 -0
- mindcode/bench/__pycache__/schema.cpython-313.pyc +0 -0
- mindcode/bench/__pycache__/trace.cpython-313.pyc +0 -0
- mindcode/bench/__pycache__/workspace.cpython-313.pyc +0 -0
- mindcode/bench/adapters/__pycache__/__init__.cpython-313.pyc +0 -0
- mindcode/bench/adapters/__pycache__/base.cpython-313.pyc +0 -0
- mindcode/bench/adapters/__pycache__/mini_bfcl.cpython-313.pyc +0 -0
- mindcode/bench/adapters/__pycache__/mini_gaia.cpython-313.pyc +0 -0
- mindcode/bench/adapters/__pycache__/mini_terminal.cpython-313.pyc +0 -0
- mindcode/bench/adapters/__pycache__/swe_bench.cpython-313.pyc +0 -0
- mindcode/bench/adapters/__pycache__/terminal_bench.cpython-313.pyc +0 -0
- mindcode/bench/scorers/__pycache__/base.cpython-313.pyc +0 -0
- mindcode/bench/scorers/__pycache__/composite.cpython-313.pyc +0 -0
- mindcode/bench/scorers/__pycache__/exact.cpython-313.pyc +0 -0
- mindcode/bench/scorers/__pycache__/json_call.cpython-313.pyc +0 -0
- mindcode/bench/scorers/__pycache__/swe.cpython-313.pyc +0 -0
- mindcode/bench/scorers/__pycache__/terminal.cpython-313.pyc +0 -0
- mindcode/bench/scorers/__pycache__/terminal_bench.cpython-313.pyc +0 -0
- mindcode/cli/__pycache__/__init__.cpython-313.pyc +0 -0
- mindcode/cli/__pycache__/_shared.cpython-313.pyc +0 -0
- mindcode/cli/commands/__pycache__/__init__.cpython-313.pyc +0 -0
- mindcode/cli/commands/__pycache__/bench.cpython-313.pyc +0 -0
- mindcode/cli/commands/__pycache__/chat.cpython-313.pyc +0 -0
- mindcode/cli/commands/__pycache__/config_cmd.cpython-313.pyc +0 -0
- mindcode/cli/commands/__pycache__/remote.cpython-313.pyc +0 -0
- mindcode/cli/commands/__pycache__/shell.cpython-313.pyc +0 -0
- mindcode/cli/commands/__pycache__/status.cpython-313.pyc +0 -0
- mindcode/cli/commands/__pycache__/task.cpython-313.pyc +0 -0
- mindcode/cli/commands/__pycache__/terminal.cpython-313.pyc +0 -0
- mindcode/cli/shell/__pycache__/__init__.cpython-313.pyc +0 -0
- mindcode/cli/shell/__pycache__/completion.cpython-313.pyc +0 -0
- mindcode/cli/shell/__pycache__/menu.cpython-313.pyc +0 -0
- mindcode/cli/shell/__pycache__/repl.cpython-313.pyc +0 -0
- mindcode/cli/shell/__pycache__/slash.cpython-313.pyc +0 -0
- mindcode/cli/shell/__pycache__/startup.cpython-313.pyc +0 -0
- mindcode/terminal/__pycache__/__init__.cpython-313.pyc +0 -0
- mindcode/terminal/__pycache__/__main__.cpython-313.pyc +0 -0
- mindcode-0.2.0.dist-info/METADATA +0 -244
- mindcode-0.2.0.dist-info/RECORD +0 -116
- {mindcode-0.2.0.dist-info → mindcode-0.3.2.dist-info}/WHEEL +0 -0
- {mindcode-0.2.0.dist-info → mindcode-0.3.2.dist-info}/entry_points.txt +0 -0
- {mindcode-0.2.0.dist-info → mindcode-0.3.2.dist-info}/top_level.txt +0 -0
mindcode/_version.py
CHANGED
mindcode/approval.py
CHANGED
|
@@ -9,12 +9,13 @@ one-shot / TUI 未启动时回退到 ``menu.prompt_yes_no``。
|
|
|
9
9
|
from __future__ import annotations
|
|
10
10
|
|
|
11
11
|
import json
|
|
12
|
+
import time
|
|
12
13
|
from collections.abc import Awaitable, Callable
|
|
13
14
|
from typing import Any
|
|
14
15
|
|
|
15
16
|
from mindagent.core import ActionRequest, AgentContext
|
|
16
17
|
|
|
17
|
-
from .policy import ApprovalCallback
|
|
18
|
+
from .policy import ApprovalCallback, FileAccessCallback
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
def risk_label(risk: Any) -> str:
|
|
@@ -47,10 +48,7 @@ def describe_action(action: ActionRequest) -> str:
|
|
|
47
48
|
return f"{verb} {path} [{risk_label(action.risk)}]"
|
|
48
49
|
if name == "exec_command":
|
|
49
50
|
command = arguments.get("command", "")
|
|
50
|
-
if isinstance(command,
|
|
51
|
-
preview = " ".join(_one_line(item) for item in command)
|
|
52
|
-
else:
|
|
53
|
-
preview = _one_line(command)
|
|
51
|
+
preview = _one_line(command) if isinstance(command, str) else ""
|
|
54
52
|
if len(preview) > 120:
|
|
55
53
|
preview = preview[:117] + "..."
|
|
56
54
|
return f"Command {preview} [{risk_label(action.risk)}]"
|
|
@@ -103,3 +101,30 @@ def make_shell_approval(
|
|
|
103
101
|
)
|
|
104
102
|
|
|
105
103
|
return _approve
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def make_shell_file_access_approval(
|
|
107
|
+
get_chooser: Callable[[], Chooser | None],
|
|
108
|
+
) -> FileAccessCallback:
|
|
109
|
+
"""Ask for a precise, single-call external read using a bound decision."""
|
|
110
|
+
from mindagent.core import ExternalFileReadDecision
|
|
111
|
+
|
|
112
|
+
async def approve(context, request):
|
|
113
|
+
title = (
|
|
114
|
+
"允许读取 workspace 外部文件?\n"
|
|
115
|
+
f"精确文件:{request.path}\n"
|
|
116
|
+
"权限:只读;范围:仅此次工具调用(一次),不扩大 workspace。\n"
|
|
117
|
+
f"有效期:剩余 {max(0, int(request.expires_at - time.time()))} 秒,过期需重新请求。"
|
|
118
|
+
)
|
|
119
|
+
chooser = get_chooser()
|
|
120
|
+
if chooser is not None:
|
|
121
|
+
result = await chooser(
|
|
122
|
+
title, [("allow", "允许此次只读访问"), ("deny", "拒绝")], "deny",
|
|
123
|
+
)
|
|
124
|
+
approved = result == "allow"
|
|
125
|
+
else:
|
|
126
|
+
from .cli.shell.menu import prompt_yes_no
|
|
127
|
+
approved = await prompt_yes_no(title, default_yes=False)
|
|
128
|
+
return ExternalFileReadDecision(request_id=request.request_id, approved=approved)
|
|
129
|
+
|
|
130
|
+
return approve
|
|
@@ -4,8 +4,6 @@ import json
|
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
from typing import Any
|
|
6
6
|
|
|
7
|
-
import yaml
|
|
8
|
-
|
|
9
7
|
from ..paths import DEFAULT_TERMINAL_BENCH_ROOT
|
|
10
8
|
from ..schema import BenchmarkCase, BenchmarkFile
|
|
11
9
|
from ..scorers.base import Scorer
|
|
@@ -52,6 +50,12 @@ def _case_from_json(raw: dict[str, Any]) -> BenchmarkCase:
|
|
|
52
50
|
|
|
53
51
|
|
|
54
52
|
def _case_from_task_dir(task_dir: Path) -> BenchmarkCase:
|
|
53
|
+
try:
|
|
54
|
+
import yaml
|
|
55
|
+
except ImportError as exc:
|
|
56
|
+
raise RuntimeError(
|
|
57
|
+
"terminal_bench 需要 pyyaml,请先 pip install pyyaml"
|
|
58
|
+
) from exc
|
|
55
59
|
task = yaml.safe_load((task_dir / "task.yaml").read_text(encoding="utf-8"))
|
|
56
60
|
files = tuple(_iter_visible_files(task_dir))
|
|
57
61
|
instruction = str(task["instruction"])
|
mindcode/cli/__init__.py
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
cli/__init__.py typer app + 命令注册
|
|
5
5
|
cli/_shared.py 共享 console + find_config_file
|
|
6
6
|
cli/commands/
|
|
7
|
-
shell.py `mindcode
|
|
7
|
+
shell.py 顶层 `mindcode` 默认入口 handler
|
|
8
8
|
chat.py `mindcode chat -m "..."`
|
|
9
9
|
task.py `mindcode task run/list/status/tail`
|
|
10
10
|
status.py `mindcode status`
|
|
@@ -20,12 +20,12 @@
|
|
|
20
20
|
from __future__ import annotations
|
|
21
21
|
|
|
22
22
|
import typer
|
|
23
|
+
from click import UsageError
|
|
23
24
|
|
|
24
25
|
from .._version import __version__
|
|
25
26
|
from ._shared import console
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
"shell",
|
|
28
|
+
PUBLIC_SUBCOMMANDS = {
|
|
29
29
|
"chat",
|
|
30
30
|
"status",
|
|
31
31
|
"config",
|
|
@@ -37,21 +37,25 @@ KNOWN_SUBCOMMANDS = {
|
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
class DefaultShellGroup(typer.core.TyperGroup):
|
|
40
|
-
"""
|
|
40
|
+
"""让顶层 `mindcode` 直接复用内部 Shell 参数解析。
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
让 click 走完整的参数解析路径。
|
|
42
|
+
公开子命令保持原分派;其他参数注入隐藏的 ``shell`` handler。
|
|
44
43
|
"""
|
|
45
44
|
|
|
46
45
|
def parse_args(self, ctx, args):
|
|
47
46
|
if args:
|
|
48
47
|
first = args[0]
|
|
48
|
+
if first == "shell":
|
|
49
|
+
raise UsageError(
|
|
50
|
+
"`mindcode shell` 已移除;请改用 "
|
|
51
|
+
"`mindcode [PROMPT] [OPTIONS]`"
|
|
52
|
+
)
|
|
49
53
|
if (
|
|
50
|
-
first in
|
|
54
|
+
first in PUBLIC_SUBCOMMANDS
|
|
51
55
|
or first in {"--help", "-h", "--version", "-v"}
|
|
52
56
|
):
|
|
53
57
|
return super().parse_args(ctx, args)
|
|
54
|
-
#
|
|
58
|
+
# 无公开子命令:交给隐藏的顶层 Shell handler 做完整参数解析。
|
|
55
59
|
new_args = ["shell", *args]
|
|
56
60
|
return super().parse_args(ctx, new_args)
|
|
57
61
|
|
|
@@ -98,7 +102,8 @@ from .commands.status import status # noqa: E402
|
|
|
98
102
|
from .commands.task import app as task_app # noqa: E402
|
|
99
103
|
from .commands.terminal import app as terminal_app # noqa: E402
|
|
100
104
|
|
|
101
|
-
|
|
105
|
+
# 仅供 DefaultShellGroup 内部分派;不作为公开子命令展示。
|
|
106
|
+
app.command("shell", hidden=True)(shell)
|
|
102
107
|
app.command()(chat)
|
|
103
108
|
app.command()(status)
|
|
104
109
|
app.add_typer(config_app, name="config")
|
mindcode/cli/commands/chat.py
CHANGED
|
@@ -44,10 +44,10 @@ def chat(
|
|
|
44
44
|
None, "--max-steps", help="最大 step 数(默认 50)"
|
|
45
45
|
),
|
|
46
46
|
step_timeout: float | None = typer.Option(
|
|
47
|
-
None, "--step-timeout", help="单步超时秒数,0 表示禁用(默认
|
|
47
|
+
None, "--step-timeout", help="单步超时秒数,0 表示禁用(默认 300)"
|
|
48
48
|
),
|
|
49
49
|
total_timeout: float | None = typer.Option(
|
|
50
|
-
None, "--total-timeout", help="总超时秒数,0 表示禁用(默认
|
|
50
|
+
None, "--total-timeout", help="总超时秒数,0 表示禁用(默认 1800)"
|
|
51
51
|
),
|
|
52
52
|
) -> None:
|
|
53
53
|
"""发送单条消息,不进入交互模式。"""
|
mindcode/cli/commands/shell.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""`mindcode
|
|
1
|
+
"""顶层 `mindcode` 默认入口的交互式 REPL handler。"""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
@@ -59,13 +59,15 @@ def shell(
|
|
|
59
59
|
None, "--max-steps", help="最大 step 数(默认 50)"
|
|
60
60
|
),
|
|
61
61
|
step_timeout: float | None = typer.Option(
|
|
62
|
-
None, "--step-timeout", help="单步超时秒数,0 表示禁用(默认
|
|
62
|
+
None, "--step-timeout", help="单步超时秒数,0 表示禁用(默认 300)"
|
|
63
63
|
),
|
|
64
64
|
total_timeout: float | None = typer.Option(
|
|
65
|
-
None,
|
|
65
|
+
None,
|
|
66
|
+
"--total-timeout",
|
|
67
|
+
help="总超时秒数,0 表示禁用(交互默认禁用;一次性/子代理默认 1800)",
|
|
66
68
|
),
|
|
67
69
|
) -> None:
|
|
68
|
-
"""
|
|
70
|
+
"""启动顶层 `mindcode` 交互或 one-shot 模式。"""
|
|
69
71
|
ws = Path(workspace).expanduser().resolve()
|
|
70
72
|
if not ws.is_dir():
|
|
71
73
|
console.print(
|
|
@@ -83,6 +85,15 @@ def shell(
|
|
|
83
85
|
)
|
|
84
86
|
raise typer.Exit(2)
|
|
85
87
|
|
|
88
|
+
if total_timeout == 0 or (
|
|
89
|
+
total_timeout is None and prompt is None and not subagents
|
|
90
|
+
):
|
|
91
|
+
selected_total_timeout = None
|
|
92
|
+
else:
|
|
93
|
+
selected_total_timeout = (
|
|
94
|
+
total_timeout if total_timeout is not None else 1800.0
|
|
95
|
+
)
|
|
96
|
+
|
|
86
97
|
try:
|
|
87
98
|
rc = run_shell(
|
|
88
99
|
ws,
|
|
@@ -98,9 +109,7 @@ def shell(
|
|
|
98
109
|
step_timeout_s=None
|
|
99
110
|
if step_timeout == 0
|
|
100
111
|
else (step_timeout if step_timeout is not None else 300.0),
|
|
101
|
-
total_timeout_s=
|
|
102
|
-
if total_timeout == 0
|
|
103
|
-
else (total_timeout if total_timeout is not None else 1800.0),
|
|
112
|
+
total_timeout_s=selected_total_timeout,
|
|
104
113
|
)
|
|
105
114
|
except ValueError as exc:
|
|
106
115
|
console.print(f"[red]配置错误:[/red] {exc}")
|
mindcode/cli/shell/completion.py
CHANGED
|
@@ -10,11 +10,8 @@ SLASH_COMMANDS = {
|
|
|
10
10
|
"models": "切换当前模型",
|
|
11
11
|
"compact": "压缩整理当前会话上下文",
|
|
12
12
|
"permissions": "切换权限模式",
|
|
13
|
-
"status": "
|
|
14
|
-
"
|
|
15
|
-
"sessions": "列出本地会话",
|
|
16
|
-
"history": "打印当前会话消息",
|
|
17
|
-
"diff": "显示最后一次 diff",
|
|
13
|
+
"status": "查看当前历史 session 状态与上下文使用",
|
|
14
|
+
"resume": "恢复本地保存的历史 session",
|
|
18
15
|
"clear": "清空当前会话历史",
|
|
19
16
|
"help": "显示帮助",
|
|
20
17
|
"exit": "退出",
|