zjcode 0.0.1__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 (163) hide show
  1. deepagents_code/__init__.py +42 -0
  2. deepagents_code/__main__.py +6 -0
  3. deepagents_code/_ask_user_types.py +90 -0
  4. deepagents_code/_cli_context.py +96 -0
  5. deepagents_code/_constants.py +41 -0
  6. deepagents_code/_debug.py +148 -0
  7. deepagents_code/_debug_buffer.py +204 -0
  8. deepagents_code/_env_vars.py +411 -0
  9. deepagents_code/_fake_models.py +66 -0
  10. deepagents_code/_git.py +521 -0
  11. deepagents_code/_paths.py +69 -0
  12. deepagents_code/_server_config.py +576 -0
  13. deepagents_code/_session_stats.py +235 -0
  14. deepagents_code/_startup_error.py +45 -0
  15. deepagents_code/_testing_models.py +305 -0
  16. deepagents_code/_textual_patches.py +420 -0
  17. deepagents_code/_tool_stream.py +694 -0
  18. deepagents_code/_version.py +46 -0
  19. deepagents_code/agent.py +1976 -0
  20. deepagents_code/app.py +19239 -0
  21. deepagents_code/app.tcss +438 -0
  22. deepagents_code/approval_mode.py +131 -0
  23. deepagents_code/ask_user.py +306 -0
  24. deepagents_code/auth_display.py +185 -0
  25. deepagents_code/auth_store.py +545 -0
  26. deepagents_code/built_in_skills/__init__.py +5 -0
  27. deepagents_code/built_in_skills/remember/SKILL.md +118 -0
  28. deepagents_code/built_in_skills/skill-creator/SKILL.md +383 -0
  29. deepagents_code/built_in_skills/skill-creator/scripts/init_skill.py +366 -0
  30. deepagents_code/built_in_skills/skill-creator/scripts/quick_validate.py +158 -0
  31. deepagents_code/client/__init__.py +1 -0
  32. deepagents_code/client/commands/__init__.py +1 -0
  33. deepagents_code/client/commands/auth.py +541 -0
  34. deepagents_code/client/commands/config.py +714 -0
  35. deepagents_code/client/commands/mcp.py +250 -0
  36. deepagents_code/client/commands/tools.py +416 -0
  37. deepagents_code/client/launch/__init__.py +1 -0
  38. deepagents_code/client/launch/server.py +978 -0
  39. deepagents_code/client/launch/server_manager.py +540 -0
  40. deepagents_code/client/non_interactive.py +1758 -0
  41. deepagents_code/client/remote_client.py +794 -0
  42. deepagents_code/clipboard.py +217 -0
  43. deepagents_code/command_registry.py +450 -0
  44. deepagents_code/config.py +4829 -0
  45. deepagents_code/config_manifest.py +1451 -0
  46. deepagents_code/configurable_model.py +577 -0
  47. deepagents_code/default_agent_prompt.md +12 -0
  48. deepagents_code/doctor.py +559 -0
  49. deepagents_code/editor.py +142 -0
  50. deepagents_code/event_bus.py +411 -0
  51. deepagents_code/extras_info.py +661 -0
  52. deepagents_code/file_ops.py +576 -0
  53. deepagents_code/formatting.py +135 -0
  54. deepagents_code/goal_rubric.py +497 -0
  55. deepagents_code/goal_tools.py +459 -0
  56. deepagents_code/hooks.py +348 -0
  57. deepagents_code/input.py +1041 -0
  58. deepagents_code/integrations/__init__.py +1 -0
  59. deepagents_code/integrations/openai_codex.py +551 -0
  60. deepagents_code/integrations/sandbox_config.py +198 -0
  61. deepagents_code/integrations/sandbox_factory.py +1124 -0
  62. deepagents_code/integrations/sandbox_provider.py +137 -0
  63. deepagents_code/integrations/sandbox_registry.py +350 -0
  64. deepagents_code/iterm_cursor_guide.py +176 -0
  65. deepagents_code/local_context.py +926 -0
  66. deepagents_code/main.py +3985 -0
  67. deepagents_code/managed_tools.py +642 -0
  68. deepagents_code/mcp_auth.py +1950 -0
  69. deepagents_code/mcp_config.py +176 -0
  70. deepagents_code/mcp_disabled.py +212 -0
  71. deepagents_code/mcp_login_service.py +281 -0
  72. deepagents_code/mcp_oauth_ui.py +199 -0
  73. deepagents_code/mcp_providers/__init__.py +23 -0
  74. deepagents_code/mcp_providers/_registry.py +39 -0
  75. deepagents_code/mcp_providers/base.py +133 -0
  76. deepagents_code/mcp_providers/github.py +102 -0
  77. deepagents_code/mcp_providers/slack.py +175 -0
  78. deepagents_code/mcp_tools.py +2427 -0
  79. deepagents_code/mcp_trust.py +207 -0
  80. deepagents_code/media_utils.py +826 -0
  81. deepagents_code/memory_guard.py +474 -0
  82. deepagents_code/model_config.py +4156 -0
  83. deepagents_code/notifications.py +247 -0
  84. deepagents_code/offload.py +402 -0
  85. deepagents_code/onboarding.py +223 -0
  86. deepagents_code/output.py +69 -0
  87. deepagents_code/paste_collapse.py +103 -0
  88. deepagents_code/project_utils.py +231 -0
  89. deepagents_code/py.typed +0 -0
  90. deepagents_code/reasoning_effort.py +641 -0
  91. deepagents_code/reliable_rubric.py +97 -0
  92. deepagents_code/resume_state.py +237 -0
  93. deepagents_code/server_graph.py +310 -0
  94. deepagents_code/session_end_summary.py +329 -0
  95. deepagents_code/sessions.py +1716 -0
  96. deepagents_code/skills/__init__.py +18 -0
  97. deepagents_code/skills/commands.py +1252 -0
  98. deepagents_code/skills/invocation.py +112 -0
  99. deepagents_code/skills/load.py +196 -0
  100. deepagents_code/skills/trust.py +547 -0
  101. deepagents_code/state_migration.py +136 -0
  102. deepagents_code/subagents.py +278 -0
  103. deepagents_code/system_prompt.md +204 -0
  104. deepagents_code/terminal_capabilities.py +115 -0
  105. deepagents_code/terminal_escape.py +287 -0
  106. deepagents_code/theme.py +891 -0
  107. deepagents_code/todo_list_prompt.md +12 -0
  108. deepagents_code/tool_catalog.py +509 -0
  109. deepagents_code/tool_display.py +367 -0
  110. deepagents_code/tools.py +516 -0
  111. deepagents_code/tui/__init__.py +1 -0
  112. deepagents_code/tui/textual_adapter.py +2553 -0
  113. deepagents_code/tui/widgets/__init__.py +9 -0
  114. deepagents_code/tui/widgets/_js_eval_display.py +139 -0
  115. deepagents_code/tui/widgets/_links.py +261 -0
  116. deepagents_code/tui/widgets/agent_selector.py +420 -0
  117. deepagents_code/tui/widgets/approval.py +602 -0
  118. deepagents_code/tui/widgets/ask_user.py +515 -0
  119. deepagents_code/tui/widgets/auth.py +1997 -0
  120. deepagents_code/tui/widgets/autocomplete.py +890 -0
  121. deepagents_code/tui/widgets/chat_input.py +3181 -0
  122. deepagents_code/tui/widgets/codex_auth.py +452 -0
  123. deepagents_code/tui/widgets/cwd_switch.py +242 -0
  124. deepagents_code/tui/widgets/debug_console.py +868 -0
  125. deepagents_code/tui/widgets/diff.py +252 -0
  126. deepagents_code/tui/widgets/effort_selector.py +189 -0
  127. deepagents_code/tui/widgets/goal_review.py +390 -0
  128. deepagents_code/tui/widgets/goal_status.py +50 -0
  129. deepagents_code/tui/widgets/history.py +194 -0
  130. deepagents_code/tui/widgets/install_confirm.py +248 -0
  131. deepagents_code/tui/widgets/launch_init.py +482 -0
  132. deepagents_code/tui/widgets/loading.py +227 -0
  133. deepagents_code/tui/widgets/mcp_login.py +539 -0
  134. deepagents_code/tui/widgets/mcp_reconnect.py +212 -0
  135. deepagents_code/tui/widgets/mcp_viewer.py +1634 -0
  136. deepagents_code/tui/widgets/message_store.py +999 -0
  137. deepagents_code/tui/widgets/messages.py +3846 -0
  138. deepagents_code/tui/widgets/model_selector.py +2343 -0
  139. deepagents_code/tui/widgets/notification_center.py +456 -0
  140. deepagents_code/tui/widgets/notification_detail.py +257 -0
  141. deepagents_code/tui/widgets/notification_settings.py +170 -0
  142. deepagents_code/tui/widgets/restart_prompt.py +158 -0
  143. deepagents_code/tui/widgets/skill_trust.py +131 -0
  144. deepagents_code/tui/widgets/startup_tip.py +91 -0
  145. deepagents_code/tui/widgets/status.py +781 -0
  146. deepagents_code/tui/widgets/subagent_panel.py +969 -0
  147. deepagents_code/tui/widgets/theme_selector.py +401 -0
  148. deepagents_code/tui/widgets/thread_selector.py +2564 -0
  149. deepagents_code/tui/widgets/tool_renderers.py +190 -0
  150. deepagents_code/tui/widgets/tool_widgets.py +304 -0
  151. deepagents_code/tui/widgets/update_available.py +311 -0
  152. deepagents_code/tui/widgets/update_confirm.py +184 -0
  153. deepagents_code/tui/widgets/update_progress.py +327 -0
  154. deepagents_code/tui/widgets/welcome.py +508 -0
  155. deepagents_code/turn_end_summary.py +522 -0
  156. deepagents_code/ui.py +858 -0
  157. deepagents_code/unicode_security.py +563 -0
  158. deepagents_code/update_check.py +3124 -0
  159. zjcode-0.0.1.data/data/deepagents_code/default_agent_prompt.md +12 -0
  160. zjcode-0.0.1.dist-info/METADATA +220 -0
  161. zjcode-0.0.1.dist-info/RECORD +163 -0
  162. zjcode-0.0.1.dist-info/WHEEL +4 -0
  163. zjcode-0.0.1.dist-info/entry_points.txt +2 -0
