open-data-sci 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 (85) hide show
  1. open_data_sci-0.1.0.dist-info/METADATA +629 -0
  2. open_data_sci-0.1.0.dist-info/RECORD +85 -0
  3. open_data_sci-0.1.0.dist-info/WHEEL +4 -0
  4. open_data_sci-0.1.0.dist-info/entry_points.txt +2 -0
  5. open_data_sci-0.1.0.dist-info/licenses/LICENSE +201 -0
  6. opendatasci/__init__.py +47 -0
  7. opendatasci/_tui/__init__.py +1 -0
  8. opendatasci/_tui/adapter.py +102 -0
  9. opendatasci/_tui/app.py +429 -0
  10. opendatasci/_tui/commands.py +95 -0
  11. opendatasci/_tui/completion.py +139 -0
  12. opendatasci/_tui/controller.py +644 -0
  13. opendatasci/_tui/file_refs.py +153 -0
  14. opendatasci/_tui/models.py +4 -0
  15. opendatasci/_tui/presenter.py +259 -0
  16. opendatasci/_tui/service.py +78 -0
  17. opendatasci/_tui/session.py +53 -0
  18. opendatasci/_tui/styles.tcss +248 -0
  19. opendatasci/_tui/styles_visible.tcss +245 -0
  20. opendatasci/_tui/theme.py +113 -0
  21. opendatasci/_tui/tools_display.py +86 -0
  22. opendatasci/_tui/widgets.py +1001 -0
  23. opendatasci/_utils/__init__.py +0 -0
  24. opendatasci/_utils/async_utils.py +11 -0
  25. opendatasci/_utils/data_formats.py +135 -0
  26. opendatasci/_utils/hash_utils.py +52 -0
  27. opendatasci/_utils/langchain_utils.py +155 -0
  28. opendatasci/_utils/streaming_utils.py +23 -0
  29. opendatasci/agents/__init__.py +12 -0
  30. opendatasci/agents/agents.py +515 -0
  31. opendatasci/agents/agents_factory.py +71 -0
  32. opendatasci/agents/chat_memory.py +397 -0
  33. opendatasci/agents/graphs.py +84 -0
  34. opendatasci/agents/nodes.py +74 -0
  35. opendatasci/agents/states.py +36 -0
  36. opendatasci/agents/turn_memory.py +124 -0
  37. opendatasci/configs.py +275 -0
  38. opendatasci/context/__init__.py +7 -0
  39. opendatasci/context/base.py +56 -0
  40. opendatasci/context/local.py +236 -0
  41. opendatasci/models/__init__.py +7 -0
  42. opendatasci/models/anthropic.py +40 -0
  43. opendatasci/models/aws.py +86 -0
  44. opendatasci/models/factory.py +179 -0
  45. opendatasci/models/google.py +79 -0
  46. opendatasci/models/local.py +79 -0
  47. opendatasci/models/microsoft.py +62 -0
  48. opendatasci/models/openai.py +49 -0
  49. opendatasci/models/providers.py +12 -0
  50. opendatasci/prompts/__init__.py +5 -0
  51. opendatasci/prompts/builders.py +85 -0
  52. opendatasci/prompts/caching.py +42 -0
  53. opendatasci/prompts/message_templates.py +7 -0
  54. opendatasci/prompts/prompt_templates.py +227 -0
  55. opendatasci/resources/skills/competitive_data_science.md +241 -0
  56. opendatasci/resources/skills/data_science.md +55 -0
  57. opendatasci/resources/skills/data_science_education.md +42 -0
  58. opendatasci/resources/skills/deep_learning.md +205 -0
  59. opendatasci/resources/skills/machine_learning.md +68 -0
  60. opendatasci/resources/skills/quantitative_analysis.md +45 -0
  61. opendatasci/sandbox/__init__.py +14 -0
  62. opendatasci/sandbox/_runner.py +114 -0
  63. opendatasci/sandbox/base.py +170 -0
  64. opendatasci/sandbox/srt.py +490 -0
  65. opendatasci/skills/__init__.py +9 -0
  66. opendatasci/skills/base.py +28 -0
  67. opendatasci/skills/local.py +131 -0
  68. opendatasci/streaming/__init__.py +37 -0
  69. opendatasci/streaming/events.py +159 -0
  70. opendatasci/streaming/processors.py +387 -0
  71. opendatasci/tools/__init__.py +58 -0
  72. opendatasci/tools/coding.py +261 -0
  73. opendatasci/tools/critic.py +136 -0
  74. opendatasci/tools/dataset_info.py +391 -0
  75. opendatasci/tools/factory.py +172 -0
  76. opendatasci/tools/mcp.py +179 -0
  77. opendatasci/tools/planning.py +88 -0
  78. opendatasci/tools/skills.py +90 -0
  79. opendatasci/tools/user_interaction.py +54 -0
  80. opendatasci/tools/web.py +236 -0
  81. opendatasci/tools/workers.py +237 -0
  82. opendatasci/tools/workspace.py +55 -0
  83. opendatasci/workspace/__init__.py +9 -0
  84. opendatasci/workspace/base.py +20 -0
  85. opendatasci/workspace/local.py +25 -0
