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.
- mito_ai/__init__.py +2 -0
- mito_ai/_version.py +1 -1
- mito_ai/anthropic_client.py +7 -6
- mito_ai/chart_wizard/__init__.py +3 -0
- mito_ai/chart_wizard/handlers.py +52 -0
- mito_ai/chart_wizard/urls.py +23 -0
- mito_ai/completions/completion_handlers/completion_handler.py +11 -2
- mito_ai/completions/completion_handlers/scratchpad_result_handler.py +66 -0
- mito_ai/completions/handlers.py +5 -0
- mito_ai/completions/models.py +24 -3
- mito_ai/completions/prompt_builders/agent_execution_prompt.py +18 -50
- mito_ai/completions/prompt_builders/agent_smart_debug_prompt.py +82 -95
- mito_ai/completions/prompt_builders/agent_system_message.py +304 -276
- mito_ai/completions/prompt_builders/chart_conversion_prompt.py +27 -0
- mito_ai/completions/prompt_builders/chat_prompt.py +15 -100
- mito_ai/completions/prompt_builders/chat_system_message.py +98 -72
- mito_ai/completions/prompt_builders/explain_code_prompt.py +22 -24
- mito_ai/completions/prompt_builders/inline_completer_prompt.py +78 -107
- mito_ai/completions/prompt_builders/prompt_constants.py +35 -45
- mito_ai/completions/prompt_builders/prompt_section_registry/__init__.py +70 -0
- mito_ai/completions/prompt_builders/prompt_section_registry/active_cell_code.py +15 -0
- mito_ai/completions/prompt_builders/prompt_section_registry/active_cell_id.py +10 -0
- mito_ai/completions/prompt_builders/prompt_section_registry/active_cell_output.py +20 -0
- mito_ai/completions/prompt_builders/prompt_section_registry/base.py +37 -0
- mito_ai/completions/prompt_builders/prompt_section_registry/error_traceback.py +17 -0
- mito_ai/completions/prompt_builders/prompt_section_registry/example.py +19 -0
- mito_ai/completions/prompt_builders/prompt_section_registry/files.py +17 -0
- mito_ai/completions/prompt_builders/prompt_section_registry/generic.py +15 -0
- mito_ai/completions/prompt_builders/prompt_section_registry/get_cell_output_tool_response.py +21 -0
- mito_ai/completions/prompt_builders/prompt_section_registry/notebook.py +19 -0
- mito_ai/completions/prompt_builders/prompt_section_registry/rules.py +39 -0
- mito_ai/completions/prompt_builders/{utils.py → prompt_section_registry/selected_context.py} +51 -42
- mito_ai/completions/prompt_builders/prompt_section_registry/streamlit_app_status.py +25 -0
- mito_ai/completions/prompt_builders/prompt_section_registry/task.py +12 -0
- mito_ai/completions/prompt_builders/prompt_section_registry/variables.py +18 -0
- mito_ai/completions/prompt_builders/scratchpad_result_prompt.py +17 -0
- mito_ai/completions/prompt_builders/smart_debug_prompt.py +48 -63
- mito_ai/constants.py +0 -3
- mito_ai/tests/completions/test_prompt_section_registry.py +44 -0
- mito_ai/tests/message_history/test_message_history_utils.py +273 -340
- mito_ai/tests/providers/test_anthropic_client.py +7 -3
- mito_ai/utils/message_history_utils.py +68 -44
- mito_ai/utils/provider_utils.py +8 -1
- {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/build_log.json +102 -102
- {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/package.json +2 -2
- {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
- 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
- mito_ai-0.1.57.data/data/share/jupyter/labextensions/mito_ai/static/lib_index_js.9d26322f3e78beb2b666.js.map +1 -0
- 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
- 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
- {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
- {mito_ai-0.1.55.dist-info → mito_ai-0.1.57.dist-info}/METADATA +5 -1
- {mito_ai-0.1.55.dist-info → mito_ai-0.1.57.dist-info}/RECORD +78 -56
- mito_ai-0.1.55.data/data/share/jupyter/labextensions/mito_ai/static/lib_index_js.49c79c62671528877c61.js.map +0 -1
- {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/etc/jupyter/jupyter_server_config.d/mito_ai.json +0 -0
- {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
- {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
- {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
- {mito_ai-0.1.55.data → mito_ai-0.1.57.data}/data/share/jupyter/labextensions/mito_ai/static/style.js +0 -0
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {mito_ai-0.1.55.dist-info → mito_ai-0.1.57.dist-info}/WHEEL +0 -0
- {mito_ai-0.1.55.dist-info → mito_ai-0.1.57.dist-info}/entry_points.txt +0 -0
- {mito_ai-0.1.55.dist-info → mito_ai-0.1.57.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,27 @@
|
|
|
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.prompt_builders.prompt_section_registry import SG, Prompt
|
|
6
|
+
from mito_ai.completions.prompt_builders.prompt_section_registry.base import PromptSection
|
|
7
|
+
from mito_ai.completions.prompt_builders.prompt_constants import CHART_CONFIG_RULES
|
|
8
|
+
|
|
9
|
+
def create_chart_conversion_prompt(code: str) -> str:
|
|
10
|
+
"""
|
|
11
|
+
Create a prompt for converting matplotlib chart code to be used with the Chart Wizard.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
code: The matplotlib chart code to convert
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
A formatted prompt string
|
|
18
|
+
"""
|
|
19
|
+
sections: List[PromptSection] = []
|
|
20
|
+
|
|
21
|
+
sections.append(SG.Generic("Instructions", "The following code contains a matplotlib chart. However, the chart must be converted to a specific format for use in our tool. Below you will find the rules used to create an acceptable chart; use these rules to reformat the code."))
|
|
22
|
+
|
|
23
|
+
sections.append(SG.Generic("Chart Config Rules", CHART_CONFIG_RULES))
|
|
24
|
+
sections.append(SG.Generic("Code to Convert", f"```python\n{code}\n```"))
|
|
25
|
+
|
|
26
|
+
prompt = Prompt(sections)
|
|
27
|
+
return str(prompt)
|
|
@@ -2,18 +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, Optional, Dict
|
|
5
|
-
from mito_ai.completions.prompt_builders.
|
|
6
|
-
|
|
7
|
-
CHAT_CODE_FORMATTING_RULES,
|
|
8
|
-
FILES_SECTION_HEADING,
|
|
9
|
-
VARIABLES_SECTION_HEADING,
|
|
10
|
-
CODE_SECTION_HEADING,
|
|
11
|
-
get_active_cell_output_str,
|
|
12
|
-
)
|
|
13
|
-
from mito_ai.completions.prompt_builders.utils import (
|
|
14
|
-
get_rules_str,
|
|
15
|
-
get_selected_context_str,
|
|
16
|
-
)
|
|
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
|
|
17
7
|
|
|
18
8
|
|
|
19
9
|
def create_chat_prompt(
|
|
@@ -25,92 +15,17 @@ def create_chat_prompt(
|
|
|
25
15
|
input: str,
|
|
26
16
|
additional_context: Optional[List[Dict[str, str]]] = None,
|
|
27
17
|
) -> str:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
18
|
+
sections: List[PromptSection] = [
|
|
19
|
+
SG.Rules(additional_context),
|
|
20
|
+
SG.Generic("Instructions", "Help me complete the following task. I will provide you with a set of variables, existing code, and a task to complete."),
|
|
21
|
+
SG.Files(files),
|
|
22
|
+
SG.Variables(variables),
|
|
23
|
+
SG.SelectedContext(additional_context),
|
|
24
|
+
SG.ActiveCellId(active_cell_id),
|
|
25
|
+
SG.ActiveCellCode(active_cell_code),
|
|
26
|
+
SG.ActiveCellOutput(has_active_cell_output),
|
|
27
|
+
SG.Task(input),
|
|
28
|
+
]
|
|
34
29
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
{CHAT_CODE_FORMATTING_RULES}
|
|
38
|
-
|
|
39
|
-
<Example 1>
|
|
40
|
-
|
|
41
|
-
{FILES_SECTION_HEADING}
|
|
42
|
-
file_name: sales.csv
|
|
43
|
-
|
|
44
|
-
{VARIABLES_SECTION_HEADING}
|
|
45
|
-
{{
|
|
46
|
-
'loan_multiplier': 1.5,
|
|
47
|
-
'sales_df': pd.DataFrame({{
|
|
48
|
-
'transaction_date': ['2024-01-02', '2024-01-02', '2024-01-02', '2024-01-02', '2024-01-03'],
|
|
49
|
-
'price_per_unit': [10, 9.99, 13.99, 21.00, 100],
|
|
50
|
-
'units_sold': [1, 2, 1, 4, 5],
|
|
51
|
-
'total_price': [10, 19.98, 13.99, 84.00, 500]
|
|
52
|
-
}})
|
|
53
|
-
}}
|
|
54
|
-
|
|
55
|
-
{ACTIVE_CELL_ID_SECTION_HEADING}
|
|
56
|
-
'9c0d5fda-2b16-4f52-a1c5-a48892f3e2e8'
|
|
57
|
-
|
|
58
|
-
{CODE_SECTION_HEADING}
|
|
59
|
-
```python
|
|
60
|
-
import pandas as pd
|
|
61
|
-
sales_df = pd.read_csv('./sales.csv')
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
Your task: convert the transaction_date column to datetime and then multiply the total_price column by the sales_multiplier.
|
|
65
|
-
|
|
66
|
-
Output:
|
|
67
|
-
```python
|
|
68
|
-
import pandas as pd
|
|
69
|
-
sales_df = pd.read_csv('./sales.csv')
|
|
70
|
-
sales_df['transaction_date'] = pd.to_datetime(sales_df['transaction_date'])
|
|
71
|
-
sales_df['total_price'] = sales_df['total_price'] * sales_multiplier
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
Applied datetime conversion to enable temporal analysis[MITO_CITATION:9c0d5fda-2b16-4f52-a1c5-a48892f3e2e8:2] and revenue adjustment using the 1.5x sales multiplier[MITO_CITATION:9c0d5fda-2b16-4f52-a1c5-a48892f3e2e8:3], scaling total revenue from $627.97 to $941.96.
|
|
75
|
-
|
|
76
|
-
</Example 1>
|
|
77
|
-
|
|
78
|
-
<Example 2>
|
|
79
|
-
|
|
80
|
-
{ACTIVE_CELL_ID_SECTION_HEADING}
|
|
81
|
-
'1a2b3c4d-5e6f-7g8h-9i0j-k1l2m3n4o5p6'
|
|
82
|
-
|
|
83
|
-
{CODE_SECTION_HEADING}
|
|
84
|
-
```python
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
Your task: Hello
|
|
88
|
-
|
|
89
|
-
Output:
|
|
90
|
-
Hey there! I'm Mito AI. How can I help you today?
|
|
91
|
-
|
|
92
|
-
</Example 2>
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
{FILES_SECTION_HEADING}
|
|
96
|
-
{files_str}
|
|
97
|
-
|
|
98
|
-
{VARIABLES_SECTION_HEADING}
|
|
99
|
-
{variables_str}
|
|
100
|
-
|
|
101
|
-
{ACTIVE_CELL_ID_SECTION_HEADING}
|
|
102
|
-
{active_cell_id}
|
|
103
|
-
|
|
104
|
-
{CODE_SECTION_HEADING}
|
|
105
|
-
```python
|
|
106
|
-
{active_cell_code}
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
{selected_context_str}
|
|
110
|
-
|
|
111
|
-
{get_active_cell_output_str(has_active_cell_output)}
|
|
112
|
-
|
|
113
|
-
Your task: {input}
|
|
114
|
-
"""
|
|
115
|
-
|
|
116
|
-
return prompt
|
|
30
|
+
prompt = Prompt(sections)
|
|
31
|
+
return str(prompt)
|
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
# Copyright (c) Saga Inc.
|
|
2
2
|
# Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
3
3
|
|
|
4
|
+
from typing import List
|
|
5
|
+
from mito_ai.completions.prompt_builders.prompt_section_registry import SG, Prompt
|
|
4
6
|
from mito_ai.completions.prompt_builders.prompt_constants import (
|
|
7
|
+
CHART_CONFIG_RULES,
|
|
5
8
|
CHAT_CODE_FORMATTING_RULES,
|
|
6
9
|
CITATION_RULES,
|
|
7
10
|
CELL_REFERENCE_RULES,
|
|
8
|
-
ACTIVE_CELL_ID_SECTION_HEADING,
|
|
9
|
-
CODE_SECTION_HEADING,
|
|
10
11
|
get_database_rules
|
|
11
12
|
)
|
|
13
|
+
from mito_ai.completions.prompt_builders.prompt_section_registry.base import PromptSection
|
|
12
14
|
|
|
13
15
|
def create_chat_system_message_prompt() -> str:
|
|
14
|
-
|
|
16
|
+
sections: List[PromptSection] = []
|
|
17
|
+
|
|
18
|
+
# Add intro text
|
|
19
|
+
sections.append(SG.Generic("Instructions", """You are Mito Data Copilot, an AI assistant for Jupyter. You're a great python programmer, a seasoned data scientist and a subject matter expert.
|
|
15
20
|
|
|
16
21
|
The user is going to ask you for help writing code, debugging code, explaining code, or drawing conclusions from their data/graphs. It is your job to help them accomplish their goal.
|
|
17
22
|
|
|
@@ -25,77 +30,96 @@ There are three possible types of responses you might give:
|
|
|
25
30
|
Other useful information:
|
|
26
31
|
1. The user has two types of modes that they can collaborate with you in: Chat Mode (this mode) and agent mode. Chat mode gives the user more control over the edits made to the notebook and only edits the active cell. Agent mode gives you more autonomy over completing the user's task across mulitple messages. In agent mode, you can edit or create new cells, see the entire notebook, automatically run the code you write, and more.
|
|
27
32
|
2. If the user asks you to generate a dashboard, app, or streamlit app for them, you should tell them that they must use Agent mode to complete the task. You are not able to automatically switch the user to agent mode, but they can switch to it themselves by using the Chat/Agent mode toggle in the bottom left corner of the Ai taskpane.
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
{
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
33
|
+
"""))
|
|
34
|
+
|
|
35
|
+
sections.append(SG.Generic("Chart Config Rules", CHART_CONFIG_RULES))
|
|
36
|
+
sections.append(SG.Generic("DatabaseRules", get_database_rules()))
|
|
37
|
+
sections.append(SG.Generic("Citation Rules", CITATION_RULES))
|
|
38
|
+
sections.append(SG.Generic("Cell Reference Rules", CELL_REFERENCE_RULES))
|
|
39
|
+
|
|
40
|
+
# Example 1
|
|
41
|
+
sections.append(SG.Example("Example 1", f"""
|
|
42
|
+
|
|
43
|
+
Notice in this example:
|
|
44
|
+
- Citations support specific facts and numbers, not vague summaries
|
|
45
|
+
- Single line citations reference specific calculations (e.g., :4 for growth rate)
|
|
46
|
+
- Multiline citations reference broader analysis blocks (e.g., :1-2 for the groupby operation)
|
|
47
|
+
- Language is information-dense with concrete metrics
|
|
48
|
+
- All line numbers are 0-indexed
|
|
49
|
+
|
|
50
|
+
Active Cell ID: '7b3a9e2c-5d14-4c83-b2f9-d67891e4a5f2'
|
|
51
|
+
|
|
52
|
+
Active Cell Code:
|
|
53
|
+
```python
|
|
54
|
+
sales_df = pd.read_csv('sales_data.csv')\nmonthly_revenue = sales_df.groupby('month')['revenue'].sum()\ntop_month = monthly_revenue.idxmax()\npeak_revenue = monthly_revenue.max()\ngrowth_rate = (monthly_revenue.iloc[-1] / monthly_revenue.iloc[0] - 1) * 100
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Your Task: What are the key revenue insights from this sales data?
|
|
58
|
+
|
|
59
|
+
Output:
|
|
60
|
+
Peak monthly revenue reached $847,392 in March[MITO_CITATION:7b3a9e2c-5d14-4c83-b2f9-d67891e4a5f2:2-3], representing a 23.8% year-over-year growth rate[MITO_CITATION:7b3a9e2c-5d14-4c83-b2f9-d67891e4a5f2:4]. The revenue aggregation analysis[MITO_CITATION:7b3a9e2c-5d14-4c83-b2f9-d67891e4a5f2:1-2] reveals strong seasonal performance patterns."""))
|
|
61
|
+
|
|
62
|
+
sections.append(SG.Example("Example 2", """
|
|
63
|
+
|
|
64
|
+
Notice in this example that the user is just sending a friendly message, so we respond with a friendly message and do not return any code.
|
|
65
|
+
|
|
66
|
+
Active Cell ID:
|
|
67
|
+
'1a2b3c4d-5e6f-7g8h-9i0j-k1l2m3n4o5p6'
|
|
68
|
+
|
|
69
|
+
Active Cell Code:
|
|
70
|
+
```python
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Your task: Hello
|
|
74
|
+
|
|
75
|
+
Output:
|
|
76
|
+
Hey there! I'm Mito AI. How can I help you today?"""))
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
sections.append(SG.Example("Example 3", """
|
|
80
|
+
Files:
|
|
81
|
+
"file_name: sales.csv"
|
|
82
|
+
|
|
83
|
+
Variables:
|
|
84
|
+
{{
|
|
85
|
+
'loan_multiplier': 1.5,
|
|
86
|
+
'sales_df': pd.DataFrame({
|
|
87
|
+
'transaction_date': ['2024-01-02', '2024-01-02', '2024-01-02', '2024-01-02', '2024-01-03'],
|
|
88
|
+
'price_per_unit': [10, 9.99, 13.99, 21.00, 100],
|
|
89
|
+
'units_sold': [1, 2, 1, 4, 5],
|
|
90
|
+
'total_price': [10, 19.98, 13.99, 84.00, 500]
|
|
91
|
+
})
|
|
92
|
+
}}
|
|
93
|
+
|
|
94
|
+
Active Cell ID: '9c0d5fda-2b16-4f52-a1c5-a48892f3e2e8'
|
|
95
|
+
|
|
96
|
+
Active Cell Code: import pandas as pd\nsales_df = pd.read_csv('./sales.csv')
|
|
97
|
+
|
|
98
|
+
Your Task: convert the transaction_date column to datetime and then multiply the total_price column by the sales_multiplier.
|
|
99
|
+
|
|
100
|
+
Output:
|
|
101
|
+
```python
|
|
102
|
+
import pandas as pd
|
|
103
|
+
sales_df = pd.read_csv('./sales.csv')
|
|
104
|
+
sales_df['transaction_date'] = pd.to_datetime(sales_df['transaction_date'])
|
|
105
|
+
sales_df['total_price'] = sales_df['total_price'] * sales_multiplier
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Applied datetime conversion to enable temporal analysis[MITO_CITATION:9c0d5fda-2b16-4f52-a1c5-a48892f3e2e8:2] and revenue adjustment using the 1.5x sales multiplier[MITO_CITATION:9c0d5fda-2b16-4f52-a1c5-a48892f3e2e8:3], scaling total revenue from $627.97 to $941.96."""))
|
|
109
|
+
|
|
110
|
+
# Add code formatting rules
|
|
111
|
+
sections.append(SG.Generic("CODE FORMATTING RULES", CHAT_CODE_FORMATTING_RULES))
|
|
112
|
+
|
|
113
|
+
# Add code style
|
|
114
|
+
sections.append(SG.Generic("CODE STYLE", """
|
|
90
115
|
- Avoid using try/except blocks and other defensive programming patterns (like checking if files exist before reading them, verifying variables are defined before using them, etc.) unless there is a really good reason. In Jupyter notebooks, errors should surface immediately so users can identify and fix issues. When errors are caught and suppressed or when defensive checks hide problems, users continue running broken code without realizing it, and the agent's auto-error-fix loop cannot trigger. If a column doesn't exist, a file is missing, a variable isn't defined, or a module isn't installed, let it error. The user needs to know.
|
|
91
116
|
- Write code that preserves the intent of the original code shared with you and the task to complete.
|
|
92
117
|
- Make the solution as simple as possible.
|
|
93
118
|
- Do not add temporary comments like '# Fixed the typo here' or '# Added this line to fix the error'
|
|
94
|
-
- When importing matplotlib, write the code `%matplotlib inline` to make sure the graphs render in Jupyter.
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
IMPORTANT RULES:
|
|
119
|
+
- When importing matplotlib, write the code `%matplotlib inline` to make sure the graphs render in Jupyter."""))
|
|
120
|
+
|
|
121
|
+
# Add important rules
|
|
122
|
+
sections.append(SG.Generic("IMPORTANT RULES", """
|
|
99
123
|
- Do not recreate variables that already exist
|
|
100
124
|
- Keep as much of the original code as possible
|
|
101
125
|
- When updating an existing code cell, return the full code cell with the update applied. Do not only return part of the code cell with a comment like "# Updated code starts here", etc.
|
|
@@ -103,5 +127,7 @@ IMPORTANT RULES:
|
|
|
103
127
|
- Write code that preserves the intent of the original code shared with you and the task to complete.
|
|
104
128
|
- Make the solution as simple as possible.
|
|
105
129
|
- Reuse as much of the existing code as possible.
|
|
106
|
-
- Whenever writing Python code, it should be a python code block starting with ```python and ending with ```
|
|
107
|
-
|
|
130
|
+
- Whenever writing Python code, it should be a python code block starting with ```python and ending with ```"""))
|
|
131
|
+
|
|
132
|
+
prompt = Prompt(sections)
|
|
133
|
+
return str(prompt)
|
|
@@ -1,32 +1,30 @@
|
|
|
1
1
|
# Copyright (c) Saga Inc.
|
|
2
2
|
# Distributed under the terms of the GNU Affero General Public License v3.0 License.
|
|
3
3
|
|
|
4
|
-
from
|
|
4
|
+
from typing import List
|
|
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
|
|
5
7
|
|
|
6
|
-
def create_explain_code_prompt(active_cell_code: str) -> str:
|
|
7
|
-
prompt = f"""Explain the code in the active code cell to me like I have a basic understanding of Python. Don't explain each line, but instead explain the overall logic of the code.
|
|
8
|
-
|
|
9
|
-
<Example>
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
def create_explain_code_prompt(active_cell_code: str) -> str:
|
|
10
|
+
sections: List[PromptSection] = []
|
|
11
|
+
# Add intro text
|
|
12
|
+
sections.append(SG.Generic("Instructions", "Explain the code in the active code cell to me like I have a basic understanding of Python. Don't explain each line, but instead explain the overall logic of the code."))
|
|
13
|
+
|
|
14
|
+
# Add example
|
|
15
|
+
example_content = f"""{SG.ActiveCellCode('''def multiply(x, y):
|
|
16
|
+
return x * y''')}
|
|
17
17
|
|
|
18
18
|
Output:
|
|
19
19
|
|
|
20
|
-
This code creates a function called `multiply` that takes two arguments `x` and `y`, and returns the product of `x` and `y`.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
"""
|
|
32
|
-
return prompt
|
|
20
|
+
This code creates a function called `multiply` that takes two arguments `x` and `y`, and returns the product of `x` and `y`."""
|
|
21
|
+
sections.append(SG.Example("Example", example_content))
|
|
22
|
+
|
|
23
|
+
# Add actual code section
|
|
24
|
+
sections.append(SG.ActiveCellCode(active_cell_code))
|
|
25
|
+
|
|
26
|
+
# Add output prompt
|
|
27
|
+
sections.append(SG.Task("Output:"))
|
|
28
|
+
|
|
29
|
+
prompt = Prompt(sections)
|
|
30
|
+
return str(prompt)
|
|
@@ -2,11 +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.
|
|
6
|
-
|
|
7
|
-
VARIABLES_SECTION_HEADING,
|
|
8
|
-
CODE_SECTION_HEADING
|
|
9
|
-
)
|
|
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
|
|
10
7
|
|
|
11
8
|
|
|
12
9
|
def create_inline_prompt(
|
|
@@ -15,10 +12,10 @@ def create_inline_prompt(
|
|
|
15
12
|
variables: List[str],
|
|
16
13
|
files: List[str]
|
|
17
14
|
) -> str:
|
|
18
|
-
|
|
19
|
-
files_str = '\n'.join([f"file_name: {file}" for file in files])
|
|
15
|
+
sections: List[PromptSection] = []
|
|
20
16
|
|
|
21
|
-
|
|
17
|
+
# Add intro text
|
|
18
|
+
sections.append(SG.Task("""You are a coding assistant that lives inside of JupyterLab. Your job is to help the user write code.
|
|
22
19
|
|
|
23
20
|
You're given the current code cell, the user's cursor position, and the variables defined in the notebook. The user's cursor is signified by the symbol <cursor>.
|
|
24
21
|
|
|
@@ -27,28 +24,30 @@ CRITICAL FORMATTING RULES:
|
|
|
27
24
|
2. If you are finishing a line of code that the user started, return the full line of code with no newline character at the start or end.
|
|
28
25
|
3. Your response must preserve correct Python indentation and spacing. For example, if you're completing a line of indented code, you must preserve the indentation.
|
|
29
26
|
|
|
30
|
-
Your job is to complete the code that matches the user's intent. Write the minimal code to achieve the user's intent. Don't expand upon the user's intent.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
27
|
+
Your job is to complete the code that matches the user's intent. Write the minimal code to achieve the user's intent. Don't expand upon the user's intent."""))
|
|
28
|
+
|
|
29
|
+
# Example 1
|
|
30
|
+
example1_content = f"""
|
|
31
|
+
Files:
|
|
32
|
+
"file_name: sales.csv"
|
|
35
33
|
|
|
36
|
-
|
|
34
|
+
Variables:
|
|
37
35
|
{{
|
|
38
36
|
'loan_multiplier': 1.5,
|
|
39
|
-
'sales_df': pd.DataFrame({
|
|
37
|
+
'sales_df': pd.DataFrame({
|
|
40
38
|
'transaction_date': ['2024-01-02', '2024-01-02', '2024-01-02', '2024-01-02', '2024-01-03'],
|
|
41
39
|
'price_per_unit': [10, 9.99, 13.99, 21.00, 100],
|
|
42
40
|
'units_sold': [1, 2, 1, 4, 5],
|
|
43
41
|
'total_price': [10, 19.98, 13.99, 84.00, 500]
|
|
44
|
-
}
|
|
42
|
+
})
|
|
45
43
|
}}
|
|
46
44
|
|
|
47
|
-
|
|
45
|
+
Active Cell Code:
|
|
48
46
|
```python
|
|
49
47
|
import pandas as pd
|
|
50
48
|
sales_df = pd.read_csv('./sales.csv')
|
|
51
49
|
|
|
50
|
+
|
|
52
51
|
# Multiply the total_price column by the loan_multiplier<cursor>
|
|
53
52
|
```
|
|
54
53
|
|
|
@@ -57,23 +56,22 @@ Output:
|
|
|
57
56
|
|
|
58
57
|
sales_df['total_price'] = sales_df['total_price'] * loan_multiplier
|
|
59
58
|
```
|
|
60
|
-
</Example 1>
|
|
61
59
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
<Example 2>
|
|
65
|
-
{FILES_SECTION_HEADING}
|
|
60
|
+
Notice in Example 1 that the output starts with a newline because the cursor was at the end of a comment. This newline is REQUIRED to maintain proper Python formatting."""
|
|
66
61
|
|
|
62
|
+
sections.append(SG.Example("Example 1", example1_content))
|
|
63
|
+
|
|
64
|
+
# Example 2
|
|
65
|
+
example2_content = """
|
|
66
|
+
Files:
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
{
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}})
|
|
74
|
-
}}
|
|
68
|
+
Variables:
|
|
69
|
+
df: pd.DataFrame({
|
|
70
|
+
'age': [20, 25, 22, 23, 29],
|
|
71
|
+
'name': ['Nawaz', 'Aaron', 'Charlie', 'Tamir', 'Eve'],
|
|
72
|
+
})
|
|
75
73
|
|
|
76
|
-
|
|
74
|
+
Active Cell Code:
|
|
77
75
|
```python
|
|
78
76
|
df['age'] = df[<cursor>['age'] > 23]
|
|
79
77
|
```
|
|
@@ -82,18 +80,20 @@ Output:
|
|
|
82
80
|
```python
|
|
83
81
|
df['age'] = df[df['age'] > 23]
|
|
84
82
|
```
|
|
85
|
-
</Example 2>
|
|
86
|
-
|
|
87
|
-
IMPORTANT: Notice in Example 2 that the output does NOT start with a newline because the cursor is in the middle of existing code.
|
|
88
83
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
84
|
+
IMPORTANT: Notice in Example 2 that the output does NOT start with a newline because the cursor is in the middle of existing code."
|
|
85
|
+
"""
|
|
86
|
+
sections.append(SG.Example("Example 2", example2_content))
|
|
87
|
+
|
|
88
|
+
# Example 3
|
|
89
|
+
example3_content = f"""
|
|
90
|
+
Files:
|
|
91
|
+
"file_name: voters.csv"
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
Variables:
|
|
94
94
|
{{}}
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
Active Cell Code:
|
|
97
97
|
```python
|
|
98
98
|
voters = pd.read_csv('./voters.csv')
|
|
99
99
|
|
|
@@ -108,90 +108,61 @@ ohio_voters = voters[voters['state'] == 'OH']
|
|
|
108
108
|
ca_voters = voters[voters['state'] == 'CA']
|
|
109
109
|
tx_voters = voters[voters['state'] == 'TX']
|
|
110
110
|
```
|
|
111
|
-
</Example 3>
|
|
112
|
-
|
|
113
|
-
IMPORTANT: Notice in Example 3 that output does not start with a newline character because it wasnts to continue the line of code that the user started. Also notice the output contains three lines of code because that is the minimal code to achieve the user's intent.
|
|
114
111
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
112
|
+
IMPORTANT: Notice in Example 3 that output does not start with a newline character because it wasnts to continue the line of code that the user started. Also notice the output contains three lines of code because that is the minimal code to achieve the user's intent."""
|
|
113
|
+
sections.append(SG.Example("Example 3", example3_content))
|
|
114
|
+
|
|
115
|
+
# Example 4
|
|
116
|
+
example4_content = f"""
|
|
117
|
+
Files:
|
|
118
|
+
"file_name: july_2025.xlsx"
|
|
119
|
+
"file_name: august_2025.xlsx"
|
|
119
120
|
|
|
120
|
-
|
|
121
|
+
Variables:
|
|
121
122
|
{{}}
|
|
122
123
|
|
|
123
|
-
|
|
124
|
+
Active Cell Code:
|
|
124
125
|
```python
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
```python
|
|
132
|
-
```
|
|
133
|
-
</Example 4>
|
|
134
|
-
|
|
135
|
-
IMPORTANT: Notice in Example 4 that the output is empty becuase the user's intent is already complete.
|
|
136
|
-
|
|
137
|
-
<Example 5>
|
|
138
|
-
{FILES_SECTION_HEADING}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
{VARIABLES_SECTION_HEADING}
|
|
126
|
+
```"""
|
|
127
|
+
sections.append(SG.Example("Example 4", example4_content))
|
|
128
|
+
|
|
129
|
+
# Example 5
|
|
130
|
+
example5_content = f"""
|
|
131
|
+
Files:
|
|
142
132
|
{{}}
|
|
143
133
|
|
|
144
|
-
|
|
134
|
+
Active Cell Code:
|
|
145
135
|
```python
|
|
146
|
-
def even_and_odd():
|
|
147
|
-
for i in range(10):
|
|
148
|
-
if i % 2 == 0:
|
|
149
|
-
print(f"Even: {{i}}")
|
|
150
|
-
else:
|
|
151
|
-
pri<cursor>
|
|
136
|
+
def even_and_odd():\n for i in range(10):\n if i % 2 == 0:\n print(f\"Even: {{i}}\")\n else:\n pri<cursor>
|
|
152
137
|
```
|
|
153
138
|
|
|
154
139
|
Output:
|
|
155
|
-
```python
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
<Example 6>
|
|
163
|
-
{FILES_SECTION_HEADING}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
{VARIABLES_SECTION_HEADING}
|
|
140
|
+
```python"""
|
|
141
|
+
sections.append(SG.Example("Example 5", example5_content))
|
|
142
|
+
|
|
143
|
+
# Example 6
|
|
144
|
+
example6_content = f"""
|
|
145
|
+
Files:
|
|
167
146
|
{{}}
|
|
168
147
|
|
|
169
|
-
|
|
170
|
-
```python
|
|
171
|
-
days_in_week <cursor>
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
Output:
|
|
148
|
+
Active Cell Code:
|
|
175
149
|
```python
|
|
176
150
|
days_in_week = 7
|
|
177
151
|
```
|
|
178
|
-
</Example 6>
|
|
179
|
-
|
|
180
|
-
IMPORTANT: Notice in Example 6 that inorder to finish the variable declaration, the output continues the existing line of code and does not start with a new line character.
|
|
181
152
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
153
|
+
IMPORTANT: Notice in Example 6 that inorder to finish the variable declaration, the output continues the existing line of code and does not start with a new line character."""
|
|
154
|
+
sections.append(SG.Example("Example 6", example6_content))
|
|
155
|
+
|
|
156
|
+
# Add task sections
|
|
157
|
+
sections.append(SG.Task("Your Task:"))
|
|
158
|
+
|
|
159
|
+
sections.append(SG.Files(files))
|
|
160
|
+
sections.append(SG.Variables(variables))
|
|
161
|
+
|
|
162
|
+
code_content = f"{prefix}<cursor>{suffix}\n"
|
|
163
|
+
sections.append(SG.ActiveCellCode(code_content))
|
|
164
|
+
|
|
165
|
+
sections.append(SG.Task("Output:"))
|
|
194
166
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
return prompt
|
|
167
|
+
prompt = Prompt(sections)
|
|
168
|
+
return str(prompt)
|