@@ -0,0 +1,411 @@
1
+ """Canonical registry of `DEEPAGENTS_CODE_*` environment variables.
2
+
3
+ Every env var the app reads whose name starts with `DEEPAGENTS_CODE_` must
4
+ be defined here as a module-level constant. A drift-detection test
5
+ (`tests/unit_tests/test_env_vars.py`) fails when a bare string literal
6
+ like `"DEEPAGENTS_CODE_FOO"` appears in source code instead of a constant
7
+ imported from this module.
8
+
9
+ Import the short-name constants (e.g. `AUTO_UPDATE`, `DEBUG`) and pass them
10
+ to `os.environ.get()` instead of using raw string literals. If the env var is
11
+ ever renamed, only the value here changes.
12
+
13
+ !!! note
14
+
15
+ `resolve_env_var` also supports a dynamic prefix override for API keys
16
+ and provider credentials: setting `DEEPAGENTS_CODE_{NAME}` takes priority
17
+ over `{NAME}`. For example, `DEEPAGENTS_CODE_OPENAI_API_KEY` overrides
18
+ `OPENAI_API_KEY`. Only call sites that use `resolve_env_var` benefit from
19
+ this -- direct `os.environ.get` lookups (like the constants below) do not.
20
+ Dynamic overrides are not listed here because they mirror third-party
21
+ variable names.
22
+ """
23
+
24
+ from __future__ import annotations
25
+
26
+ import os
27
+
28
+ # ---------------------------------------------------------------------------
29
+ # Constants — import these instead of bare string literals.
30
+ # Keep alphabetically sorted by constant name.
31
+ # ---------------------------------------------------------------------------
32
+
33
+ AUTO_UPDATE = "DEEPAGENTS_CODE_AUTO_UPDATE"
34
+ """Toggle automatic app updates. Enabled by default; set to a falsy value
35
+ ('0', 'false', 'no', 'off', or empty) to opt out."""
36
+
37
+ COLLAPSE_PASTES = "DEEPAGENTS_CODE_COLLAPSE_PASTES"
38
+ """Collapse large chat-input pastes into `[Pasted text #N +M lines]` placeholders.
39
+
40
+ Enabled by default; set to a falsy value (`0`, `false`, `no`, `off`, or empty)
41
+ to disable auto-collapsing so pasted text is inserted verbatim. Parsed by
42
+ `classify_env_bool` (an unrecognized value falls through to the config value
43
+ rather than forcing the default). Also settable via `[ui].collapse_pastes` in
44
+ config.toml.
45
+ """
46
+
47
+ CURSOR_STYLE = "DEEPAGENTS_CODE_CURSOR_STYLE"
48
+ """Chat input cursor style (`block` or `underline`).
49
+
50
+ Takes precedence over `[ui].cursor_style` in config.toml. Invalid values fall
51
+ through to the config file and then the default block cursor.
52
+ """
53
+
54
+ DEBUG = "DEEPAGENTS_CODE_DEBUG"
55
+ """Enable verbose debug logging and preserve the server subprocess log.
56
+
57
+ Parsed by `is_env_truthy`: accepts `1`, `true`, `yes`, `on` (case-insensitive)
58
+ as enabled, and `0`, `false`, `no`, `off`, empty string, or unset as disabled.
59
+ """
60
+
61
+ DEBUG_FILE = "DEEPAGENTS_CODE_DEBUG_FILE"
62
+ """Path for the debug log file (default: `DEFAULT_DEBUG_FILE`)."""
63
+
64
+ DEFAULT_DEBUG_FILE = "/tmp/deepagents_debug.log" # noqa: S108 # opt-in debug log
65
+ """Default path for the debug log when `DEBUG_FILE` is unset."""
66
+
67
+ DEBUG_MCP_PROJECT_TRUST = "DEEPAGENTS_CODE_DEBUG_MCP_PROJECT_TRUST"
68
+ """Force the project MCP approval prompt for manual UI testing.
69
+
70
+ Set to a truthy value when launching the interactive TUI to render the
71
+ project-level MCP trust prompt without relying on an untrusted config state. If
72
+ project MCP servers are discovered, the prompt shows those real servers;
73
+ otherwise it shows a sample server. The TUI exits after the prompt response so
74
+ the debug run does not continue into TUI or server startup, and it does not
75
+ persist trust decisions.
76
+
77
+ Parsed by `is_env_truthy`: accepts `1`, `true`, `yes`, `on` as enabled.
78
+ """
79
+
80
+ DEBUG_NOTIFICATIONS = "DEEPAGENTS_CODE_DEBUG_NOTIFICATIONS"
81
+ """Inject sample missing-dependency notifications at launch so the notification
82
+ center UI can be exercised without waiting for real conditions.
83
+
84
+ Does not auto-open the update modal (use `DEEPAGENTS_CODE_DEBUG_UPDATE` for that).
85
+
86
+ Any non-empty value enables the flag (including `"0"` or `"false"`).
87
+ """
88
+
89
+ DEBUG_ONBOARDING = "DEEPAGENTS_CODE_DEBUG_ONBOARDING"
90
+ """Force the onboarding flow to open on every interactive startup.
91
+
92
+ Parsed by `is_env_truthy`: accepts `1`, `true`, `yes`, `on` as enabled.
93
+ """
94
+
95
+ DEBUG_UPDATE = "DEEPAGENTS_CODE_DEBUG_UPDATE"
96
+ """Inject a sample update-available notification and auto-open the update modal
97
+ at launch so the update-available flow can be exercised without waiting for a
98
+ real PyPI release.
99
+
100
+ Any non-empty value enables the flag (including `"0"` or `"false"`).
101
+ """
102
+
103
+ DISABLED_PROJECT_MCP_SERVERS = "DEEPAGENTS_CODE_DISABLED_PROJECT_MCP_SERVERS"
104
+ """Comma-separated project MCP server names to always reject by name.
105
+
106
+ A user-level equivalent of `[mcp].disabled_project_servers`.
107
+
108
+ Rejection wins over approval: a name listed here is dropped even when it also
109
+ appears in `ENABLED_PROJECT_MCP_SERVERS` (or `[mcp].enabled_project_servers`)
110
+ and even when the project config is otherwise trusted. Unlike the enabled list,
111
+ this env var *unions* with (rather than replaces)
112
+ `[mcp].disabled_project_servers` — denies accumulate across sources, so neither
113
+ can silently empty a deny set in the other. This is process env the user
114
+ controls, not a repo file, so it does not weaken the user-level-only
115
+ trust boundary: a committed *project* `.env` is blocked from setting it
116
+ (see `config._PROJECT_DOTENV_DENIED_ENV_KEYS`); only the user's shell,
117
+ launch env, or global `~/.deepagents/.env` can.
118
+ """
119
+
120
+ ENABLED_PROJECT_MCP_SERVERS = "DEEPAGENTS_CODE_ENABLED_PROJECT_MCP_SERVERS"
121
+ """Comma-separated project MCP server names to pre-approve by name.
122
+
123
+ A user-level equivalent of `[mcp].enabled_project_servers`.
124
+
125
+ Servers named here load from an otherwise-untrusted project `.mcp.json` without
126
+ prompting (they are omitted from the interactive approval prompt), while
127
+ non-listed servers stay dropped. Like `DISABLED_PROJECT_MCP_SERVERS`, this is
128
+ user-controlled process env, not a repo file, so it does not weaken
129
+ the user-level-only trust boundary (a committed *project* `.env` cannot set it;
130
+ see `config._PROJECT_DOTENV_DENIED_ENV_KEYS`). This contract is name-based:
131
+ a project command or URL change under the same server name still matches.
132
+
133
+ When set, this replaces (takes precedence over) the
134
+ `[mcp].enabled_project_servers` TOML list.
135
+ (`DISABLED_PROJECT_MCP_SERVERS` instead *unions* with its TOML list, so a deny
136
+ is never silently emptied.)
137
+ """
138
+
139
+ EXPERIMENTAL = "DEEPAGENTS_CODE_EXPERIMENTAL"
140
+ """Opt into experimental, unstable dcode behavior.
141
+
142
+ Off by default; parsed by `is_env_truthy` (see there for the accepted truthy
143
+ values). Currently gates dropping the SDK's `TodoListMiddleware` (and its
144
+ `write_todos` tool) from the agent and its subagents, along with the matching
145
+ todo-list prompt guidance. Behavior behind this flag may change or be removed
146
+ without notice.
147
+ """
148
+
149
+ EXTERNAL_EVENT_SOCKET = "DEEPAGENTS_CODE_EXTERNAL_EVENT_SOCKET"
150
+ """Enable the local Unix-socket external event listener.
151
+
152
+ Parsed by `is_env_truthy`; off by default. Wire format and behavior are
153
+ considered experimental until the listener is documented in the README.
154
+ """
155
+
156
+ EXTERNAL_EVENT_SOCKET_PATH = "DEEPAGENTS_CODE_EXTERNAL_EVENT_SOCKET_PATH"
157
+ """Override the default Unix-socket path for the external event listener."""
158
+
159
+ EXTRA_SKILLS_DIRS = "DEEPAGENTS_CODE_EXTRA_SKILLS_DIRS"
160
+ """Colon-separated paths added to the skill containment allowlist."""
161
+
162
+ HIDE_CWD = "DEEPAGENTS_CODE_HIDE_CWD"
163
+ """Hide local path displays in the TUI footer and the editable-install path in
164
+ the startup splash when enabled.
165
+
166
+ Does not control the splash working-directory row, which is gated solely by
167
+ `SPLASH_SHOW_CWD`.
168
+ """
169
+
170
+ HIDE_GIT_BRANCH = "DEEPAGENTS_CODE_HIDE_GIT_BRANCH"
171
+ """Hide the current git branch in the TUI footer when enabled."""
172
+
173
+ HIDE_LANGSMITH_TRACING = "DEEPAGENTS_CODE_HIDE_LANGSMITH_TRACING"
174
+ """Hide LangSmith tracing project/thread info in the startup splash when enabled."""
175
+
176
+ HIDE_SPLASH_TIPS = "DEEPAGENTS_CODE_HIDE_SPLASH_TIPS"
177
+ """Hide the startup tip shown above the chat input when enabled."""
178
+
179
+ HIDE_SPLASH_VERSION = "DEEPAGENTS_CODE_HIDE_SPLASH_VERSION"
180
+ """Hide version and local-install details in the splash screen when enabled."""
181
+
182
+ KITTY_KEYBOARD = "DEEPAGENTS_CODE_KITTY_KEYBOARD"
183
+ """Override kitty-keyboard detection (`1` forces on, `0` forces off)."""
184
+
185
+ LANGSMITH_PROJECT = "DEEPAGENTS_CODE_LANGSMITH_PROJECT"
186
+ """Override LangSmith project name for agent traces."""
187
+
188
+ LANGSMITH_REDACT = "DEEPAGENTS_CODE_LANGSMITH_REDACT"
189
+ """Toggle LangSmith secret redaction for agent traces (defaults to on)."""
190
+
191
+ LANGSMITH_REPLICA_PROJECTS = "DEEPAGENTS_CODE_LANGSMITH_REPLICA_PROJECTS"
192
+ """Comma-separated LangSmith project names to *also* write agent traces to.
193
+
194
+ When set (and tracing is active), each agent run is dual-written to the primary
195
+ deepagents-code project *and* one extra project via LangSmith write replicas.
196
+
197
+ Only the first listed project is used: the LangGraph server mirrors a run to a
198
+ single extra project, so any additional entries are dropped (with a warning).
199
+ The value is comma-separated for forward-compatibility, not because multiple
200
+ destinations are written today.
201
+ """
202
+
203
+ LOG_LEVEL = "DEEPAGENTS_CODE_LOG_LEVEL"
204
+ """Minimum level for `deepagents_code` runtime logging.
205
+
206
+ Accepted values are DEBUG, INFO, WARNING, ERROR, and CRITICAL.
207
+ """
208
+
209
+ MEMORY_AUTO_SAVE = "DEEPAGENTS_CODE_MEMORY_AUTO_SAVE"
210
+ """Toggle automatic memory saving (defaults to on).
211
+
212
+ When enabled, the memory prompt tells the agent to proactively persist
213
+ learnings to the `AGENTS.md` memory files. Set to a falsy value (`0`, `false`,
214
+ `no`, `off`, or empty) to keep loading memory into context while disabling the
215
+ auto-save guidance; explicit saves (e.g. the `remember` skill) still work.
216
+ """
217
+
218
+ NO_MOUSE = "DEEPAGENTS_CODE_NO_MOUSE"
219
+ """Disable Textual mouse tracking when enabled.
220
+
221
+ Useful for web-based terminals (e.g. 1Panel, ttyd, wetty) that forward mouse
222
+ events but strip the ESC prefix from SGR mouse-report sequences, causing
223
+ garbled input like `[<35;36;33M...` to leak into the input field.
224
+
225
+ Parsed by `is_env_truthy`: accepts `1`, `true`, `yes`, `on` as enabled.
226
+ Equivalent to passing `--no-mouse` on the command line.
227
+ """
228
+
229
+ NO_TERMINAL_ESCAPE = "DEEPAGENTS_CODE_NO_TERMINAL_ESCAPE"
230
+ """Disable all terminal escape/control sequence output when enabled."""
231
+
232
+ NO_UPDATE_CHECK = "DEEPAGENTS_CODE_NO_UPDATE_CHECK"
233
+ """Disable automatic update checking when set."""
234
+
235
+ OFFLINE = "DEEPAGENTS_CODE_OFFLINE"
236
+ """Disable network downloads of managed binaries (e.g. ripgrep).
237
+
238
+ Parsed by `is_env_truthy`: accepts `1`, `true`, `yes`, `on` as enabled. When
239
+ truthy, `managed_tools.ensure_ripgrep` will not attempt to download a binary
240
+ and falls back to the existing missing-tool notification + slow Python regex
241
+ path."""
242
+
243
+ OLLAMA_DISCOVERY = "DEEPAGENTS_CODE_OLLAMA_DISCOVERY"
244
+ """Toggle Ollama model and profile discovery probes.
245
+
246
+ Defaults to enabled. Suppress the probe when the daemon is intentionally
247
+ offline or the probe latency is undesirable. The probe is lazy and never
248
+ runs on the startup hot path. When enabled, discovery may call `/api/tags`
249
+ and `/api/show`. See `_ollama_discovery_enabled` for accepted truthy/falsy
250
+ values.
251
+ """
252
+
253
+ ONBOARDING_INTEGRATIONS_SCREEN = "DEEPAGENTS_CODE_ONBOARDING_INTEGRATIONS_SCREEN"
254
+ """Show the "Installed Integrations" summary screen during first-run onboarding.
255
+
256
+ Off by default: onboarding goes straight from the name prompt to the model
257
+ selector, which already surfaces (and installs) uninstalled model providers.
258
+ Set to a truthy value to bring the standalone integrations screen back into the
259
+ flow. Parsed by `is_env_truthy`: accepts `1`, `true`, `yes`, `on` as enabled.
260
+ """
261
+
262
+ PYPI_URL = "DEEPAGENTS_CODE_PYPI_URL"
263
+ """Override the JSON API URL used to check for `zjcode` updates.
264
+
265
+ Defaults (in `_version.py`) to `https://pypi.org/pypi/zjcode/json`.
266
+ """
267
+
268
+ RESTARTED_AFTER_UPDATE = "DEEPAGENTS_CODE_RESTARTED_AFTER_UPDATE"
269
+ """Internal sentinel recording the target version immediately before the
270
+ startup auto-update re-execs the process.
271
+
272
+ Not user-facing. The re-exec'd process consumes it and, if that same version
273
+ still reports as available (a no-op upgrade that did not change the running
274
+ version), skips auto-updating to break out of an otherwise endless
275
+ upgrade/restart loop. Set and read internally across `os.execv`.
276
+ """
277
+
278
+ RIPGREP_INSTALLER = "DEEPAGENTS_CODE_RIPGREP_INSTALLER"
279
+ """Select how ripgrep is provisioned: `managed` (default) or `system`.
280
+
281
+ `managed` downloads the pinned, SHA-256-verified upstream binary into
282
+ `~/.deepagents/bin` (no sudo). `system` skips that download so power users can
283
+ rely on their distro package / existing toolchain instead; the install script's
284
+ `system` mode keeps the brew/apt/cargo path. A system `rg` already on `PATH` is
285
+ reused under either setting. Unrecognized values fall back to `managed`. See
286
+ `managed_tools.ripgrep_installer`."""
287
+
288
+ SDK_PYPI_URL = "DEEPAGENTS_CODE_SDK_PYPI_URL"
289
+ """Override the JSON API URL used to read `deepagents` SDK release metadata.
290
+
291
+ Defaults (in `_version.py`) to the private static mirror. Set to
292
+ `https://pypi.org/pypi/deepagents/json` to read from public PyPI instead.
293
+ """
294
+
295
+ SERVER_ENV_PREFIX = "DEEPAGENTS_CODE_SERVER_"
296
+ """Environment variable prefix used to pass CLI config to the server subprocess."""
297
+
298
+ SHELL_ALLOW_LIST = "DEEPAGENTS_CODE_SHELL_ALLOW_LIST"
299
+ """Comma-separated shell commands to allow (or 'recommended'/'all')."""
300
+
301
+ SHOW_HEADER = "DEEPAGENTS_CODE_SHOW_HEADER"
302
+ """Show Textual's native header bar at the top of the TUI when enabled."""
303
+
304
+ SHOW_LANGSMITH_REPLICA_TRACING = "DEEPAGENTS_CODE_SHOW_LANGSMITH_REPLICA_TRACING"
305
+ """Show LangSmith replica project info in the startup splash when enabled.
306
+
307
+ Defaults to enabled; set to a falsy value (`0`, `false`, `no`, `off`, or empty)
308
+ to hide replica tracing details from the splash while leaving tracing active.
309
+ """
310
+
311
+ SHOW_SCROLLBAR = "DEEPAGENTS_CODE_SHOW_SCROLLBAR"
312
+ """Show the vertical scrollbar in the chat area when enabled.
313
+
314
+ Off by default; use the `/scrollbar` slash command or `[ui].show_scrollbar` in
315
+ config.toml to toggle. Parsed by `classify_env_bool` (an unrecognized or empty
316
+ value falls through to the config value rather than forcing the default).
317
+
318
+ When set, this env var takes precedence over the persisted `[ui].show_scrollbar`
319
+ config value on launch, so a `/scrollbar` toggle will not appear to "stick"
320
+ across restarts while the env var remains set.
321
+ """
322
+
323
+ SHOW_URL_OPEN_TOAST = "DEEPAGENTS_CODE_SHOW_URL_OPEN_TOAST"
324
+ """Show a confirmation toast after clicking a URL that opens in a browser.
325
+
326
+ Defaults to enabled; set to a falsy value (`0`, `false`, `no`, `off`, or empty)
327
+ to suppress the success toast while still opening URLs normally.
328
+ """
329
+
330
+ SPLASH_SHOW_CWD = "DEEPAGENTS_CODE_SPLASH_SHOW_CWD"
331
+ """Show the working-directory row in the startup welcome banner when enabled.
332
+
333
+ Off by default and independent of the status bar's `HIDE_CWD`.
334
+ """
335
+
336
+ SPLASH_SHOW_MODEL = "DEEPAGENTS_CODE_SPLASH_SHOW_MODEL"
337
+ """Show the active model row in the startup welcome banner when enabled.
338
+
339
+ Off by default; the model is always visible in the status bar, so the banner
340
+ row is opt-in to avoid duplicating it.
341
+ """
342
+
343
+ SUPPRESS_ENV_OVERRIDE_WARNING = "DEEPAGENTS_CODE_SUPPRESS_ENV_OVERRIDE_WARNING"
344
+ """Silence the startup warning emitted when a `DEEPAGENTS_CODE_`-prefixed
345
+ LangSmith variable overrides its canonical counterpart (e.g. both
346
+ `LANGSMITH_API_KEY` and `DEEPAGENTS_CODE_LANGSMITH_API_KEY` are set to
347
+ different values).
348
+
349
+ The override is intentional: the prefixed value overwrites the canonical
350
+ variable inside the Deep Agents Code process (so the LangSmith SDK, which
351
+ only reads canonical names, picks it up). The value you exported in your own
352
+ shell is unaffected, since a process cannot change its parent's environment.
353
+ Off by default; set to a truthy value (`1`, `true`, `yes`, `on`) to suppress
354
+ the warning when this coexistence is expected. Parsed by `is_env_truthy`.
355
+ """
356
+
357
+ THEME = "DEEPAGENTS_CODE_THEME"
358
+ """Force the CLI to launch with this theme name when set."""
359
+
360
+ USER_ID = "DEEPAGENTS_CODE_USER_ID"
361
+ """Attach a user identifier to LangSmith trace metadata."""
362
+
363
+ _TRUTHY_VALUES = frozenset({"1", "true", "yes", "on"})
364
+ _FALSY_VALUES = frozenset({"0", "false", "no", "off", ""})
365
+
366
+
367
+ def classify_env_bool(raw: str) -> bool | None:
368
+ """Classify a raw env-var string as a truthy, falsy, or unrecognized token.
369
+
370
+ The single source of truth for which strings count as boolean on/off
371
+ values; `is_env_truthy` and the config resolver both build on it so they
372
+ agree on what "recognizably boolean" means.
373
+
374
+ Args:
375
+ raw: The raw (unstripped) environment-variable value.
376
+
377
+ Returns:
378
+ `True` for `1`/`true`/`yes`/`on`, `False` for `0`/`false`/`no`/`off`/
379
+ empty string (case-insensitive), or `None` when the value
380
+ is neither.
381
+ """
382
+ lowered = raw.strip().lower()
383
+ if lowered in _TRUTHY_VALUES:
384
+ return True
385
+ if lowered in _FALSY_VALUES:
386
+ return False
387
+ return None
388
+
389
+
390
+ def is_env_truthy(name: str, *, default: bool = False) -> bool:
391
+ """Return whether env var *name* is set to a recognizably truthy value.
392
+
393
+ Unlike `bool(os.environ.get(name))`, this does not treat `"0"` or
394
+ `"false"` as enabled. Use this for on/off flags where the user would
395
+ reasonably expect `VAR=0` to mean "disabled".
396
+
397
+ Args:
398
+ name: Environment variable name (typically a `DEEPAGENTS_CODE_*`
399
+ constant from this module).
400
+ default: Value returned when the variable is unset OR set to a
401
+ value that is neither recognizably truthy nor falsy.
402
+
403
+ Returns:
404
+ `True` for `1`/`true`/`yes`/`on` (case-insensitive), `False` for
405
+ `0`/`false`/`no`/`off`/empty string, or `default` otherwise.
406
+ """
407
+ raw = os.environ.get(name)
408
+ if raw is None:
409
+ return default
410
+ classified = classify_env_bool(raw)
411
+ return default if classified is None else classified
@@ -0,0 +1,66 @@
1
+ """Fake chat model base shared by integration tests and tool enumeration.
2
+
3
+ Holds the tool-binding base that both the local integration-test fakes
4
+ (`_testing_models`) and the `dcode tools list` tool-enumeration path
5
+ (`tool_catalog._CatalogModel`) build on. It lives in a use-neutral module — not
6
+ under a `_testing_`-prefixed name — so a production import path never depends on
7
+ something that reads as test-only and might be pruned or excluded from the wheel.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from typing import TYPE_CHECKING, Any
13
+
14
+ from langchain_core.language_models.fake_chat_models import GenericFakeChatModel
15
+ from pydantic import Field
16
+
17
+ if TYPE_CHECKING:
18
+ from collections.abc import Callable, Sequence
19
+
20
+ from langchain_core.language_models import LanguageModelInput
21
+ from langchain_core.messages import AIMessage
22
+ from langchain_core.runnables import Runnable
23
+ from langchain_core.tools import BaseTool
24
+
25
+
26
+ _TOOL_BINDING_MODEL_PROFILE: dict[str, Any] = {
27
+ "tool_calling": True,
28
+ "max_input_tokens": 8000,
29
+ }
30
+ """Minimal capability profile the agent runtime reads while compiling a model.
31
+
32
+ Only `tool_calling` is load-bearing — the agent negotiates tool support at
33
+ setup. `max_input_tokens` is part of the profile surface but inert here: these
34
+ models are compiled to bind tools and are never invoked, so no token budget ever
35
+ applies. Defined once so both the integration-test fakes and
36
+ `tool_catalog._CatalogModel` share a single source of truth.
37
+ """
38
+
39
+
40
+ class _ToolBindingFakeModel(GenericFakeChatModel):
41
+ """Base for fake chat models that must bind tools but are never invoked.
42
+
43
+ The agent runtime calls `model.bind_tools(schemas)` and reads `model.profile`
44
+ while compiling the graph, and a bare `GenericFakeChatModel` cannot be
45
+ compiled into an agent graph: it inherits `BaseChatModel.bind_tools`, which
46
+ raises `NotImplementedError`, and its `profile` is `None`, which breaks
47
+ capability negotiation. This base supplies a no-op `bind_tools` passthrough
48
+ and a minimal `profile`, leaving subclasses to add generation behavior
49
+ (tests) or nothing at all (tool enumeration).
50
+ """
51
+
52
+ # Required by `GenericFakeChatModel`, but subclasses never consume it.
53
+ messages: object = Field(default_factory=lambda: iter(()))
54
+ profile: dict[str, Any] | None = Field(
55
+ default_factory=lambda: dict(_TOOL_BINDING_MODEL_PROFILE)
56
+ )
57
+
58
+ def bind_tools(
59
+ self,
60
+ tools: Sequence[dict[str, Any] | type | Callable | BaseTool], # noqa: ARG002
61
+ *,
62
+ tool_choice: str | None = None, # noqa: ARG002
63
+ **kwargs: Any, # noqa: ARG002
64
+ ) -> Runnable[LanguageModelInput, AIMessage]:
65
+ """Return self so the agent can bind tool schemas without a real model."""
66
+ return self