diff --git a/src/ibis_birdbrain/attachments/__init__.py b/src/ibis_birdbrain/attachments/__init__.py index fab0592..82faee1 100644 --- a/src/ibis_birdbrain/attachments/__init__.py +++ b/src/ibis_birdbrain/attachments/__init__.py @@ -99,6 +99,7 @@ def __repr__(self): from ibis_birdbrain.attachments.text import ( TextAttachment, CodeAttachment, + ErrorAttachment, WebpageAttachment, ) @@ -110,5 +111,6 @@ def __repr__(self): "ChartAttachment", "TextAttachment", "CodeAttachment", + "ErrorAttachment", "WebpageAttachment", ] diff --git a/src/ibis_birdbrain/attachments/text.py b/src/ibis_birdbrain/attachments/text.py index c3937b3..02df5c8 100644 --- a/src/ibis_birdbrain/attachments/text.py +++ b/src/ibis_birdbrain/attachments/text.py @@ -97,3 +97,24 @@ def __str__(self): **language**: {self.language} **code**:\n{self.content}""" ) + +class ErrorAttachment(TextAttachment): + """An error attachment.""" + + content: str + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + def encode(self): + ... + + def decode(self): + ... + + def __str__(self): + return ( + super().__str__() + + f""" + **error**:\n{self.content}""" + ) \ No newline at end of file diff --git a/src/ibis_birdbrain/bot.py b/src/ibis_birdbrain/bot.py index fdceb69..1d7f789 100644 --- a/src/ibis_birdbrain/bot.py +++ b/src/ibis_birdbrain/bot.py @@ -16,6 +16,7 @@ Attachments, TableAttachment, CodeAttachment, + ErrorAttachment, ) from ibis_birdbrain.messages import Message, Messages, Email from ibis_birdbrain.utils.messages import to_message @@ -84,8 +85,8 @@ class Flows(Enum): VISUALIZE = "visualize" -class EDAFlows(Enum): - """Ibis Birdbrain EDA flows.""" +class SQLFlows(Enum): + """Ibis Birdbrain SQL flows.""" GET_CODE = "get_code" FIX_CODE = "fix_code" @@ -102,7 +103,7 @@ def respond(messages: Messages) -> str: @marvin.fn def messages_to_text_query(messages: Messages) -> str: """Convert the messages to an English text query. - + Returns the English prose that concisely describes the desired query. """ @@ -120,61 +121,6 @@ def text_to_sql(text: str, attachments: Attachments) -> str: return _text_to_sql(text, attachments).strip().strip(";") -def respond_flow(messages: Messages) -> Messages: - pass - - -def sql_flow(messages: Messages) -> Messages: - extract_guid_instructions = f""" - Extract relevant attachment GUIDs (ONLY the ATTACHMENT GUIDs) from the messages. - - Options include: {messages.attachments()} - """ - - rm = Messages() - - extract_guid_instructions = inspect.cleandoc(extract_guid_instructions) - - guids = marvin.extract( - messages, - str, - instructions=extract_guid_instructions, - ) - log.info(f"Extracted GUIDs: {guids}") - - # get the attachments - attachments = Attachments() - # TODO: fix this ugliness - for guid in guids: - for message in messages: - if guid in messages[message].attachments: - attachments.append(messages[message].attachments[guid]) - log.info(f"Attachments: {attachments}") - - # get the text query - text_query = messages_to_text_query(messages) - - # convert the text to SQL - sql = text_to_sql(text_query, attachments) - a = CodeAttachment(language="sql", content=sql) - - # construct the response message - m = Email( - body=f"SQL attachted for query: {text_query}", - subject="SQL code", - attachments=[a], - ) - - # append the message to the response messages - rm.append(m) - - return rm - - -def visualize_flow(messages: Messages) -> Messages: - pass - - # bot class Bot: """Ibis Birdbrain bot.""" @@ -253,22 +199,85 @@ def __call__( match flow: case Flows.RESPOND: - response = respond(self.messages) - m = Email( - body=response, - subject="response", - to_address=self.user_name, - from_address=self.name, - ) - self.messages.append(m) + self.respond_flow() case Flows.SQL_CODE: - ms = sql_flow(self.messages) + self.sql_flow() + self.respond_flow() + # append the table attachment(s) to the response message # TODO: fix this ugliness - for m in ms: - self.messages.append(ms[m]) + for attachment in self.messages[-2].attachments: + if isinstance( + self.messages[-2].attachments[attachment], TableAttachment + ): + self.messages[-1].attachments.append( + self.messages[-2].attachments[attachment] + ) case Flows.VISUALIZE: pass case _: pass return self.messages[-1] + + def sql_flow(self) -> None: + extract_guid_instructions = f""" + Extract relevant attachment GUIDs (ONLY the ATTACHMENT GUIDs) from the messages. + + Options include: {self.messages.attachments()} + """ + + extract_guid_instructions = inspect.cleandoc(extract_guid_instructions) + + guids = marvin.extract( + self.messages, + str, + instructions=extract_guid_instructions, + ) + log.info(f"Extracted GUIDs: {guids}") + + # get the attachments + attachments = Attachments() + # TODO: fix this ugliness + for guid in guids: + for message in self.messages: + if guid in self.messages[message].attachments: + attachments.append(self.messages[message].attachments[guid]) + # log.info(f"Attachments: {attachments}") + + # get the text query + text_query = messages_to_text_query(self.messages) + + # convert the text to SQL + sql = text_to_sql(text_query, attachments) + a = CodeAttachment(language="sql", content=sql) + + # run the SQL + try: + t = self.con.sql(sql) + at = TableAttachment(t) + except Exception as e: + at = ErrorAttachment(e) + log.error(f"SQL error: {e}") + + # construct the response message + m = Email( + body=f"SQL attachted for query: {text_query}", + subject="SQL code", + attachments=[a, at], + ) + + # append the message to the response messages + self.messages.append(m) + + def respond_flow(self) -> None: + response = respond(self.messages) + m = Email( + body=response, + subject="response", + to_address=self.user_name, + from_address=self.name, + ) + self.messages.append(m) + + def visualize_flow(self) -> None: + pass diff --git a/untitled.ipynb b/untitled.ipynb index 7652398..af5d711 100644 --- a/untitled.ipynb +++ b/untitled.ipynb @@ -57,34 +57,41 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "1" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "len(bot.messages)" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "bot(\"describe the data\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "bot(\"what's the extact schema? give me all the columns and their types\")" + ] + }, + { + "cell_type": "code", + "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "INFO:root:Bot birdbrain called with text: describe the data\n" + "INFO:root:Bot birdbrain called with text: what's the average interest rate?\n" ] }, { @@ -102,7 +109,7 @@ "output_type": "stream", "text": [ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n", - "INFO:root:Bot birdbrain selected flow: Flows.RESPOND\n" + "INFO:root:Bot birdbrain selected flow: Flows.SQL_CODE\n" ] }, { @@ -119,43 +126,8 @@ "name": "stderr", "output_type": "stream", "text": [ - "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n" - ] - }, - { - "data": { - "text/plain": [ - "To: user\n", - "From: birdbrain\n", - "Subject: response\n", - "Sent at: 2024-02-12 21:14:13.606857\n", - "Message: 9f35f048-ef48-42c1-bd7c-65ee2ce3da38\n", - "\n", - "The 'mortgage' table reflects a dataset providing information on mortgage loans. Each row represents a loan with fields describing various attributes such as loan ID, seller and servicer names, interest rates, outstanding balance, loan terms, and borrower information. Additionally, it details loan performance, including payment history, current delinquency status, and any foreclosure proceedings. The table also contains data on loan modifications, property valuation, and recovery proceeds, enabling analysis regarding the mortgage portfolio's health and performance.\n", - "\n", - "Attachments:\n", - "\n" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "bot(\"describe the data\")" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "INFO:root:Bot birdbrain called with text: what's the average interest rate?\n" + "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n", + "INFO:root:Extracted GUIDs: ['8cd54641-150d-4fc2-b32e-f89916c16f53']\n" ] }, { @@ -172,8 +144,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n", - "INFO:root:Bot birdbrain selected flow: Flows.SQL_CODE\n" + "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n" ] }, { @@ -190,8 +161,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n", - "INFO:root:Extracted GUIDs: ['e9f1ae72-0693-4a70-adde-9af181c5bf51']\n" + "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n" ] }, { @@ -204,155 +174,6 @@ "metadata": {}, "output_type": "display_data" }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "INFO:root:Attachments: TableAttachment\n", - " **guid**: e9f1ae72-0693-4a70-adde-9af181c5bf51\n", - " **time**: 2024-02-12 21:13:53.864277\n", - " **name**: mortgage\n", - " **desc**: \n", - "ibis.Schema {\n", - " reference_pool_id string\n", - " loan_id string\n", - " monthly_reporting_period string\n", - " channel string\n", - " seller_name string\n", - " servicer_name string\n", - " master_servicer string\n", - " original_interest_rate float64\n", - " current_interest_rate float64\n", - " original_upb float64\n", - " upb_at_issuance float64\n", - " current_upb float64\n", - " original_loan_term int32\n", - " origination_date string\n", - " first_payment_date string\n", - " loan_age int64\n", - " remaining_months_to_legal_maturity int32\n", - " remaining_months_to_maturity int32\n", - " maturity_date string\n", - " original_ltv int64\n", - " original_cltv int64\n", - " number_of_borrowers int32\n", - " dti float64\n", - " borrower_credit_score_at_origination int32\n", - " coborrower_credit_score_at_origination int32\n", - " first_time_buyer string\n", - " loan_purpose string\n", - " property_type string\n", - " number_of_units int64\n", - " occupancy_status string\n", - " property_state string\n", - " msa string\n", - " zip string\n", - " mortgage_issuance_percentage float64\n", - " amortization_type string\n", - " payment_penalty_flag string\n", - " interest_only_flag string\n", - " interest_only_first_payment string\n", - " months_to_amortization int32\n", - " current_loan_delinquency_status string\n", - " loan_payment_history string\n", - " modification_flag string\n", - " mortgage_insurance_cancellation_flag string\n", - " zero_balance_code string\n", - " zero_balance_effective_date string\n", - " upb_at_removal float64\n", - " repurchase_date string\n", - " scheduled_principal_current float64\n", - " total_principal_current float64\n", - " unscheduled_principal_current float64\n", - " last_paid_installment_date string\n", - " foreclosure_date string\n", - " disposition_date string\n", - " foreclosure_costs float64\n", - " preservation_repair_costs float64\n", - " asset_recovery_costs float64\n", - " misc_holding_expenses float64\n", - " taxes_holding_property float64\n", - " net_sales_proceeds float64\n", - " credit_enhancement_proceeds float64\n", - " repurchase_make_whole_proceeds float64\n", - " other_foreclosure_proceeds float64\n", - " modification_noninterest_bearing_upb float64\n", - " principal_foregiveness_amount float64\n", - " original_list_start_date string\n", - " original_list_price int64\n", - " current_list_start_date string\n", - " current_list_price int64\n", - " borrower_credit_score_at_issuance int32\n", - " coborrower_credit_score_at_issuance int32\n", - " borrower_credit_score_current int32\n", - " coborrower_credit_score_current int32\n", - " mortgage_insurance_type string\n", - " servicing_activity_flag string\n", - " current_period_modification_loss_amount float64\n", - " cumulative_modification_loss_amount float64\n", - " current_period_net_gain_loss float64\n", - " cumulative_period_net_gain_loss float64\n", - " special_eligibility_program string\n", - " foreclosure_principal_writeoff_amount float64\n", - " relocation_mortgage_indicator string\n", - " zero_balance_code_change_date string\n", - " loan_holdback_flag string\n", - " loan_holdback_effective_date string\n", - " delinquent_accrued_interest float64\n", - " property_valuation_method string\n", - " high_balance_loan_indicator string\n", - " arm_initial_rate_period_less_than_5y string\n", - " arm_product_type string\n", - " initial_fixed_rate_period int32\n", - " interest_rate_adjustment_frequency int32\n", - " next_interest_rate_adjustment_date string\n", - " next_payment_change_date string\n", - " index string\n", - " arm_cap_structure string\n", - " initial_interest_rate_cap_up_percent float64\n", - " periodic_interest_rate_cap_up_percent float64\n", - " lifetime_interest_rate_cap_up_percent float64\n", - " mortgage_margin float64\n", - " arm_baloon_indicator string\n", - " arm_plan_number int32\n", - " borrower_assistance_plan string\n", - " hltv_refi_option_flag string\n", - " deal_name string\n", - " repurchase_make_whole_proceeds_flag string\n", - " alternative_delinquency_resolution string\n", - " alternative_delinquency_resolution_count int32\n", - " total_deferral_amount float64\n", - "}\n", - " **table**:\n", - "┏━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳\n", - "┃\u001b[1m \u001b[0m\u001b[1mreference_pool_id\u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mloan_id\u001b[0m\u001b[1m \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mmonthly_reporting_period\u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mchannel\u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mseller_name\u001b[0m\u001b[1m \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mservicer_name\u001b[0m\u001b[1m \u001b[0m┃\n", - "┡━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇\n", - "│ \u001b[2mstring\u001b[0m │ \u001b[2mstring\u001b[0m │ \u001b[2mstring\u001b[0m │ \u001b[2mstring\u001b[0m │ \u001b[2mstring\u001b[0m │ \u001b[2mstring\u001b[0m │\n", - "├───────────────────┼──────────────┼──────────────────────────┼─────────┼─────────────────────────┼───────────────┼\n", - "│ \u001b[2m~\u001b[0m │ \u001b[32m100007365142\u001b[0m │ \u001b[32m012000 \u001b[0m │ \u001b[32mR \u001b[0m │ \u001b[32mJpmorgan Chase Bank, Na\u001b[0m │ \u001b[2m~\u001b[0m │\n", - "│ \u001b[2m~\u001b[0m │ \u001b[32m100007365142\u001b[0m │ \u001b[32m022000 \u001b[0m │ \u001b[32mR \u001b[0m │ \u001b[32mJpmorgan Chase Bank, Na\u001b[0m │ \u001b[2m~\u001b[0m │\n", - "│ \u001b[2m~\u001b[0m │ \u001b[32m100007365142\u001b[0m │ \u001b[32m032000 \u001b[0m │ \u001b[32mR \u001b[0m │ \u001b[32mJpmorgan Chase Bank, Na\u001b[0m │ \u001b[2m~\u001b[0m │\n", - "│ \u001b[2m~\u001b[0m │ \u001b[32m100007365142\u001b[0m │ \u001b[32m042000 \u001b[0m │ \u001b[32mR \u001b[0m │ \u001b[32mJpmorgan Chase Bank, Na\u001b[0m │ \u001b[2m~\u001b[0m │\n", - "│ \u001b[2m~\u001b[0m │ \u001b[32m100007365142\u001b[0m │ \u001b[32m052000 \u001b[0m │ \u001b[32mR \u001b[0m │ \u001b[32mJpmorgan Chase Bank, Na\u001b[0m │ \u001b[2m~\u001b[0m │\n", - "│ \u001b[2m~\u001b[0m │ \u001b[32m100007365142\u001b[0m │ \u001b[32m062000 \u001b[0m │ \u001b[32mR \u001b[0m │ \u001b[32mJpmorgan Chase Bank, Na\u001b[0m │ \u001b[2m~\u001b[0m │\n", - "│ \u001b[2m~\u001b[0m │ \u001b[32m100007365142\u001b[0m │ \u001b[32m072000 \u001b[0m │ \u001b[32mR \u001b[0m │ \u001b[32mJpmorgan Chase Bank, Na\u001b[0m │ \u001b[2m~\u001b[0m │\n", - "│ \u001b[2m~\u001b[0m │ \u001b[32m100007365142\u001b[0m │ \u001b[32m082000 \u001b[0m │ \u001b[32mR \u001b[0m │ \u001b[32mJpmorgan Chase Bank, Na\u001b[0m │ \u001b[2m~\u001b[0m │\n", - "│ \u001b[2m~\u001b[0m │ \u001b[32m100007365142\u001b[0m │ \u001b[32m092000 \u001b[0m │ \u001b[32mR \u001b[0m │ \u001b[32mJpmorgan Chase Bank, Na\u001b[0m │ \u001b[2m~\u001b[0m │\n", - "│ \u001b[2m~\u001b[0m │ \u001b[32m100007365142\u001b[0m │ \u001b[32m102000 \u001b[0m │ \u001b[32mR \u001b[0m │ \u001b[32mJpmorgan Chase Bank, Na\u001b[0m │ \u001b[2m~\u001b[0m │\n", - "│ \u001b[2m~\u001b[0m │ \u001b[32m100007365142\u001b[0m │ \u001b[32m112000 \u001b[0m │ \u001b[32mR \u001b[0m │ \u001b[32mJpmorgan Chase Bank, Na\u001b[0m │ \u001b[2m~\u001b[0m │\n", - "│ \u001b[2m~\u001b[0m │ \u001b[32m100007365142\u001b[0m │ \u001b[32m122000 \u001b[0m │ \u001b[32mR \u001b[0m │ \u001b[32mJpmorgan Chase Bank, Na\u001b[0m │ \u001b[2m~\u001b[0m │\n", - "│ \u001b[2m~\u001b[0m │ \u001b[32m100007365142\u001b[0m │ \u001b[32m012001 \u001b[0m │ \u001b[32mR \u001b[0m │ \u001b[32mJpmorgan Chase Bank, Na\u001b[0m │ \u001b[2m~\u001b[0m │\n", - "│ \u001b[2m~\u001b[0m │ \u001b[32m100007365142\u001b[0m │ \u001b[32m022001 \u001b[0m │ \u001b[32mR \u001b[0m │ \u001b[32mJpmorgan Chase Bank, Na\u001b[0m │ \u001b[2m~\u001b[0m │\n", - "│ \u001b[2m~\u001b[0m │ \u001b[32m100007365142\u001b[0m │ \u001b[32m032001 \u001b[0m │ \u001b[32mR \u001b[0m │ \u001b[32mJpmorgan Chase Bank, Na\u001b[0m │ \u001b[2m~\u001b[0m │\n", - "│ \u001b[2m~\u001b[0m │ \u001b[32m100007365142\u001b[0m │ \u001b[32m042001 \u001b[0m │ \u001b[32mR \u001b[0m │ \u001b[32mJpmorgan Chase Bank, Na\u001b[0m │ \u001b[2m~\u001b[0m │\n", - "│ \u001b[2m~\u001b[0m │ \u001b[32m100007365142\u001b[0m │ \u001b[32m052001 \u001b[0m │ \u001b[32mR \u001b[0m │ \u001b[32mJpmorgan Chase Bank, Na\u001b[0m │ \u001b[2m~\u001b[0m │\n", - "│ \u001b[2m~\u001b[0m │ \u001b[32m100007365142\u001b[0m │ \u001b[32m062001 \u001b[0m │ \u001b[32mR \u001b[0m │ \u001b[32mJpmorgan Chase Bank, Na\u001b[0m │ \u001b[2m~\u001b[0m │\n", - "│ \u001b[2m~\u001b[0m │ \u001b[32m100007365142\u001b[0m │ \u001b[32m072001 \u001b[0m │ \u001b[32mR \u001b[0m │ \u001b[32mJpmorgan Chase Bank, Na\u001b[0m │ \u001b[2m~\u001b[0m │\n", - "│ \u001b[2m~\u001b[0m │ \u001b[32m100007365142\u001b[0m │ \u001b[32m082001 \u001b[0m │ \u001b[32mR \u001b[0m │ \u001b[32mJpmorgan Chase Bank, Na\u001b[0m │ \u001b[2m~\u001b[0m │\n", - "│ \u001b[2m…\u001b[0m │ \u001b[2m…\u001b[0m │ \u001b[2m…\u001b[0m │ \u001b[2m…\u001b[0m │ \u001b[2m…\u001b[0m │ \u001b[2m…\u001b[0m │\n", - "└───────────────────┴──────────────┴──────────────────────────┴─────────┴─────────────────────────┴───────────────┴\n" - ] - }, { "data": { "text/html": [ @@ -380,36 +201,82 @@ "metadata": {}, "output_type": "display_data" }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n" - ] - }, { "data": { "text/plain": [ - "To: \n", - "From: \n", - "Subject: SQL code\n", - "Sent at: 2024-02-12 21:14:37.107152\n", - "Message: 07cef6a7-551b-44e7-9f50-ba9a62f70035\n", + "To: user\n", + "From: birdbrain\n", + "Subject: response\n", + "Sent at: 2024-02-13 09:30:33.592647\n", + "Message: 109fdc7a-588d-48e4-a33b-f1949060305d\n", "\n", - "SQL attachted for query: The query is to calculate the average current interest rate across all loans in the 'mortgage' table.\n", + "The average original interest rate is 7.960559 and the average current interest rate is 7.928592.\n", "\n", "Attachments:\n", "\n", - "CodeAttachment\n", - " **guid**: 9db96d25-afe9-4926-b24a-b3f5d0176ecc\n", - " **time**: 2024-02-12 21:14:37.107135\n", + "TableAttachment\n", + " **guid**: 4b2d1a99-3e13-4d06-836b-e2b81357fd9d\n", + " **time**: 2024-02-13 09:30:28.500084\n", + " **name**: None\n", + " **desc**: \n", + "ibis.Schema {\n", + " avg_original_interest_rate float64\n", + " avg_current_interest_rate float64\n", + "}\n", + " **table**:\n", + "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n", + "┃\u001b[1m \u001b[0m\u001b[1mavg_original_interest_rate\u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mavg_current_interest_rate\u001b[0m\u001b[1m \u001b[0m┃\n", + "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n", + "│ \u001b[2mfloat64\u001b[0m │ \u001b[2mfloat64\u001b[0m │\n", + "├────────────────────────────┼───────────────────────────┤\n", + "│ \u001b[1;36m7.960559\u001b[0m │ \u001b[1;36m7.928592\u001b[0m │\n", + "└────────────────────────────┴───────────────────────────┘" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bot(\"what's the average interest rate (original and current)?\")" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "TableAttachment\n",
+       "    **guid**: 4b2d1a99-3e13-4d06-836b-e2b81357fd9d\n",
+       "    **time**: 2024-02-13 09:30:28.500084\n",
        "    **name**: None\n",
-       "    **desc**: None\n",
-       "    **text**:\n",
-       "SELECT AVG(current_interest_rate) FROM mortgage\n",
-       "    **language**: sql\n",
-       "    **code**:\n",
-       "SELECT AVG(current_interest_rate) FROM mortgage"
+       "    **desc**: \n",
+       "ibis.Schema {\n",
+       "  avg_original_interest_rate  float64\n",
+       "  avg_current_interest_rate   float64\n",
+       "}\n",
+       "    **table**:\n",
+       "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n",
+       "┃\u001b[1m \u001b[0m\u001b[1mavg_original_interest_rate\u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mavg_current_interest_rate\u001b[0m\u001b[1m \u001b[0m┃\n",
+       "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n",
+       "│ \u001b[2mfloat64\u001b[0m                    │ \u001b[2mfloat64\u001b[0m                   │\n",
+       "├────────────────────────────┼───────────────────────────┤\n",
+       "│                   \u001b[1;36m7.960559\u001b[0m │                  \u001b[1;36m7.928592\u001b[0m │\n",
+       "└────────────────────────────┴───────────────────────────┘"
       ]
      },
      "execution_count": 7,
@@ -418,7 +285,8 @@
     }
    ],
    "source": [
-    "bot(\"what's the average interest rate?\")"
+    "a = bot.messages[-1].attachments[0]\n",
+    "a"
    ]
   },
   {
@@ -429,23 +297,23 @@
     {
      "data": {
       "text/html": [
-       "
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n",
-       "┃ avg(current_interest_rate) ┃\n",
-       "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n",
-       "│ float64                    │\n",
-       "├────────────────────────────┤\n",
-       "│                   7.928592 │\n",
-       "└────────────────────────────┘\n",
+       "
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n",
+       "┃ avg_original_interest_rate  avg_current_interest_rate ┃\n",
+       "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n",
+       "│ float64float64                   │\n",
+       "├────────────────────────────┼───────────────────────────┤\n",
+       "│                   7.9605597.928592 │\n",
+       "└────────────────────────────┴───────────────────────────┘\n",
        "
\n" ], "text/plain": [ - "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n", - "┃\u001b[1m \u001b[0m\u001b[1mavg(current_interest_rate)\u001b[0m\u001b[1m \u001b[0m┃\n", - "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n", - "│ \u001b[2mfloat64\u001b[0m │\n", - "├────────────────────────────┤\n", - "│ \u001b[1;36m7.928592\u001b[0m │\n", - "└────────────────────────────┘" + "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n", + "┃\u001b[1m \u001b[0m\u001b[1mavg_original_interest_rate\u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mavg_current_interest_rate\u001b[0m\u001b[1m \u001b[0m┃\n", + "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n", + "│ \u001b[2mfloat64\u001b[0m │ \u001b[2mfloat64\u001b[0m │\n", + "├────────────────────────────┼───────────────────────────┤\n", + "│ \u001b[1;36m7.960559\u001b[0m │ \u001b[1;36m7.928592\u001b[0m │\n", + "└────────────────────────────┴───────────────────────────┘" ] }, "execution_count": 8, @@ -453,9 +321,20 @@ "output_type": "execute_result" } ], + "source": [ + "t = a.open()\n", + "t" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "#bot.con.sql(\"SELECT AVG(original_interest_rate) as average_interest_rate FROM mortgage\")\n", - "bot.con.sql(\"SELECT AVG(current_interest_rate) FROM mortgage\")" + "bot.con.sql(\"SELECT AVG(current_interest_rate) FROM mortgage\")\n", + "#bot.con.sql(\"SELECT AVG(original_interest_rate) AS avg_original_interest_rate, AVG(current_interest_rate) AS avg_current_interest_rate FROM mortgage\")" ] }, {