deep-agent-cli 0.1.0__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.
Files changed (50) hide show
  1. agent/__init__.py +42 -0
  2. agent/attachments.py +303 -0
  3. agent/bootstrap.py +44 -0
  4. agent/cancel.py +107 -0
  5. agent/cli/__init__.py +5 -0
  6. agent/cli/app.py +1768 -0
  7. agent/cli/clipboard.py +224 -0
  8. agent/cli/commands.py +94 -0
  9. agent/cli/gitinfo.py +84 -0
  10. agent/cli/input.py +65 -0
  11. agent/cli/interactions.py +187 -0
  12. agent/cli/main.py +124 -0
  13. agent/cli/previews.py +710 -0
  14. agent/cli/rendering.py +770 -0
  15. agent/cli/session_controller.py +221 -0
  16. agent/cli/state.py +326 -0
  17. agent/config.example.yaml +76 -0
  18. agent/config.py +528 -0
  19. agent/control.py +171 -0
  20. agent/factory.py +232 -0
  21. agent/file_mutation.py +5 -0
  22. agent/llm.py +339 -0
  23. agent/middleware/__init__.py +9 -0
  24. agent/middleware/attachments.py +31 -0
  25. agent/middleware/cancel_tools.py +39 -0
  26. agent/middleware/pause.py +18 -0
  27. agent/middleware/recovery.py +65 -0
  28. agent/middleware/steering.py +35 -0
  29. agent/middleware/tool_arg_hints.py +128 -0
  30. agent/middleware/workspace_filesystem.py +38 -0
  31. agent/middleware/write_operation.py +60 -0
  32. agent/network.py +30 -0
  33. agent/permission.py +80 -0
  34. agent/runner.py +1393 -0
  35. agent/sandbox.py +699 -0
  36. agent/session.py +431 -0
  37. agent/session_lock.py +223 -0
  38. agent/session_runtime.py +209 -0
  39. agent/stream.py +168 -0
  40. agent/tools/__init__.py +9 -0
  41. agent/tools/examples.py +30 -0
  42. agent/tools/execute.py +73 -0
  43. agent/tools/human_input.py +170 -0
  44. agent/tools/human_interaction.py +101 -0
  45. agent/tools/web_search.py +131 -0
  46. deep_agent_cli-0.1.0.dist-info/METADATA +408 -0
  47. deep_agent_cli-0.1.0.dist-info/RECORD +50 -0
  48. deep_agent_cli-0.1.0.dist-info/WHEEL +4 -0
  49. deep_agent_cli-0.1.0.dist-info/entry_points.txt +2 -0
  50. deep_agent_cli-0.1.0.dist-info/licenses/LICENSE +21 -0
