mito-ai 0.1.55__py3-none-any.whl → 0.1.57__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 (79) hide show
  1. mito_ai/__init__.py +2 -0
  2. mito_ai/_version.py +1 -1
  3. mito_ai/anthropic_client.py +7 -6
  4. mito_ai/chart_wizard/__init__.py +3 -0
  5. mito_ai/chart_wizard/handlers.py +52 -0
  6. mito_ai/chart_wizard/urls.py +23 -0
  7. mito_ai/completions/completion_handlers/completion_handler.py +11 -2
  8. mito_ai/completions/completion_handlers/scratchpad_result_handler.py +66 -0
  9. mito_ai/completions/handlers.py +5 -0
  10. mito_ai/completions/models.py +24 -3
  11. mito_ai/completions/prompt_builders/agent_execution_prompt.py +18 -50
  12. mito_ai/completions/prompt_builders/agent_smart_debug_prompt.py +82 -95
  13. mito_ai/completions/prompt_builders/agent_system_message.py +304 -276
  14. mito_ai/completions/prompt_builders/chart_conversion_prompt.py +27 -0
  15. mito_ai/completions/prompt_builders/chat_prompt.py +15 -100
  16. mito_ai/completions/prompt_builders/chat_system_message.py +98 -72
  17. mito_ai/completions/prompt_builders/explain_code_prompt.py +22 -24
  18. mito_ai/completions/prompt_builders/inline_completer_prompt.py +78 -107
  19. mito_ai/completions/prompt_builders/prompt_constants.py +35 -45
  20. mito_ai/completions/prompt_builders/prompt_section_registry/__init__.py +70 -0
  21. mito_ai/completions/prompt_builders/prompt_section_registry/active_cell_code.py +15 -0
  22. mito_ai/completions/prompt_builders/prompt_section_registry/active_cell_id.py +10 -0
  23. mito_ai/completions/prompt_builders/prompt_section_registry/active_cell_output.py +20 -0
  24. mito_ai/completions/prompt_builders/prompt_section_registry/base.py +37 -0
  25. mito_ai/completions/prompt_builders/prompt_section_registry/error_traceback.py +17 -0
  26. mito_ai/completions/prompt_builders/prompt_section_registry/example.py +19 -0
  27. mito_ai/completions/prompt_builders/prompt_section_registry/files.py +17 -0
  28. mito_ai/completions/prompt_builders/prompt_section_registry/generic.py +15 -0
  29. mito_ai/completions/prompt_builders/prompt_section_registry/get_cell_output_tool_response.py +21 -0
  30. mito_ai/completions/prompt_builders/prompt_section_registry/notebook.py +19 -0
  31. mito_ai/completions/prompt_builders/prompt_section_registry/rules.py +39 -0
  32. mito_ai/completions/prompt_builders/{utils.py → prompt_section_registry/selected_context.py} +51 -42
  33. mito_ai/completions/prompt_builders/prompt_section_registry/streamlit_app_status.py +25 -0
  34. mito_ai/completions/prompt_builders/prompt_section_registry/task.py +12 -0
  35. mito_ai/completions/prompt_builders/prompt_section_registry/variables.py +18 -0
  36. mito_ai/completions/prompt_builders/scratchpad_result_prompt.py +17 -0
  37. mito_ai/completions/prompt_builders/smart_debug_prompt.py +48 -63
  38. mito_ai/constants.py +0 -3
  39. mito_ai/tests/completions/test_prompt_section_registry.py +44 -0
  40. mito_ai/tests/message_history/test_message_history_utils.py +273 -340
  41. mito_ai/tests/providers/test_anthropic_client.py +7 -3
  42. mito_ai/utils/message_history_utils.py +68 -44
  43. mito_ai/utils/provider_utils.py +8 -1
  44. {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/build_log.json +102 -102
  45. {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/package.json +2 -2
  46. {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/schemas/mito_ai/package.json.orig +1 -1
  47. mito_ai-0.1.55.data/data/share/jupyter/labextensions/mito_ai/static/lib_index_js.49c79c62671528877c61.js → mito_ai-0.1.57.data/data/share/jupyter/labextensions/mito_ai/static/lib_index_js.9d26322f3e78beb2b666.js +2778 -297
  48. mito_ai-0.1.57.data/data/share/jupyter/labextensions/mito_ai/static/lib_index_js.9d26322f3e78beb2b666.js.map +1 -0
  49. mito_ai-0.1.55.data/data/share/jupyter/labextensions/mito_ai/static/remoteEntry.9dfbffc3592eb6f0aef9.js → mito_ai-0.1.57.data/data/share/jupyter/labextensions/mito_ai/static/remoteEntry.79c1ea8a3cda73a4cb6f.js +17 -17
  50. mito_ai-0.1.55.data/data/share/jupyter/labextensions/mito_ai/static/remoteEntry.9dfbffc3592eb6f0aef9.js.map → mito_ai-0.1.57.data/data/share/jupyter/labextensions/mito_ai/static/remoteEntry.79c1ea8a3cda73a4cb6f.js.map +1 -1
  51. {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/themes/mito_ai/index.css +7 -2
  52. {mito_ai-0.1.55.dist-info → mito_ai-0.1.57.dist-info}/METADATA +5 -1
  53. {mito_ai-0.1.55.dist-info → mito_ai-0.1.57.dist-info}/RECORD +78 -56
  54. mito_ai-0.1.55.data/data/share/jupyter/labextensions/mito_ai/static/lib_index_js.49c79c62671528877c61.js.map +0 -1
  55. {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/etc/jupyter/jupyter_server_config.d/mito_ai.json +0 -0
  56. {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/schemas/mito_ai/toolbar-buttons.json +0 -0
  57. {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/static/node_modules_process_browser_js.4b128e94d31a81ebd209.js +0 -0
  58. {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/static/node_modules_process_browser_js.4b128e94d31a81ebd209.js.map +0 -0
  59. {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/static/style.js +0 -0
  60. {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/static/style_index_js.f5d476ac514294615881.js +0 -0
  61. {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/static/style_index_js.f5d476ac514294615881.js.map +0 -0
  62. {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_auth_dist_esm_providers_cognito_apis_signOut_mjs-node_module-75790d.688c25857e7b81b1740f.js +0 -0
  63. {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_auth_dist_esm_providers_cognito_apis_signOut_mjs-node_module-75790d.688c25857e7b81b1740f.js.map +0 -0
  64. {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_auth_dist_esm_providers_cognito_tokenProvider_tokenProvider_-72f1c8.a917210f057fcfe224ad.js +0 -0
  65. {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_auth_dist_esm_providers_cognito_tokenProvider_tokenProvider_-72f1c8.a917210f057fcfe224ad.js.map +0 -0
  66. {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_dist_esm_index_mjs.6bac1a8c4cc93f15f6b7.js +0 -0
  67. {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_dist_esm_index_mjs.6bac1a8c4cc93f15f6b7.js.map +0 -0
  68. {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_ui-react_dist_esm_index_mjs.4fcecd65bef9e9847609.js +0 -0
  69. {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_ui-react_dist_esm_index_mjs.4fcecd65bef9e9847609.js.map +0 -0
  70. {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_react-dom_client_js-node_modules_aws-amplify_ui-react_dist_styles_css.b43d4249e4d3dac9ad7b.js +0 -0
  71. {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_react-dom_client_js-node_modules_aws-amplify_ui-react_dist_styles_css.b43d4249e4d3dac9ad7b.js.map +0 -0
  72. {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_semver_index_js.3f6754ac5116d47de76b.js +0 -0
  73. {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_semver_index_js.3f6754ac5116d47de76b.js.map +0 -0
  74. {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_vscode-diff_dist_index_js.ea55f1f9346638aafbcf.js +0 -0
  75. {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_vscode-diff_dist_index_js.ea55f1f9346638aafbcf.js.map +0 -0
  76. {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/themes/mito_ai/index.js +0 -0
  77. {mito_ai-0.1.55.dist-info → mito_ai-0.1.57.dist-info}/WHEEL +0 -0
  78. {mito_ai-0.1.55.dist-info → mito_ai-0.1.57.dist-info}/entry_points.txt +0 -0
  79. {mito_ai-0.1.55.dist-info → mito_ai-0.1.57.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,17 @@
1
+ # Copyright (c) Saga Inc.
2
+ # Distributed under the terms of the GNU Affero General Public License v3.0 License.
3
+
4
+ from typing import List
5
+ from mito_ai.completions.models import ScratchpadResultMetadata
6
+ from mito_ai.completions.prompt_builders.prompt_section_registry import SG, Prompt
7
+ from mito_ai.completions.prompt_builders.prompt_section_registry.base import PromptSection
8
+
9
+
10
+ def create_scratchpad_result_prompt(md: ScratchpadResultMetadata) -> str:
11
+ sections: List[PromptSection] = [
12
+ SG.Generic("Reminder", "Continue working on your current task using the scratchpad results below."),
13
+ SG.Generic("Scratchpad Result", f"The result of your scratchpad is: {md.scratchpadResult}"),
14
+ ]
15
+
16
+ prompt = Prompt(sections)
17
+ return str(prompt)
@@ -2,12 +2,8 @@
2
2
  # Distributed under the terms of the GNU Affero General Public License v3.0 License.
3
3
 
4
4
  from typing import List
5
- from mito_ai.completions.prompt_builders.prompt_constants import (
6
- ACTIVE_CELL_ID_SECTION_HEADING,
7
- FILES_SECTION_HEADING,
8
- VARIABLES_SECTION_HEADING,
9
- CODE_SECTION_HEADING
10
- )
5
+ from mito_ai.completions.prompt_builders.prompt_section_registry import SG, Prompt
6
+ from mito_ai.completions.prompt_builders.prompt_section_registry.base import PromptSection
11
7
 
12
8
 
13
9
  def create_error_prompt(
@@ -17,29 +13,30 @@ def create_error_prompt(
17
13
  variables: List[str],
18
14
  files: List[str]
19
15
  ) -> str:
20
- variables_str = '\n'.join([f"{variable}" for variable in variables])
21
- files_str = '\n'.join([f"{file}" for file in files])
22
- return f"""Help me debug this code in JupyterLab. Analyze the error and provide a solution that maintains the original intent.
23
-
24
- <Example 1>
25
- {FILES_SECTION_HEADING}
26
- file_name: sales.csv
16
+ sections: List[PromptSection] = []
17
+
18
+ # Add intro text
19
+ sections.append(SG.Generic("Instructions", "Help me debug this code in JupyterLab. Analyze the error and provide a solution that maintains the original intent."))
20
+
21
+ # Example 1
22
+ sections.append(SG.Example("Example 1", '''
23
+ Files:
24
+ "file_name: sales.csv"
27
25
 
28
- {VARIABLES_SECTION_HEADING}
26
+ Variables:
29
27
  {{
30
28
  'revenue_multiplier': 1.5,
31
- 'sales_df': pd.DataFrame({{
29
+ 'sales_df': pd.DataFrame({
32
30
  'transaction_date': ['2024-01-02', '2024-01-02', '2024-01-02', '2024-01-02', '2024-01-03'],
33
31
  'price_per_unit': [10, 9.99, 13.99, 21.00, 100],
34
32
  'units_sold': [1, 2, 1, 4, 5],
35
33
  'total_price': [10, 19.98, 13.99, 84.00, 500]
36
- }})
34
+ })
37
35
  }}
38
36
 
39
- {ACTIVE_CELL_ID_SECTION_HEADING}
40
- '9e38c62b-38f8-457d-bb8d-28bfc52edf2c'
37
+ Active Cell ID: '9e38c62b-38f8-457d-bb8d-28bfc52edf2c'
41
38
 
42
- {CODE_SECTION_HEADING}
39
+ Active Cell Code:
43
40
  ```python
44
41
  import pandas as pd
45
42
  sales_df = pd.read_csv('./sales.csv')
@@ -48,14 +45,17 @@ sales_df['total_revenue'] = sales_df['price'] * revenue_multiplier
48
45
  ```
49
46
 
50
47
  Error Traceback:
51
- Cell In[24], line 4
48
+ Cell ID: '9e38c62b-38f8-457d-bb8d-28bfc52edf2c'
49
+ Traceback:
50
+ ```
51
+ Cell In[24], line 4
52
52
  1 import pandas as pd
53
53
  2 sales_df = pd.read_csv('./sales.csv')
54
54
  3 revenue_multiplier = 1.5
55
55
  ----> 4 sales_df['total_revenue'] = sales_df['price'] * revenue_multiplier
56
56
 
57
57
  KeyError: 'price'
58
-
58
+ ```
59
59
 
60
60
  ERROR ANALYSIS:
61
61
  Runtime error: Attempted to access non-existent DataFrame column
@@ -71,31 +71,32 @@ revenue_multiplier = 1.5
71
71
  sales_df['total_revenue'] = sales_df['total_price'] * revenue_multiplier
72
72
  ```
73
73
 
74
- The DataFrame contains 'total_price' rather than 'price'. Updated column reference to match existing data structure.
75
- </Example 1>
76
-
77
- <Example 2>
78
- {FILES_SECTION_HEADING}
74
+ The DataFrame contains 'total_price' rather than 'price'. Updated column reference to match existing data structure.'''))
79
75
 
76
+
77
+ # Example 2
78
+ sections.append(SG.Example("Example 2", '''Files:
79
+ "file_name: sales.csv"
80
80
 
81
- {VARIABLES_SECTION_HEADING}
81
+ Variables:
82
82
  {{
83
- 'df': pd.DataFrame({{
83
+ 'df': pd.DataFrame({
84
84
  'order_id': [1, 2, 3, 4],
85
85
  'date': ['Mar 7, 2025', 'Sep 24, 2024', '25 June, 2024', 'June 29, 2024'],
86
86
  'amount': [100, 150, 299, 99]
87
- }})
87
+ })
88
88
  }}
89
89
 
90
- {ACTIVE_CELL_ID_SECTION_HEADING}
91
- 'c68fdf19-db8c-46dd-926f-d90ad35bb3bc'
90
+ Active Cell ID: 'c68fdf19-db8c-46dd-926f-d90ad35bb3bc'
92
91
 
93
- {CODE_SECTION_HEADING}
92
+ Active Cell Code:
94
93
  ```python
95
94
  df['date'] = pd.to_datetime(df['date'])
96
95
  ```
97
96
 
98
97
  Error Traceback:
98
+ Cell ID: 'c68fdf19-db8c-46dd-926f-d90ad35bb3bc'
99
+ Traceback:
99
100
  Cell In[27], line 1
100
101
  ----> 1 df['date'] = pd.to_datetime(df['date'])
101
102
 
@@ -130,13 +131,10 @@ df['date'] = df['date'].apply(lambda x: parse_date(x))
130
131
 
131
132
  Since the dates are not in a consistent format, we need to first figure out which format to use for each date string and then use that format to convert the date.
132
133
 
133
- The best way to do this is with a function. We can call this function `parse_date`.
134
- </Example 2>
135
-
136
-
137
- Guidelines for Solutions:
134
+ The best way to do this is with a function. We can call this function `parse_date`.'''))
138
135
 
139
- Error Analysis:
136
+ # Add guidelines
137
+ sections.append(SG.Generic("Guidelines for Solutions", """Error Analysis:
140
138
 
141
139
  - Identify error type (Syntax, Runtime, Logic).
142
140
  - Use the defined variables and code in the active cell to understand the error.
@@ -156,32 +154,19 @@ Solution Requirements:
156
154
  - Do not add temporary comments like '# Fixed the typo here' or '# Added this line to fix the error'
157
155
  - The code in the SOLUTION section should be a python code block starting with ```python and ending with ```
158
156
  - If you encounter a ModuleNotFoundError, you can install the package by adding the the following line to the top of the code cell: `!pip install <package_name> --quiet`.
157
+ """))
158
+
159
+ # Add actual task sections
160
+ sections.append(SG.Files(files))
161
+ sections.append(SG.Variables(variables))
162
+ sections.append(SG.ActiveCellId(active_cell_id))
163
+ sections.append(SG.ActiveCellCode(active_cell_code))
164
+ sections.append(SG.ErrorTraceback(active_cell_id, error_message))
165
+
166
+ sections.append(SG.Task("Perform the ERROR ANALYSIS, INTENT ANALYSIS, and SOLUTION steps to fix the error."))
159
167
 
160
- Here is your task.
161
-
162
- {FILES_SECTION_HEADING}
163
- {files_str}
164
-
165
- {VARIABLES_SECTION_HEADING}
166
- {variables_str}
167
-
168
- {ACTIVE_CELL_ID_SECTION_HEADING}
169
- {active_cell_id}
170
-
171
- {CODE_SECTION_HEADING}
172
- ```python
173
- {active_cell_code}
174
- ```
175
-
176
- Error Traceback:
177
- {error_message}
178
-
179
- ERROR ANALYSIS:
180
-
181
- INTENT ANALYSIS:
182
-
183
- SOLUTION:
184
- """
168
+ prompt = Prompt(sections)
169
+ return str(prompt)
185
170
 
186
171
 
187
172
  def remove_inner_thoughts_from_message(message: str) -> str:
mito_ai/constants.py CHANGED
@@ -58,6 +58,3 @@ COGNITO_CONFIG_DEV = {
58
58
  }
59
59
 
60
60
  ACTIVE_COGNITO_CONFIG = COGNITO_CONFIG_DEV # Change to COGNITO_CONFIG_DEV for dev
61
-
62
-
63
- MESSAGE_HISTORY_TRIM_THRESHOLD: int = 3
@@ -0,0 +1,44 @@
1
+ # Copyright (c) Saga Inc.
2
+ # Distributed under the terms of the GNU Affero General Public License v3.0 License.
3
+
4
+ import pytest
5
+ from mito_ai.completions.prompt_builders.prompt_section_registry import (
6
+ get_max_trim_after_messages,
7
+ get_all_section_classes,
8
+ SectionRegistry
9
+ )
10
+
11
+ def test_get_max_trim_after_messages_returns_actual_max():
12
+ """Test that get_max_trim_after_messages returns the correct maximum value from all sections."""
13
+ # Get all section classes and their trim_after_messages values
14
+ section_classes = get_all_section_classes()
15
+ trim_values = []
16
+
17
+ for section_class in section_classes:
18
+ trim_value = getattr(section_class, 'trim_after_messages', None)
19
+ if trim_value is not None:
20
+ trim_values.append(trim_value)
21
+
22
+ if trim_values:
23
+ expected_max = max(trim_values)
24
+ actual_max = get_max_trim_after_messages()
25
+ assert actual_max == expected_max
26
+ else:
27
+ # If all are None, should return 0
28
+ assert get_max_trim_after_messages() == 0
29
+
30
+
31
+ def test_get_all_section_classes():
32
+ """Test that get_all_section_classes returns all section classes."""
33
+ section_classes = get_all_section_classes()
34
+
35
+ # Verify it returns a list
36
+ assert isinstance(section_classes, list)
37
+ assert len(section_classes) > 0
38
+
39
+ # Verify all items are classes from SectionRegistry
40
+ for section_class in section_classes:
41
+ assert section_class in SectionRegistry.__dict__.values()
42
+ # Verify they have trim_after_messages attribute
43
+ assert hasattr(section_class, 'trim_after_messages')
44
+