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.
- deepagents_code/__init__.py +42 -0
- deepagents_code/__main__.py +6 -0
- deepagents_code/_ask_user_types.py +90 -0
- deepagents_code/_cli_context.py +96 -0
- deepagents_code/_constants.py +41 -0
- deepagents_code/_debug.py +148 -0
- deepagents_code/_debug_buffer.py +204 -0
- deepagents_code/_env_vars.py +411 -0
- deepagents_code/_fake_models.py +66 -0
- deepagents_code/_git.py +521 -0
- deepagents_code/_paths.py +69 -0
- deepagents_code/_server_config.py +576 -0
- deepagents_code/_session_stats.py +235 -0
- deepagents_code/_startup_error.py +45 -0
- deepagents_code/_testing_models.py +305 -0
- deepagents_code/_textual_patches.py +420 -0
- deepagents_code/_tool_stream.py +694 -0
- deepagents_code/_version.py +46 -0
- deepagents_code/agent.py +1976 -0
- deepagents_code/app.py +19239 -0
- deepagents_code/app.tcss +438 -0
- deepagents_code/approval_mode.py +131 -0
- deepagents_code/ask_user.py +306 -0
- deepagents_code/auth_display.py +185 -0
- deepagents_code/auth_store.py +545 -0
- deepagents_code/built_in_skills/__init__.py +5 -0
- deepagents_code/built_in_skills/remember/SKILL.md +118 -0
- deepagents_code/built_in_skills/skill-creator/SKILL.md +383 -0
- deepagents_code/built_in_skills/skill-creator/scripts/init_skill.py +366 -0
- deepagents_code/built_in_skills/skill-creator/scripts/quick_validate.py +158 -0
- deepagents_code/client/__init__.py +1 -0
- deepagents_code/client/commands/__init__.py +1 -0
- deepagents_code/client/commands/auth.py +541 -0
- deepagents_code/client/commands/config.py +714 -0
- deepagents_code/client/commands/mcp.py +250 -0
- deepagents_code/client/commands/tools.py +416 -0
- deepagents_code/client/launch/__init__.py +1 -0
- deepagents_code/client/launch/server.py +978 -0
- deepagents_code/client/launch/server_manager.py +540 -0
- deepagents_code/client/non_interactive.py +1758 -0
- deepagents_code/client/remote_client.py +794 -0
- deepagents_code/clipboard.py +217 -0
- deepagents_code/command_registry.py +450 -0
- deepagents_code/config.py +4829 -0
- deepagents_code/config_manifest.py +1451 -0
- deepagents_code/configurable_model.py +577 -0
- deepagents_code/default_agent_prompt.md +12 -0
- deepagents_code/doctor.py +559 -0
- deepagents_code/editor.py +142 -0
- deepagents_code/event_bus.py +411 -0
- deepagents_code/extras_info.py +661 -0
- deepagents_code/file_ops.py +576 -0
- deepagents_code/formatting.py +135 -0
- deepagents_code/goal_rubric.py +497 -0
- deepagents_code/goal_tools.py +459 -0
- deepagents_code/hooks.py +348 -0
- deepagents_code/input.py +1041 -0
- deepagents_code/integrations/__init__.py +1 -0
- deepagents_code/integrations/openai_codex.py +551 -0
- deepagents_code/integrations/sandbox_config.py +198 -0
- deepagents_code/integrations/sandbox_factory.py +1124 -0
- deepagents_code/integrations/sandbox_provider.py +137 -0
- deepagents_code/integrations/sandbox_registry.py +350 -0
- deepagents_code/iterm_cursor_guide.py +176 -0
- deepagents_code/local_context.py +926 -0
- deepagents_code/main.py +3985 -0
- deepagents_code/managed_tools.py +642 -0
- deepagents_code/mcp_auth.py +1950 -0
- deepagents_code/mcp_config.py +176 -0
- deepagents_code/mcp_disabled.py +212 -0
- deepagents_code/mcp_login_service.py +281 -0
- deepagents_code/mcp_oauth_ui.py +199 -0
- deepagents_code/mcp_providers/__init__.py +23 -0
- deepagents_code/mcp_providers/_registry.py +39 -0
- deepagents_code/mcp_providers/base.py +133 -0
- deepagents_code/mcp_providers/github.py +102 -0
- deepagents_code/mcp_providers/slack.py +175 -0
- deepagents_code/mcp_tools.py +2427 -0
- deepagents_code/mcp_trust.py +207 -0
- deepagents_code/media_utils.py +826 -0
- deepagents_code/memory_guard.py +474 -0
- deepagents_code/model_config.py +4156 -0
- deepagents_code/notifications.py +247 -0
- deepagents_code/offload.py +402 -0
- deepagents_code/onboarding.py +223 -0
- deepagents_code/output.py +69 -0
- deepagents_code/paste_collapse.py +103 -0
- deepagents_code/project_utils.py +231 -0
- deepagents_code/py.typed +0 -0
- deepagents_code/reasoning_effort.py +641 -0
- deepagents_code/reliable_rubric.py +97 -0
- deepagents_code/resume_state.py +237 -0
- deepagents_code/server_graph.py +310 -0
- deepagents_code/session_end_summary.py +329 -0
- deepagents_code/sessions.py +1716 -0
- deepagents_code/skills/__init__.py +18 -0
- deepagents_code/skills/commands.py +1252 -0
- deepagents_code/skills/invocation.py +112 -0
- deepagents_code/skills/load.py +196 -0
- deepagents_code/skills/trust.py +547 -0
- deepagents_code/state_migration.py +136 -0
- deepagents_code/subagents.py +278 -0
- deepagents_code/system_prompt.md +204 -0
- deepagents_code/terminal_capabilities.py +115 -0
- deepagents_code/terminal_escape.py +287 -0
- deepagents_code/theme.py +891 -0
- deepagents_code/todo_list_prompt.md +12 -0
- deepagents_code/tool_catalog.py +509 -0
- deepagents_code/tool_display.py +367 -0
- deepagents_code/tools.py +516 -0
- deepagents_code/tui/__init__.py +1 -0
- deepagents_code/tui/textual_adapter.py +2553 -0
- deepagents_code/tui/widgets/__init__.py +9 -0
- deepagents_code/tui/widgets/_js_eval_display.py +139 -0
- deepagents_code/tui/widgets/_links.py +261 -0
- deepagents_code/tui/widgets/agent_selector.py +420 -0
- deepagents_code/tui/widgets/approval.py +602 -0
- deepagents_code/tui/widgets/ask_user.py +515 -0
- deepagents_code/tui/widgets/auth.py +1997 -0
- deepagents_code/tui/widgets/autocomplete.py +890 -0
- deepagents_code/tui/widgets/chat_input.py +3181 -0
- deepagents_code/tui/widgets/codex_auth.py +452 -0
- deepagents_code/tui/widgets/cwd_switch.py +242 -0
- deepagents_code/tui/widgets/debug_console.py +868 -0
- deepagents_code/tui/widgets/diff.py +252 -0
- deepagents_code/tui/widgets/effort_selector.py +189 -0
- deepagents_code/tui/widgets/goal_review.py +390 -0
- deepagents_code/tui/widgets/goal_status.py +50 -0
- deepagents_code/tui/widgets/history.py +194 -0
- deepagents_code/tui/widgets/install_confirm.py +248 -0
- deepagents_code/tui/widgets/launch_init.py +482 -0
- deepagents_code/tui/widgets/loading.py +227 -0
- deepagents_code/tui/widgets/mcp_login.py +539 -0
- deepagents_code/tui/widgets/mcp_reconnect.py +212 -0
- deepagents_code/tui/widgets/mcp_viewer.py +1634 -0
- deepagents_code/tui/widgets/message_store.py +999 -0
- deepagents_code/tui/widgets/messages.py +3846 -0
- deepagents_code/tui/widgets/model_selector.py +2343 -0
- deepagents_code/tui/widgets/notification_center.py +456 -0
- deepagents_code/tui/widgets/notification_detail.py +257 -0
- deepagents_code/tui/widgets/notification_settings.py +170 -0
- deepagents_code/tui/widgets/restart_prompt.py +158 -0
- deepagents_code/tui/widgets/skill_trust.py +131 -0
- deepagents_code/tui/widgets/startup_tip.py +91 -0
- deepagents_code/tui/widgets/status.py +781 -0
- deepagents_code/tui/widgets/subagent_panel.py +969 -0
- deepagents_code/tui/widgets/theme_selector.py +401 -0
- deepagents_code/tui/widgets/thread_selector.py +2564 -0
- deepagents_code/tui/widgets/tool_renderers.py +190 -0
- deepagents_code/tui/widgets/tool_widgets.py +304 -0
- deepagents_code/tui/widgets/update_available.py +311 -0
- deepagents_code/tui/widgets/update_confirm.py +184 -0
- deepagents_code/tui/widgets/update_progress.py +327 -0
- deepagents_code/tui/widgets/welcome.py +508 -0
- deepagents_code/turn_end_summary.py +522 -0
- deepagents_code/ui.py +858 -0
- deepagents_code/unicode_security.py +563 -0
- deepagents_code/update_check.py +3124 -0
- zjcode-0.0.1.data/data/deepagents_code/default_agent_prompt.md +12 -0
- zjcode-0.0.1.dist-info/METADATA +220 -0
- zjcode-0.0.1.dist-info/RECORD +163 -0
- zjcode-0.0.1.dist-info/WHEEL +4 -0
- zjcode-0.0.1.dist-info/entry_points.txt +2 -0
deepagents_code/app.tcss
ADDED
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
/* Deep Agents Code Textual Stylesheet */
|
|
2
|
+
|
|
3
|
+
/* Define layers for z-ordering */
|
|
4
|
+
Screen {
|
|
5
|
+
layout: vertical;
|
|
6
|
+
layers: base autocomplete;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/* Thin scrollbars app-wide */
|
|
10
|
+
* {
|
|
11
|
+
scrollbar-size-vertical: 1;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* Hide the Header's clickable ⭘ icon. It opens the command palette by default,
|
|
15
|
+
but ENABLE_COMMAND_PALETTE = False on the app, so it's already inert. We use
|
|
16
|
+
`visibility: hidden` (not `display: none`) so the 8-cell gutter is preserved
|
|
17
|
+
and balances the clock-space gutter on the right, keeping the title centered. */
|
|
18
|
+
#app-header HeaderIcon {
|
|
19
|
+
visibility: hidden;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/* Main content goes on base layer by default */
|
|
23
|
+
|
|
24
|
+
.message-timestamp-footer {
|
|
25
|
+
display: none;
|
|
26
|
+
height: auto;
|
|
27
|
+
color: $text-muted;
|
|
28
|
+
text-style: dim;
|
|
29
|
+
margin: -1 0 1 0;
|
|
30
|
+
padding: 0;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/*
|
|
34
|
+
* Visibility is toggled per-footer (not via a class on #messages) so a
|
|
35
|
+
* `/timestamps` toggle restyles only the footer leaves instead of forcing a
|
|
36
|
+
* re-cascade across every message subtree.
|
|
37
|
+
*/
|
|
38
|
+
.message-timestamp-footer.message-timestamp-footer-visible {
|
|
39
|
+
display: block;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* Chat area - main scrollable messages area.
|
|
43
|
+
No horizontal padding so message blocks span the same full width as the
|
|
44
|
+
input box below (whose border is flush to both edges). The scrollbar is
|
|
45
|
+
toggled at runtime via the /scrollbar command (off by default). */
|
|
46
|
+
#chat {
|
|
47
|
+
height: 1fr;
|
|
48
|
+
padding: 1 0 0 0;
|
|
49
|
+
background: $background;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/* Welcome banner */
|
|
53
|
+
#welcome-banner {
|
|
54
|
+
height: auto;
|
|
55
|
+
margin-bottom: 1;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* Messages area — uses undocumented "stream" layout (Textual ≥5.2.0) for
|
|
59
|
+
O(1) append performance via incremental placement caching. */
|
|
60
|
+
#messages {
|
|
61
|
+
layout: stream;
|
|
62
|
+
height: auto;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* Bottom app container - holds ChatInput (now inside scroll) */
|
|
66
|
+
#bottom-app-container {
|
|
67
|
+
height: auto;
|
|
68
|
+
margin-top: 0;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* Input area */
|
|
72
|
+
#input-area {
|
|
73
|
+
height: auto;
|
|
74
|
+
min-height: 3;
|
|
75
|
+
max-height: 25;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* Approval Menu - inline in messages area */
|
|
79
|
+
.approval-menu {
|
|
80
|
+
height: auto;
|
|
81
|
+
margin: 1 0;
|
|
82
|
+
padding: 0 1;
|
|
83
|
+
background: $surface;
|
|
84
|
+
border: solid $warning;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/* Placeholder shown while the user is actively typing (approval deferred) */
|
|
88
|
+
.approval-placeholder {
|
|
89
|
+
height: auto;
|
|
90
|
+
margin: 1 0;
|
|
91
|
+
padding: 0 1;
|
|
92
|
+
border: solid $panel;
|
|
93
|
+
color: $text-muted;
|
|
94
|
+
text-style: italic;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.approval-menu .approval-title {
|
|
98
|
+
text-style: bold;
|
|
99
|
+
color: $warning;
|
|
100
|
+
margin-bottom: 0;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.approval-menu .approval-info {
|
|
104
|
+
height: auto;
|
|
105
|
+
color: $text-muted;
|
|
106
|
+
margin-bottom: 1;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.approval-menu .approval-option {
|
|
110
|
+
height: 1;
|
|
111
|
+
padding: 0 1;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.approval-menu .approval-option-selected {
|
|
115
|
+
background: $primary;
|
|
116
|
+
text-style: bold;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.approval-menu .approval-help {
|
|
120
|
+
color: $text-muted;
|
|
121
|
+
text-style: italic;
|
|
122
|
+
margin-top: 0;
|
|
123
|
+
margin-bottom: 0;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/* Status bar */
|
|
127
|
+
#status-bar {
|
|
128
|
+
height: 1;
|
|
129
|
+
dock: bottom;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* Tool approval widgets */
|
|
133
|
+
.tool-approval-widget {
|
|
134
|
+
height: auto;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.approval-description {
|
|
138
|
+
color: $text-muted;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/* Diff styling — used by EditFileApprovalWidget (fg + bg + padding) */
|
|
142
|
+
.diff-removed {
|
|
143
|
+
height: auto;
|
|
144
|
+
color: $text-error;
|
|
145
|
+
background: $error-muted;
|
|
146
|
+
padding: 0 1;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.diff-added {
|
|
150
|
+
height: auto;
|
|
151
|
+
color: $text-success;
|
|
152
|
+
background: $success-muted;
|
|
153
|
+
padding: 0 1;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.diff-context {
|
|
157
|
+
height: auto;
|
|
158
|
+
color: $text-muted;
|
|
159
|
+
padding: 0 1;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/* Diff line backgrounds — used by compose_diff_lines (bg only, fg via Content) */
|
|
163
|
+
.diff-line-removed {
|
|
164
|
+
background: $error-muted;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.diff-line-added {
|
|
168
|
+
background: $success-muted;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/* Mode-specific borders for UserMessage */
|
|
172
|
+
UserMessage.-mode-shell {
|
|
173
|
+
border-left: wide $mode-bash;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
UserMessage.-mode-shell-incognito {
|
|
177
|
+
border-left: wide $mode-incognito;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
UserMessage.-mode-command {
|
|
181
|
+
border-left: wide $mode-command;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/* ASCII border overrides */
|
|
185
|
+
UserMessage.-ascii {
|
|
186
|
+
border-left: ascii $primary;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
UserMessage.-ascii.-mode-shell {
|
|
190
|
+
border-left: ascii $mode-bash;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
UserMessage.-ascii.-mode-shell-incognito {
|
|
194
|
+
border-left: ascii $mode-incognito;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
UserMessage.-ascii.-mode-command {
|
|
198
|
+
border-left: ascii $mode-command;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
QueuedUserMessage.-ascii {
|
|
202
|
+
border-left: ascii $panel;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
ToolCallMessage.-ascii {
|
|
206
|
+
border-left: ascii $panel;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
ToolCallMessage.-ascii:hover {
|
|
210
|
+
border-left: ascii $secondary;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/* Approval command — warning color for shell commands */
|
|
214
|
+
.approval-menu .approval-command {
|
|
215
|
+
height: auto;
|
|
216
|
+
margin: 0 0 1 0;
|
|
217
|
+
padding: 0 1;
|
|
218
|
+
color: $warning;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/* Separator line between tool details and options */
|
|
222
|
+
.approval-menu .approval-separator {
|
|
223
|
+
height: 1;
|
|
224
|
+
color: $warning;
|
|
225
|
+
margin: 0;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/* Scrollable tool info area in approval menu */
|
|
229
|
+
.approval-menu .tool-info-scroll {
|
|
230
|
+
height: auto;
|
|
231
|
+
max-height: 10;
|
|
232
|
+
margin-top: 0;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/* Inner container for tool info - allows content to expand for scrolling */
|
|
236
|
+
.approval-menu .tool-info-container {
|
|
237
|
+
height: auto;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/* Options container with background */
|
|
241
|
+
.approval-menu .approval-options-container {
|
|
242
|
+
height: auto;
|
|
243
|
+
background: $surface-darken-1;
|
|
244
|
+
padding: 0 1;
|
|
245
|
+
margin-top: 0;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/* Free-text reject reason input (Tab on Reject) */
|
|
249
|
+
.approval-menu .approval-reason-input {
|
|
250
|
+
margin: 1 0 0 0;
|
|
251
|
+
border: solid $warning;
|
|
252
|
+
background: $surface;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/* Persistent goal status */
|
|
256
|
+
.goal-status-panel {
|
|
257
|
+
height: auto;
|
|
258
|
+
max-height: 5;
|
|
259
|
+
margin: 0 1;
|
|
260
|
+
padding: 0 1;
|
|
261
|
+
color: $text;
|
|
262
|
+
background: $surface-darken-1;
|
|
263
|
+
border-left: thick $primary;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/* Goal review widget */
|
|
267
|
+
.goal-review-menu {
|
|
268
|
+
height: auto;
|
|
269
|
+
margin: 1 0;
|
|
270
|
+
padding: 0 1;
|
|
271
|
+
background: $surface;
|
|
272
|
+
border: solid $success;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
.goal-review-menu .goal-review-title {
|
|
276
|
+
text-style: bold;
|
|
277
|
+
color: $success;
|
|
278
|
+
margin-bottom: 0;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.goal-review-menu .goal-review-content {
|
|
282
|
+
height: auto;
|
|
283
|
+
max-height: 12;
|
|
284
|
+
padding: 0 1;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.goal-review-menu .goal-review-body {
|
|
288
|
+
height: auto;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
.goal-review-menu .goal-review-markdown {
|
|
292
|
+
margin: 0 0 1 0;
|
|
293
|
+
padding: 0;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.goal-review-menu .goal-review-options-container {
|
|
297
|
+
height: auto;
|
|
298
|
+
background: $surface-darken-1;
|
|
299
|
+
padding: 0 1;
|
|
300
|
+
margin-top: 0;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.goal-review-menu .goal-review-option {
|
|
304
|
+
height: 1;
|
|
305
|
+
padding: 0 1;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
.goal-review-menu .goal-review-option-selected {
|
|
309
|
+
background: $primary;
|
|
310
|
+
text-style: bold;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.goal-review-menu .goal-review-edit-input {
|
|
314
|
+
margin: 1 1 0 1;
|
|
315
|
+
height: auto;
|
|
316
|
+
min-height: 4;
|
|
317
|
+
max-height: 12;
|
|
318
|
+
background: transparent;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.goal-review-menu .goal-review-help {
|
|
322
|
+
color: $text-muted;
|
|
323
|
+
text-style: italic;
|
|
324
|
+
margin-top: 0;
|
|
325
|
+
margin-bottom: 0;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
.goal-review-menu AskUserTextArea {
|
|
329
|
+
& .text-area--cursor-line {
|
|
330
|
+
background: transparent;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
& .text-area--cursor-gutter {
|
|
334
|
+
background: transparent;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/* Ask user widget */
|
|
339
|
+
.ask-user-menu {
|
|
340
|
+
height: auto;
|
|
341
|
+
margin: 1 0;
|
|
342
|
+
padding: 0 1;
|
|
343
|
+
background: $surface;
|
|
344
|
+
border: solid $success;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
.ask-user-menu .ask-user-title {
|
|
348
|
+
text-style: bold;
|
|
349
|
+
color: $success;
|
|
350
|
+
margin-bottom: 0;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
.ask-user-menu .ask-user-help {
|
|
354
|
+
color: $text-muted;
|
|
355
|
+
text-style: italic;
|
|
356
|
+
margin-top: 0;
|
|
357
|
+
margin-bottom: 0;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
.ask-user-menu .ask-user-questions {
|
|
361
|
+
height: auto;
|
|
362
|
+
padding: 0 1;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
.ask-user-menu .ask-user-question {
|
|
366
|
+
height: auto;
|
|
367
|
+
margin-bottom: 1;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
.ask-user-menu .ask-user-question-active {
|
|
371
|
+
border-left: thick $success;
|
|
372
|
+
padding-left: 1;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
.ask-user-menu .ask-user-question-inactive {
|
|
376
|
+
opacity: 0.5;
|
|
377
|
+
padding-left: 2;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
.ask-user-menu .ask-user-question-text {
|
|
381
|
+
margin: 0 0 0 2;
|
|
382
|
+
padding: 0;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
.ask-user-menu .ask-user-choice {
|
|
386
|
+
height: auto;
|
|
387
|
+
padding: 0 1;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
.ask-user-menu .ask-user-text-input {
|
|
391
|
+
margin: 1 1 0 1;
|
|
392
|
+
height: auto;
|
|
393
|
+
min-height: 3;
|
|
394
|
+
max-height: 10;
|
|
395
|
+
background: transparent;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
.ask-user-menu .ask-user-other-input {
|
|
399
|
+
margin: 1 1 0 1;
|
|
400
|
+
height: auto;
|
|
401
|
+
min-height: 3;
|
|
402
|
+
max-height: 10;
|
|
403
|
+
background: transparent;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
.ask-user-menu AskUserTextArea {
|
|
407
|
+
& .text-area--cursor-line {
|
|
408
|
+
background: transparent;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
& .text-area--cursor-gutter {
|
|
412
|
+
background: transparent;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/* ChatTextArea: override TextArea's built-in $surface background */
|
|
417
|
+
ChatTextArea {
|
|
418
|
+
background: transparent;
|
|
419
|
+
|
|
420
|
+
& .text-area--cursor-line {
|
|
421
|
+
background: transparent;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
& .text-area--cursor-gutter {
|
|
425
|
+
background: transparent;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/* Completion popup styling (used by ChatInput) - appears BELOW input */
|
|
430
|
+
#completion-popup {
|
|
431
|
+
height: auto;
|
|
432
|
+
max-height: 12;
|
|
433
|
+
width: 100%;
|
|
434
|
+
margin-left: 3;
|
|
435
|
+
margin-top: 0;
|
|
436
|
+
padding: 0;
|
|
437
|
+
color: $text;
|
|
438
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"""Live approval-mode state shared through the LangGraph Store."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
from collections.abc import Mapping
|
|
7
|
+
from hashlib import sha256
|
|
8
|
+
from typing import TypedDict
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
APPROVAL_MODE_NAMESPACE: tuple[str, str] = ("deepagents_code", "approval_mode")
|
|
13
|
+
"""Store namespace for per-thread approval-mode control records."""
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ApprovalModePayload(TypedDict):
|
|
17
|
+
"""Stored approval-mode control payload."""
|
|
18
|
+
|
|
19
|
+
auto_approve: bool
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def approval_mode_key(thread_id: str) -> str:
|
|
23
|
+
"""Return the store key for a thread's live approval mode.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
thread_id: LangGraph thread id for the active session.
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
Deterministic store key that does not expose the raw thread id.
|
|
30
|
+
"""
|
|
31
|
+
return sha256(thread_id.encode("utf-8")).hexdigest()
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def approval_mode_payload(*, auto_approve: bool) -> ApprovalModePayload:
|
|
35
|
+
"""Return the stored approval-mode payload.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
auto_approve: Whether gated tool calls should skip HITL approval.
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
JSON-serializable store value.
|
|
42
|
+
"""
|
|
43
|
+
return {"auto_approve": auto_approve}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _item_value(item: object) -> object:
|
|
47
|
+
"""Extract a store item's value from SDK and runtime item shapes.
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
The item's stored value, or `None` when the shape is unrecognized.
|
|
51
|
+
"""
|
|
52
|
+
if isinstance(item, Mapping):
|
|
53
|
+
return item.get("value")
|
|
54
|
+
return getattr(item, "value", None)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def read_approval_mode_from_store(store: object, key: str | None) -> bool | None:
|
|
58
|
+
"""Read a live approval mode from the server-side LangGraph Store.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
store: `request.runtime.store` from the graph server.
|
|
62
|
+
key: Store key produced by `approval_mode_key`. The `isinstance` guard
|
|
63
|
+
below still rejects non-string keys as defense-in-depth, since the
|
|
64
|
+
value crosses the JSON/RemoteGraph boundary before reaching here.
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
`True` or `False` when the store contains a valid mode, otherwise
|
|
68
|
+
`None`. Callers should treat `None` as fail-closed.
|
|
69
|
+
"""
|
|
70
|
+
if store is None:
|
|
71
|
+
logger.debug("Approval-mode store is unavailable")
|
|
72
|
+
return None
|
|
73
|
+
if not isinstance(key, str) or not key:
|
|
74
|
+
logger.debug("Approval-mode store key is missing or invalid")
|
|
75
|
+
return None
|
|
76
|
+
|
|
77
|
+
get = getattr(store, "get", None)
|
|
78
|
+
if get is None:
|
|
79
|
+
logger.debug("Approval-mode store does not expose get()")
|
|
80
|
+
return None
|
|
81
|
+
|
|
82
|
+
try:
|
|
83
|
+
item = get(APPROVAL_MODE_NAMESPACE, key)
|
|
84
|
+
except Exception:
|
|
85
|
+
logger.warning("Could not read approval-mode store item", exc_info=True)
|
|
86
|
+
return None
|
|
87
|
+
if item is None:
|
|
88
|
+
logger.debug("Approval-mode store item is missing")
|
|
89
|
+
return None
|
|
90
|
+
|
|
91
|
+
value = _item_value(item)
|
|
92
|
+
auto_approve = value.get("auto_approve") if isinstance(value, Mapping) else None
|
|
93
|
+
if isinstance(auto_approve, bool):
|
|
94
|
+
return auto_approve
|
|
95
|
+
|
|
96
|
+
logger.debug("Approval-mode store item has invalid contents")
|
|
97
|
+
return None
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
async def awrite_approval_mode(
|
|
101
|
+
agent: object,
|
|
102
|
+
thread_id: str,
|
|
103
|
+
*,
|
|
104
|
+
auto_approve: bool,
|
|
105
|
+
) -> str | None:
|
|
106
|
+
"""Persist approval mode through an agent's remote store client.
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
agent: Agent object. Remote agents expose `aput_store_item`; agents
|
|
110
|
+
without a writer use run context only.
|
|
111
|
+
thread_id: LangGraph thread id for the active session.
|
|
112
|
+
auto_approve: Whether gated tool calls should skip HITL approval.
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
Store key written, or `None` when the agent has no store writer.
|
|
116
|
+
|
|
117
|
+
Notes:
|
|
118
|
+
Remote agents rely on the server-side store being visible to the
|
|
119
|
+
running graph before the next gated tool predicate executes.
|
|
120
|
+
"""
|
|
121
|
+
put = getattr(agent, "aput_store_item", None)
|
|
122
|
+
if put is None:
|
|
123
|
+
return None
|
|
124
|
+
|
|
125
|
+
key = approval_mode_key(thread_id)
|
|
126
|
+
await put(
|
|
127
|
+
APPROVAL_MODE_NAMESPACE,
|
|
128
|
+
key,
|
|
129
|
+
approval_mode_payload(auto_approve=auto_approve),
|
|
130
|
+
)
|
|
131
|
+
return key
|