agent/cli/main.py ADDED
@@ -0,0 +1,124 @@
1
+ #!/usr/bin/env python3
2
+ """Installed entry point for the interactive Deep Agent CLI."""
3
+ from __future__ import annotations
4
+
5
+ import sys
6
+ from dataclasses import replace
7
+ from prompt_toolkit import PromptSession
8
+ from prompt_toolkit.validation import Validator
9
+ from rich.console import Console
10
+ from rich.panel import Panel
11
+
12
+ from agent.cli import CliApplication
13
+ from agent.cli.app import default_config_dir
14
+ from agent.bootstrap import initialize_user_files
15
+ from agent.config import ConfigError, Settings, require_keybindings_outside_workspace
16
+ from agent.runner import AgentRunner
17
+ from agent.sandbox import ExecutionMode, SandboxUnavailableError, UNSANDBOXED_WARNING
18
+ from agent.session import SessionStore
19
+
20
+
21
+ def create_runner(settings: Settings) -> AgentRunner:
22
+ session_store = SessionStore.for_workspace(
23
+ settings.sandbox.workspace,
24
+ override=settings.state_path,
25
+ )
26
+ try:
27
+ runner = AgentRunner(
28
+ settings=settings,
29
+ sandbox_config=settings.sandbox,
30
+ session_store=session_store,
31
+ enable_sessions=True,
32
+ workspace=settings.sandbox.workspace,
33
+ )
34
+ except SandboxUnavailableError as exc:
35
+ if not sys.stdin.isatty():
36
+ raise SystemExit(
37
+ "Non-interactive startup refused UNSANDBOXED fallback. Install bwrap or set "
38
+ "sandbox.allow_unsandboxed: true in ~/.deep-agent/config.yaml。"
39
+ ) from exc
40
+ _confirm_unsandboxed(str(exc))
41
+ runner = AgentRunner(
42
+ settings=settings,
43
+ sandbox_config=replace(settings.sandbox, allow_unsandboxed=True),
44
+ session_store=session_store,
45
+ enable_sessions=True,
46
+ workspace=settings.sandbox.workspace,
47
+ )
48
+ return runner
49
+
50
+
51
+ def _confirm_unsandboxed(error: str) -> None:
52
+ Console(stderr=True).print(Panel(
53
+ f"[bold red]{error}[/bold red]\n\n{UNSANDBOXED_WARNING}\n\n"
54
+ "Type [bold]UNSANDBOXED[/bold] to accept the risk. Escape/Ctrl+C cancels startup.",
55
+ title="Sandbox unavailable",
56
+ border_style="red",
57
+ ))
58
+ validator = Validator.from_callable(
59
+ lambda value: value == "UNSANDBOXED",
60
+ error_message="Enter UNSANDBOXED exactly, or press Ctrl+C to cancel.",
61
+ move_cursor_to_end=True,
62
+ )
63
+ try:
64
+ PromptSession().prompt("Confirm: ", validator=validator, validate_while_typing=False)
65
+ except (EOFError, KeyboardInterrupt) as exc:
66
+ raise SystemExit("Startup cancelled.") from exc
67
+
68
+
69
+ def parse_startup_args(argv: list[str]) -> tuple[str | None, bool]:
70
+ if not argv:
71
+ return None, False
72
+ if argv[0] in {"-h", "--help"}:
73
+ print("Usage: deep-agent [resume [session-id]]")
74
+ raise SystemExit(0)
75
+ if argv[0] != "resume" or len(argv) > 2:
76
+ raise SystemExit(f"Unknown command: {argv[0]}\nUsage: deep-agent [resume [session-id]]")
77
+ return (argv[1] if len(argv) > 1 else None), True
78
+
79
+
80
+ def main(argv: list[str] | None = None) -> None:
81
+ resume_id, open_picker = parse_startup_args(sys.argv[1:] if argv is None else argv)
82
+ created = initialize_user_files()
83
+ if created is not None:
84
+ Console(stderr=True).print(
85
+ f"Created {created} and ~/.deep-agent/skills/.\n"
86
+ "Edit the model endpoint and API key in the config, then run deep-agent again."
87
+ )
88
+ return
89
+ try:
90
+ settings = Settings.load()
91
+ except (ConfigError, FileNotFoundError) as exc:
92
+ print(f"Configuration error: {exc}", file=sys.stderr)
93
+ raise SystemExit(2) from None
94
+ config_dir = settings.config_dir or default_config_dir()
95
+ require_keybindings_outside_workspace(config_dir, settings.sandbox.workspace)
96
+ runner = create_runner(settings)
97
+ if runner.prepared.execution_mode is ExecutionMode.UNSANDBOXED:
98
+ Console(stderr=True).print(f"[bold red]UNSANDBOXED: {runner.prepared.security_warning}[/bold red]")
99
+ Console(stderr=True).print(f"[dim]workspace={settings.sandbox.workspace}[/dim]")
100
+ app = CliApplication(runner, config_dir=config_dir)
101
+ # Startup resume shares the controller workflow: a busy session waits
102
+ # inside the TUI (Esc cancels) instead of aborting the launch.
103
+ if resume_id:
104
+ app.sessions.startup_session_id = resume_id
105
+ elif open_picker:
106
+ app.sessions.open_picker_on_start = True
107
+ try:
108
+ app.run()
109
+ finally:
110
+ message = app.continue_session_message()
111
+ if message:
112
+ Console().print(message)
113
+ try:
114
+ runner.close()
115
+ except RuntimeError as exc:
116
+ print(
117
+ f"{exc}\nThe session lock is not released early; the operating "
118
+ "system releases it when this process actually exits.",
119
+ file=sys.stderr,
120
+ )
121
+
122
+
123
+ if __name__ == "__main__":
124
+ main()