@@ -0,0 +1,248 @@
1
+ /* ─── OpenDataSci TUI Theme (Dark+) ─────────────────────────────────────────── */
2
+
3
+ Screen {
4
+ background: #060a10;
5
+ color: #e6edf3;
6
+ }
7
+
8
+ AppHeader {
9
+ dock: top;
10
+ height: 5;
11
+ background: #0d1117;
12
+ border-bottom: solid #1a2030;
13
+ }
14
+
15
+ #header-logo {
16
+ width: 23;
17
+ height: 5;
18
+ padding-left: 2;
19
+ content-align: center middle;
20
+ }
21
+
22
+ #header-info {
23
+ height: 5;
24
+ padding: 1 3 1 2;
25
+ content-align: left middle;
26
+ }
27
+
28
+ #header-timer {
29
+ width: auto;
30
+ content-align: right middle;
31
+ padding-right: 1;
32
+ }
33
+
34
+ /* ─── Main layout ─────────────────────────────────────────────────────────── */
35
+
36
+ #main {
37
+ height: 1fr;
38
+ layout: horizontal;
39
+ }
40
+
41
+ /* ─── Chat Pane ───────────────────────────────────────────────────────────── */
42
+
43
+ ChatPane {
44
+ width: 100%;
45
+ layout: vertical;
46
+ background: #060a10;
47
+ }
48
+
49
+ #messages {
50
+ height: 1fr;
51
+ padding: 1 2;
52
+ scrollbar-color: #4a6080 #0d1520;
53
+ scrollbar-background: #0d1520;
54
+ scrollbar-corner-color: #0d1520;
55
+ }
56
+
57
+ #input-bar {
58
+ height: auto;
59
+ border-top: solid #1a2030;
60
+ padding: 1 2 1 2;
61
+ background: #060a10;
62
+ }
63
+
64
+ #completion-popup {
65
+ display: none;
66
+ height: auto;
67
+ background: #0d1117;
68
+ border: solid #30363d;
69
+ padding: 0 1;
70
+ margin-bottom: 1;
71
+ }
72
+
73
+ #completion-popup.active {
74
+ display: block;
75
+ }
76
+
77
+ #attachment-bar {
78
+ display: none;
79
+ height: auto;
80
+ padding: 0 1;
81
+ margin-bottom: 1;
82
+ }
83
+
84
+ #attachment-bar.active {
85
+ display: block;
86
+ }
87
+
88
+ #user-input {
89
+ background: #0d1117;
90
+ border: solid #1a2030;
91
+ color: #e6edf3;
92
+ padding: 0 1;
93
+ width: 100%;
94
+ height: 3;
95
+ }
96
+
97
+ #user-input:focus {
98
+ border: solid #79c0ff;
99
+ }
100
+
101
+ #user-input.awaiting-choice {
102
+ border: solid #c9963a;
103
+ }
104
+
105
+
106
+ /* ─── Workspace Panel ─────────────────────────────────────────────────────── */
107
+
108
+ WorkspacePanel {
109
+ display: none;
110
+ height: auto;
111
+ max-height: 10;
112
+ border-top: solid #1a2030;
113
+ background: #0d1117;
114
+ padding: 0 2 1 2;
115
+ }
116
+
117
+ WorkspacePanel.active {
118
+ display: block;
119
+ }
120
+
121
+ /* ─── Message widgets ─────────────────────────────────────────────────────── */
122
+
123
+ MessageBubble {
124
+ height: auto;
125
+ padding: 0;
126
+ margin-bottom: 1;
127
+ }
128
+
129
+ MessageBubble.user {
130
+ background: #0e1520;
131
+ border-left: thick #79c0ff;
132
+ padding: 0 2;
133
+ }
134
+
135
+ MessageBubble.thinking {
136
+ background: #1e2228;
137
+ border-left: thick #6e7681;
138
+ padding: 0 2;
139
+ }
140
+
141
+ MessageBubble.question {
142
+ background: #1c1408;
143
+ border-left: thick #c9963a;
144
+ padding: 0 2;
145
+ }
146
+
147
+ MessageBubble.agent {
148
+ padding: 0 0;
149
+ }
150
+
151
+ .msg-divider {
152
+ height: 1;
153
+ color: #1a2030;
154
+ margin: 0 0 1 0;
155
+ }
156
+
157
+ /* ─── Footer ──────────────────────────────────────────────────────────────── */
158
+
159
+ Footer {
160
+ background: #0d1117;
161
+ color: #8b949e;
162
+ border-top: solid #1a2030;
163
+ }
164
+
165
+ Footer > .footer--key {
166
+ background: #1a2030;
167
+ color: #e6edf3;
168
+ }
169
+
170
+ Footer > .footer--highlight {
171
+ background: #79c0ff26;
172
+ color: #79c0ff;
173
+ }
174
+
175
+ /* ─── Markdown (agent response) ───────────────────────────────────────────── */
176
+
177
+ Markdown {
178
+ background: transparent;
179
+ height: auto;
180
+ padding: 0;
181
+ margin: 0;
182
+ }
183
+
184
+ MarkdownH1 {
185
+ background: transparent;
186
+ border: none;
187
+ color: #79c0ff;
188
+ text-style: bold underline;
189
+ padding: 0 0 1 0;
190
+ margin: 0 0 1 0;
191
+ text-align: left;
192
+ }
193
+
194
+ MarkdownH2 {
195
+ background: transparent;
196
+ border: none;
197
+ color: #79c0ff;
198
+ text-style: bold;
199
+ padding: 0;
200
+ margin: 0 0 1 0;
201
+ text-align: left;
202
+ }
203
+
204
+ MarkdownH3, MarkdownH4, MarkdownH5, MarkdownH6 {
205
+ background: transparent;
206
+ border: none;
207
+ color: #8b949e;
208
+ text-style: bold;
209
+ padding: 0;
210
+ margin: 0 0 1 0;
211
+ text-align: left;
212
+ }
213
+
214
+ MarkdownParagraph {
215
+ background: transparent;
216
+ color: #e6edf3;
217
+ padding: 0;
218
+ margin: 0 0 1 0;
219
+ }
220
+
221
+ MarkdownFence {
222
+ background: #0d1117;
223
+ border: solid #1a2030;
224
+ padding: 0 1;
225
+ margin: 0 0 1 0;
226
+ }
227
+
228
+ MarkdownBlockQuote {
229
+ background: #0a1520;
230
+ border-left: thick #4caa5e;
231
+ padding: 0 1;
232
+ margin: 0 0 1 0;
233
+ }
234
+
235
+ MarkdownBulletList, MarkdownOrderedList {
236
+ background: transparent;
237
+ padding: 0;
238
+ margin: 0 0 1 0;
239
+ }
240
+
241
+ MarkdownHorizontalRule {
242
+ color: #1a2030;
243
+ margin: 1 0;
244
+ }
245
+
246
+ MarkdownTable {
247
+ margin: 0 0 1 0;
248
+ }
@@ -0,0 +1,245 @@
1
+ /* ─── OpenDataSci TUI Theme (Visible / Color-blind safe) ────────────────────── */
2
+ /* Uses the Okabe-Ito color palette, which is safe for most forms of */
3
+ /* color vision deficiency (deuteranopia, protanopia, tritanopia). */
4
+
5
+ Screen {
6
+ background: #060a10;
7
+ color: #f5f5f5;
8
+ }
9
+
10
+ /* ─── Header ──────────────────────────────────────────────────────────────── */
11
+
12
+ AppHeader {
13
+ dock: top;
14
+ height: 5;
15
+ background: #0d1117;
16
+ border-bottom: solid #1e2d40;
17
+ }
18
+
19
+ #header-info {
20
+ height: 5;
21
+ padding: 1 3;
22
+ content-align: left middle;
23
+ }
24
+
25
+ #header-timer {
26
+ width: auto;
27
+ content-align: right middle;
28
+ padding-right: 1;
29
+ }
30
+
31
+ /* ─── Main layout ─────────────────────────────────────────────────────────── */
32
+
33
+ #main {
34
+ height: 1fr;
35
+ layout: horizontal;
36
+ }
37
+
38
+ /* ─── Chat Pane ───────────────────────────────────────────────────────────── */
39
+
40
+ ChatPane {
41
+ width: 100%;
42
+ layout: vertical;
43
+ background: #060a10;
44
+ }
45
+
46
+ #messages {
47
+ height: 1fr;
48
+ padding: 1 2;
49
+ scrollbar-color: #4a6080 #0d1520;
50
+ scrollbar-background: #0d1520;
51
+ scrollbar-corner-color: #0d1520;
52
+ }
53
+
54
+ #input-bar {
55
+ height: auto;
56
+ border-top: solid #1e2d40;
57
+ padding: 1 2 1 2;
58
+ background: #060a10;
59
+ }
60
+
61
+ #completion-popup {
62
+ display: none;
63
+ height: auto;
64
+ background: #0d1117;
65
+ border: solid #1e2d40;
66
+ padding: 0 1;
67
+ margin-bottom: 1;
68
+ }
69
+
70
+ #completion-popup.active {
71
+ display: block;
72
+ }
73
+
74
+ #attachment-bar {
75
+ display: none;
76
+ height: auto;
77
+ padding: 0 1;
78
+ margin-bottom: 1;
79
+ }
80
+
81
+ #attachment-bar.active {
82
+ display: block;
83
+ }
84
+
85
+ #user-input {
86
+ background: #0d1117;
87
+ border: solid #1e2d40;
88
+ color: #f5f5f5;
89
+ padding: 0 1;
90
+ width: 100%;
91
+ height: 3;
92
+ }
93
+
94
+ #user-input:focus {
95
+ border: solid #56b4e9;
96
+ }
97
+
98
+ #user-input.awaiting-choice {
99
+ border: solid #e69f00;
100
+ }
101
+
102
+
103
+ /* ─── Workspace Panel ─────────────────────────────────────────────────────── */
104
+
105
+ WorkspacePanel {
106
+ display: none;
107
+ height: auto;
108
+ max-height: 10;
109
+ border-top: solid #1e2d40;
110
+ background: #0d1117;
111
+ padding: 0 2 1 2;
112
+ }
113
+
114
+ WorkspacePanel.active {
115
+ display: block;
116
+ }
117
+
118
+ /* ─── Message widgets ─────────────────────────────────────────────────────── */
119
+
120
+ MessageBubble {
121
+ height: auto;
122
+ padding: 0;
123
+ margin-bottom: 1;
124
+ }
125
+
126
+ MessageBubble.user {
127
+ background: #0a1520;
128
+ border-left: thick #56b4e9;
129
+ padding: 0 2;
130
+ }
131
+
132
+ MessageBubble.thinking {
133
+ background: #1e2228;
134
+ border-left: thick #8090a0;
135
+ padding: 0 2;
136
+ }
137
+
138
+ MessageBubble.question {
139
+ background: #1c1608;
140
+ border-left: thick #e69f00;
141
+ padding: 0 2;
142
+ }
143
+
144
+ MessageBubble.agent {
145
+ padding: 0 0;
146
+ }
147
+
148
+ .msg-divider {
149
+ height: 1;
150
+ color: #1e2d40;
151
+ margin: 0 0 1 0;
152
+ }
153
+
154
+ /* ─── Footer ──────────────────────────────────────────────────────────────── */
155
+
156
+ Footer {
157
+ background: #0d1117;
158
+ color: #a0b0c0;
159
+ border-top: solid #1e2d40;
160
+ }
161
+
162
+ Footer > .footer--key {
163
+ background: #1e2d40;
164
+ color: #f5f5f5;
165
+ }
166
+
167
+ Footer > .footer--highlight {
168
+ background: #56b4e926;
169
+ color: #56b4e9;
170
+ }
171
+
172
+ /* ─── Markdown (agent response) ───────────────────────────────────────────── */
173
+
174
+ Markdown {
175
+ background: transparent;
176
+ height: auto;
177
+ padding: 0;
178
+ margin: 0;
179
+ }
180
+
181
+ MarkdownH1 {
182
+ background: transparent;
183
+ border: none;
184
+ color: #56b4e9;
185
+ text-style: bold underline;
186
+ padding: 0 0 1 0;
187
+ margin: 0 0 1 0;
188
+ text-align: left;
189
+ }
190
+
191
+ MarkdownH2 {
192
+ background: transparent;
193
+ border: none;
194
+ color: #56b4e9;
195
+ text-style: bold;
196
+ padding: 0;
197
+ margin: 0 0 1 0;
198
+ text-align: left;
199
+ }
200
+
201
+ MarkdownH3, MarkdownH4, MarkdownH5, MarkdownH6 {
202
+ background: transparent;
203
+ border: none;
204
+ color: #a0b0c0;
205
+ text-style: bold;
206
+ padding: 0;
207
+ margin: 0 0 1 0;
208
+ text-align: left;
209
+ }
210
+
211
+ MarkdownParagraph {
212
+ background: transparent;
213
+ color: #f5f5f5;
214
+ padding: 0;
215
+ margin: 0 0 1 0;
216
+ }
217
+
218
+ MarkdownFence {
219
+ background: #0d1117;
220
+ border: solid #1e2d40;
221
+ padding: 0 1;
222
+ margin: 0 0 1 0;
223
+ }
224
+
225
+ MarkdownBlockQuote {
226
+ background: #0a1520;
227
+ border-left: thick #009e73;
228
+ padding: 0 1;
229
+ margin: 0 0 1 0;
230
+ }
231
+
232
+ MarkdownBulletList, MarkdownOrderedList {
233
+ background: transparent;
234
+ padding: 0;
235
+ margin: 0 0 1 0;
236
+ }
237
+
238
+ MarkdownHorizontalRule {
239
+ color: #1e2d40;
240
+ margin: 1 0;
241
+ }
242
+
243
+ MarkdownTable {
244
+ margin: 0 0 1 0;
245
+ }
@@ -0,0 +1,113 @@
1
+ """Color theme definitions for OpenDataSci TUI."""
2
+
3
+ # Default dark theme — deeper backgrounds, muted accents
4
+ DARK: dict[str, str] = {
5
+ "accent": "#79c0ff", # soft blue
6
+ "success": "#4caa5e", # muted sage-green
7
+ "error": "#c97a74", # muted terracotta-red
8
+ "warning": "#c9963a", # muted amber
9
+ "thinking": "#9f75d6", # muted lavender
10
+ "text_primary": "#e6edf3",
11
+ "text_secondary": "#8b949e",
12
+ "text_muted": "#6e7681",
13
+ "text_dim": "#21262d",
14
+ "separator": "#1a2030",
15
+ "logo": "#c9a86c",
16
+ "timer": "bright_green",
17
+ "tool_running": "#58a6ff",
18
+ "tool_done": "#3fb950",
19
+ }
20
+
21
+ # Color-blind safe theme — Okabe-Ito palette
22
+ VISIBLE: dict[str, str] = {
23
+ "accent": "#56b4e9", # sky blue
24
+ "success": "#009e73", # bluish green / teal
25
+ "error": "#d55e00", # vermilion
26
+ "warning": "#e69f00", # orange
27
+ "thinking": "#cc79a7", # reddish purple
28
+ "text_primary": "#f5f5f5",
29
+ "text_secondary": "#a0b0c0",
30
+ "text_muted": "#8090a0",
31
+ "text_dim": "#3d4a5c",
32
+ "separator": "#1a2030",
33
+ "logo": "#e69f00",
34
+ "timer": "cyan",
35
+ "tool_running": "#56b4e9",
36
+ "tool_done": "#009e73",
37
+ }
38
+
39
+ # Light theme — light background, dark text (GitHub-inspired)
40
+ LIGHT: dict[str, str] = {
41
+ "accent": "#0969da",
42
+ "success": "#1a7f37",
43
+ "error": "#cf222e",
44
+ "warning": "#9a6700",
45
+ "thinking": "#8250df",
46
+ "text_primary": "#1f2328",
47
+ "text_secondary": "#656d76",
48
+ "text_muted": "#8c959f",
49
+ "text_dim": "#d0d7de",
50
+ "separator": "#d8dee4",
51
+ "logo": "#bf8700",
52
+ "timer": "blue",
53
+ "tool_running": "#0969da",
54
+ "tool_done": "#1a7f37",
55
+ }
56
+
57
+ # Solarized Dark — Ethan Schoonover palette
58
+ SOLARIZED: dict[str, str] = {
59
+ "accent": "#268bd2", # blue
60
+ "success": "#859900", # green
61
+ "error": "#dc322f", # red
62
+ "warning": "#b58900", # yellow
63
+ "thinking": "#6c71c4", # violet
64
+ "text_primary": "#fdf6e3", # base3
65
+ "text_secondary": "#93a1a1", # base1
66
+ "text_muted": "#586e75", # base01
67
+ "text_dim": "#073642", # base02
68
+ "separator": "#002b36", # base03
69
+ "logo": "#cb4b16", # orange
70
+ "timer": "bright_cyan",
71
+ "tool_running": "#268bd2",
72
+ "tool_done": "#2aa198", # cyan
73
+ }
74
+
75
+ # Dracula — popular dark palette
76
+ DRACULA: dict[str, str] = {
77
+ "accent": "#bd93f9", # purple
78
+ "success": "#50fa7b", # green
79
+ "error": "#ff5555", # red
80
+ "warning": "#ffb86c", # orange
81
+ "thinking": "#ff79c6", # pink
82
+ "text_primary": "#f8f8f2", # foreground
83
+ "text_secondary": "#6272a4", # comment
84
+ "text_muted": "#44475a",
85
+ "text_dim": "#282a36",
86
+ "separator": "#21222c",
87
+ "logo": "#f1fa8c", # yellow
88
+ "timer": "bright_magenta",
89
+ "tool_running": "#8be9fd", # cyan
90
+ "tool_done": "#50fa7b",
91
+ }
92
+
93
+ # Registry of selectable themes. Keys are the names users pass to --theme
94
+ # and to the /themes command.
95
+ THEMES: dict[str, dict[str, str]] = {
96
+ "default": DARK,
97
+ "accessible": VISIBLE,
98
+ "light": LIGHT,
99
+ "solarized": SOLARIZED,
100
+ "dracula": DRACULA,
101
+ }
102
+
103
+ THEME_DESCRIPTIONS: dict[str, str] = {
104
+ "default": "Dark background with muted accents (built-in default)",
105
+ "accessible": "Okabe-Ito palette — colour-blind safe",
106
+ "light": "Light background with dark text",
107
+ "solarized": "Solarized Dark by Ethan Schoonover",
108
+ "dracula": "Dracula — vivid pastels on near-black",
109
+ }
110
+
111
+ # Mutated at startup by OpenDataSciApp based on --theme flag.
112
+ active: dict[str, str] = dict(DARK)
113
+ active_name: str = "default"
@@ -0,0 +1,86 @@
1
+ """Tool display metadata for the TUI renderer.
2
+
3
+ Centralises ToolDisplay declarations and the global REGISTRY so the TUI
4
+ and streaming layer can look up icons, labels, and summary arguments without
5
+ knowing anything about tool internals.
6
+
7
+ Usage::
8
+
9
+ from opendatasci._tui.tools_display import REGISTRY, ToolDisplay
10
+
11
+ display = REGISTRY.get("execute_python_code", ToolDisplay(label="execute_python_code"))
12
+ print(display.icon, display.label) # 🐍 Code
13
+ """
14
+
15
+ import types
16
+ from dataclasses import dataclass
17
+
18
+
19
+ @dataclass(frozen=True)
20
+ class ToolDisplay:
21
+ """Display metadata for a single tool.
22
+
23
+ Attributes:
24
+ label: Human-readable tool name shown in the TUI
25
+ (e.g. ``"Python"``, ``"Web Search"``).
26
+ icon: Optional single emoji rendered before the label
27
+ (e.g. ``"🐍"``).
28
+ summary_arg: Name of the tool argument whose value is used as the
29
+ short summary line in the ephemeral block. ``None``
30
+ means no summary (the block shows only the label and
31
+ communication).
32
+ display: When ``True`` (default) an ephemeral block is shown
33
+ while the tool runs and kept as a breadcrumb afterwards.
34
+ Set to ``False`` for silent internal tools.
35
+ """
36
+
37
+ label: str
38
+ icon: str = ""
39
+ summary_arg: str | None = None
40
+ display: bool = True
41
+
42
+
43
+ # Global registry: canonical tool name → ToolDisplay.
44
+ # _registry is the mutable backing dict; REGISTRY is the public read-only view.
45
+ _registry: dict[str, ToolDisplay] = {}
46
+ REGISTRY: types.MappingProxyType[str, ToolDisplay] = types.MappingProxyType(_registry)
47
+
48
+
49
+ def register(tool_name: str, display: ToolDisplay) -> None:
50
+ """Associate *display* with *tool_name* in the global registry."""
51
+ _registry[tool_name] = display
52
+
53
+
54
+ # ── Registrations ─────────────────────────────────────────────────────────────
55
+ # String literals are used for tool names so this module stays free of imports
56
+ # from opendatasci.tools.factory (which creates a circular dependency).
57
+
58
+ register("execute_python_code", ToolDisplay(label="Code", icon="🐍", summary_arg="summary"))
59
+ register("execute_cli_command", ToolDisplay(label="Command", icon="⌨️", summary_arg="summary"))
60
+ register("list_python_libs", ToolDisplay(label="Checking available libraries", icon="📦"))
61
+ register("enter_plan_mode", ToolDisplay(label="Planning", icon="🎯"))
62
+ register("exit_plan_mode", ToolDisplay(label="Done planning", icon="✅"))
63
+ register("load_skill", ToolDisplay(label="Loading skill", icon="🧠", summary_arg="summary"))
64
+ register("spawn_workers", ToolDisplay(label="Spawning workers", icon="⚙️"))
65
+ register(
66
+ "read_dataset_info",
67
+ ToolDisplay(label="Reading dataset info", icon="📚", summary_arg="summary"),
68
+ )
69
+ register(
70
+ "update_dataset_info",
71
+ ToolDisplay(label="Updating dataset notes", icon="📝", display=False),
72
+ )
73
+ register("profile_dataset", ToolDisplay(label="Profiling dataset", icon="📊"))
74
+ register("list_workspace_files", ToolDisplay(label="Listing workspace files", icon="📁"))
75
+ register(
76
+ "web_search",
77
+ ToolDisplay(label="Searching the web", icon="🌐", summary_arg="summary"),
78
+ )
79
+ register(
80
+ "fetch_url",
81
+ ToolDisplay(label="Fetching content", icon="🔗", summary_arg="summary"),
82
+ )
83
+ register("ask_user_mcq", ToolDisplay(label="Question", icon="💬", display=False))
84
+ register("enter_self_review_mode", ToolDisplay(label="Reviewing progress so far", icon="🔍"))
85
+ register("exit_self_review_mode", ToolDisplay(label="Done reviewing progress", icon="✅"))
86
+ register("verify_python_code", ToolDisplay(label="Reviewing code", icon="🔎"))