diff --git a/deploy_ai_search/text_2_sql_query_cache.py b/deploy_ai_search/text_2_sql_query_cache.py index 18296c6..4c685cf 100644 --- a/deploy_ai_search/text_2_sql_query_cache.py +++ b/deploy_ai_search/text_2_sql_query_cache.py @@ -7,6 +7,10 @@ SearchableField, SimpleField, ComplexField, + SemanticField, + SemanticPrioritizedFields, + SemanticConfiguration, + SemanticSearch, ) from ai_search import AISearch from environment import ( @@ -107,3 +111,22 @@ def get_index_fields(self) -> list[SearchableField]: ] return fields + + def get_semantic_search(self) -> SemanticSearch: + """This function returns the semantic search configuration for sql index + + Returns: + SemanticSearch: The semantic search configuration""" + + semantic_config = SemanticConfiguration( + name=self.semantic_config_name, + prioritized_fields=SemanticPrioritizedFields( + content_fields=[ + SemanticField(field_name="Question"), + ], + ), + ) + + semantic_search = SemanticSearch(configurations=[semantic_config]) + + return semantic_search diff --git a/text_2_sql/autogen/README.md b/text_2_sql/autogen/README.md new file mode 100644 index 0000000..4b05a49 --- /dev/null +++ b/text_2_sql/autogen/README.md @@ -0,0 +1,3 @@ +# Multi-Shot Text2SQL Component - AutoGen + +Very much still work in progress, more documentation coming soon. diff --git a/text_2_sql/autogen/agentic_text_2_sql.ipynb b/text_2_sql/autogen/agentic_text_2_sql.ipynb new file mode 100644 index 0000000..3a14137 --- /dev/null +++ b/text_2_sql/autogen/agentic_text_2_sql.ipynb @@ -0,0 +1,80 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import dotenv\n", + "import logging\n", + "from autogen_agentchat.task import Console\n", + "from agentic_text_2_sql import text_2_sql_generator" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "logging.basicConfig(level=logging.INFO)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "dotenv.load_dotenv()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "result = text_2_sql_generator.run_stream(task=\"What are the total number of sales within 2008?\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "await Console(result)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.6" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/text_2_sql/autogen/agentic_text_2_sql.py b/text_2_sql/autogen/agentic_text_2_sql.py new file mode 100644 index 0000000..ada9b05 --- /dev/null +++ b/text_2_sql/autogen/agentic_text_2_sql.py @@ -0,0 +1,81 @@ +from autogen_agentchat.task import TextMentionTermination, MaxMessageTermination +from autogen_agentchat.teams import SelectorGroupChat +from utils.models import MINI_MODEL +from utils.llm_agent_creator import LLMAgentCreator +import logging +from custom_agents.sql_query_cache_agent import SqlQueryCacheAgent +import json + +SQL_QUERY_GENERATION_AGENT = LLMAgentCreator.create( + "sql_query_generation_agent", + target_engine="Microsoft SQL Server", + engine_specific_rules="Use TOP X to limit the number of rows returned instead of LIMIT X. NEVER USE LIMIT X as it produces a syntax error.", +) +SQL_SCHEMA_SELECTION_AGENT = LLMAgentCreator.create("sql_schema_selection_agent") +SQL_QUERY_CORRECTION_AGENT = LLMAgentCreator.create( + "sql_query_correction_agent", + target_engine="Microsoft SQL Server", + engine_specific_rules="Use TOP X to limit the number of rows returned instead of LIMIT X. NEVER USE LIMIT X as it produces a syntax error.", +) +SQL_QUERY_CACHE_AGENT = SqlQueryCacheAgent() +ANSWER_AGENT = LLMAgentCreator.create("answer_agent") +QUESTION_DECOMPOSITION_AGENT = LLMAgentCreator.create("question_decomposition_agent") + + +def text_2_sql_generator_selector_func(messages): + logging.info("Messages: %s", messages) + decision = None # Initialize decision variable + + if len(messages) == 1: + decision = "sql_query_cache_agent" + + elif ( + messages[-1].source == "sql_query_cache_agent" + and messages[-1].content is not None + ): + cache_result = json.loads(messages[-1].content) + if cache_result.get("cached_questions_and_schemas") is not None: + decision = "sql_query_correction_agent" + else: + decision = "sql_schema_selection_agent" + + elif messages[-1].source == "question_decomposition_agent": + decision = "sql_schema_selection_agent" + + elif messages[-1].source == "sql_schema_selection_agent": + decision = "sql_query_generation_agent" + + elif ( + messages[-1].source == "sql_query_correction_agent" + and messages[-1].content == "VALIDATED" + ): + decision = "answer_agent" + + elif messages[-1].source == "sql_query_correction_agent": + decision = "sql_query_correction_agent" + + # Log the decision + logging.info("Decision: %s", decision) + + return decision + + +termination = TextMentionTermination("TERMINATE") | MaxMessageTermination(10) +text_2_sql_generator = SelectorGroupChat( + [ + SQL_QUERY_GENERATION_AGENT, + SQL_SCHEMA_SELECTION_AGENT, + SQL_QUERY_CORRECTION_AGENT, + SQL_QUERY_CACHE_AGENT, + ANSWER_AGENT, + QUESTION_DECOMPOSITION_AGENT, + ], + allow_repeated_speaker=False, + model_client=MINI_MODEL, + termination_condition=termination, + selector_func=text_2_sql_generator_selector_func, +) + +# text_2_sql_cache_updater = SelectorGroupChat( +# [SQL_QUERY_CACHE_AGENT], model_client=MINI_MODEL, termination_condition=termination +# ) diff --git a/text_2_sql/autogen/custom_agents/__init__.py b/text_2_sql/autogen/custom_agents/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/text_2_sql/autogen/custom_agents/sql_query_cache_agent.py b/text_2_sql/autogen/custom_agents/sql_query_cache_agent.py new file mode 100644 index 0000000..a1f62f8 --- /dev/null +++ b/text_2_sql/autogen/custom_agents/sql_query_cache_agent.py @@ -0,0 +1,51 @@ +from typing import AsyncGenerator, List, Sequence + +from autogen_agentchat.agents import BaseChatAgent +from autogen_agentchat.base import Response +from autogen_agentchat.messages import AgentMessage, ChatMessage, TextMessage +from autogen_core.base import CancellationToken +from utils.sql_utils import fetch_queries_from_cache +import json +import logging + + +class SqlQueryCacheAgent(BaseChatAgent): + def __init__(self): + super().__init__( + "sql_query_cache_agent", + "An agent that fetches the queries from the cache based on the user question.", + ) + + @property + def produced_message_types(self) -> List[type[ChatMessage]]: + return [TextMessage] + + async def on_messages( + self, messages: Sequence[ChatMessage], cancellation_token: CancellationToken + ) -> Response: + # Calls the on_messages_stream. + response: Response | None = None + async for message in self.on_messages_stream(messages, cancellation_token): + if isinstance(message, Response): + response = message + assert response is not None + return response + + async def on_messages_stream( + self, messages: Sequence[ChatMessage], cancellation_token: CancellationToken + ) -> AsyncGenerator[AgentMessage | Response, None]: + user_question = messages[0].content + + # Fetch the queries from the cache based on the user question. + logging.info("Fetching queries from cache based on the user question...") + + cached_queries = await fetch_queries_from_cache(user_question) + + yield Response( + chat_message=TextMessage( + content=json.dumps(cached_queries), source=self.name + ) + ) + + async def on_reset(self, cancellation_token: CancellationToken) -> None: + pass diff --git a/text_2_sql/autogen/environment.py b/text_2_sql/autogen/environment.py new file mode 100644 index 0000000..232254e --- /dev/null +++ b/text_2_sql/autogen/environment.py @@ -0,0 +1,30 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +import os +from enum import Enum + + +class IdentityType(Enum): + """The type of the indexer""" + + USER_ASSIGNED = "user_assigned" + SYSTEM_ASSIGNED = "system_assigned" + KEY = "key" + + +def get_identity_type() -> IdentityType: + """This function returns the identity type. + + Returns: + IdentityType: The identity type + """ + identity = os.environ.get("IdentityType") + + if identity == "user_assigned": + return IdentityType.USER_ASSIGNED + elif identity == "system_assigned": + return IdentityType.SYSTEM_ASSIGNED + elif identity == "key": + return IdentityType.KEY + else: + raise ValueError("Invalid identity type") diff --git a/text_2_sql/autogen/llm_agents/answer_agent.yaml b/text_2_sql/autogen/llm_agents/answer_agent.yaml new file mode 100644 index 0000000..61b5893 --- /dev/null +++ b/text_2_sql/autogen/llm_agents/answer_agent.yaml @@ -0,0 +1,20 @@ +model: + gpt-4o-mini +description: + "An agent that takes the final results from the SQL query and writes the answer to the user's question" +system_message: + "Write a data-driven answer that directly addresses the user's question. Use the results from the SQL query to provide the answer. Do not make up or guess the answer. + + Return your answer in the following format: + + { + 'answer': '', + 'sources': [ + {'title': , 'chunk': , 'reference': ''}, + {'title': , 'chunk': , 'reference': ''} + ] + } + + Title is the entity name of the schema, chunk is the result of the SQL query and reference is the SQL query used to generate the answer. + + End your answer with 'TERMINATE'" diff --git a/text_2_sql/autogen/llm_agents/question_decomposition_agent.yaml b/text_2_sql/autogen/llm_agents/question_decomposition_agent.yaml new file mode 100644 index 0000000..0520028 --- /dev/null +++ b/text_2_sql/autogen/llm_agents/question_decomposition_agent.yaml @@ -0,0 +1,10 @@ +model: + gpt-4o-mini +description: + "An agent that will decompose the user's question into smaller parts to be used in the SQL queries. Use this agent when the user's question is too complex to be answered in one SQL query. Only use if the user's question is too complex to be answered in one SQL query. + + Only use this agent once per user question and after the 'Query Cache Agent' if the results are none." +system_message: + "You are a helpful AI Assistant that specialises in decomposing complex user questions into smaller parts that can be used in SQL queries. + + Break down the user's question into smaller parts that can be used in SQL queries." diff --git a/text_2_sql/autogen/llm_agents/sql_query_correction_agent.yaml b/text_2_sql/autogen/llm_agents/sql_query_correction_agent.yaml new file mode 100644 index 0000000..684eb77 --- /dev/null +++ b/text_2_sql/autogen/llm_agents/sql_query_correction_agent.yaml @@ -0,0 +1,19 @@ +model: + gpt-4o-mini +description: + "An agent that will look at the SQL query, SQL query results and correct any mistakes in the SQL query to ensure the correct results are returned. Use this agent AFTER the SQL query has been executed and the results are not as expected." +system_message: + "You are a helpful AI Assistant that specialises in correcting invalid SQL queries or queries that do not return the expected results. + + Review the SQL query provided and correct any errors or issues that you find. Bear in mind that the target database engine is {{ target_engine }}, SQL queries must be able compatible to run on {{ target_engine }} {{ engine_specific_rules }} + + Ensure that the corrected query returns the expected results in context of the question. + + If there are no errors and the SQL query is correct, return 'VALIDATED'. + + If the SQL query needs adjustment, correct the SQL query and provide the corrected SQL query and then run the query. + + If you are consistently unable to correct the SQL query and cannot use the schemas to answer the question. Say 'I am unable to correct the SQL query. Please ask another question.' and then end your answer with 'TERMINATE'" +tools: + - sql_get_entity_schemas_tool + - sql_query_execution_tool diff --git a/text_2_sql/autogen/llm_agents/sql_query_generation_agent.yaml b/text_2_sql/autogen/llm_agents/sql_query_generation_agent.yaml new file mode 100644 index 0000000..38497d5 --- /dev/null +++ b/text_2_sql/autogen/llm_agents/sql_query_generation_agent.yaml @@ -0,0 +1,25 @@ +model: + gpt-4o-mini +description: + "An agent that can generate SQL queries once given the schema and the user's question. It will run the SQL query to fetch the results. Use this agent after the SQL Schema Selection Agent has selected the correct schema." +system_message: + "You are a helpful AI Assistant that specialises in writing and executing SQL Queries to answer a given user's question. + + If you need more information from the user to generate the SQL query, ask the user for the information you need with a question and end your answer with 'TERMINATE'. + + Only use schema / column information provided when constructing a SQL query. Do not use any other entities and columns in your SQL query, other than those defined above. + Do not makeup or guess column names. + + The target database engine is {{ target_engine }}, SQL queries must be able compatible to run on {{ target_engine }} {{ engine_specific_rules }} + You must only provide SELECT SQL queries. + For a given entity, use the 'SelectFromEntity' property returned in the schema in the SELECT FROM part of the SQL query. If the property is {'SelectFromEntity': 'test_schema.test_table'}, the select statement will be formulated from 'SELECT FROM test_schema.test_table WHERE . + + If you don't know how the value is formatted in a column, run a query against the column to get the unique values that might match your query or use the corresponding lookup values. Use a 'like' operator to match the values, rather than a direct match unless you are sure of the value. + Some columns in the schema may have the properties 'AllowedValues' or 'SampleValues'. Use these values to determine the possible values that can be used in the SQL query. + + The complete entity relationship graph shows you all the entities and their relationships. You can use this information to get a better understanding of the schema and the relationships between the entities and request more schema information if needed. + + Always run any SQL query you generate to return the results." +tools: + - sql_query_execution_tool + - sql_get_entity_schemas_tool diff --git a/text_2_sql/autogen/llm_agents/sql_schema_selection_agent.yaml b/text_2_sql/autogen/llm_agents/sql_schema_selection_agent.yaml new file mode 100644 index 0000000..67430c5 --- /dev/null +++ b/text_2_sql/autogen/llm_agents/sql_schema_selection_agent.yaml @@ -0,0 +1,16 @@ +model: + gpt-4o-mini +description: + "An agent that can take a user's question and extract the schema of a view or table in the SQL Database by selecting the most relevant entity based on the search term. + + Call this in parallel if needed multiple times. Limit the use of this agent where possible." +system_message: + "You are a helpful AI Assistant that specialises in selecting relevant SQL schemas to answer a given user's question. + + Use the tools available to you to select the correct schemas that will help. Extract key terms from the user's question and use them to search for the correct schema. + + Limit the number of calls to the 'sql_get_entity_schemas_tool' tool to avoid unnecessary calls. + + If you are unsure about the schema, you can ask the user for more information or ask for clarification." +tools: + - sql_get_entity_schemas_tool diff --git a/text_2_sql/autogen/requirements.txt b/text_2_sql/autogen/requirements.txt new file mode 100644 index 0000000..3edc6fb --- /dev/null +++ b/text_2_sql/autogen/requirements.txt @@ -0,0 +1,10 @@ +autogen-core==0.4.0.dev6 +autogen-agentchat==0.4.0.dev6 +autogen-ext[openai,azure]==0.4.0.dev6 +aioodbc +azure-search +azure-search-documents==11.6.0b5 +azure-identity +python-dotenv +openai +jinja2 diff --git a/text_2_sql/autogen/utils/__init__.py b/text_2_sql/autogen/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/text_2_sql/semantic_kernel/utils/ai_search.py b/text_2_sql/autogen/utils/ai_search_utils.py similarity index 100% rename from text_2_sql/semantic_kernel/utils/ai_search.py rename to text_2_sql/autogen/utils/ai_search_utils.py diff --git a/text_2_sql/autogen/utils/llm_agent_creator.py b/text_2_sql/autogen/utils/llm_agent_creator.py new file mode 100644 index 0000000..b281f05 --- /dev/null +++ b/text_2_sql/autogen/utils/llm_agent_creator.py @@ -0,0 +1,71 @@ +import yaml +from autogen_core.components.tools import FunctionTool +from autogen_agentchat.agents import AssistantAgent +from utils.sql_utils import ( + query_execution, + get_entity_schemas, +) +from utils.models import MINI_MODEL +from jinja2 import Template + + +class LLMAgentCreator: + @classmethod + def load_agent_file(cls, name): + with open(f"llm_agents/{name.lower()}.yaml", "r") as file: + file = yaml.safe_load(file) + + return file + + @classmethod + def get_model(cls, model_name): + if model_name == "gpt-4o-mini": + return MINI_MODEL + else: + raise ValueError(f"Model {model_name} not found") + + @classmethod + def get_tool(cls, tool_name): + if tool_name == "sql_query_execution_tool": + return FunctionTool( + query_execution, + description="Runs an SQL query against the SQL Database to extract information", + ) + elif tool_name == "sql_get_entity_schemas_tool": + return FunctionTool( + get_entity_schemas, + description="Gets the schema of a view or table in the SQL Database by selecting the most relevant entity based on the search term. Extract key terms from the user question and use these as the search term. Several entities may be returned. Only use when the provided schemas in the system prompt are not sufficient to answer the question.", + ) + else: + raise ValueError(f"Tool {tool_name} not found") + + @classmethod + def get_property_and_render_parameters(cls, agent_file, property, parameters): + unrendered_parameters = agent_file[property] + + rendered_template = Template(unrendered_parameters).render(parameters) + + return rendered_template + + @classmethod + def create(cls, name: str, **kwargs): + agent_file = cls.load_agent_file(name) + + tools = [] + if "tools" in agent_file and len(agent_file["tools"]) > 0: + for tool in agent_file["tools"]: + tools.append(cls.get_tool(tool)) + + agent = AssistantAgent( + name=name, + tools=tools, + model_client=cls.get_model(agent_file["model"]), + description=cls.get_property_and_render_parameters( + agent_file, "description", kwargs + ), + system_message=cls.get_property_and_render_parameters( + agent_file, "system_message", kwargs + ), + ) + + return agent diff --git a/text_2_sql/autogen/utils/models.py b/text_2_sql/autogen/utils/models.py new file mode 100644 index 0000000..2eb4f13 --- /dev/null +++ b/text_2_sql/autogen/utils/models.py @@ -0,0 +1,26 @@ +from autogen_ext.models import AzureOpenAIChatCompletionClient + +# from azure.identity import DefaultAzureCredential, get_bearer_token_provider +import os +import dotenv + +dotenv.load_dotenv() + +# # Create the token provider +# token_provider = get_bearer_token_provider( +# DefaultAzureCredential(), "https://cognitiveservices.azure.com/.default" +# ) + +MINI_MODEL = AzureOpenAIChatCompletionClient( + model=os.environ["OpenAI__MiniCompletionDeployment"], + api_version="2024-08-01-preview", + azure_endpoint=os.environ["OpenAI__Endpoint"], + # # Optional if you choose key-based authentication. + # azure_ad_token_provider=token_provider, + api_key=os.environ["OpenAI__ApiKey"], # For key-based authentication. + model_capabilities={ + "vision": False, + "function_calling": True, + "json_output": True, + }, +) diff --git a/text_2_sql/autogen/utils/sql_utils.py b/text_2_sql/autogen/utils/sql_utils.py new file mode 100644 index 0000000..0a3d7f7 --- /dev/null +++ b/text_2_sql/autogen/utils/sql_utils.py @@ -0,0 +1,144 @@ +import logging +import os +import aioodbc +from typing import Annotated +from utils.ai_search_utils import run_ai_search_query +import json +import asyncio + +USE_QUERY_CACHE = os.environ.get("Text2Sql__UseQueryCache", "False").lower() == "true" + +PRE_RUN_QUERY_CACHE = ( + os.environ.get("Text2Sql__PreRunQueryCache", "False").lower() == "true" +) + + +async def get_entity_schemas( + text: Annotated[ + str, + "The text to run a semantic search against. Relevant entities will be returned.", + ], + excluded_entities: Annotated[ + list[str], + "The entities to exclude from the search results. Pass the entity property of entities (e.g. 'SalesLT.Address') you already have the schemas for to avoid getting repeated entities.", + ] = [], +) -> str: + """Gets the schema of a view or table in the SQL Database by selecting the most relevant entity based on the search term. Several entities may be returned. + + Args: + ---- + text (str): The text to run the search against. + + Returns: + str: The schema of the views or tables in JSON format. + """ + + schemas = await run_ai_search_query( + text, + ["DefinitionEmbedding"], + [ + "Entity", + "EntityName", + "Definition", + "Columns", + "EntityRelationships", + "CompleteEntityRelationshipsGraph", + ], + os.environ["AIService__AzureSearchOptions__Text2Sql__Index"], + os.environ["AIService__AzureSearchOptions__Text2Sql__SemanticConfig"], + top=3, + ) + + for schema in schemas: + entity = schema["Entity"] + database = os.environ["Text2Sql__DatabaseName"] + schema["SelectFromEntity"] = f"{database}.{entity}" + + filtered_schemas = [] + for excluded_entity in excluded_entities: + if excluded_entity.lower() == entity.lower(): + logging.info("Excluded entity: %s", excluded_entity) + else: + filtered_schemas.append(schema) + + return json.dumps(schemas, default=str) + + +async def query_execution(sql_query: str) -> list[dict]: + """Run the SQL query against the database. + + Args: + ---- + sql_query (str): The SQL query to run against the database. + + Returns: + ------- + list[dict]: The results of the SQL query. + """ + connection_string = os.environ["Text2Sql__DatabaseConnectionString"] + async with await aioodbc.connect(dsn=connection_string) as sql_db_client: + async with sql_db_client.cursor() as cursor: + await cursor.execute(sql_query) + + columns = [column[0] for column in cursor.description] + + rows = await cursor.fetchall() + results = [dict(zip(columns, returned_row)) for returned_row in rows] + + logging.debug("Results: %s", results) + return results + + +async def fetch_queries_from_cache(question: str) -> str: + """Fetch the queries from the cache based on the question. + + Args: + ---- + question (str): The question to use to fetch the queries. + + Returns: + ------- + str: The formatted string of the queries fetched from the cache. This is injected into the prompt. + """ + cached_schemas = await run_ai_search_query( + question, + ["QuestionEmbedding"], + ["Question", "SqlQueryDecomposition"], + os.environ["AIService__AzureSearchOptions__Text2SqlQueryCache__Index"], + os.environ["AIService__AzureSearchOptions__Text2SqlQueryCache__SemanticConfig"], + top=1, + include_scores=True, + minimum_score=1.5, + ) + + if len(cached_schemas) == 0: + return {"cached_questions_and_schemas": None} + + logging.info("Cached schemas: %s", cached_schemas) + if PRE_RUN_QUERY_CACHE and len(cached_schemas) > 0: + # check the score + if cached_schemas[0]["@search.reranker_score"] > 2.75: + logging.info("Score is greater than 3") + + sql_queries = cached_schemas[0]["SqlQueryDecomposition"] + query_result_store = {} + + query_tasks = [] + + for sql_query in sql_queries: + logging.info("SQL Query: %s", sql_query) + + # Run the SQL query + query_tasks.append(query_execution(sql_query["SqlQuery"])) + + sql_results = await asyncio.gather(*query_tasks) + + for sql_query, sql_result in zip(sql_queries, sql_results): + query_result_store[sql_query["SqlQuery"]] = { + "result": sql_result, + "schemas": sql_query["Schemas"], + } + + return {"cached_questions_and_schemas": query_result_store} + + return {"cached_questions_and_schemas": cached_schemas} diff --git a/text_2_sql/semantic_kernel/plugins/ai_search_plugin/ai_search_plugin.py b/text_2_sql/semantic_kernel/plugins/ai_search_plugin/ai_search_plugin.py index 34fcbde..f169a23 100644 --- a/text_2_sql/semantic_kernel/plugins/ai_search_plugin/ai_search_plugin.py +++ b/text_2_sql/semantic_kernel/plugins/ai_search_plugin/ai_search_plugin.py @@ -5,7 +5,7 @@ import os import json import logging -from utils.ai_search import run_ai_search_query +from text_2_sql.semantic_kernel.utils.ai_search_utils import run_ai_search_query class AISearchPlugin: diff --git a/text_2_sql/semantic_kernel/plugins/vector_based_sql_plugin/vector_based_sql_plugin.py b/text_2_sql/semantic_kernel/plugins/vector_based_sql_plugin/vector_based_sql_plugin.py index 53bfa31..35c7032 100644 --- a/text_2_sql/semantic_kernel/plugins/vector_based_sql_plugin/vector_based_sql_plugin.py +++ b/text_2_sql/semantic_kernel/plugins/vector_based_sql_plugin/vector_based_sql_plugin.py @@ -5,7 +5,10 @@ import os import json import logging -from utils.ai_search import add_entry_to_index, run_ai_search_query +from utils.ai_search_utils import ( + add_entry_to_index, + run_ai_search_query, +) import asyncio import aioodbc @@ -110,8 +113,15 @@ async def fetch_schemas_from_store(self, search: str) -> list[dict]: list[dict]: The list of schemas fetched from the store.""" schemas = await run_ai_search_query( search, - ["DescriptionEmbedding"], - ["Entity", "EntityName", "Description", "Columns"], + ["DefinitionEmbedding"], + [ + "Entity", + "EntityName", + "Definition", + "Columns", + "EntityRelationships", + "CompleteEntityRelationshipsGraph", + ], os.environ["AIService__AzureSearchOptions__Text2Sql__Index"], os.environ["AIService__AzureSearchOptions__Text2Sql__SemanticConfig"], top=3, @@ -143,7 +153,7 @@ async def fetch_queries_from_cache(self, question: str) -> str: cached_schemas = await run_ai_search_query( question, ["QuestionEmbedding"], - ["Question", "SqlQueryDecomposition", "Schemas"], + ["Question", "SqlQueryDecomposition"], os.environ["AIService__AzureSearchOptions__Text2SqlQueryCache__Index"], os.environ[ "AIService__AzureSearchOptions__Text2SqlQueryCache__SemanticConfig" @@ -157,7 +167,7 @@ async def fetch_queries_from_cache(self, question: str) -> str: return None else: database = os.environ["Text2Sql__DatabaseName"] - for entry in cached_schemas: + for entry in cached_schemas["SqlQueryDecomposition"]: for schema in entry["Schemas"]: entity = schema["Entity"] schema["SelectFromEntity"] = f"{database}.{entity}" @@ -188,7 +198,7 @@ async def fetch_queries_from_cache(self, question: str) -> str: for sql_query, sql_result in zip(sql_queries, sql_results): query_result_store[sql_query["SqlQuery"]] = { "result": sql_result, - "schemas": sql_queries["schemas"], + "schemas": sql_query["Schemas"], } pre_fetched_results_string = f"""[BEGIN PRE-FETCHED RESULTS FOR CACHED SQL QUERIES]\n{ @@ -340,10 +350,12 @@ async def run_sql_query( entry = { "Question": self.question, - "SqlQueryDecomposition": { - "SqlQuery": sql_query, - "Schemas": cleaned_schemas, - }, + "SqlQueryDecomposition": [ + { + "SqlQuery": sql_query, + "Schemas": cleaned_schemas, + } + ], } except Exception as e: logging.error("Error: %s", e) diff --git a/text_2_sql/semantic_kernel/rag_with_vector_based_text_2_sql.ipynb b/text_2_sql/semantic_kernel/rag_with_vector_based_text_2_sql.ipynb index 8fdc8cb..53dbc97 100644 --- a/text_2_sql/semantic_kernel/rag_with_vector_based_text_2_sql.ipynb +++ b/text_2_sql/semantic_kernel/rag_with_vector_based_text_2_sql.ipynb @@ -22,7 +22,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { "gather": { "logged": 1718623217703 @@ -65,7 +65,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -82,7 +82,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": { "gather": { "logged": 1718623218006 @@ -104,7 +104,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": { "gather": { "logged": 1718623218267 @@ -132,7 +132,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": { "gather": { "logged": 1718623218614 @@ -147,18 +147,7 @@ } } }, - "outputs": [ - { - "data": { - "text/plain": [ - "KernelPlugin(name='SQL', description=None, functions={'GetEntitySchema': KernelFunctionFromMethod(metadata=KernelFunctionMetadata(name='GetEntitySchema', plugin_name='SQL', description='Gets the schema of a view or table in the SQL Database by selecting the most relevant entity based on the search term. Extract key terms from the user question and use these as the search term. Several entities may be returned. Only use when the provided schemas in the system prompt are not sufficient to answer the question.', parameters=[KernelParameterMetadata(name='text', description='The text to run a semantic search against. Relevant entities will be returned.', default_value=None, type_='str', is_required=True, type_object=, schema_data={'type': 'string', 'description': 'The text to run a semantic search against. Relevant entities will be returned.'}, function_schema_include=True)], is_prompt=False, is_asynchronous=True, return_parameter=KernelParameterMetadata(name='return', description='', default_value=None, type_='str', is_required=True, type_object=, schema_data={'type': 'string'}, function_schema_include=True), additional_properties={}), invocation_duration_histogram=, streaming_duration_histogram=, method=>, stream_method=None), 'RunSQLQuery': KernelFunctionFromMethod(metadata=KernelFunctionMetadata(name='RunSQLQuery', plugin_name='SQL', description='Runs an SQL query against the SQL Database to extract information.', parameters=[KernelParameterMetadata(name='sql_query', description='The SQL query to run against the DB', default_value=None, type_='str', is_required=True, type_object=, schema_data={'type': 'string', 'description': 'The SQL query to run against the DB'}, function_schema_include=True)], is_prompt=False, is_asynchronous=True, return_parameter=KernelParameterMetadata(name='return', description='', default_value=None, type_='str', is_required=True, type_object=, schema_data={'type': 'string'}, function_schema_include=True), additional_properties={}), invocation_duration_histogram=, streaming_duration_histogram=, method=>, stream_method=None)})" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# Register the SQL Plugin with the Database name to use.\n", "sql_plugin = VectorBasedSQLPlugin()\n", @@ -180,7 +169,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -192,7 +181,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -212,7 +201,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -221,7 +210,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -271,609 +260,18 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "INFO:httpx:HTTP Request: POST https://aoai-text2sql-adi.openai.azure.com/openai/deployments/text-embedding-ada-002/embeddings?api-version=2023-03-15-preview \"HTTP/1.1 200 OK\"\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "INFO:azure.core.pipeline.policies.http_logging_policy:Request URL: 'https://open-ai-vector-db.search.windows.net/indexes('text-2-sql-query-cache-index')/docs/search.post.search?api-version=REDACTED'\n", - "Request method: 'POST'\n", - "Request headers:\n", - " 'Content-Type': 'application/json'\n", - " 'Content-Length': '34853'\n", - " 'api-key': 'REDACTED'\n", - " 'Accept': 'application/json;odata.metadata=none'\n", - " 'x-ms-client-request-id': '926fce74-7784-11ef-822e-0242ac110002'\n", - " 'User-Agent': 'azsdk-python-search-documents/11.6.0b4 Python/3.12.6 (Linux-5.15.153.1-microsoft-standard-WSL2-x86_64-with-glibc2.36)'\n", - "A body is sent with the request\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Response status: 200\n", - "Response headers:\n", - " 'Transfer-Encoding': 'chunked'\n", - " 'Content-Type': 'application/json; odata.metadata=none; odata.streaming=true; charset=utf-8'\n", - " 'Content-Encoding': 'REDACTED'\n", - " 'Vary': 'REDACTED'\n", - " 'Server': 'Microsoft-IIS/10.0'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Preference-Applied': 'REDACTED'\n", - " 'OData-Version': 'REDACTED'\n", - " 'request-id': '926fce74-7784-11ef-822e-0242ac110002'\n", - " 'elapsed-time': 'REDACTED'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Date': 'Fri, 20 Sep 2024 19:14:36 GMT'\n", - "INFO:root:Results: []\n", - "INFO:root:Question: What are the different product categories we have?\n", - "INFO:semantic_kernel.functions.kernel_function:Function ChatBot-Chat invoking.\n", - "INFO:semantic_kernel.contents.chat_history:Could not parse prompt \n", - "As a senior analyst, your primary responsibility is to provide accurate, thorough answers to user queries. Use all available functions to craft detailed final responses with clear explanations and actionable insights.\n", - "\n", - "- Always use the provided functions to obtain key information.\n", - "- If a function is required, you must use it to complement the answer.\n", - "- Use multiple functions in parallel to enhance the results.\n", - "- Always provide an answer; never leave it blank.\n", - "\n", - "The response must meet the following requirements:\n", - "\n", - "[RESPONSE OUTPUT REQUIREMENTS]\n", - "\n", - " The answer MUST be in JSON format:\n", - " {\n", - " \"answer\": \"\",\n", - " \"sources\": [\n", - " {\"title\": , \"chunk\": , \"reference\": \"\"},\n", - " {\"title\": , \"chunk\": , \"reference\": \"\"}\n", - " ]\n", - " }\n", - "\n", - " [ANSWER PROPERTY REQUIREMENTS]\n", - " - **Language & Tone**:\n", - " Use British English, business-friendly language that is professional and clear.\n", - " - **Content Restrictions**:\n", - " Avoid profanity, offensive language, and code. Rephrase or omit inappropriate content.\n", - " - **Information Sources**:\n", - " Only use provided functions and important information. Prioritize SQL Database data in case of conflicts.\n", - " - **Calculations**:\n", - " Use context-provided values and explain calculations briefly.\n", - " - **Structure**:\n", - " Responses must be direct, easy to understand, and formatted using Markdown.\n", - " Use Level 3 and 4 headings, bold sub-headings, and lists where appropriate. Keep font size consistent.\n", - " - **Citations**:\n", - " Factual statements must be cited using numbered references like [1]. Each citation must match a source in the 'sources' object.\n", - "\n", - " [SOURCES PROPERTY REQUIREMENTS]\n", - " - **Reference Inclusion**:\n", - " All cited content must have a corresponding reference in the 'sources' object.\n", - " - **Source Format**:\n", - " Each source must follow this format: {\"title\": \"\", \"chunk\": \"\", \"reference\": \"\"}\n", - " - **Source Chunk**:\n", - " Include a concise, unedited snippet of relevant context in the 'chunk' property.\n", - " - **Mandatory Citations**:\n", - " Every source listed must be cited at least once in the answer.\n", - "\n", - "[IMPORTANT INFORMATION]\n", - "\n", - "\n", - " [SQL DATABASE INFORMATION]\n", - " First consider the PRE-FETCHED SQL query and the results from execution. Consider if you can use this data to answer the question without running another SQL query. If the data is sufficient, use it to answer the question instead of running a new query.\n", - "\n", - " \n", - "\n", - " If this data or query will not answer the question, look at the provided CACHED QUERIES AND SCHEMAS below, to see if you can use them to formulate a SQL query.\n", - "\n", - " \n", - "\n", - " Finally, if you can't use or adjust a previous generated SQL query, use the 'GetEntitySchema()' function to search for the most relevant schemas for the data that you wish to obtain.\n", - "\n", - " If needed, use the 'RunSQLQuery()' function to run the SQL query against the database. Never just return the SQL query as the answer.\n", - "\n", - " Output corresponding text values in the answer for columns where there is an ID. For example, if the column is 'ProductID', output the corresponding 'ProductModel' in the response. Do not include the ID in the response.\n", - " If a user is asking for a comparison, always compare the relevant values in the database.\n", - "\n", - " Only use schema / column information provided as part of this prompt or from the 'GetEntitySchema()' function output when constructing a SQL query. Do not use any other entities and columns in your SQL query, other than those defined above.\n", - " Do not makeup or guess column names.\n", - "\n", - " The target database engine is Microsoft TSQL Server, SQL queries must be able compatible to run on Microsoft TSQL Server. \n", - " The following Microsoft TSQL Server Syntax rules must be adhered to.\n", - " Use TOP X to limit the number of rows returned instead of LIMIT X. NEVER USE LIMIT X as it produces a syntax error.\n", - " You must only provide SELECT SQL queries.\n", - " For a given entity, use the 'SelectFromEntity' property returned in the schema in the SELECT FROM part of the SQL query. If the property is {'SelectFromEntity': 'test_schema.test_table'}, the select statement will be formulated from 'SELECT <VALUES> FROM test_schema.test_table WHERE <CONDITION>.\n", - "\n", - " If you don't know how the value is formatted in a column, run a query against the column to get the unique values that might match your query.\n", - " Some columns in the schema may have the properties 'AllowedValues' or 'SampleValues'. Use these values to determine the possible values that can be used in the SQL query.\n", - "\n", - " The source title to cite is the 'EntityName' property. The source reference is the SQL query used. The source chunk is the result of the SQL query used to answer the user query in Markdown table format. e.g. { 'title': "vProductAndDescription", 'chunk': '| ProductID | Name | ProductModel | Culture | Description |\\n|-----------|-------------------|--------------|---------|----------------------------------|\\n| 101 | Mountain Bike | MT-100 | en | A durable bike for mountain use. |\\n| 102 | Road Bike | RB-200 | en | Lightweight bike for road use. |\\n| 103 | Hybrid Bike | HB-300 | fr | V\u00e9lo hybride pour usage mixte. |\\n', 'reference': 'SELECT ProductID, Name, ProductModel, Culture, Description FROM vProductAndDescription WHERE Culture = "en";' }\n", - " [END SQL DATABASE INFORMATION]\n", - " \n", - "\n", - "[END]\n", - "\n", - "\n", - "What are the different product categories we have? as xml, treating as text, error was: not well-formed (invalid token): line 15, column 32\n", - "INFO:httpx:HTTP Request: POST https://aoai-text2sql-adi.openai.azure.com/openai/deployments/gpt-4o/chat/completions?api-version=2024-02-01 \"HTTP/1.1 200 OK\"\n", - "INFO:semantic_kernel.connectors.ai.open_ai.services.open_ai_handler:OpenAI usage: CompletionUsage(completion_tokens=18, prompt_tokens=1400, total_tokens=1418, completion_tokens_details=None)\n", - "INFO:semantic_kernel.connectors.ai.chat_completion_client_base:processing 1 tool calls in parallel.\n", - "INFO:semantic_kernel.kernel:Calling SQL-GetEntitySchema function with args: {\"text\":\"product categories\"}\n", - "INFO:semantic_kernel.functions.kernel_function:Function SQL-GetEntitySchema invoking.\n", - "INFO:httpx:HTTP Request: POST https://aoai-text2sql-adi.openai.azure.com/openai/deployments/text-embedding-ada-002/embeddings?api-version=2023-03-15-preview \"HTTP/1.1 200 OK\"\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Request URL: 'https://open-ai-vector-db.search.windows.net/indexes('text-2-sql-index')/docs/search.post.search?api-version=REDACTED'\n", - "Request method: 'POST'\n", - "Request headers:\n", - " 'Content-Type': 'application/json'\n", - " 'Content-Length': '34770'\n", - " 'api-key': 'REDACTED'\n", - " 'Accept': 'application/json;odata.metadata=none'\n", - " 'x-ms-client-request-id': '93290038-7784-11ef-822e-0242ac110002'\n", - " 'User-Agent': 'azsdk-python-search-documents/11.6.0b4 Python/3.12.6 (Linux-5.15.153.1-microsoft-standard-WSL2-x86_64-with-glibc2.36)'\n", - "A body is sent with the request\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Response status: 200\n", - "Response headers:\n", - " 'Transfer-Encoding': 'chunked'\n", - " 'Content-Type': 'application/json; odata.metadata=none; odata.streaming=true; charset=utf-8'\n", - " 'Content-Encoding': 'REDACTED'\n", - " 'Vary': 'REDACTED'\n", - " 'Server': 'Microsoft-IIS/10.0'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Preference-Applied': 'REDACTED'\n", - " 'OData-Version': 'REDACTED'\n", - " 'request-id': '93290038-7784-11ef-822e-0242ac110002'\n", - " 'elapsed-time': 'REDACTED'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Date': 'Fri, 20 Sep 2024 19:14:38 GMT'\n", - "INFO:root:Item: {'EntityName': 'Get All Categories', 'Columns': [{'Name': 'ProductCategoryID', 'Definition': 'A unique identifier for each product category. This ID is used to reference specific categories.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ParentProductCategoryName', 'Definition': 'The name of the parent product category. This represents the top-level category under which subcategories are grouped.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductCategoryName', 'Definition': 'The name of the product category. This can refer to either a top-level category or a subcategory, depending on the context.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'vGetAllCategories', 'Description': 'This view provides a comprehensive list of all product categories and their corresponding subcategories in the SalesLT schema of the AdventureWorksLT database. It is used to understand the hierarchical structure of product categories, facilitating product organization and categorization.'}\n", - "INFO:root:Item: {'EntityName': 'Product Model Catalog Description', 'Columns': [{'Name': 'ProductModelID', 'Definition': 'A unique identifier for each product model. This ID is used to distinguish different product models.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Name', 'Definition': 'The name of the product model, providing a recognizable title for each model.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Summary', 'Definition': 'A brief summary of the product model, highlighting key features and characteristics.', 'Type': 'NVARCHAR(MAX)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Manufacturer', 'Definition': 'The name of the manufacturer of the product model.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Copyright', 'Definition': 'Copyright information related to the product model, indicating the legal ownership of the product design and content.', 'Type': 'NVARCHAR(30)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductURL', 'Definition': 'The URL for the product model, providing a link to more information or to purchase the product.', 'Type': 'NVARCHAR(256)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'WarrantyPeriod', 'Definition': 'The duration of the warranty period for the product model, specifying how long the warranty is valid.', 'Type': 'NVARCHAR(30)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'WarrantyDescription', 'Definition': 'A description of the warranty provided for the product model, detailing what is covered under the warranty.', 'Type': 'NVARCHAR(255)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'NoOfYears', 'Definition': 'The number of years the warranty is valid for the product model.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'MaintenanceDescription', 'Definition': 'A description of the maintenance requirements and recommendations for the product model.', 'Type': 'NVARCHAR(MAX)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Wheel', 'Definition': 'Details about the type of wheels used in the product model.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Saddle', 'Definition': 'Information about the saddle of the product model, such as material and design.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Pedal', 'Definition': 'Details regarding the pedal design and specifications of the product model.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'BikeFrame', 'Definition': 'Description of the bike frame used in the product model, including material and type.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Crankset', 'Definition': 'Information about the crankset of the product model, specifying its design and features.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PictureAngle', 'Definition': 'The angle at which the product model is photographed, providing a visual perspective of the product.', 'Type': 'NVARCHAR(20)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PictureSize', 'Definition': \"The size of the product model's picture, specifying dimensions or resolution.\", 'Type': 'NVARCHAR(20)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductPhotoID', 'Definition': 'An identifier linking to the product photo, which provides a visual representation of the product model.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Material', 'Definition': 'The material used in the construction of the product model, indicating durability and quality.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Color', 'Definition': 'The color of the product model, providing information about the appearance of the product.', 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductLine', 'Definition': 'A code representing the product line to which the model belongs, categorizing the product within a broader product range.', 'Type': 'NVARCHAR(2)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Style', 'Definition': 'The style of the product model, indicating design and aesthetic aspects.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'RiderExperience', 'Definition': \"A description of the target rider's experience level for which the product model is designed, such as beginner, intermediate, or expert.\", 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the product model information was last modified, indicating the currency of the data.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'vProductModelCatalogDescription', 'Description': 'This view provides detailed catalog information about product models, including descriptions, manufacturing details, warranty information, and specifications related to product design and features. It is useful for generating comprehensive product catalogs and providing detailed product information to customers.'}\n", - "INFO:root:Item: {'EntityName': 'Product and Description', 'Columns': [{'Name': 'ProductID', 'Definition': 'A unique identifier for each product. This ID is used to distinguish individual products.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Name', 'Definition': 'The name of the product. This provides a brief and identifiable name for each product.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductModel', 'Definition': 'The model name associated with the product. This indicates the specific model type or version of the product.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Culture', 'Definition': \"The culture or language code for the product description. This is used to localize the product description, such as 'en' for English or 'fr' for French.\", 'Type': 'NVARCHAR(6)', 'AllowedValues': None, 'SampleValues': '[\"en\",\"fr\",\"es\",\"de\"]'}, {'Name': 'Description', 'Definition': 'A detailed description of the product. This text provides additional information about the product, which can vary based on the culture or language.', 'Type': 'NVARCHAR(400)', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'vProductAndDescription', 'Description': 'This view provides detailed information about products, including their names, associated product models, descriptions, and the specific culture or language of the description. It is useful for understanding product details and translating product descriptions for different cultures.'}\n", - "INFO:root:Results: [{'EntityName': 'Get All Categories', 'Columns': [{'Name': 'ProductCategoryID', 'Definition': 'A unique identifier for each product category. This ID is used to reference specific categories.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ParentProductCategoryName', 'Definition': 'The name of the parent product category. This represents the top-level category under which subcategories are grouped.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductCategoryName', 'Definition': 'The name of the product category. This can refer to either a top-level category or a subcategory, depending on the context.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'vGetAllCategories', 'Description': 'This view provides a comprehensive list of all product categories and their corresponding subcategories in the SalesLT schema of the AdventureWorksLT database. It is used to understand the hierarchical structure of product categories, facilitating product organization and categorization.'}, {'EntityName': 'Product Model Catalog Description', 'Columns': [{'Name': 'ProductModelID', 'Definition': 'A unique identifier for each product model. This ID is used to distinguish different product models.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Name', 'Definition': 'The name of the product model, providing a recognizable title for each model.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Summary', 'Definition': 'A brief summary of the product model, highlighting key features and characteristics.', 'Type': 'NVARCHAR(MAX)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Manufacturer', 'Definition': 'The name of the manufacturer of the product model.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Copyright', 'Definition': 'Copyright information related to the product model, indicating the legal ownership of the product design and content.', 'Type': 'NVARCHAR(30)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductURL', 'Definition': 'The URL for the product model, providing a link to more information or to purchase the product.', 'Type': 'NVARCHAR(256)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'WarrantyPeriod', 'Definition': 'The duration of the warranty period for the product model, specifying how long the warranty is valid.', 'Type': 'NVARCHAR(30)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'WarrantyDescription', 'Definition': 'A description of the warranty provided for the product model, detailing what is covered under the warranty.', 'Type': 'NVARCHAR(255)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'NoOfYears', 'Definition': 'The number of years the warranty is valid for the product model.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'MaintenanceDescription', 'Definition': 'A description of the maintenance requirements and recommendations for the product model.', 'Type': 'NVARCHAR(MAX)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Wheel', 'Definition': 'Details about the type of wheels used in the product model.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Saddle', 'Definition': 'Information about the saddle of the product model, such as material and design.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Pedal', 'Definition': 'Details regarding the pedal design and specifications of the product model.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'BikeFrame', 'Definition': 'Description of the bike frame used in the product model, including material and type.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Crankset', 'Definition': 'Information about the crankset of the product model, specifying its design and features.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PictureAngle', 'Definition': 'The angle at which the product model is photographed, providing a visual perspective of the product.', 'Type': 'NVARCHAR(20)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PictureSize', 'Definition': \"The size of the product model's picture, specifying dimensions or resolution.\", 'Type': 'NVARCHAR(20)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductPhotoID', 'Definition': 'An identifier linking to the product photo, which provides a visual representation of the product model.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Material', 'Definition': 'The material used in the construction of the product model, indicating durability and quality.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Color', 'Definition': 'The color of the product model, providing information about the appearance of the product.', 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductLine', 'Definition': 'A code representing the product line to which the model belongs, categorizing the product within a broader product range.', 'Type': 'NVARCHAR(2)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Style', 'Definition': 'The style of the product model, indicating design and aesthetic aspects.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'RiderExperience', 'Definition': \"A description of the target rider's experience level for which the product model is designed, such as beginner, intermediate, or expert.\", 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the product model information was last modified, indicating the currency of the data.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'vProductModelCatalogDescription', 'Description': 'This view provides detailed catalog information about product models, including descriptions, manufacturing details, warranty information, and specifications related to product design and features. It is useful for generating comprehensive product catalogs and providing detailed product information to customers.'}, {'EntityName': 'Product and Description', 'Columns': [{'Name': 'ProductID', 'Definition': 'A unique identifier for each product. This ID is used to distinguish individual products.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Name', 'Definition': 'The name of the product. This provides a brief and identifiable name for each product.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductModel', 'Definition': 'The model name associated with the product. This indicates the specific model type or version of the product.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Culture', 'Definition': \"The culture or language code for the product description. This is used to localize the product description, such as 'en' for English or 'fr' for French.\", 'Type': 'NVARCHAR(6)', 'AllowedValues': None, 'SampleValues': '[\"en\",\"fr\",\"es\",\"de\"]'}, {'Name': 'Description', 'Definition': 'A detailed description of the product. This text provides additional information about the product, which can vary based on the culture or language.', 'Type': 'NVARCHAR(400)', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'vProductAndDescription', 'Description': 'This view provides detailed information about products, including their names, associated product models, descriptions, and the specific culture or language of the description. It is useful for understanding product details and translating product descriptions for different cultures.'}]\n", - "INFO:semantic_kernel.functions.kernel_function:Function SQL-GetEntitySchema succeeded.\n", - "INFO:semantic_kernel.functions.kernel_function:Function completed. Duration: 0.451198s\n", - "INFO:httpx:HTTP Request: POST https://aoai-text2sql-adi.openai.azure.com/openai/deployments/gpt-4o/chat/completions?api-version=2024-02-01 \"HTTP/1.1 200 OK\"\n", - "INFO:semantic_kernel.connectors.ai.open_ai.services.open_ai_handler:OpenAI usage: CompletionUsage(completion_tokens=34, prompt_tokens=3263, total_tokens=3297, completion_tokens_details=None)\n", - "INFO:semantic_kernel.connectors.ai.chat_completion_client_base:processing 1 tool calls in parallel.\n", - "INFO:semantic_kernel.kernel:Calling SQL-RunSQLQuery function with args: {\"sql_query\":\"SELECT ProductCategoryName, ParentProductCategoryName FROM SalesLT.vGetAllCategories;\"}\n", - "INFO:semantic_kernel.functions.kernel_function:Function SQL-RunSQLQuery invoking.\n", - "INFO:root:Executing SQL Query\n", - "INFO:root:SQL Statement: SELECT ProductCategoryName, ParentProductCategoryName FROM SalesLT.vGetAllCategories;\n", - "INFO:root:Filtering schemas against SQL statement\n", - "INFO:root:Schema: {'EntityName': 'Get All Categories', 'Columns': [{'Name': 'ProductCategoryID', 'Definition': 'A unique identifier for each product category. This ID is used to reference specific categories.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ParentProductCategoryName', 'Definition': 'The name of the parent product category. This represents the top-level category under which subcategories are grouped.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductCategoryName', 'Definition': 'The name of the product category. This can refer to either a top-level category or a subcategory, depending on the context.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'vGetAllCategories', 'Description': 'This view provides a comprehensive list of all product categories and their corresponding subcategories in the SalesLT schema of the AdventureWorksLT database. It is used to understand the hierarchical structure of product categories, facilitating product organization and categorization.', 'SelectFromEntity': 'SalesLT.vGetAllCategories'}\n", - "INFO:root:Entity: SalesLT.vGetAllCategories\n", - "INFO:root:Loaded Schema: {'EntityName': 'Get All Categories', 'Columns': [{'Name': 'ProductCategoryID', 'Definition': 'A unique identifier for each product category. This ID is used to reference specific categories.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ParentProductCategoryName', 'Definition': 'The name of the parent product category. This represents the top-level category under which subcategories are grouped.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductCategoryName', 'Definition': 'The name of the product category. This can refer to either a top-level category or a subcategory, depending on the context.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'vGetAllCategories', 'Description': 'This view provides a comprehensive list of all product categories and their corresponding subcategories in the SalesLT schema of the AdventureWorksLT database. It is used to understand the hierarchical structure of product categories, facilitating product organization and categorization.', 'SelectFromEntity': 'SalesLT.vGetAllCategories'}\n", - "INFO:semantic_kernel.functions.kernel_function:Function SQL-RunSQLQuery succeeded.\n", - "INFO:semantic_kernel.functions.kernel_function:Function completed. Duration: 0.397681s\n", - "INFO:root:Document: {'Question': 'What are the different product categories we have?', 'Query': 'SELECT ProductCategoryName, ParentProductCategoryName FROM SalesLT.vGetAllCategories;', 'Schemas': [{'Entity': 'vGetAllCategories', 'Columns': [{'Name': 'ProductCategoryID', 'Definition': 'A unique identifier for each product category. This ID is used to reference specific categories.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ParentProductCategoryName', 'Definition': 'The name of the parent product category. This represents the top-level category under which subcategories are grouped.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductCategoryName', 'Definition': 'The name of the product category. This can refer to either a top-level category or a subcategory, depending on the context.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}]}]}\n", - "INFO:root:Vector Fields: {'Question': 'QuestionEmbedding'}\n", - "INFO:httpx:HTTP Request: POST https://aoai-text2sql-adi.openai.azure.com/openai/deployments/text-embedding-ada-002/embeddings?api-version=2023-03-15-preview \"HTTP/1.1 200 OK\"\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Request URL: 'https://open-ai-vector-db.search.windows.net/indexes('text-2-sql-query-cache-index')/docs/search.index?api-version=REDACTED'\n", - "Request method: 'POST'\n", - "Request headers:\n", - " 'Content-Type': 'application/json'\n", - " 'Content-Length': '35643'\n", - " 'api-key': 'REDACTED'\n", - " 'Accept': 'application/json;odata.metadata=none'\n", - " 'x-ms-client-request-id': '9402c534-7784-11ef-822e-0242ac110002'\n", - " 'User-Agent': 'azsdk-python-search-documents/11.6.0b4 Python/3.12.6 (Linux-5.15.153.1-microsoft-standard-WSL2-x86_64-with-glibc2.36)'\n", - "A body is sent with the request\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Response status: 200\n", - "Response headers:\n", - " 'Transfer-Encoding': 'chunked'\n", - " 'Content-Type': 'application/json; odata.metadata=none; odata.streaming=true; charset=utf-8'\n", - " 'Content-Encoding': 'REDACTED'\n", - " 'Vary': 'REDACTED'\n", - " 'Server': 'Microsoft-IIS/10.0'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Preference-Applied': 'REDACTED'\n", - " 'OData-Version': 'REDACTED'\n", - " 'request-id': '9402c534-7784-11ef-822e-0242ac110002'\n", - " 'elapsed-time': 'REDACTED'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Date': 'Fri, 20 Sep 2024 19:14:39 GMT'\n", - "INFO:httpx:HTTP Request: POST https://aoai-text2sql-adi.openai.azure.com/openai/deployments/gpt-4o/chat/completions?api-version=2024-02-01 \"HTTP/1.1 200 OK\"\n", - "INFO:semantic_kernel.connectors.ai.open_ai.services.open_ai_handler:OpenAI usage: CompletionUsage(completion_tokens=607, prompt_tokens=4001, total_tokens=4608, completion_tokens_details=None)\n", - "INFO:semantic_kernel.functions.kernel_function:Function ChatBot-Chat succeeded.\n", - "INFO:semantic_kernel.functions.kernel_function:Function completed. Duration: 7.946406s\n", - "INFO:root:Answer: {\n", - " \"answer\": \"The product categories available are organised under four main parent categories: Accessories, Clothing, Components, and Bikes. Here are the details:\\n\\n### Accessories\\n- Bike Racks\\n- Bike Stands\\n- Bottles and Cages\\n- Cleaners\\n- Fenders\\n- Helmets\\n- Hydration Packs\\n- Lights\\n- Locks\\n- Panniers\\n- Pumps\\n- Tires and Tubes\\n\\n### Clothing\\n- Bib-Shorts\\n- Caps\\n- Gloves\\n- Jerseys\\n- Shorts\\n- Socks\\n- Tights\\n- Vests\\n\\n### Components\\n- Handlebars\\n- Bottom Brackets\\n- Brakes\\n- Chains\\n- Cranksets\\n- Derailleurs\\n- Forks\\n- Headsets\\n- Mountain Frames\\n- Pedals\\n- Road Frames\\n- Saddles\\n- Touring Frames\\n- Wheels\\n\\n### Bikes\\n- Mountain Bikes\\n- Road Bikes\\n- Touring Bikes\",\n", - " \"sources\": [\n", - " {\n", - " \"title\": \"vGetAllCategories\",\n", - " \"chunk\": \"| ProductCategoryName | ParentProductCategoryName |\\n|---------------------|--------------------------|\\n| Bike Racks | Accessories |\\n| Bike Stands | Accessories |\\n| Bottles and Cages | Accessories |\\n| Cleaners | Accessories |\\n| Fenders | Accessories |\\n| Helmets | Accessories |\\n| Hydration Packs | Accessories |\\n| Lights | Accessories |\\n| Locks | Accessories |\\n| Panniers | Accessories |\\n| Pumps | Accessories |\\n| Tires and Tubes | Accessories |\\n| Bib-Shorts | Clothing |\\n| Caps | Clothing |\\n| Gloves | Clothing |\\n| Jerseys | Clothing |\\n| Shorts | Clothing |\\n| Socks | Clothing |\\n| Tights | Clothing |\\n| Vests | Clothing |\\n| Handlebars | Components |\\n| Bottom Brackets | Components |\\n| Brakes | Components |\\n| Chains | Components |\\n| Cranksets | Components |\\n| Derailleurs | Components |\\n| Forks | Components |\\n| Headsets | Components |\\n| Mountain Frames | Components |\\n| Pedals | Components |\\n| Road Frames | Components |\\n| Saddles | Components |\\n| Touring Frames | Components |\\n| Wheels | Components |\\n| Mountain Bikes | Bikes |\\n| Road Bikes | Bikes |\\n| Touring Bikes | Bikes |\\n\",\n", - " \"reference\": \"SELECT ProductCategoryName, ParentProductCategoryName FROM SalesLT.vGetAllCategories;\"\n", - " }\n", - " ]\n", - "}\n" - ] - }, - { - "data": { - "text/markdown": [ - "The product categories available are organised under four main parent categories: Accessories, Clothing, Components, and Bikes. Here are the details:\n", - "\n", - "### Accessories\n", - "- Bike Racks\n", - "- Bike Stands\n", - "- Bottles and Cages\n", - "- Cleaners\n", - "- Fenders\n", - "- Helmets\n", - "- Hydration Packs\n", - "- Lights\n", - "- Locks\n", - "- Panniers\n", - "- Pumps\n", - "- Tires and Tubes\n", - "\n", - "### Clothing\n", - "- Bib-Shorts\n", - "- Caps\n", - "- Gloves\n", - "- Jerseys\n", - "- Shorts\n", - "- Socks\n", - "- Tights\n", - "- Vests\n", - "\n", - "### Components\n", - "- Handlebars\n", - "- Bottom Brackets\n", - "- Brakes\n", - "- Chains\n", - "- Cranksets\n", - "- Derailleurs\n", - "- Forks\n", - "- Headsets\n", - "- Mountain Frames\n", - "- Pedals\n", - "- Road Frames\n", - "- Saddles\n", - "- Touring Frames\n", - "- Wheels\n", - "\n", - "### Bikes\n", - "- Mountain Bikes\n", - "- Road Bikes\n", - "- Touring Bikes" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "await ask_question(\"What are the different product categories we have?\", history)" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "INFO:httpx:HTTP Request: POST https://aoai-text2sql-adi.openai.azure.com/openai/deployments/text-embedding-ada-002/embeddings?api-version=2023-03-15-preview \"HTTP/1.1 200 OK\"\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Request URL: 'https://open-ai-vector-db.search.windows.net/indexes('text-2-sql-query-cache-index')/docs/search.post.search?api-version=REDACTED'\n", - "Request method: 'POST'\n", - "Request headers:\n", - " 'Content-Type': 'application/json'\n", - " 'Content-Length': '34715'\n", - " 'api-key': 'REDACTED'\n", - " 'Accept': 'application/json;odata.metadata=none'\n", - " 'x-ms-client-request-id': '97849cdc-7784-11ef-822e-0242ac110002'\n", - " 'User-Agent': 'azsdk-python-search-documents/11.6.0b4 Python/3.12.6 (Linux-5.15.153.1-microsoft-standard-WSL2-x86_64-with-glibc2.36)'\n", - "A body is sent with the request\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Response status: 200\n", - "Response headers:\n", - " 'Transfer-Encoding': 'chunked'\n", - " 'Content-Type': 'application/json; odata.metadata=none; odata.streaming=true; charset=utf-8'\n", - " 'Content-Encoding': 'REDACTED'\n", - " 'Vary': 'REDACTED'\n", - " 'Server': 'Microsoft-IIS/10.0'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Preference-Applied': 'REDACTED'\n", - " 'OData-Version': 'REDACTED'\n", - " 'request-id': '97849cdc-7784-11ef-822e-0242ac110002'\n", - " 'elapsed-time': 'REDACTED'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Date': 'Fri, 20 Sep 2024 19:14:45 GMT'\n", - "INFO:root:Results: []\n", - "INFO:root:Question: What is the top performing product by quantity of units sold?\n", - "INFO:semantic_kernel.functions.kernel_function:Function ChatBot-Chat invoking.\n", - "INFO:semantic_kernel.contents.chat_history:Could not parse prompt \n", - "As a senior analyst, your primary responsibility is to provide accurate, thorough answers to user queries. Use all available functions to craft detailed final responses with clear explanations and actionable insights.\n", - "\n", - "- Always use the provided functions to obtain key information.\n", - "- If a function is required, you must use it to complement the answer.\n", - "- Use multiple functions in parallel to enhance the results.\n", - "- Always provide an answer; never leave it blank.\n", - "\n", - "The response must meet the following requirements:\n", - "\n", - "[RESPONSE OUTPUT REQUIREMENTS]\n", - "\n", - " The answer MUST be in JSON format:\n", - " {\n", - " \"answer\": \"\",\n", - " \"sources\": [\n", - " {\"title\": , \"chunk\": , \"reference\": \"\"},\n", - " {\"title\": , \"chunk\": , \"reference\": \"\"}\n", - " ]\n", - " }\n", - "\n", - " [ANSWER PROPERTY REQUIREMENTS]\n", - " - **Language & Tone**:\n", - " Use British English, business-friendly language that is professional and clear.\n", - " - **Content Restrictions**:\n", - " Avoid profanity, offensive language, and code. Rephrase or omit inappropriate content.\n", - " - **Information Sources**:\n", - " Only use provided functions and important information. Prioritize SQL Database data in case of conflicts.\n", - " - **Calculations**:\n", - " Use context-provided values and explain calculations briefly.\n", - " - **Structure**:\n", - " Responses must be direct, easy to understand, and formatted using Markdown.\n", - " Use Level 3 and 4 headings, bold sub-headings, and lists where appropriate. Keep font size consistent.\n", - " - **Citations**:\n", - " Factual statements must be cited using numbered references like [1]. Each citation must match a source in the 'sources' object.\n", - "\n", - " [SOURCES PROPERTY REQUIREMENTS]\n", - " - **Reference Inclusion**:\n", - " All cited content must have a corresponding reference in the 'sources' object.\n", - " - **Source Format**:\n", - " Each source must follow this format: {\"title\": \"\", \"chunk\": \"\", \"reference\": \"\"}\n", - " - **Source Chunk**:\n", - " Include a concise, unedited snippet of relevant context in the 'chunk' property.\n", - " - **Mandatory Citations**:\n", - " Every source listed must be cited at least once in the answer.\n", - "\n", - "[IMPORTANT INFORMATION]\n", - "\n", - "\n", - " [SQL DATABASE INFORMATION]\n", - " First consider the PRE-FETCHED SQL query and the results from execution. Consider if you can use this data to answer the question without running another SQL query. If the data is sufficient, use it to answer the question instead of running a new query.\n", - "\n", - " \n", - "\n", - " If this data or query will not answer the question, look at the provided CACHED QUERIES AND SCHEMAS below, to see if you can use them to formulate a SQL query.\n", - "\n", - " \n", - "\n", - " Finally, if you can't use or adjust a previous generated SQL query, use the 'GetEntitySchema()' function to search for the most relevant schemas for the data that you wish to obtain.\n", - "\n", - " If needed, use the 'RunSQLQuery()' function to run the SQL query against the database. Never just return the SQL query as the answer.\n", - "\n", - " Output corresponding text values in the answer for columns where there is an ID. For example, if the column is 'ProductID', output the corresponding 'ProductModel' in the response. Do not include the ID in the response.\n", - " If a user is asking for a comparison, always compare the relevant values in the database.\n", - "\n", - " Only use schema / column information provided as part of this prompt or from the 'GetEntitySchema()' function output when constructing a SQL query. Do not use any other entities and columns in your SQL query, other than those defined above.\n", - " Do not makeup or guess column names.\n", - "\n", - " The target database engine is Microsoft TSQL Server, SQL queries must be able compatible to run on Microsoft TSQL Server. \n", - " The following Microsoft TSQL Server Syntax rules must be adhered to.\n", - " Use TOP X to limit the number of rows returned instead of LIMIT X. NEVER USE LIMIT X as it produces a syntax error.\n", - " You must only provide SELECT SQL queries.\n", - " For a given entity, use the 'SelectFromEntity' property returned in the schema in the SELECT FROM part of the SQL query. If the property is {'SelectFromEntity': 'test_schema.test_table'}, the select statement will be formulated from 'SELECT <VALUES> FROM test_schema.test_table WHERE <CONDITION>.\n", - "\n", - " If you don't know how the value is formatted in a column, run a query against the column to get the unique values that might match your query.\n", - " Some columns in the schema may have the properties 'AllowedValues' or 'SampleValues'. Use these values to determine the possible values that can be used in the SQL query.\n", - "\n", - " The source title to cite is the 'EntityName' property. The source reference is the SQL query used. The source chunk is the result of the SQL query used to answer the user query in Markdown table format. e.g. { 'title': "vProductAndDescription", 'chunk': '| ProductID | Name | ProductModel | Culture | Description |\\n|-----------|-------------------|--------------|---------|----------------------------------|\\n| 101 | Mountain Bike | MT-100 | en | A durable bike for mountain use. |\\n| 102 | Road Bike | RB-200 | en | Lightweight bike for road use. |\\n| 103 | Hybrid Bike | HB-300 | fr | V\u00e9lo hybride pour usage mixte. |\\n', 'reference': 'SELECT ProductID, Name, ProductModel, Culture, Description FROM vProductAndDescription WHERE Culture = "en";' }\n", - " [END SQL DATABASE INFORMATION]\n", - " \n", - "\n", - "[END]\n", - "\n", - "What are the different product categories we have?\n", - "What is the top performing product by quantity of units sold? as xml, treating as text, error was: not well-formed (invalid token): line 15, column 32\n", - "INFO:httpx:HTTP Request: POST https://aoai-text2sql-adi.openai.azure.com/openai/deployments/gpt-4o/chat/completions?api-version=2024-02-01 \"HTTP/1.1 200 OK\"\n", - "INFO:semantic_kernel.connectors.ai.open_ai.services.open_ai_handler:OpenAI usage: CompletionUsage(completion_tokens=52, prompt_tokens=1432, total_tokens=1484, completion_tokens_details=None)\n", - "INFO:semantic_kernel.connectors.ai.chat_completion_client_base:processing 2 tool calls in parallel.\n", - "INFO:semantic_kernel.kernel:Calling SQL-GetEntitySchema function with args: {\"text\": \"product sales\"}\n", - "INFO:semantic_kernel.functions.kernel_function:Function SQL-GetEntitySchema invoking.\n", - "INFO:semantic_kernel.kernel:Calling SQL-GetEntitySchema function with args: {\"text\": \"product categories\"}\n", - "INFO:semantic_kernel.functions.kernel_function:Function SQL-GetEntitySchema invoking.\n", - "INFO:httpx:HTTP Request: POST https://aoai-text2sql-adi.openai.azure.com/openai/deployments/text-embedding-ada-002/embeddings?api-version=2023-03-15-preview \"HTTP/1.1 200 OK\"\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Request URL: 'https://open-ai-vector-db.search.windows.net/indexes('text-2-sql-index')/docs/search.post.search?api-version=REDACTED'\n", - "Request method: 'POST'\n", - "Request headers:\n", - " 'Content-Type': 'application/json'\n", - " 'Content-Length': '34770'\n", - " 'api-key': 'REDACTED'\n", - " 'Accept': 'application/json;odata.metadata=none'\n", - " 'x-ms-client-request-id': '9838c518-7784-11ef-822e-0242ac110002'\n", - " 'User-Agent': 'azsdk-python-search-documents/11.6.0b4 Python/3.12.6 (Linux-5.15.153.1-microsoft-standard-WSL2-x86_64-with-glibc2.36)'\n", - "A body is sent with the request\n", - "INFO:httpx:HTTP Request: POST https://aoai-text2sql-adi.openai.azure.com/openai/deployments/text-embedding-ada-002/embeddings?api-version=2023-03-15-preview \"HTTP/1.1 200 OK\"\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Request URL: 'https://open-ai-vector-db.search.windows.net/indexes('text-2-sql-index')/docs/search.post.search?api-version=REDACTED'\n", - "Request method: 'POST'\n", - "Request headers:\n", - " 'Content-Type': 'application/json'\n", - " 'Content-Length': '34746'\n", - " 'api-key': 'REDACTED'\n", - " 'Accept': 'application/json;odata.metadata=none'\n", - " 'x-ms-client-request-id': '9840725e-7784-11ef-822e-0242ac110002'\n", - " 'User-Agent': 'azsdk-python-search-documents/11.6.0b4 Python/3.12.6 (Linux-5.15.153.1-microsoft-standard-WSL2-x86_64-with-glibc2.36)'\n", - "A body is sent with the request\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Response status: 200\n", - "Response headers:\n", - " 'Transfer-Encoding': 'chunked'\n", - " 'Content-Type': 'application/json; odata.metadata=none; odata.streaming=true; charset=utf-8'\n", - " 'Content-Encoding': 'REDACTED'\n", - " 'Vary': 'REDACTED'\n", - " 'Server': 'Microsoft-IIS/10.0'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Preference-Applied': 'REDACTED'\n", - " 'OData-Version': 'REDACTED'\n", - " 'request-id': '9838c518-7784-11ef-822e-0242ac110002'\n", - " 'elapsed-time': 'REDACTED'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Date': 'Fri, 20 Sep 2024 19:14:47 GMT'\n", - "INFO:root:Item: {'EntityName': 'Get All Categories', 'Columns': [{'Name': 'ProductCategoryID', 'Definition': 'A unique identifier for each product category. This ID is used to reference specific categories.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ParentProductCategoryName', 'Definition': 'The name of the parent product category. This represents the top-level category under which subcategories are grouped.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductCategoryName', 'Definition': 'The name of the product category. This can refer to either a top-level category or a subcategory, depending on the context.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'vGetAllCategories', 'Description': 'This view provides a comprehensive list of all product categories and their corresponding subcategories in the SalesLT schema of the AdventureWorksLT database. It is used to understand the hierarchical structure of product categories, facilitating product organization and categorization.'}\n", - "INFO:root:Item: {'EntityName': 'Product Model Catalog Description', 'Columns': [{'Name': 'ProductModelID', 'Definition': 'A unique identifier for each product model. This ID is used to distinguish different product models.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Name', 'Definition': 'The name of the product model, providing a recognizable title for each model.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Summary', 'Definition': 'A brief summary of the product model, highlighting key features and characteristics.', 'Type': 'NVARCHAR(MAX)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Manufacturer', 'Definition': 'The name of the manufacturer of the product model.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Copyright', 'Definition': 'Copyright information related to the product model, indicating the legal ownership of the product design and content.', 'Type': 'NVARCHAR(30)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductURL', 'Definition': 'The URL for the product model, providing a link to more information or to purchase the product.', 'Type': 'NVARCHAR(256)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'WarrantyPeriod', 'Definition': 'The duration of the warranty period for the product model, specifying how long the warranty is valid.', 'Type': 'NVARCHAR(30)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'WarrantyDescription', 'Definition': 'A description of the warranty provided for the product model, detailing what is covered under the warranty.', 'Type': 'NVARCHAR(255)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'NoOfYears', 'Definition': 'The number of years the warranty is valid for the product model.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'MaintenanceDescription', 'Definition': 'A description of the maintenance requirements and recommendations for the product model.', 'Type': 'NVARCHAR(MAX)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Wheel', 'Definition': 'Details about the type of wheels used in the product model.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Saddle', 'Definition': 'Information about the saddle of the product model, such as material and design.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Pedal', 'Definition': 'Details regarding the pedal design and specifications of the product model.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'BikeFrame', 'Definition': 'Description of the bike frame used in the product model, including material and type.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Crankset', 'Definition': 'Information about the crankset of the product model, specifying its design and features.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PictureAngle', 'Definition': 'The angle at which the product model is photographed, providing a visual perspective of the product.', 'Type': 'NVARCHAR(20)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PictureSize', 'Definition': \"The size of the product model's picture, specifying dimensions or resolution.\", 'Type': 'NVARCHAR(20)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductPhotoID', 'Definition': 'An identifier linking to the product photo, which provides a visual representation of the product model.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Material', 'Definition': 'The material used in the construction of the product model, indicating durability and quality.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Color', 'Definition': 'The color of the product model, providing information about the appearance of the product.', 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductLine', 'Definition': 'A code representing the product line to which the model belongs, categorizing the product within a broader product range.', 'Type': 'NVARCHAR(2)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Style', 'Definition': 'The style of the product model, indicating design and aesthetic aspects.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'RiderExperience', 'Definition': \"A description of the target rider's experience level for which the product model is designed, such as beginner, intermediate, or expert.\", 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the product model information was last modified, indicating the currency of the data.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'vProductModelCatalogDescription', 'Description': 'This view provides detailed catalog information about product models, including descriptions, manufacturing details, warranty information, and specifications related to product design and features. It is useful for generating comprehensive product catalogs and providing detailed product information to customers.'}\n", - "INFO:root:Item: {'EntityName': 'Product and Description', 'Columns': [{'Name': 'ProductID', 'Definition': 'A unique identifier for each product. This ID is used to distinguish individual products.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Name', 'Definition': 'The name of the product. This provides a brief and identifiable name for each product.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductModel', 'Definition': 'The model name associated with the product. This indicates the specific model type or version of the product.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Culture', 'Definition': \"The culture or language code for the product description. This is used to localize the product description, such as 'en' for English or 'fr' for French.\", 'Type': 'NVARCHAR(6)', 'AllowedValues': None, 'SampleValues': '[\"en\",\"fr\",\"es\",\"de\"]'}, {'Name': 'Description', 'Definition': 'A detailed description of the product. This text provides additional information about the product, which can vary based on the culture or language.', 'Type': 'NVARCHAR(400)', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'vProductAndDescription', 'Description': 'This view provides detailed information about products, including their names, associated product models, descriptions, and the specific culture or language of the description. It is useful for understanding product details and translating product descriptions for different cultures.'}\n", - "INFO:root:Results: [{'EntityName': 'Get All Categories', 'Columns': [{'Name': 'ProductCategoryID', 'Definition': 'A unique identifier for each product category. This ID is used to reference specific categories.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ParentProductCategoryName', 'Definition': 'The name of the parent product category. This represents the top-level category under which subcategories are grouped.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductCategoryName', 'Definition': 'The name of the product category. This can refer to either a top-level category or a subcategory, depending on the context.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'vGetAllCategories', 'Description': 'This view provides a comprehensive list of all product categories and their corresponding subcategories in the SalesLT schema of the AdventureWorksLT database. It is used to understand the hierarchical structure of product categories, facilitating product organization and categorization.'}, {'EntityName': 'Product Model Catalog Description', 'Columns': [{'Name': 'ProductModelID', 'Definition': 'A unique identifier for each product model. This ID is used to distinguish different product models.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Name', 'Definition': 'The name of the product model, providing a recognizable title for each model.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Summary', 'Definition': 'A brief summary of the product model, highlighting key features and characteristics.', 'Type': 'NVARCHAR(MAX)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Manufacturer', 'Definition': 'The name of the manufacturer of the product model.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Copyright', 'Definition': 'Copyright information related to the product model, indicating the legal ownership of the product design and content.', 'Type': 'NVARCHAR(30)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductURL', 'Definition': 'The URL for the product model, providing a link to more information or to purchase the product.', 'Type': 'NVARCHAR(256)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'WarrantyPeriod', 'Definition': 'The duration of the warranty period for the product model, specifying how long the warranty is valid.', 'Type': 'NVARCHAR(30)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'WarrantyDescription', 'Definition': 'A description of the warranty provided for the product model, detailing what is covered under the warranty.', 'Type': 'NVARCHAR(255)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'NoOfYears', 'Definition': 'The number of years the warranty is valid for the product model.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'MaintenanceDescription', 'Definition': 'A description of the maintenance requirements and recommendations for the product model.', 'Type': 'NVARCHAR(MAX)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Wheel', 'Definition': 'Details about the type of wheels used in the product model.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Saddle', 'Definition': 'Information about the saddle of the product model, such as material and design.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Pedal', 'Definition': 'Details regarding the pedal design and specifications of the product model.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'BikeFrame', 'Definition': 'Description of the bike frame used in the product model, including material and type.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Crankset', 'Definition': 'Information about the crankset of the product model, specifying its design and features.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PictureAngle', 'Definition': 'The angle at which the product model is photographed, providing a visual perspective of the product.', 'Type': 'NVARCHAR(20)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PictureSize', 'Definition': \"The size of the product model's picture, specifying dimensions or resolution.\", 'Type': 'NVARCHAR(20)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductPhotoID', 'Definition': 'An identifier linking to the product photo, which provides a visual representation of the product model.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Material', 'Definition': 'The material used in the construction of the product model, indicating durability and quality.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Color', 'Definition': 'The color of the product model, providing information about the appearance of the product.', 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductLine', 'Definition': 'A code representing the product line to which the model belongs, categorizing the product within a broader product range.', 'Type': 'NVARCHAR(2)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Style', 'Definition': 'The style of the product model, indicating design and aesthetic aspects.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'RiderExperience', 'Definition': \"A description of the target rider's experience level for which the product model is designed, such as beginner, intermediate, or expert.\", 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the product model information was last modified, indicating the currency of the data.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'vProductModelCatalogDescription', 'Description': 'This view provides detailed catalog information about product models, including descriptions, manufacturing details, warranty information, and specifications related to product design and features. It is useful for generating comprehensive product catalogs and providing detailed product information to customers.'}, {'EntityName': 'Product and Description', 'Columns': [{'Name': 'ProductID', 'Definition': 'A unique identifier for each product. This ID is used to distinguish individual products.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Name', 'Definition': 'The name of the product. This provides a brief and identifiable name for each product.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductModel', 'Definition': 'The model name associated with the product. This indicates the specific model type or version of the product.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Culture', 'Definition': \"The culture or language code for the product description. This is used to localize the product description, such as 'en' for English or 'fr' for French.\", 'Type': 'NVARCHAR(6)', 'AllowedValues': None, 'SampleValues': '[\"en\",\"fr\",\"es\",\"de\"]'}, {'Name': 'Description', 'Definition': 'A detailed description of the product. This text provides additional information about the product, which can vary based on the culture or language.', 'Type': 'NVARCHAR(400)', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'vProductAndDescription', 'Description': 'This view provides detailed information about products, including their names, associated product models, descriptions, and the specific culture or language of the description. It is useful for understanding product details and translating product descriptions for different cultures.'}]\n", - "INFO:semantic_kernel.functions.kernel_function:Function SQL-GetEntitySchema succeeded.\n", - "INFO:semantic_kernel.functions.kernel_function:Function completed. Duration: 0.589778s\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Response status: 200\n", - "Response headers:\n", - " 'Transfer-Encoding': 'chunked'\n", - " 'Content-Type': 'application/json; odata.metadata=none; odata.streaming=true; charset=utf-8'\n", - " 'Content-Encoding': 'REDACTED'\n", - " 'Vary': 'REDACTED'\n", - " 'Server': 'Microsoft-IIS/10.0'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Preference-Applied': 'REDACTED'\n", - " 'OData-Version': 'REDACTED'\n", - " 'request-id': '9840725e-7784-11ef-822e-0242ac110002'\n", - " 'elapsed-time': 'REDACTED'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Date': 'Fri, 20 Sep 2024 19:14:46 GMT'\n", - "INFO:root:Item: {'EntityName': 'Sales Order Header', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order. This ID is auto-generated and serves as the primary key for the SalesOrderHeader table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This field is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'OnlineOrderFlag', 'Definition': 'Indicates whether the order was placed online.', 'Type': 'BIT', 'AllowedValues': '[\"True\",\"False\"]', 'SampleValues': None}, {'Name': 'SalesOrderNumber', 'Definition': 'A unique order number assigned to the sales order. This is used for tracking and identification purposes.', 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PurchaseOrderNumber', 'Definition': \"The purchase order number provided by the customer. This field links the sales order to the customer's purchase order.\", 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'AccountNumber', 'Definition': \"The account number of the customer placing the order. This helps link the order to the customer's account.\", 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CustomerID', 'Definition': 'A foreign key that links to the Customer table, representing the customer who placed the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the shipping address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'BillToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the billing address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipMethod', 'Definition': 'The shipping method used for the order (e.g., UPS, FedEx). This field helps track shipping preferences.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'SubTotal', 'Definition': 'The total cost of the order before taxes and shipping charges. This field is used to calculate the final total. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TaxAmt', 'Definition': 'The tax amount applied to the order. This is calculated based on the order subtotal and applicable tax rates. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Freight', 'Definition': 'The shipping charge applied to the order. This field represents the cost of shipping the order to the customer. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Comment', 'Definition': 'Any additional comments or notes related to the sales order. This field can include special instructions or remarks.', 'Type': 'NVARCHAR(255)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order header record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'SalesOrderHeader', 'Description': 'This table contains high-level information about sales orders, including order dates, customer details, shipping information, and order status. It is used to manage and track sales orders from initiation to fulfillment.'}\n", - "INFO:root:Item: {'EntityName': 'Sales Order Detail', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order ticket. This ID is auto-generated and serves as the primary key for the SalesOrderTicket table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges.', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order ticket record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'SalesOrderDetail', 'Description': 'This table stores detailed information about sales order tickets, including the order details, customer information, order status, and timestamps. It is used to manage and track sales orders throughout the order lifecycle, from creation to fulfillment.'}\n", - "INFO:root:Item: {'EntityName': 'Get All Categories', 'Columns': [{'Name': 'ProductCategoryID', 'Definition': 'A unique identifier for each product category. This ID is used to reference specific categories.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ParentProductCategoryName', 'Definition': 'The name of the parent product category. This represents the top-level category under which subcategories are grouped.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductCategoryName', 'Definition': 'The name of the product category. This can refer to either a top-level category or a subcategory, depending on the context.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'vGetAllCategories', 'Description': 'This view provides a comprehensive list of all product categories and their corresponding subcategories in the SalesLT schema of the AdventureWorksLT database. It is used to understand the hierarchical structure of product categories, facilitating product organization and categorization.'}\n", - "INFO:root:Results: [{'EntityName': 'Sales Order Header', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order. This ID is auto-generated and serves as the primary key for the SalesOrderHeader table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This field is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'OnlineOrderFlag', 'Definition': 'Indicates whether the order was placed online.', 'Type': 'BIT', 'AllowedValues': '[\"True\",\"False\"]', 'SampleValues': None}, {'Name': 'SalesOrderNumber', 'Definition': 'A unique order number assigned to the sales order. This is used for tracking and identification purposes.', 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PurchaseOrderNumber', 'Definition': \"The purchase order number provided by the customer. This field links the sales order to the customer's purchase order.\", 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'AccountNumber', 'Definition': \"The account number of the customer placing the order. This helps link the order to the customer's account.\", 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CustomerID', 'Definition': 'A foreign key that links to the Customer table, representing the customer who placed the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the shipping address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'BillToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the billing address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipMethod', 'Definition': 'The shipping method used for the order (e.g., UPS, FedEx). This field helps track shipping preferences.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'SubTotal', 'Definition': 'The total cost of the order before taxes and shipping charges. This field is used to calculate the final total. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TaxAmt', 'Definition': 'The tax amount applied to the order. This is calculated based on the order subtotal and applicable tax rates. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Freight', 'Definition': 'The shipping charge applied to the order. This field represents the cost of shipping the order to the customer. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Comment', 'Definition': 'Any additional comments or notes related to the sales order. This field can include special instructions or remarks.', 'Type': 'NVARCHAR(255)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order header record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'SalesOrderHeader', 'Description': 'This table contains high-level information about sales orders, including order dates, customer details, shipping information, and order status. It is used to manage and track sales orders from initiation to fulfillment.'}, {'EntityName': 'Sales Order Detail', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order ticket. This ID is auto-generated and serves as the primary key for the SalesOrderTicket table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges.', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order ticket record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'SalesOrderDetail', 'Description': 'This table stores detailed information about sales order tickets, including the order details, customer information, order status, and timestamps. It is used to manage and track sales orders throughout the order lifecycle, from creation to fulfillment.'}, {'EntityName': 'Get All Categories', 'Columns': [{'Name': 'ProductCategoryID', 'Definition': 'A unique identifier for each product category. This ID is used to reference specific categories.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ParentProductCategoryName', 'Definition': 'The name of the parent product category. This represents the top-level category under which subcategories are grouped.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductCategoryName', 'Definition': 'The name of the product category. This can refer to either a top-level category or a subcategory, depending on the context.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'vGetAllCategories', 'Description': 'This view provides a comprehensive list of all product categories and their corresponding subcategories in the SalesLT schema of the AdventureWorksLT database. It is used to understand the hierarchical structure of product categories, facilitating product organization and categorization.'}]\n", - "INFO:semantic_kernel.functions.kernel_function:Function SQL-GetEntitySchema succeeded.\n", - "INFO:semantic_kernel.functions.kernel_function:Function completed. Duration: 0.653652s\n", - "INFO:httpx:HTTP Request: POST https://aoai-text2sql-adi.openai.azure.com/openai/deployments/gpt-4o/chat/completions?api-version=2024-02-01 \"HTTP/1.1 200 OK\"\n", - "INFO:semantic_kernel.connectors.ai.open_ai.services.open_ai_handler:OpenAI usage: CompletionUsage(completion_tokens=104, prompt_tokens=5142, total_tokens=5246, completion_tokens_details=None)\n", - "INFO:semantic_kernel.connectors.ai.chat_completion_client_base:processing 2 tool calls in parallel.\n", - "INFO:semantic_kernel.kernel:Calling SQL-RunSQLQuery function with args: {\"sql_query\": \"SELECT TOP 1 ProductID, SUM(OrderQty) as TotalUnitsSold FROM SalesLT.SalesOrderDetail GROUP BY ProductID ORDER BY TotalUnitsSold DESC;\"}\n", - "INFO:semantic_kernel.functions.kernel_function:Function SQL-RunSQLQuery invoking.\n", - "INFO:root:Executing SQL Query\n", - "INFO:semantic_kernel.kernel:Calling SQL-RunSQLQuery function with args: {\"sql_query\": \"SELECT ProductCategoryID, ParentProductCategoryName, ProductCategoryName FROM SalesLT.vGetAllCategories;\"}\n", - "INFO:semantic_kernel.functions.kernel_function:Function SQL-RunSQLQuery invoking.\n", - "INFO:root:Executing SQL Query\n", - "INFO:root:SQL Statement: SELECT TOP 1 ProductID, SUM(OrderQty) as TotalUnitsSold FROM SalesLT.SalesOrderDetail GROUP BY ProductID ORDER BY TotalUnitsSold DESC;\n", - "INFO:root:Filtering schemas against SQL statement\n", - "INFO:root:Schema: {'EntityName': 'Get All Categories', 'Columns': [{'Name': 'ProductCategoryID', 'Definition': 'A unique identifier for each product category. This ID is used to reference specific categories.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ParentProductCategoryName', 'Definition': 'The name of the parent product category. This represents the top-level category under which subcategories are grouped.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductCategoryName', 'Definition': 'The name of the product category. This can refer to either a top-level category or a subcategory, depending on the context.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'vGetAllCategories', 'Description': 'This view provides a comprehensive list of all product categories and their corresponding subcategories in the SalesLT schema of the AdventureWorksLT database. It is used to understand the hierarchical structure of product categories, facilitating product organization and categorization.', 'SelectFromEntity': 'SalesLT.vGetAllCategories'}\n", - "INFO:root:Entity: SalesLT.vGetAllCategories\n", - "INFO:root:Schema: {'EntityName': 'Product Model Catalog Description', 'Columns': [{'Name': 'ProductModelID', 'Definition': 'A unique identifier for each product model. This ID is used to distinguish different product models.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Name', 'Definition': 'The name of the product model, providing a recognizable title for each model.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Summary', 'Definition': 'A brief summary of the product model, highlighting key features and characteristics.', 'Type': 'NVARCHAR(MAX)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Manufacturer', 'Definition': 'The name of the manufacturer of the product model.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Copyright', 'Definition': 'Copyright information related to the product model, indicating the legal ownership of the product design and content.', 'Type': 'NVARCHAR(30)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductURL', 'Definition': 'The URL for the product model, providing a link to more information or to purchase the product.', 'Type': 'NVARCHAR(256)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'WarrantyPeriod', 'Definition': 'The duration of the warranty period for the product model, specifying how long the warranty is valid.', 'Type': 'NVARCHAR(30)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'WarrantyDescription', 'Definition': 'A description of the warranty provided for the product model, detailing what is covered under the warranty.', 'Type': 'NVARCHAR(255)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'NoOfYears', 'Definition': 'The number of years the warranty is valid for the product model.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'MaintenanceDescription', 'Definition': 'A description of the maintenance requirements and recommendations for the product model.', 'Type': 'NVARCHAR(MAX)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Wheel', 'Definition': 'Details about the type of wheels used in the product model.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Saddle', 'Definition': 'Information about the saddle of the product model, such as material and design.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Pedal', 'Definition': 'Details regarding the pedal design and specifications of the product model.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'BikeFrame', 'Definition': 'Description of the bike frame used in the product model, including material and type.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Crankset', 'Definition': 'Information about the crankset of the product model, specifying its design and features.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PictureAngle', 'Definition': 'The angle at which the product model is photographed, providing a visual perspective of the product.', 'Type': 'NVARCHAR(20)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PictureSize', 'Definition': \"The size of the product model's picture, specifying dimensions or resolution.\", 'Type': 'NVARCHAR(20)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductPhotoID', 'Definition': 'An identifier linking to the product photo, which provides a visual representation of the product model.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Material', 'Definition': 'The material used in the construction of the product model, indicating durability and quality.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Color', 'Definition': 'The color of the product model, providing information about the appearance of the product.', 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductLine', 'Definition': 'A code representing the product line to which the model belongs, categorizing the product within a broader product range.', 'Type': 'NVARCHAR(2)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Style', 'Definition': 'The style of the product model, indicating design and aesthetic aspects.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'RiderExperience', 'Definition': \"A description of the target rider's experience level for which the product model is designed, such as beginner, intermediate, or expert.\", 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the product model information was last modified, indicating the currency of the data.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'vProductModelCatalogDescription', 'Description': 'This view provides detailed catalog information about product models, including descriptions, manufacturing details, warranty information, and specifications related to product design and features. It is useful for generating comprehensive product catalogs and providing detailed product information to customers.', 'SelectFromEntity': 'SalesLT.vProductModelCatalogDescription'}\n", - "INFO:root:Entity: SalesLT.vProductModelCatalogDescription\n", - "INFO:root:Schema: {'EntityName': 'Product and Description', 'Columns': [{'Name': 'ProductID', 'Definition': 'A unique identifier for each product. This ID is used to distinguish individual products.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Name', 'Definition': 'The name of the product. This provides a brief and identifiable name for each product.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductModel', 'Definition': 'The model name associated with the product. This indicates the specific model type or version of the product.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Culture', 'Definition': \"The culture or language code for the product description. This is used to localize the product description, such as 'en' for English or 'fr' for French.\", 'Type': 'NVARCHAR(6)', 'AllowedValues': None, 'SampleValues': '[\"en\",\"fr\",\"es\",\"de\"]'}, {'Name': 'Description', 'Definition': 'A detailed description of the product. This text provides additional information about the product, which can vary based on the culture or language.', 'Type': 'NVARCHAR(400)', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'vProductAndDescription', 'Description': 'This view provides detailed information about products, including their names, associated product models, descriptions, and the specific culture or language of the description. It is useful for understanding product details and translating product descriptions for different cultures.', 'SelectFromEntity': 'SalesLT.vProductAndDescription'}\n", - "INFO:root:Entity: SalesLT.vProductAndDescription\n", - "INFO:root:Schema: {'EntityName': 'Sales Order Header', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order. This ID is auto-generated and serves as the primary key for the SalesOrderHeader table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This field is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'OnlineOrderFlag', 'Definition': 'Indicates whether the order was placed online.', 'Type': 'BIT', 'AllowedValues': '[\"True\",\"False\"]', 'SampleValues': None}, {'Name': 'SalesOrderNumber', 'Definition': 'A unique order number assigned to the sales order. This is used for tracking and identification purposes.', 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PurchaseOrderNumber', 'Definition': \"The purchase order number provided by the customer. This field links the sales order to the customer's purchase order.\", 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'AccountNumber', 'Definition': \"The account number of the customer placing the order. This helps link the order to the customer's account.\", 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CustomerID', 'Definition': 'A foreign key that links to the Customer table, representing the customer who placed the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the shipping address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'BillToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the billing address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipMethod', 'Definition': 'The shipping method used for the order (e.g., UPS, FedEx). This field helps track shipping preferences.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'SubTotal', 'Definition': 'The total cost of the order before taxes and shipping charges. This field is used to calculate the final total. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TaxAmt', 'Definition': 'The tax amount applied to the order. This is calculated based on the order subtotal and applicable tax rates. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Freight', 'Definition': 'The shipping charge applied to the order. This field represents the cost of shipping the order to the customer. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Comment', 'Definition': 'Any additional comments or notes related to the sales order. This field can include special instructions or remarks.', 'Type': 'NVARCHAR(255)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order header record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'SalesOrderHeader', 'Description': 'This table contains high-level information about sales orders, including order dates, customer details, shipping information, and order status. It is used to manage and track sales orders from initiation to fulfillment.', 'SelectFromEntity': 'SalesLT.SalesOrderHeader'}\n", - "INFO:root:Entity: SalesLT.SalesOrderHeader\n", - "INFO:root:Schema: {'EntityName': 'Sales Order Detail', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order ticket. This ID is auto-generated and serves as the primary key for the SalesOrderTicket table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges.', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order ticket record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'SalesOrderDetail', 'Description': 'This table stores detailed information about sales order tickets, including the order details, customer information, order status, and timestamps. It is used to manage and track sales orders throughout the order lifecycle, from creation to fulfillment.', 'SelectFromEntity': 'SalesLT.SalesOrderDetail'}\n", - "INFO:root:Entity: SalesLT.SalesOrderDetail\n", - "INFO:root:Loaded Schema: {'EntityName': 'Sales Order Detail', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order ticket. This ID is auto-generated and serves as the primary key for the SalesOrderTicket table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges.', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order ticket record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'SalesOrderDetail', 'Description': 'This table stores detailed information about sales order tickets, including the order details, customer information, order status, and timestamps. It is used to manage and track sales orders throughout the order lifecycle, from creation to fulfillment.', 'SelectFromEntity': 'SalesLT.SalesOrderDetail'}\n", - "INFO:semantic_kernel.functions.kernel_function:Function SQL-RunSQLQuery succeeded.\n", - "INFO:semantic_kernel.functions.kernel_function:Function completed. Duration: 0.372590s\n", - "INFO:root:Document: {'Question': 'What is the top performing product by quantity of units sold?', 'Query': 'SELECT TOP 1 ProductID, SUM(OrderQty) as TotalUnitsSold FROM SalesLT.SalesOrderDetail GROUP BY ProductID ORDER BY TotalUnitsSold DESC;', 'Schemas': [{'Entity': 'SalesOrderDetail', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order ticket. This ID is auto-generated and serves as the primary key for the SalesOrderTicket table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges.', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order ticket record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}]}]}\n", - "INFO:root:Vector Fields: {'Question': 'QuestionEmbedding'}\n", - "INFO:root:SQL Statement: SELECT ProductCategoryID, ParentProductCategoryName, ProductCategoryName FROM SalesLT.vGetAllCategories;\n", - "INFO:root:Filtering schemas against SQL statement\n", - "INFO:root:Schema: {'EntityName': 'Get All Categories', 'Columns': [{'Name': 'ProductCategoryID', 'Definition': 'A unique identifier for each product category. This ID is used to reference specific categories.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ParentProductCategoryName', 'Definition': 'The name of the parent product category. This represents the top-level category under which subcategories are grouped.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductCategoryName', 'Definition': 'The name of the product category. This can refer to either a top-level category or a subcategory, depending on the context.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'vGetAllCategories', 'Description': 'This view provides a comprehensive list of all product categories and their corresponding subcategories in the SalesLT schema of the AdventureWorksLT database. It is used to understand the hierarchical structure of product categories, facilitating product organization and categorization.', 'SelectFromEntity': 'SalesLT.vGetAllCategories'}\n", - "INFO:root:Entity: SalesLT.vGetAllCategories\n", - "INFO:root:Loaded Schema: {'EntityName': 'Get All Categories', 'Columns': [{'Name': 'ProductCategoryID', 'Definition': 'A unique identifier for each product category. This ID is used to reference specific categories.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ParentProductCategoryName', 'Definition': 'The name of the parent product category. This represents the top-level category under which subcategories are grouped.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductCategoryName', 'Definition': 'The name of the product category. This can refer to either a top-level category or a subcategory, depending on the context.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'vGetAllCategories', 'Description': 'This view provides a comprehensive list of all product categories and their corresponding subcategories in the SalesLT schema of the AdventureWorksLT database. It is used to understand the hierarchical structure of product categories, facilitating product organization and categorization.', 'SelectFromEntity': 'SalesLT.vGetAllCategories'}\n", - "INFO:semantic_kernel.functions.kernel_function:Function SQL-RunSQLQuery succeeded.\n", - "INFO:semantic_kernel.functions.kernel_function:Function completed. Duration: 0.455522s\n", - "INFO:root:Document: {'Question': 'What is the top performing product by quantity of units sold?', 'Query': 'SELECT ProductCategoryID, ParentProductCategoryName, ProductCategoryName FROM SalesLT.vGetAllCategories;', 'Schemas': [{'Entity': 'vGetAllCategories', 'Columns': [{'Name': 'ProductCategoryID', 'Definition': 'A unique identifier for each product category. This ID is used to reference specific categories.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ParentProductCategoryName', 'Definition': 'The name of the parent product category. This represents the top-level category under which subcategories are grouped.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductCategoryName', 'Definition': 'The name of the product category. This can refer to either a top-level category or a subcategory, depending on the context.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}]}]}\n", - "INFO:root:Vector Fields: {'Question': 'QuestionEmbedding'}\n", - "INFO:httpx:HTTP Request: POST https://aoai-text2sql-adi.openai.azure.com/openai/deployments/text-embedding-ada-002/embeddings?api-version=2023-03-15-preview \"HTTP/1.1 200 OK\"\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Request URL: 'https://open-ai-vector-db.search.windows.net/indexes('text-2-sql-query-cache-index')/docs/search.index?api-version=REDACTED'\n", - "Request method: 'POST'\n", - "Request headers:\n", - " 'Content-Type': 'application/json'\n", - " 'Content-Length': '36417'\n", - " 'api-key': 'REDACTED'\n", - " 'Accept': 'application/json;odata.metadata=none'\n", - " 'x-ms-client-request-id': '99b27cc2-7784-11ef-822e-0242ac110002'\n", - " 'User-Agent': 'azsdk-python-search-documents/11.6.0b4 Python/3.12.6 (Linux-5.15.153.1-microsoft-standard-WSL2-x86_64-with-glibc2.36)'\n", - "A body is sent with the request\n", - "INFO:httpx:HTTP Request: POST https://aoai-text2sql-adi.openai.azure.com/openai/deployments/text-embedding-ada-002/embeddings?api-version=2023-03-15-preview \"HTTP/1.1 200 OK\"\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Request URL: 'https://open-ai-vector-db.search.windows.net/indexes('text-2-sql-query-cache-index')/docs/search.index?api-version=REDACTED'\n", - "Request method: 'POST'\n", - "Request headers:\n", - " 'Content-Type': 'application/json'\n", - " 'Content-Length': '35540'\n", - " 'api-key': 'REDACTED'\n", - " 'Accept': 'application/json;odata.metadata=none'\n", - " 'x-ms-client-request-id': '99b5be64-7784-11ef-822e-0242ac110002'\n", - " 'User-Agent': 'azsdk-python-search-documents/11.6.0b4 Python/3.12.6 (Linux-5.15.153.1-microsoft-standard-WSL2-x86_64-with-glibc2.36)'\n", - "A body is sent with the request\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Response status: 200\n", - "Response headers:\n", - " 'Transfer-Encoding': 'chunked'\n", - " 'Content-Type': 'application/json; odata.metadata=none; odata.streaming=true; charset=utf-8'\n", - " 'Content-Encoding': 'REDACTED'\n", - " 'Vary': 'REDACTED'\n", - " 'Server': 'Microsoft-IIS/10.0'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Preference-Applied': 'REDACTED'\n", - " 'OData-Version': 'REDACTED'\n", - " 'request-id': '99b27cc2-7784-11ef-822e-0242ac110002'\n", - " 'elapsed-time': 'REDACTED'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Date': 'Fri, 20 Sep 2024 19:14:49 GMT'\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Response status: 200\n", - "Response headers:\n", - " 'Transfer-Encoding': 'chunked'\n", - " 'Content-Type': 'application/json; odata.metadata=none; odata.streaming=true; charset=utf-8'\n", - " 'Content-Encoding': 'REDACTED'\n", - " 'Vary': 'REDACTED'\n", - " 'Server': 'Microsoft-IIS/10.0'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Preference-Applied': 'REDACTED'\n", - " 'OData-Version': 'REDACTED'\n", - " 'request-id': '99b5be64-7784-11ef-822e-0242ac110002'\n", - " 'elapsed-time': 'REDACTED'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Date': 'Fri, 20 Sep 2024 19:14:49 GMT'\n", - "INFO:httpx:HTTP Request: POST https://aoai-text2sql-adi.openai.azure.com/openai/deployments/gpt-4o/chat/completions?api-version=2024-02-01 \"HTTP/1.1 200 OK\"\n", - "INFO:semantic_kernel.connectors.ai.open_ai.services.open_ai_handler:OpenAI usage: CompletionUsage(completion_tokens=33, prompt_tokens=6260, total_tokens=6293, completion_tokens_details=None)\n", - "INFO:semantic_kernel.connectors.ai.chat_completion_client_base:processing 1 tool calls in parallel.\n", - "INFO:semantic_kernel.kernel:Calling SQL-RunSQLQuery function with args: {\"sql_query\":\"SELECT Name FROM SalesLT.vProductAndDescription WHERE ProductID = 864;\"}\n", - "INFO:semantic_kernel.functions.kernel_function:Function SQL-RunSQLQuery invoking.\n", - "INFO:root:Executing SQL Query\n", - "INFO:root:SQL Statement: SELECT Name FROM SalesLT.vProductAndDescription WHERE ProductID = 864;\n", - "INFO:root:Filtering schemas against SQL statement\n", - "INFO:root:Schema: {'EntityName': 'Get All Categories', 'Columns': [{'Name': 'ProductCategoryID', 'Definition': 'A unique identifier for each product category. This ID is used to reference specific categories.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ParentProductCategoryName', 'Definition': 'The name of the parent product category. This represents the top-level category under which subcategories are grouped.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductCategoryName', 'Definition': 'The name of the product category. This can refer to either a top-level category or a subcategory, depending on the context.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'vGetAllCategories', 'Description': 'This view provides a comprehensive list of all product categories and their corresponding subcategories in the SalesLT schema of the AdventureWorksLT database. It is used to understand the hierarchical structure of product categories, facilitating product organization and categorization.', 'SelectFromEntity': 'SalesLT.vGetAllCategories'}\n", - "INFO:root:Entity: SalesLT.vGetAllCategories\n", - "INFO:root:Schema: {'EntityName': 'Product Model Catalog Description', 'Columns': [{'Name': 'ProductModelID', 'Definition': 'A unique identifier for each product model. This ID is used to distinguish different product models.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Name', 'Definition': 'The name of the product model, providing a recognizable title for each model.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Summary', 'Definition': 'A brief summary of the product model, highlighting key features and characteristics.', 'Type': 'NVARCHAR(MAX)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Manufacturer', 'Definition': 'The name of the manufacturer of the product model.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Copyright', 'Definition': 'Copyright information related to the product model, indicating the legal ownership of the product design and content.', 'Type': 'NVARCHAR(30)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductURL', 'Definition': 'The URL for the product model, providing a link to more information or to purchase the product.', 'Type': 'NVARCHAR(256)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'WarrantyPeriod', 'Definition': 'The duration of the warranty period for the product model, specifying how long the warranty is valid.', 'Type': 'NVARCHAR(30)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'WarrantyDescription', 'Definition': 'A description of the warranty provided for the product model, detailing what is covered under the warranty.', 'Type': 'NVARCHAR(255)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'NoOfYears', 'Definition': 'The number of years the warranty is valid for the product model.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'MaintenanceDescription', 'Definition': 'A description of the maintenance requirements and recommendations for the product model.', 'Type': 'NVARCHAR(MAX)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Wheel', 'Definition': 'Details about the type of wheels used in the product model.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Saddle', 'Definition': 'Information about the saddle of the product model, such as material and design.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Pedal', 'Definition': 'Details regarding the pedal design and specifications of the product model.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'BikeFrame', 'Definition': 'Description of the bike frame used in the product model, including material and type.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Crankset', 'Definition': 'Information about the crankset of the product model, specifying its design and features.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PictureAngle', 'Definition': 'The angle at which the product model is photographed, providing a visual perspective of the product.', 'Type': 'NVARCHAR(20)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PictureSize', 'Definition': \"The size of the product model's picture, specifying dimensions or resolution.\", 'Type': 'NVARCHAR(20)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductPhotoID', 'Definition': 'An identifier linking to the product photo, which provides a visual representation of the product model.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Material', 'Definition': 'The material used in the construction of the product model, indicating durability and quality.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Color', 'Definition': 'The color of the product model, providing information about the appearance of the product.', 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductLine', 'Definition': 'A code representing the product line to which the model belongs, categorizing the product within a broader product range.', 'Type': 'NVARCHAR(2)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Style', 'Definition': 'The style of the product model, indicating design and aesthetic aspects.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'RiderExperience', 'Definition': \"A description of the target rider's experience level for which the product model is designed, such as beginner, intermediate, or expert.\", 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the product model information was last modified, indicating the currency of the data.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'vProductModelCatalogDescription', 'Description': 'This view provides detailed catalog information about product models, including descriptions, manufacturing details, warranty information, and specifications related to product design and features. It is useful for generating comprehensive product catalogs and providing detailed product information to customers.', 'SelectFromEntity': 'SalesLT.vProductModelCatalogDescription'}\n", - "INFO:root:Entity: SalesLT.vProductModelCatalogDescription\n", - "INFO:root:Schema: {'EntityName': 'Product and Description', 'Columns': [{'Name': 'ProductID', 'Definition': 'A unique identifier for each product. This ID is used to distinguish individual products.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Name', 'Definition': 'The name of the product. This provides a brief and identifiable name for each product.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductModel', 'Definition': 'The model name associated with the product. This indicates the specific model type or version of the product.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Culture', 'Definition': \"The culture or language code for the product description. This is used to localize the product description, such as 'en' for English or 'fr' for French.\", 'Type': 'NVARCHAR(6)', 'AllowedValues': None, 'SampleValues': '[\"en\",\"fr\",\"es\",\"de\"]'}, {'Name': 'Description', 'Definition': 'A detailed description of the product. This text provides additional information about the product, which can vary based on the culture or language.', 'Type': 'NVARCHAR(400)', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'vProductAndDescription', 'Description': 'This view provides detailed information about products, including their names, associated product models, descriptions, and the specific culture or language of the description. It is useful for understanding product details and translating product descriptions for different cultures.', 'SelectFromEntity': 'SalesLT.vProductAndDescription'}\n", - "INFO:root:Entity: SalesLT.vProductAndDescription\n", - "INFO:root:Loaded Schema: {'EntityName': 'Product and Description', 'Columns': [{'Name': 'ProductID', 'Definition': 'A unique identifier for each product. This ID is used to distinguish individual products.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Name', 'Definition': 'The name of the product. This provides a brief and identifiable name for each product.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductModel', 'Definition': 'The model name associated with the product. This indicates the specific model type or version of the product.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Culture', 'Definition': \"The culture or language code for the product description. This is used to localize the product description, such as 'en' for English or 'fr' for French.\", 'Type': 'NVARCHAR(6)', 'AllowedValues': None, 'SampleValues': '[\"en\",\"fr\",\"es\",\"de\"]'}, {'Name': 'Description', 'Definition': 'A detailed description of the product. This text provides additional information about the product, which can vary based on the culture or language.', 'Type': 'NVARCHAR(400)', 'AllowedValues': None, 'SampleValues': None}], 'Entity': 'vProductAndDescription', 'Description': 'This view provides detailed information about products, including their names, associated product models, descriptions, and the specific culture or language of the description. It is useful for understanding product details and translating product descriptions for different cultures.', 'SelectFromEntity': 'SalesLT.vProductAndDescription'}\n", - "INFO:semantic_kernel.functions.kernel_function:Function SQL-RunSQLQuery succeeded.\n", - "INFO:semantic_kernel.functions.kernel_function:Function completed. Duration: 0.467656s\n", - "INFO:root:Document: {'Question': 'What is the top performing product by quantity of units sold?', 'Query': 'SELECT Name FROM SalesLT.vProductAndDescription WHERE ProductID = 864;', 'Schemas': [{'Entity': 'vProductAndDescription', 'Columns': [{'Name': 'ProductID', 'Definition': 'A unique identifier for each product. This ID is used to distinguish individual products.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Name', 'Definition': 'The name of the product. This provides a brief and identifiable name for each product.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductModel', 'Definition': 'The model name associated with the product. This indicates the specific model type or version of the product.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Culture', 'Definition': \"The culture or language code for the product description. This is used to localize the product description, such as 'en' for English or 'fr' for French.\", 'Type': 'NVARCHAR(6)', 'AllowedValues': None, 'SampleValues': '[\"en\",\"fr\",\"es\",\"de\"]'}, {'Name': 'Description', 'Definition': 'A detailed description of the product. This text provides additional information about the product, which can vary based on the culture or language.', 'Type': 'NVARCHAR(400)', 'AllowedValues': None, 'SampleValues': None}]}]}\n", - "INFO:root:Vector Fields: {'Question': 'QuestionEmbedding'}\n", - "INFO:httpx:HTTP Request: POST https://aoai-text2sql-adi.openai.azure.com/openai/deployments/text-embedding-ada-002/embeddings?api-version=2023-03-15-preview \"HTTP/1.1 200 OK\"\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Request URL: 'https://open-ai-vector-db.search.windows.net/indexes('text-2-sql-query-cache-index')/docs/search.index?api-version=REDACTED'\n", - "Request method: 'POST'\n", - "Request headers:\n", - " 'Content-Type': 'application/json'\n", - " 'Content-Length': '35969'\n", - " 'api-key': 'REDACTED'\n", - " 'Accept': 'application/json;odata.metadata=none'\n", - " 'x-ms-client-request-id': '9a8ef8aa-7784-11ef-822e-0242ac110002'\n", - " 'User-Agent': 'azsdk-python-search-documents/11.6.0b4 Python/3.12.6 (Linux-5.15.153.1-microsoft-standard-WSL2-x86_64-with-glibc2.36)'\n", - "A body is sent with the request\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Response status: 200\n", - "Response headers:\n", - " 'Transfer-Encoding': 'chunked'\n", - " 'Content-Type': 'application/json; odata.metadata=none; odata.streaming=true; charset=utf-8'\n", - " 'Content-Encoding': 'REDACTED'\n", - " 'Vary': 'REDACTED'\n", - " 'Server': 'Microsoft-IIS/10.0'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Preference-Applied': 'REDACTED'\n", - " 'OData-Version': 'REDACTED'\n", - " 'request-id': '9a8ef8aa-7784-11ef-822e-0242ac110002'\n", - " 'elapsed-time': 'REDACTED'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Date': 'Fri, 20 Sep 2024 19:14:50 GMT'\n" - ] - } - ], + "outputs": [], "source": [ "await ask_question(\"What is the top performing product by quantity of units sold?\", history)" ] @@ -882,309 +280,7 @@ "cell_type": "code", "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "INFO:httpx:HTTP Request: POST https://aoai-text2sql-adi.openai.azure.com/openai/deployments/text-embedding-ada-002/embeddings?api-version=2023-03-15-preview \"HTTP/1.1 200 OK\"\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Request URL: 'https://open-ai-vector-db.search.windows.net/indexes('text-2-sql-query-cache-index')/docs/search.post.search?api-version=REDACTED'\n", - "Request method: 'POST'\n", - "Request headers:\n", - " 'Content-Type': 'application/json'\n", - " 'Content-Length': '34774'\n", - " 'api-key': 'REDACTED'\n", - " 'Accept': 'application/json;odata.metadata=none'\n", - " 'x-ms-client-request-id': '18181f5a-7784-11ef-9963-0242ac110002'\n", - " 'User-Agent': 'azsdk-python-search-documents/11.6.0b4 Python/3.12.6 (Linux-5.15.153.1-microsoft-standard-WSL2-x86_64-with-glibc2.36)'\n", - "A body is sent with the request\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Response status: 200\n", - "Response headers:\n", - " 'Transfer-Encoding': 'chunked'\n", - " 'Content-Type': 'application/json; odata.metadata=none; odata.streaming=true; charset=utf-8'\n", - " 'Content-Encoding': 'REDACTED'\n", - " 'Vary': 'REDACTED'\n", - " 'Server': 'Microsoft-IIS/10.0'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Preference-Applied': 'REDACTED'\n", - " 'OData-Version': 'REDACTED'\n", - " 'request-id': '18181f5a-7784-11ef-9963-0242ac110002'\n", - " 'elapsed-time': 'REDACTED'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Date': 'Fri, 20 Sep 2024 19:11:12 GMT'\n", - "INFO:root:Results: []\n", - "INFO:root:Question: Which country did we sell the most to in June 2008?\n", - "INFO:semantic_kernel.functions.kernel_function:Function ChatBot-Chat invoking.\n", - "INFO:semantic_kernel.contents.chat_history:Could not parse prompt \n", - "As a senior analyst, your primary responsibility is to provide accurate, thorough answers to user queries. Use all available functions to craft detailed final responses with clear explanations and actionable insights.\n", - "\n", - "- Always use the provided functions to obtain key information.\n", - "- If a function is required, you must use it to complement the answer.\n", - "- Use multiple functions in parallel to enhance the results.\n", - "- Always provide an answer; never leave it blank.\n", - "\n", - "The response must meet the following requirements:\n", - "\n", - "[RESPONSE OUTPUT REQUIREMENTS]\n", - "\n", - " The answer MUST be in JSON format:\n", - " {\n", - " \"answer\": \"\",\n", - " \"sources\": [\n", - " {\"title\": , \"chunk\": , \"reference\": \"\"},\n", - " {\"title\": , \"chunk\": , \"reference\": \"\"}\n", - " ]\n", - " }\n", - "\n", - " [ANSWER PROPERTY REQUIREMENTS]\n", - " - **Language & Tone**:\n", - " Use British English, business-friendly language that is professional and clear.\n", - " - **Content Restrictions**:\n", - " Avoid profanity, offensive language, and code. Rephrase or omit inappropriate content.\n", - " - **Information Sources**:\n", - " Only use provided functions and important information. Prioritize SQL Database data in case of conflicts.\n", - " - **Calculations**:\n", - " Use context-provided values and explain calculations briefly.\n", - " - **Structure**:\n", - " Responses must be direct, easy to understand, and formatted using Markdown.\n", - " Use Level 3 and 4 headings, bold sub-headings, and lists where appropriate. Keep font size consistent.\n", - " - **Citations**:\n", - " Factual statements must be cited using numbered references like [1]. Each citation must match a source in the 'sources' object.\n", - "\n", - " [SOURCES PROPERTY REQUIREMENTS]\n", - " - **Reference Inclusion**:\n", - " All cited content must have a corresponding reference in the 'sources' object.\n", - " - **Source Format**:\n", - " Each source must follow this format: {\"title\": \"\", \"chunk\": \"\", \"reference\": \"\"}\n", - " - **Source Chunk**:\n", - " Include a concise, unedited snippet of relevant context in the 'chunk' property.\n", - " - **Mandatory Citations**:\n", - " Every source listed must be cited at least once in the answer.\n", - "\n", - "[IMPORTANT INFORMATION]\n", - "\n", - "\n", - " [SQL DATABASE INFORMATION]\n", - " First consider the PRE-FETCHED SQL query and the results from execution. Consider if you can use this data to answer the question without running another SQL query. If the data is sufficient, use it to answer the question instead of running a new query.\n", - "\n", - " \n", - "\n", - " If this data or query will not answer the question, look at the provided CACHED QUERIES AND SCHEMAS below, to see if you can use them to formulate a SQL query.\n", - "\n", - " \n", - "\n", - " Finally, if you can't use or adjust a previous generated SQL query, use the 'GetEntitySchema()' function to search for the most relevant schemas for the data that you wish to obtain.\n", - "\n", - " If needed, use the 'RunSQLQuery()' function to run the SQL query against the database. Never just return the SQL query as the answer.\n", - "\n", - " Output corresponding text values in the answer for columns where there is an ID. For example, if the column is 'ProductID', output the corresponding 'ProductModel' in the response. Do not include the ID in the response.\n", - " If a user is asking for a comparison, always compare the relevant values in the database.\n", - "\n", - " Only use schema / column information provided as part of this prompt or from the 'GetEntitySchema()' function output when constructing a SQL query. Do not use any other entities and columns in your SQL query, other than those defined above.\n", - " Do not makeup or guess column names.\n", - "\n", - " The target database engine is Microsoft TSQL Server, SQL queries must be able compatible to run on Microsoft TSQL Server. \n", - " The following Microsoft TSQL Server Syntax rules must be adhered to.\n", - " Use TOP X to limit the number of rows returned instead of LIMIT X. NEVER USE LIMIT X as it produces a syntax error.\n", - " You must only provide SELECT SQL queries.\n", - " For a given entity, use the 'SelectFromEntity' property returned in the schema in the SELECT FROM part of the SQL query. If the property is {'SelectFromEntity': 'test_schema.test_table'}, the select statement will be formulated from 'SELECT <VALUES> FROM test_schema.test_table WHERE <CONDITION>.\n", - "\n", - " If you don't know how the value is formatted in a column, run a query against the column to get the unique values that might match your query.\n", - " Some columns in the schema may have the properties 'AllowedValues' or 'SampleValues'. Use these values to determine the possible values that can be used in the SQL query.\n", - "\n", - " The source title to cite is the 'EntityName' property. The source reference is the SQL query used. The source chunk is the result of the SQL query used to answer the user query in Markdown table format. e.g. { 'title': "vProductAndDescription", 'chunk': '| ProductID | Name | ProductModel | Culture | Description |\\n|-----------|-------------------|--------------|---------|----------------------------------|\\n| 101 | Mountain Bike | MT-100 | en | A durable bike for mountain use. |\\n| 102 | Road Bike | RB-200 | en | Lightweight bike for road use. |\\n| 103 | Hybrid Bike | HB-300 | fr | V\u00e9lo hybride pour usage mixte. |\\n', 'reference': 'SELECT ProductID, Name, ProductModel, Culture, Description FROM vProductAndDescription WHERE Culture = "en";' }\n", - " [END SQL DATABASE INFORMATION]\n", - " \n", - "\n", - "[END]\n", - "\n", - "What are the different product categories we have?What is the top performing product by quantity of units sold?\n", - "Which country did we sell the most to in June 2008? as xml, treating as text, error was: not well-formed (invalid token): line 15, column 32\n", - "INFO:httpx:HTTP Request: POST https://aoai-text2sql-adi.openai.azure.com/openai/deployments/gpt-4o/chat/completions?api-version=2024-02-01 \"HTTP/1.1 200 OK\"\n", - "INFO:semantic_kernel.connectors.ai.open_ai.services.open_ai_handler:OpenAI usage: CompletionUsage(completion_tokens=72, prompt_tokens=1463, total_tokens=1535, completion_tokens_details=None)\n", - "INFO:semantic_kernel.connectors.ai.chat_completion_client_base:processing 3 tool calls in parallel.\n", - "INFO:semantic_kernel.kernel:Calling SQL-GetEntitySchema function with args: {\"text\": \"sales data\"}\n", - "INFO:semantic_kernel.functions.kernel_function:Function SQL-GetEntitySchema invoking.\n", - "INFO:semantic_kernel.kernel:Calling SQL-GetEntitySchema function with args: {\"text\": \"country sales\"}\n", - "INFO:semantic_kernel.functions.kernel_function:Function SQL-GetEntitySchema invoking.\n", - "INFO:semantic_kernel.kernel:Calling SQL-GetEntitySchema function with args: {\"text\": \"June 2008\"}\n", - "INFO:semantic_kernel.functions.kernel_function:Function SQL-GetEntitySchema invoking.\n", - "INFO:httpx:HTTP Request: POST https://aoai-text2sql-adi.openai.azure.com/openai/deployments/text-embedding-ada-002/embeddings?api-version=2023-03-15-preview \"HTTP/1.1 200 OK\"\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Request URL: 'https://open-ai-vector-db.search.windows.net/indexes('text-2-sql-index')/docs/search.post.search?api-version=REDACTED'\n", - "Request method: 'POST'\n", - "Request headers:\n", - " 'Content-Type': 'application/json'\n", - " 'Content-Length': '34735'\n", - " 'api-key': 'REDACTED'\n", - " 'Accept': 'application/json;odata.metadata=none'\n", - " 'x-ms-client-request-id': '18f32352-7784-11ef-9963-0242ac110002'\n", - " 'User-Agent': 'azsdk-python-search-documents/11.6.0b4 Python/3.12.6 (Linux-5.15.153.1-microsoft-standard-WSL2-x86_64-with-glibc2.36)'\n", - "A body is sent with the request\n", - "INFO:httpx:HTTP Request: POST https://aoai-text2sql-adi.openai.azure.com/openai/deployments/text-embedding-ada-002/embeddings?api-version=2023-03-15-preview \"HTTP/1.1 200 OK\"\n", - "INFO:httpx:HTTP Request: POST https://aoai-text2sql-adi.openai.azure.com/openai/deployments/text-embedding-ada-002/embeddings?api-version=2023-03-15-preview \"HTTP/1.1 200 OK\"\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Request URL: 'https://open-ai-vector-db.search.windows.net/indexes('text-2-sql-index')/docs/search.post.search?api-version=REDACTED'\n", - "Request method: 'POST'\n", - "Request headers:\n", - " 'Content-Type': 'application/json'\n", - " 'Content-Length': '34684'\n", - " 'api-key': 'REDACTED'\n", - " 'Accept': 'application/json;odata.metadata=none'\n", - " 'x-ms-client-request-id': '18fce702-7784-11ef-9963-0242ac110002'\n", - " 'User-Agent': 'azsdk-python-search-documents/11.6.0b4 Python/3.12.6 (Linux-5.15.153.1-microsoft-standard-WSL2-x86_64-with-glibc2.36)'\n", - "A body is sent with the request\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Request URL: 'https://open-ai-vector-db.search.windows.net/indexes('text-2-sql-index')/docs/search.post.search?api-version=REDACTED'\n", - "Request method: 'POST'\n", - "Request headers:\n", - " 'Content-Type': 'application/json'\n", - " 'Content-Length': '34716'\n", - " 'api-key': 'REDACTED'\n", - " 'Accept': 'application/json;odata.metadata=none'\n", - " 'x-ms-client-request-id': '19040384-7784-11ef-9963-0242ac110002'\n", - " 'User-Agent': 'azsdk-python-search-documents/11.6.0b4 Python/3.12.6 (Linux-5.15.153.1-microsoft-standard-WSL2-x86_64-with-glibc2.36)'\n", - "A body is sent with the request\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Response status: 200\n", - "Response headers:\n", - " 'Transfer-Encoding': 'chunked'\n", - " 'Content-Type': 'application/json; odata.metadata=none; odata.streaming=true; charset=utf-8'\n", - " 'Content-Encoding': 'REDACTED'\n", - " 'Vary': 'REDACTED'\n", - " 'Server': 'Microsoft-IIS/10.0'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Preference-Applied': 'REDACTED'\n", - " 'OData-Version': 'REDACTED'\n", - " 'request-id': '18f32352-7784-11ef-9963-0242ac110002'\n", - " 'elapsed-time': 'REDACTED'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Date': 'Fri, 20 Sep 2024 19:11:13 GMT'\n", - "INFO:root:Item: {'EntityName': 'Sales Order Detail', 'Description': 'This table stores detailed information about sales order tickets, including the order details, customer information, order status, and timestamps. It is used to manage and track sales orders throughout the order lifecycle, from creation to fulfillment.', 'Entity': 'SalesOrderDetail', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order ticket. This ID is auto-generated and serves as the primary key for the SalesOrderTicket table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges.', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order ticket record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}]}\n", - "INFO:root:Item: {'EntityName': 'Address', 'Description': 'This table stores address information for customers, including street addresses, city, state, postal code, and country/region. It is used to maintain contact and shipping information for orders, as well as to manage customer locations.', 'Entity': 'Address', 'Columns': [{'Name': 'AddressID', 'Definition': 'A unique identifier for each address. This ID is auto-generated and serves as the primary key for the Address table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'City', 'Definition': 'The city in which the address is located. This is used to specify the city for the address.', 'Type': 'NVARCHAR(30)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'StateProvince', 'Definition': 'The state or province in which the address is located. This is used to specify the state or province for the address.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CountryRegion', 'Definition': 'The country or region in which the address is located. This is used to specify the country or region for the address.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PostalCode', 'Definition': 'The postal code associated with the address. This is used to specify the postal code for the address, which helps in geographical sorting and shipping.', 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the address record was last modified. This is used for tracking updates and changes to the address information.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}]}\n", - "INFO:root:Item: {'EntityName': 'Sales Order Header', 'Description': 'This table contains high-level information about sales orders, including order dates, customer details, shipping information, and order status. It is used to manage and track sales orders from initiation to fulfillment.', 'Entity': 'SalesOrderHeader', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order. This ID is auto-generated and serves as the primary key for the SalesOrderHeader table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This field is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'OnlineOrderFlag', 'Definition': 'Indicates whether the order was placed online.', 'Type': 'BIT', 'AllowedValues': '[\"True\",\"False\"]', 'SampleValues': None}, {'Name': 'SalesOrderNumber', 'Definition': 'A unique order number assigned to the sales order. This is used for tracking and identification purposes.', 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PurchaseOrderNumber', 'Definition': \"The purchase order number provided by the customer. This field links the sales order to the customer's purchase order.\", 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'AccountNumber', 'Definition': \"The account number of the customer placing the order. This helps link the order to the customer's account.\", 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CustomerID', 'Definition': 'A foreign key that links to the Customer table, representing the customer who placed the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the shipping address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'BillToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the billing address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipMethod', 'Definition': 'The shipping method used for the order (e.g., UPS, FedEx). This field helps track shipping preferences.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'SubTotal', 'Definition': 'The total cost of the order before taxes and shipping charges. This field is used to calculate the final total. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TaxAmt', 'Definition': 'The tax amount applied to the order. This is calculated based on the order subtotal and applicable tax rates. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Freight', 'Definition': 'The shipping charge applied to the order. This field represents the cost of shipping the order to the customer. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Comment', 'Definition': 'Any additional comments or notes related to the sales order. This field can include special instructions or remarks.', 'Type': 'NVARCHAR(255)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order header record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}]}\n", - "INFO:root:Results: [{'EntityName': 'Sales Order Detail', 'Description': 'This table stores detailed information about sales order tickets, including the order details, customer information, order status, and timestamps. It is used to manage and track sales orders throughout the order lifecycle, from creation to fulfillment.', 'Entity': 'SalesOrderDetail', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order ticket. This ID is auto-generated and serves as the primary key for the SalesOrderTicket table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges.', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order ticket record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}]}, {'EntityName': 'Address', 'Description': 'This table stores address information for customers, including street addresses, city, state, postal code, and country/region. It is used to maintain contact and shipping information for orders, as well as to manage customer locations.', 'Entity': 'Address', 'Columns': [{'Name': 'AddressID', 'Definition': 'A unique identifier for each address. This ID is auto-generated and serves as the primary key for the Address table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'City', 'Definition': 'The city in which the address is located. This is used to specify the city for the address.', 'Type': 'NVARCHAR(30)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'StateProvince', 'Definition': 'The state or province in which the address is located. This is used to specify the state or province for the address.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CountryRegion', 'Definition': 'The country or region in which the address is located. This is used to specify the country or region for the address.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PostalCode', 'Definition': 'The postal code associated with the address. This is used to specify the postal code for the address, which helps in geographical sorting and shipping.', 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the address record was last modified. This is used for tracking updates and changes to the address information.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}]}, {'EntityName': 'Sales Order Header', 'Description': 'This table contains high-level information about sales orders, including order dates, customer details, shipping information, and order status. It is used to manage and track sales orders from initiation to fulfillment.', 'Entity': 'SalesOrderHeader', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order. This ID is auto-generated and serves as the primary key for the SalesOrderHeader table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This field is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'OnlineOrderFlag', 'Definition': 'Indicates whether the order was placed online.', 'Type': 'BIT', 'AllowedValues': '[\"True\",\"False\"]', 'SampleValues': None}, {'Name': 'SalesOrderNumber', 'Definition': 'A unique order number assigned to the sales order. This is used for tracking and identification purposes.', 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PurchaseOrderNumber', 'Definition': \"The purchase order number provided by the customer. This field links the sales order to the customer's purchase order.\", 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'AccountNumber', 'Definition': \"The account number of the customer placing the order. This helps link the order to the customer's account.\", 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CustomerID', 'Definition': 'A foreign key that links to the Customer table, representing the customer who placed the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the shipping address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'BillToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the billing address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipMethod', 'Definition': 'The shipping method used for the order (e.g., UPS, FedEx). This field helps track shipping preferences.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'SubTotal', 'Definition': 'The total cost of the order before taxes and shipping charges. This field is used to calculate the final total. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TaxAmt', 'Definition': 'The tax amount applied to the order. This is calculated based on the order subtotal and applicable tax rates. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Freight', 'Definition': 'The shipping charge applied to the order. This field represents the cost of shipping the order to the customer. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Comment', 'Definition': 'Any additional comments or notes related to the sales order. This field can include special instructions or remarks.', 'Type': 'NVARCHAR(255)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order header record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}]}]\n", - "INFO:semantic_kernel.functions.kernel_function:Function SQL-GetEntitySchema succeeded.\n", - "INFO:semantic_kernel.functions.kernel_function:Function completed. Duration: 0.583193s\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Response status: 200\n", - "Response headers:\n", - " 'Transfer-Encoding': 'chunked'\n", - " 'Content-Type': 'application/json; odata.metadata=none; odata.streaming=true; charset=utf-8'\n", - " 'Content-Encoding': 'REDACTED'\n", - " 'Vary': 'REDACTED'\n", - " 'Server': 'Microsoft-IIS/10.0'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Preference-Applied': 'REDACTED'\n", - " 'OData-Version': 'REDACTED'\n", - " 'request-id': '19040384-7784-11ef-9963-0242ac110002'\n", - " 'elapsed-time': 'REDACTED'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Date': 'Fri, 20 Sep 2024 19:11:12 GMT'\n", - "INFO:root:Item: {'EntityName': 'Address', 'Description': 'This table stores address information for customers, including street addresses, city, state, postal code, and country/region. It is used to maintain contact and shipping information for orders, as well as to manage customer locations.', 'Entity': 'Address', 'Columns': [{'Name': 'AddressID', 'Definition': 'A unique identifier for each address. This ID is auto-generated and serves as the primary key for the Address table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'City', 'Definition': 'The city in which the address is located. This is used to specify the city for the address.', 'Type': 'NVARCHAR(30)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'StateProvince', 'Definition': 'The state or province in which the address is located. This is used to specify the state or province for the address.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CountryRegion', 'Definition': 'The country or region in which the address is located. This is used to specify the country or region for the address.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PostalCode', 'Definition': 'The postal code associated with the address. This is used to specify the postal code for the address, which helps in geographical sorting and shipping.', 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the address record was last modified. This is used for tracking updates and changes to the address information.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}]}\n", - "INFO:root:Item: {'EntityName': 'Sales Order Header', 'Description': 'This table contains high-level information about sales orders, including order dates, customer details, shipping information, and order status. It is used to manage and track sales orders from initiation to fulfillment.', 'Entity': 'SalesOrderHeader', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order. This ID is auto-generated and serves as the primary key for the SalesOrderHeader table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This field is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'OnlineOrderFlag', 'Definition': 'Indicates whether the order was placed online.', 'Type': 'BIT', 'AllowedValues': '[\"True\",\"False\"]', 'SampleValues': None}, {'Name': 'SalesOrderNumber', 'Definition': 'A unique order number assigned to the sales order. This is used for tracking and identification purposes.', 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PurchaseOrderNumber', 'Definition': \"The purchase order number provided by the customer. This field links the sales order to the customer's purchase order.\", 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'AccountNumber', 'Definition': \"The account number of the customer placing the order. This helps link the order to the customer's account.\", 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CustomerID', 'Definition': 'A foreign key that links to the Customer table, representing the customer who placed the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the shipping address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'BillToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the billing address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipMethod', 'Definition': 'The shipping method used for the order (e.g., UPS, FedEx). This field helps track shipping preferences.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'SubTotal', 'Definition': 'The total cost of the order before taxes and shipping charges. This field is used to calculate the final total. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TaxAmt', 'Definition': 'The tax amount applied to the order. This is calculated based on the order subtotal and applicable tax rates. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Freight', 'Definition': 'The shipping charge applied to the order. This field represents the cost of shipping the order to the customer. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Comment', 'Definition': 'Any additional comments or notes related to the sales order. This field can include special instructions or remarks.', 'Type': 'NVARCHAR(255)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order header record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}]}\n", - "INFO:root:Item: {'EntityName': 'Sales Order Detail', 'Description': 'This table stores detailed information about sales order tickets, including the order details, customer information, order status, and timestamps. It is used to manage and track sales orders throughout the order lifecycle, from creation to fulfillment.', 'Entity': 'SalesOrderDetail', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order ticket. This ID is auto-generated and serves as the primary key for the SalesOrderTicket table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges.', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order ticket record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}]}\n", - "INFO:root:Results: [{'EntityName': 'Address', 'Description': 'This table stores address information for customers, including street addresses, city, state, postal code, and country/region. It is used to maintain contact and shipping information for orders, as well as to manage customer locations.', 'Entity': 'Address', 'Columns': [{'Name': 'AddressID', 'Definition': 'A unique identifier for each address. This ID is auto-generated and serves as the primary key for the Address table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'City', 'Definition': 'The city in which the address is located. This is used to specify the city for the address.', 'Type': 'NVARCHAR(30)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'StateProvince', 'Definition': 'The state or province in which the address is located. This is used to specify the state or province for the address.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CountryRegion', 'Definition': 'The country or region in which the address is located. This is used to specify the country or region for the address.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PostalCode', 'Definition': 'The postal code associated with the address. This is used to specify the postal code for the address, which helps in geographical sorting and shipping.', 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the address record was last modified. This is used for tracking updates and changes to the address information.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}]}, {'EntityName': 'Sales Order Header', 'Description': 'This table contains high-level information about sales orders, including order dates, customer details, shipping information, and order status. It is used to manage and track sales orders from initiation to fulfillment.', 'Entity': 'SalesOrderHeader', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order. This ID is auto-generated and serves as the primary key for the SalesOrderHeader table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This field is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'OnlineOrderFlag', 'Definition': 'Indicates whether the order was placed online.', 'Type': 'BIT', 'AllowedValues': '[\"True\",\"False\"]', 'SampleValues': None}, {'Name': 'SalesOrderNumber', 'Definition': 'A unique order number assigned to the sales order. This is used for tracking and identification purposes.', 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PurchaseOrderNumber', 'Definition': \"The purchase order number provided by the customer. This field links the sales order to the customer's purchase order.\", 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'AccountNumber', 'Definition': \"The account number of the customer placing the order. This helps link the order to the customer's account.\", 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CustomerID', 'Definition': 'A foreign key that links to the Customer table, representing the customer who placed the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the shipping address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'BillToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the billing address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipMethod', 'Definition': 'The shipping method used for the order (e.g., UPS, FedEx). This field helps track shipping preferences.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'SubTotal', 'Definition': 'The total cost of the order before taxes and shipping charges. This field is used to calculate the final total. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TaxAmt', 'Definition': 'The tax amount applied to the order. This is calculated based on the order subtotal and applicable tax rates. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Freight', 'Definition': 'The shipping charge applied to the order. This field represents the cost of shipping the order to the customer. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Comment', 'Definition': 'Any additional comments or notes related to the sales order. This field can include special instructions or remarks.', 'Type': 'NVARCHAR(255)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order header record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}]}, {'EntityName': 'Sales Order Detail', 'Description': 'This table stores detailed information about sales order tickets, including the order details, customer information, order status, and timestamps. It is used to manage and track sales orders throughout the order lifecycle, from creation to fulfillment.', 'Entity': 'SalesOrderDetail', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order ticket. This ID is auto-generated and serves as the primary key for the SalesOrderTicket table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges.', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order ticket record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}]}]\n", - "INFO:semantic_kernel.functions.kernel_function:Function SQL-GetEntitySchema succeeded.\n", - "INFO:semantic_kernel.functions.kernel_function:Function completed. Duration: 0.650481s\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Response status: 200\n", - "Response headers:\n", - " 'Transfer-Encoding': 'chunked'\n", - " 'Content-Type': 'application/json; odata.metadata=none; odata.streaming=true; charset=utf-8'\n", - " 'Content-Encoding': 'REDACTED'\n", - " 'Vary': 'REDACTED'\n", - " 'Server': 'Microsoft-IIS/10.0'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Preference-Applied': 'REDACTED'\n", - " 'OData-Version': 'REDACTED'\n", - " 'request-id': '18fce702-7784-11ef-9963-0242ac110002'\n", - " 'elapsed-time': 'REDACTED'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Date': 'Fri, 20 Sep 2024 19:11:13 GMT'\n", - "INFO:root:Item: {'EntityName': 'Sales Order Detail', 'Description': 'This table stores detailed information about sales order tickets, including the order details, customer information, order status, and timestamps. It is used to manage and track sales orders throughout the order lifecycle, from creation to fulfillment.', 'Entity': 'SalesOrderDetail', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order ticket. This ID is auto-generated and serves as the primary key for the SalesOrderTicket table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges.', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order ticket record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}]}\n", - "INFO:root:Item: {'EntityName': 'Sales Order Header', 'Description': 'This table contains high-level information about sales orders, including order dates, customer details, shipping information, and order status. It is used to manage and track sales orders from initiation to fulfillment.', 'Entity': 'SalesOrderHeader', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order. This ID is auto-generated and serves as the primary key for the SalesOrderHeader table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This field is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'OnlineOrderFlag', 'Definition': 'Indicates whether the order was placed online.', 'Type': 'BIT', 'AllowedValues': '[\"True\",\"False\"]', 'SampleValues': None}, {'Name': 'SalesOrderNumber', 'Definition': 'A unique order number assigned to the sales order. This is used for tracking and identification purposes.', 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PurchaseOrderNumber', 'Definition': \"The purchase order number provided by the customer. This field links the sales order to the customer's purchase order.\", 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'AccountNumber', 'Definition': \"The account number of the customer placing the order. This helps link the order to the customer's account.\", 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CustomerID', 'Definition': 'A foreign key that links to the Customer table, representing the customer who placed the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the shipping address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'BillToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the billing address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipMethod', 'Definition': 'The shipping method used for the order (e.g., UPS, FedEx). This field helps track shipping preferences.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'SubTotal', 'Definition': 'The total cost of the order before taxes and shipping charges. This field is used to calculate the final total. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TaxAmt', 'Definition': 'The tax amount applied to the order. This is calculated based on the order subtotal and applicable tax rates. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Freight', 'Definition': 'The shipping charge applied to the order. This field represents the cost of shipping the order to the customer. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Comment', 'Definition': 'Any additional comments or notes related to the sales order. This field can include special instructions or remarks.', 'Type': 'NVARCHAR(255)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order header record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}]}\n", - "INFO:root:Item: {'EntityName': 'Get All Categories', 'Description': 'This view provides a comprehensive list of all product categories and their corresponding subcategories in the SalesLT schema of the AdventureWorksLT database. It is used to understand the hierarchical structure of product categories, facilitating product organization and categorization.', 'Entity': 'vGetAllCategories', 'Columns': [{'Name': 'ProductCategoryID', 'Definition': 'A unique identifier for each product category. This ID is used to reference specific categories.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ParentProductCategoryName', 'Definition': 'The name of the parent product category. This represents the top-level category under which subcategories are grouped.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductCategoryName', 'Definition': 'The name of the product category. This can refer to either a top-level category or a subcategory, depending on the context.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}]}\n", - "INFO:root:Results: [{'EntityName': 'Sales Order Detail', 'Description': 'This table stores detailed information about sales order tickets, including the order details, customer information, order status, and timestamps. It is used to manage and track sales orders throughout the order lifecycle, from creation to fulfillment.', 'Entity': 'SalesOrderDetail', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order ticket. This ID is auto-generated and serves as the primary key for the SalesOrderTicket table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges.', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order ticket record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}]}, {'EntityName': 'Sales Order Header', 'Description': 'This table contains high-level information about sales orders, including order dates, customer details, shipping information, and order status. It is used to manage and track sales orders from initiation to fulfillment.', 'Entity': 'SalesOrderHeader', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order. This ID is auto-generated and serves as the primary key for the SalesOrderHeader table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This field is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'OnlineOrderFlag', 'Definition': 'Indicates whether the order was placed online.', 'Type': 'BIT', 'AllowedValues': '[\"True\",\"False\"]', 'SampleValues': None}, {'Name': 'SalesOrderNumber', 'Definition': 'A unique order number assigned to the sales order. This is used for tracking and identification purposes.', 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PurchaseOrderNumber', 'Definition': \"The purchase order number provided by the customer. This field links the sales order to the customer's purchase order.\", 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'AccountNumber', 'Definition': \"The account number of the customer placing the order. This helps link the order to the customer's account.\", 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CustomerID', 'Definition': 'A foreign key that links to the Customer table, representing the customer who placed the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the shipping address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'BillToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the billing address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipMethod', 'Definition': 'The shipping method used for the order (e.g., UPS, FedEx). This field helps track shipping preferences.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'SubTotal', 'Definition': 'The total cost of the order before taxes and shipping charges. This field is used to calculate the final total. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TaxAmt', 'Definition': 'The tax amount applied to the order. This is calculated based on the order subtotal and applicable tax rates. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Freight', 'Definition': 'The shipping charge applied to the order. This field represents the cost of shipping the order to the customer. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Comment', 'Definition': 'Any additional comments or notes related to the sales order. This field can include special instructions or remarks.', 'Type': 'NVARCHAR(255)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order header record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}]}, {'EntityName': 'Get All Categories', 'Description': 'This view provides a comprehensive list of all product categories and their corresponding subcategories in the SalesLT schema of the AdventureWorksLT database. It is used to understand the hierarchical structure of product categories, facilitating product organization and categorization.', 'Entity': 'vGetAllCategories', 'Columns': [{'Name': 'ProductCategoryID', 'Definition': 'A unique identifier for each product category. This ID is used to reference specific categories.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ParentProductCategoryName', 'Definition': 'The name of the parent product category. This represents the top-level category under which subcategories are grouped.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductCategoryName', 'Definition': 'The name of the product category. This can refer to either a top-level category or a subcategory, depending on the context.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}]}]\n", - "INFO:semantic_kernel.functions.kernel_function:Function SQL-GetEntitySchema succeeded.\n", - "INFO:semantic_kernel.functions.kernel_function:Function completed. Duration: 0.730997s\n", - "INFO:httpx:HTTP Request: POST https://aoai-text2sql-adi.openai.azure.com/openai/deployments/gpt-4o/chat/completions?api-version=2024-02-01 \"HTTP/1.1 200 OK\"\n", - "INFO:semantic_kernel.connectors.ai.open_ai.services.open_ai_handler:OpenAI usage: CompletionUsage(completion_tokens=91, prompt_tokens=7306, total_tokens=7397, completion_tokens_details=None)\n", - "INFO:semantic_kernel.connectors.ai.chat_completion_client_base:processing 1 tool calls in parallel.\n", - "INFO:semantic_kernel.kernel:Calling SQL-RunSQLQuery function with args: {\"sql_query\":\"SELECT TOP 1 a.CountryRegion, SUM(s.TotalDue) as TotalSales FROM SalesLT.SalesOrderHeader s INNER JOIN SalesLT.Address a ON s.ShipToAddressID = a.AddressID WHERE s.OrderDate BETWEEN '2008-06-01' AND '2008-06-30' GROUP BY a.CountryRegion ORDER BY TotalSales DESC;\"}\n", - "INFO:semantic_kernel.functions.kernel_function:Function SQL-RunSQLQuery invoking.\n", - "INFO:root:Executing SQL Query\n", - "INFO:root:SQL Statement: SELECT TOP 1 a.CountryRegion, SUM(s.TotalDue) as TotalSales FROM SalesLT.SalesOrderHeader s INNER JOIN SalesLT.Address a ON s.ShipToAddressID = a.AddressID WHERE s.OrderDate BETWEEN '2008-06-01' AND '2008-06-30' GROUP BY a.CountryRegion ORDER BY TotalSales DESC;\n", - "INFO:root:Filtering schemas against SQL statement\n", - "INFO:root:Schema: {'EntityName': 'Sales Order Detail', 'Description': 'This table stores detailed information about sales order tickets, including the order details, customer information, order status, and timestamps. It is used to manage and track sales orders throughout the order lifecycle, from creation to fulfillment.', 'Entity': 'SalesOrderDetail', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order ticket. This ID is auto-generated and serves as the primary key for the SalesOrderTicket table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges.', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order ticket record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'SelectFromEntity': 'SalesLT.SalesOrderDetail'}\n", - "INFO:root:Schema: {'EntityName': 'Address', 'Description': 'This table stores address information for customers, including street addresses, city, state, postal code, and country/region. It is used to maintain contact and shipping information for orders, as well as to manage customer locations.', 'Entity': 'Address', 'Columns': [{'Name': 'AddressID', 'Definition': 'A unique identifier for each address. This ID is auto-generated and serves as the primary key for the Address table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'City', 'Definition': 'The city in which the address is located. This is used to specify the city for the address.', 'Type': 'NVARCHAR(30)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'StateProvince', 'Definition': 'The state or province in which the address is located. This is used to specify the state or province for the address.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CountryRegion', 'Definition': 'The country or region in which the address is located. This is used to specify the country or region for the address.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PostalCode', 'Definition': 'The postal code associated with the address. This is used to specify the postal code for the address, which helps in geographical sorting and shipping.', 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the address record was last modified. This is used for tracking updates and changes to the address information.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'SelectFromEntity': 'SalesLT.Address'}\n", - "INFO:root:Schema: {'EntityName': 'Sales Order Header', 'Description': 'This table contains high-level information about sales orders, including order dates, customer details, shipping information, and order status. It is used to manage and track sales orders from initiation to fulfillment.', 'Entity': 'SalesOrderHeader', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order. This ID is auto-generated and serves as the primary key for the SalesOrderHeader table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This field is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'OnlineOrderFlag', 'Definition': 'Indicates whether the order was placed online.', 'Type': 'BIT', 'AllowedValues': '[\"True\",\"False\"]', 'SampleValues': None}, {'Name': 'SalesOrderNumber', 'Definition': 'A unique order number assigned to the sales order. This is used for tracking and identification purposes.', 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PurchaseOrderNumber', 'Definition': \"The purchase order number provided by the customer. This field links the sales order to the customer's purchase order.\", 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'AccountNumber', 'Definition': \"The account number of the customer placing the order. This helps link the order to the customer's account.\", 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CustomerID', 'Definition': 'A foreign key that links to the Customer table, representing the customer who placed the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the shipping address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'BillToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the billing address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipMethod', 'Definition': 'The shipping method used for the order (e.g., UPS, FedEx). This field helps track shipping preferences.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'SubTotal', 'Definition': 'The total cost of the order before taxes and shipping charges. This field is used to calculate the final total. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TaxAmt', 'Definition': 'The tax amount applied to the order. This is calculated based on the order subtotal and applicable tax rates. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Freight', 'Definition': 'The shipping charge applied to the order. This field represents the cost of shipping the order to the customer. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Comment', 'Definition': 'Any additional comments or notes related to the sales order. This field can include special instructions or remarks.', 'Type': 'NVARCHAR(255)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order header record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'SelectFromEntity': 'SalesLT.SalesOrderHeader'}\n", - "INFO:root:Schema: {'EntityName': 'Address', 'Description': 'This table stores address information for customers, including street addresses, city, state, postal code, and country/region. It is used to maintain contact and shipping information for orders, as well as to manage customer locations.', 'Entity': 'Address', 'Columns': [{'Name': 'AddressID', 'Definition': 'A unique identifier for each address. This ID is auto-generated and serves as the primary key for the Address table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'City', 'Definition': 'The city in which the address is located. This is used to specify the city for the address.', 'Type': 'NVARCHAR(30)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'StateProvince', 'Definition': 'The state or province in which the address is located. This is used to specify the state or province for the address.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CountryRegion', 'Definition': 'The country or region in which the address is located. This is used to specify the country or region for the address.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PostalCode', 'Definition': 'The postal code associated with the address. This is used to specify the postal code for the address, which helps in geographical sorting and shipping.', 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the address record was last modified. This is used for tracking updates and changes to the address information.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'SelectFromEntity': 'SalesLT.Address'}\n", - "INFO:root:Schema: {'EntityName': 'Sales Order Header', 'Description': 'This table contains high-level information about sales orders, including order dates, customer details, shipping information, and order status. It is used to manage and track sales orders from initiation to fulfillment.', 'Entity': 'SalesOrderHeader', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order. This ID is auto-generated and serves as the primary key for the SalesOrderHeader table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This field is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'OnlineOrderFlag', 'Definition': 'Indicates whether the order was placed online.', 'Type': 'BIT', 'AllowedValues': '[\"True\",\"False\"]', 'SampleValues': None}, {'Name': 'SalesOrderNumber', 'Definition': 'A unique order number assigned to the sales order. This is used for tracking and identification purposes.', 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PurchaseOrderNumber', 'Definition': \"The purchase order number provided by the customer. This field links the sales order to the customer's purchase order.\", 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'AccountNumber', 'Definition': \"The account number of the customer placing the order. This helps link the order to the customer's account.\", 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CustomerID', 'Definition': 'A foreign key that links to the Customer table, representing the customer who placed the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the shipping address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'BillToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the billing address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipMethod', 'Definition': 'The shipping method used for the order (e.g., UPS, FedEx). This field helps track shipping preferences.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'SubTotal', 'Definition': 'The total cost of the order before taxes and shipping charges. This field is used to calculate the final total. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TaxAmt', 'Definition': 'The tax amount applied to the order. This is calculated based on the order subtotal and applicable tax rates. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Freight', 'Definition': 'The shipping charge applied to the order. This field represents the cost of shipping the order to the customer. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Comment', 'Definition': 'Any additional comments or notes related to the sales order. This field can include special instructions or remarks.', 'Type': 'NVARCHAR(255)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order header record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'SelectFromEntity': 'SalesLT.SalesOrderHeader'}\n", - "INFO:root:Schema: {'EntityName': 'Sales Order Detail', 'Description': 'This table stores detailed information about sales order tickets, including the order details, customer information, order status, and timestamps. It is used to manage and track sales orders throughout the order lifecycle, from creation to fulfillment.', 'Entity': 'SalesOrderDetail', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order ticket. This ID is auto-generated and serves as the primary key for the SalesOrderTicket table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges.', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order ticket record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'SelectFromEntity': 'SalesLT.SalesOrderDetail'}\n", - "INFO:root:Schema: {'EntityName': 'Sales Order Detail', 'Description': 'This table stores detailed information about sales order tickets, including the order details, customer information, order status, and timestamps. It is used to manage and track sales orders throughout the order lifecycle, from creation to fulfillment.', 'Entity': 'SalesOrderDetail', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order ticket. This ID is auto-generated and serves as the primary key for the SalesOrderTicket table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges.', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order ticket record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'SelectFromEntity': 'SalesLT.SalesOrderDetail'}\n", - "INFO:root:Schema: {'EntityName': 'Sales Order Header', 'Description': 'This table contains high-level information about sales orders, including order dates, customer details, shipping information, and order status. It is used to manage and track sales orders from initiation to fulfillment.', 'Entity': 'SalesOrderHeader', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order. This ID is auto-generated and serves as the primary key for the SalesOrderHeader table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This field is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'OnlineOrderFlag', 'Definition': 'Indicates whether the order was placed online.', 'Type': 'BIT', 'AllowedValues': '[\"True\",\"False\"]', 'SampleValues': None}, {'Name': 'SalesOrderNumber', 'Definition': 'A unique order number assigned to the sales order. This is used for tracking and identification purposes.', 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PurchaseOrderNumber', 'Definition': \"The purchase order number provided by the customer. This field links the sales order to the customer's purchase order.\", 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'AccountNumber', 'Definition': \"The account number of the customer placing the order. This helps link the order to the customer's account.\", 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CustomerID', 'Definition': 'A foreign key that links to the Customer table, representing the customer who placed the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the shipping address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'BillToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the billing address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipMethod', 'Definition': 'The shipping method used for the order (e.g., UPS, FedEx). This field helps track shipping preferences.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'SubTotal', 'Definition': 'The total cost of the order before taxes and shipping charges. This field is used to calculate the final total. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TaxAmt', 'Definition': 'The tax amount applied to the order. This is calculated based on the order subtotal and applicable tax rates. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Freight', 'Definition': 'The shipping charge applied to the order. This field represents the cost of shipping the order to the customer. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Comment', 'Definition': 'Any additional comments or notes related to the sales order. This field can include special instructions or remarks.', 'Type': 'NVARCHAR(255)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order header record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'SelectFromEntity': 'SalesLT.SalesOrderHeader'}\n", - "INFO:root:Schema: {'EntityName': 'Get All Categories', 'Description': 'This view provides a comprehensive list of all product categories and their corresponding subcategories in the SalesLT schema of the AdventureWorksLT database. It is used to understand the hierarchical structure of product categories, facilitating product organization and categorization.', 'Entity': 'vGetAllCategories', 'Columns': [{'Name': 'ProductCategoryID', 'Definition': 'A unique identifier for each product category. This ID is used to reference specific categories.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ParentProductCategoryName', 'Definition': 'The name of the parent product category. This represents the top-level category under which subcategories are grouped.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ProductCategoryName', 'Definition': 'The name of the product category. This can refer to either a top-level category or a subcategory, depending on the context.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}], 'SelectFromEntity': 'SalesLT.vGetAllCategories'}\n", - "INFO:root:Loaded Schema: {'EntityName': 'Sales Order Detail', 'Description': 'This table stores detailed information about sales order tickets, including the order details, customer information, order status, and timestamps. It is used to manage and track sales orders throughout the order lifecycle, from creation to fulfillment.', 'Entity': 'SalesOrderDetail', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order ticket. This ID is auto-generated and serves as the primary key for the SalesOrderTicket table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges.', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order ticket record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'SelectFromEntity': 'SalesLT.SalesOrderDetail'}\n", - "INFO:root:Loaded Schema: {'EntityName': 'Address', 'Description': 'This table stores address information for customers, including street addresses, city, state, postal code, and country/region. It is used to maintain contact and shipping information for orders, as well as to manage customer locations.', 'Entity': 'Address', 'Columns': [{'Name': 'AddressID', 'Definition': 'A unique identifier for each address. This ID is auto-generated and serves as the primary key for the Address table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'City', 'Definition': 'The city in which the address is located. This is used to specify the city for the address.', 'Type': 'NVARCHAR(30)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'StateProvince', 'Definition': 'The state or province in which the address is located. This is used to specify the state or province for the address.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CountryRegion', 'Definition': 'The country or region in which the address is located. This is used to specify the country or region for the address.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PostalCode', 'Definition': 'The postal code associated with the address. This is used to specify the postal code for the address, which helps in geographical sorting and shipping.', 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the address record was last modified. This is used for tracking updates and changes to the address information.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'SelectFromEntity': 'SalesLT.Address'}\n", - "INFO:root:Loaded Schema: {'EntityName': 'Sales Order Header', 'Description': 'This table contains high-level information about sales orders, including order dates, customer details, shipping information, and order status. It is used to manage and track sales orders from initiation to fulfillment.', 'Entity': 'SalesOrderHeader', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order. This ID is auto-generated and serves as the primary key for the SalesOrderHeader table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This field is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'OnlineOrderFlag', 'Definition': 'Indicates whether the order was placed online.', 'Type': 'BIT', 'AllowedValues': '[\"True\",\"False\"]', 'SampleValues': None}, {'Name': 'SalesOrderNumber', 'Definition': 'A unique order number assigned to the sales order. This is used for tracking and identification purposes.', 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PurchaseOrderNumber', 'Definition': \"The purchase order number provided by the customer. This field links the sales order to the customer's purchase order.\", 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'AccountNumber', 'Definition': \"The account number of the customer placing the order. This helps link the order to the customer's account.\", 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CustomerID', 'Definition': 'A foreign key that links to the Customer table, representing the customer who placed the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the shipping address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'BillToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the billing address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipMethod', 'Definition': 'The shipping method used for the order (e.g., UPS, FedEx). This field helps track shipping preferences.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'SubTotal', 'Definition': 'The total cost of the order before taxes and shipping charges. This field is used to calculate the final total. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TaxAmt', 'Definition': 'The tax amount applied to the order. This is calculated based on the order subtotal and applicable tax rates. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Freight', 'Definition': 'The shipping charge applied to the order. This field represents the cost of shipping the order to the customer. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Comment', 'Definition': 'Any additional comments or notes related to the sales order. This field can include special instructions or remarks.', 'Type': 'NVARCHAR(255)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order header record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'SelectFromEntity': 'SalesLT.SalesOrderHeader'}\n", - "INFO:root:Loaded Schema: {'EntityName': 'Address', 'Description': 'This table stores address information for customers, including street addresses, city, state, postal code, and country/region. It is used to maintain contact and shipping information for orders, as well as to manage customer locations.', 'Entity': 'Address', 'Columns': [{'Name': 'AddressID', 'Definition': 'A unique identifier for each address. This ID is auto-generated and serves as the primary key for the Address table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'City', 'Definition': 'The city in which the address is located. This is used to specify the city for the address.', 'Type': 'NVARCHAR(30)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'StateProvince', 'Definition': 'The state or province in which the address is located. This is used to specify the state or province for the address.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CountryRegion', 'Definition': 'The country or region in which the address is located. This is used to specify the country or region for the address.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PostalCode', 'Definition': 'The postal code associated with the address. This is used to specify the postal code for the address, which helps in geographical sorting and shipping.', 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the address record was last modified. This is used for tracking updates and changes to the address information.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'SelectFromEntity': 'SalesLT.Address'}\n", - "INFO:root:Loaded Schema: {'EntityName': 'Sales Order Header', 'Description': 'This table contains high-level information about sales orders, including order dates, customer details, shipping information, and order status. It is used to manage and track sales orders from initiation to fulfillment.', 'Entity': 'SalesOrderHeader', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order. This ID is auto-generated and serves as the primary key for the SalesOrderHeader table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This field is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'OnlineOrderFlag', 'Definition': 'Indicates whether the order was placed online.', 'Type': 'BIT', 'AllowedValues': '[\"True\",\"False\"]', 'SampleValues': None}, {'Name': 'SalesOrderNumber', 'Definition': 'A unique order number assigned to the sales order. This is used for tracking and identification purposes.', 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PurchaseOrderNumber', 'Definition': \"The purchase order number provided by the customer. This field links the sales order to the customer's purchase order.\", 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'AccountNumber', 'Definition': \"The account number of the customer placing the order. This helps link the order to the customer's account.\", 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CustomerID', 'Definition': 'A foreign key that links to the Customer table, representing the customer who placed the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the shipping address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'BillToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the billing address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipMethod', 'Definition': 'The shipping method used for the order (e.g., UPS, FedEx). This field helps track shipping preferences.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'SubTotal', 'Definition': 'The total cost of the order before taxes and shipping charges. This field is used to calculate the final total. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TaxAmt', 'Definition': 'The tax amount applied to the order. This is calculated based on the order subtotal and applicable tax rates. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Freight', 'Definition': 'The shipping charge applied to the order. This field represents the cost of shipping the order to the customer. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Comment', 'Definition': 'Any additional comments or notes related to the sales order. This field can include special instructions or remarks.', 'Type': 'NVARCHAR(255)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order header record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'SelectFromEntity': 'SalesLT.SalesOrderHeader'}\n", - "INFO:root:Loaded Schema: {'EntityName': 'Sales Order Detail', 'Description': 'This table stores detailed information about sales order tickets, including the order details, customer information, order status, and timestamps. It is used to manage and track sales orders throughout the order lifecycle, from creation to fulfillment.', 'Entity': 'SalesOrderDetail', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order ticket. This ID is auto-generated and serves as the primary key for the SalesOrderTicket table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges.', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order ticket record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'SelectFromEntity': 'SalesLT.SalesOrderDetail'}\n", - "INFO:root:Loaded Schema: {'EntityName': 'Sales Order Detail', 'Description': 'This table stores detailed information about sales order tickets, including the order details, customer information, order status, and timestamps. It is used to manage and track sales orders throughout the order lifecycle, from creation to fulfillment.', 'Entity': 'SalesOrderDetail', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order ticket. This ID is auto-generated and serves as the primary key for the SalesOrderTicket table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges.', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order ticket record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'SelectFromEntity': 'SalesLT.SalesOrderDetail'}\n", - "INFO:root:Loaded Schema: {'EntityName': 'Sales Order Header', 'Description': 'This table contains high-level information about sales orders, including order dates, customer details, shipping information, and order status. It is used to manage and track sales orders from initiation to fulfillment.', 'Entity': 'SalesOrderHeader', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order. This ID is auto-generated and serves as the primary key for the SalesOrderHeader table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This field is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'OnlineOrderFlag', 'Definition': 'Indicates whether the order was placed online.', 'Type': 'BIT', 'AllowedValues': '[\"True\",\"False\"]', 'SampleValues': None}, {'Name': 'SalesOrderNumber', 'Definition': 'A unique order number assigned to the sales order. This is used for tracking and identification purposes.', 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PurchaseOrderNumber', 'Definition': \"The purchase order number provided by the customer. This field links the sales order to the customer's purchase order.\", 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'AccountNumber', 'Definition': \"The account number of the customer placing the order. This helps link the order to the customer's account.\", 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CustomerID', 'Definition': 'A foreign key that links to the Customer table, representing the customer who placed the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the shipping address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'BillToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the billing address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipMethod', 'Definition': 'The shipping method used for the order (e.g., UPS, FedEx). This field helps track shipping preferences.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'SubTotal', 'Definition': 'The total cost of the order before taxes and shipping charges. This field is used to calculate the final total. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TaxAmt', 'Definition': 'The tax amount applied to the order. This is calculated based on the order subtotal and applicable tax rates. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Freight', 'Definition': 'The shipping charge applied to the order. This field represents the cost of shipping the order to the customer. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Comment', 'Definition': 'Any additional comments or notes related to the sales order. This field can include special instructions or remarks.', 'Type': 'NVARCHAR(255)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order header record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}], 'SelectFromEntity': 'SalesLT.SalesOrderHeader'}\n", - "INFO:semantic_kernel.functions.kernel_function:Function SQL-RunSQLQuery succeeded.\n", - "INFO:semantic_kernel.functions.kernel_function:Function completed. Duration: 0.330935s\n", - "INFO:root:Document: {'Question': 'Which country did we sell the most to in June 2008?', 'Query': \"SELECT TOP 1 a.CountryRegion, SUM(s.TotalDue) as TotalSales FROM SalesLT.SalesOrderHeader s INNER JOIN SalesLT.Address a ON s.ShipToAddressID = a.AddressID WHERE s.OrderDate BETWEEN '2008-06-01' AND '2008-06-30' GROUP BY a.CountryRegion ORDER BY TotalSales DESC;\", 'Schemas': [{'Entity': 'SalesOrderDetail', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order ticket. This ID is auto-generated and serves as the primary key for the SalesOrderTicket table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges.', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order ticket record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}]}, {'Entity': 'Address', 'Columns': [{'Name': 'AddressID', 'Definition': 'A unique identifier for each address. This ID is auto-generated and serves as the primary key for the Address table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'City', 'Definition': 'The city in which the address is located. This is used to specify the city for the address.', 'Type': 'NVARCHAR(30)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'StateProvince', 'Definition': 'The state or province in which the address is located. This is used to specify the state or province for the address.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CountryRegion', 'Definition': 'The country or region in which the address is located. This is used to specify the country or region for the address.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PostalCode', 'Definition': 'The postal code associated with the address. This is used to specify the postal code for the address, which helps in geographical sorting and shipping.', 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the address record was last modified. This is used for tracking updates and changes to the address information.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}]}, {'Entity': 'SalesOrderHeader', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order. This ID is auto-generated and serves as the primary key for the SalesOrderHeader table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This field is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'OnlineOrderFlag', 'Definition': 'Indicates whether the order was placed online.', 'Type': 'BIT', 'AllowedValues': '[\"True\",\"False\"]', 'SampleValues': None}, {'Name': 'SalesOrderNumber', 'Definition': 'A unique order number assigned to the sales order. This is used for tracking and identification purposes.', 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PurchaseOrderNumber', 'Definition': \"The purchase order number provided by the customer. This field links the sales order to the customer's purchase order.\", 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'AccountNumber', 'Definition': \"The account number of the customer placing the order. This helps link the order to the customer's account.\", 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CustomerID', 'Definition': 'A foreign key that links to the Customer table, representing the customer who placed the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the shipping address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'BillToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the billing address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipMethod', 'Definition': 'The shipping method used for the order (e.g., UPS, FedEx). This field helps track shipping preferences.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'SubTotal', 'Definition': 'The total cost of the order before taxes and shipping charges. This field is used to calculate the final total. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TaxAmt', 'Definition': 'The tax amount applied to the order. This is calculated based on the order subtotal and applicable tax rates. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Freight', 'Definition': 'The shipping charge applied to the order. This field represents the cost of shipping the order to the customer. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Comment', 'Definition': 'Any additional comments or notes related to the sales order. This field can include special instructions or remarks.', 'Type': 'NVARCHAR(255)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order header record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}]}, {'Entity': 'Address', 'Columns': [{'Name': 'AddressID', 'Definition': 'A unique identifier for each address. This ID is auto-generated and serves as the primary key for the Address table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'City', 'Definition': 'The city in which the address is located. This is used to specify the city for the address.', 'Type': 'NVARCHAR(30)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'StateProvince', 'Definition': 'The state or province in which the address is located. This is used to specify the state or province for the address.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CountryRegion', 'Definition': 'The country or region in which the address is located. This is used to specify the country or region for the address.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PostalCode', 'Definition': 'The postal code associated with the address. This is used to specify the postal code for the address, which helps in geographical sorting and shipping.', 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the address record was last modified. This is used for tracking updates and changes to the address information.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}]}, {'Entity': 'SalesOrderHeader', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order. This ID is auto-generated and serves as the primary key for the SalesOrderHeader table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This field is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'OnlineOrderFlag', 'Definition': 'Indicates whether the order was placed online.', 'Type': 'BIT', 'AllowedValues': '[\"True\",\"False\"]', 'SampleValues': None}, {'Name': 'SalesOrderNumber', 'Definition': 'A unique order number assigned to the sales order. This is used for tracking and identification purposes.', 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PurchaseOrderNumber', 'Definition': \"The purchase order number provided by the customer. This field links the sales order to the customer's purchase order.\", 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'AccountNumber', 'Definition': \"The account number of the customer placing the order. This helps link the order to the customer's account.\", 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CustomerID', 'Definition': 'A foreign key that links to the Customer table, representing the customer who placed the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the shipping address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'BillToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the billing address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipMethod', 'Definition': 'The shipping method used for the order (e.g., UPS, FedEx). This field helps track shipping preferences.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'SubTotal', 'Definition': 'The total cost of the order before taxes and shipping charges. This field is used to calculate the final total. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TaxAmt', 'Definition': 'The tax amount applied to the order. This is calculated based on the order subtotal and applicable tax rates. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Freight', 'Definition': 'The shipping charge applied to the order. This field represents the cost of shipping the order to the customer. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Comment', 'Definition': 'Any additional comments or notes related to the sales order. This field can include special instructions or remarks.', 'Type': 'NVARCHAR(255)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order header record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}]}, {'Entity': 'SalesOrderDetail', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order ticket. This ID is auto-generated and serves as the primary key for the SalesOrderTicket table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges.', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order ticket record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}]}, {'Entity': 'SalesOrderDetail', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order ticket. This ID is auto-generated and serves as the primary key for the SalesOrderTicket table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges.', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order ticket record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}]}, {'Entity': 'SalesOrderHeader', 'Columns': [{'Name': 'SalesOrderID', 'Definition': 'A unique identifier for each sales order. This ID is auto-generated and serves as the primary key for the SalesOrderHeader table.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'OrderDate', 'Definition': 'The date and time when the sales order was created. This field is used to track when the order was initiated.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'DueDate', 'Definition': 'The date by which the order is expected to be fulfilled or delivered. It helps in managing delivery timelines.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipDate', 'Definition': 'The date when the order was shipped to the customer. This is used for tracking shipping and fulfillment status.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Status', 'Definition': 'The current status of the order, represented as a numeric code (e.g., 1 for In Progress, 2 for Completed, 3 for Canceled).', 'Type': 'TINYINT', 'AllowedValues': '[1,2,3]', 'SampleValues': None}, {'Name': 'OnlineOrderFlag', 'Definition': 'Indicates whether the order was placed online.', 'Type': 'BIT', 'AllowedValues': '[\"True\",\"False\"]', 'SampleValues': None}, {'Name': 'SalesOrderNumber', 'Definition': 'A unique order number assigned to the sales order. This is used for tracking and identification purposes.', 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'PurchaseOrderNumber', 'Definition': \"The purchase order number provided by the customer. This field links the sales order to the customer's purchase order.\", 'Type': 'NVARCHAR(25)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'AccountNumber', 'Definition': \"The account number of the customer placing the order. This helps link the order to the customer's account.\", 'Type': 'NVARCHAR(15)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'CustomerID', 'Definition': 'A foreign key that links to the Customer table, representing the customer who placed the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the shipping address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'BillToAddressID', 'Definition': 'A foreign key that links to the Address table, representing the billing address for the order.', 'Type': 'INT', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ShipMethod', 'Definition': 'The shipping method used for the order (e.g., UPS, FedEx). This field helps track shipping preferences.', 'Type': 'NVARCHAR(50)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'SubTotal', 'Definition': 'The total cost of the order before taxes and shipping charges. This field is used to calculate the final total. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TaxAmt', 'Definition': 'The tax amount applied to the order. This is calculated based on the order subtotal and applicable tax rates. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Freight', 'Definition': 'The shipping charge applied to the order. This field represents the cost of shipping the order to the customer. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'TotalDue', 'Definition': 'The total amount due for the order, including all line items, taxes, and shipping charges. The currency is pound sterling (GBP).', 'Type': 'MONEY', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'Comment', 'Definition': 'Any additional comments or notes related to the sales order. This field can include special instructions or remarks.', 'Type': 'NVARCHAR(255)', 'AllowedValues': None, 'SampleValues': None}, {'Name': 'ModifiedDate', 'Definition': 'The date and time when the sales order header record was last modified. This is used for tracking updates and changes to the order.', 'Type': 'DATETIME', 'AllowedValues': None, 'SampleValues': None}]}]}\n", - "INFO:root:Vector Fields: {'Question': 'QuestionEmbedding'}\n", - "INFO:httpx:HTTP Request: POST https://aoai-text2sql-adi.openai.azure.com/openai/deployments/text-embedding-ada-002/embeddings?api-version=2023-03-15-preview \"HTTP/1.1 200 OK\"\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Request URL: 'https://open-ai-vector-db.search.windows.net/indexes('text-2-sql-query-cache-index')/docs/search.index?api-version=REDACTED'\n", - "Request method: 'POST'\n", - "Request headers:\n", - " 'Content-Type': 'application/json'\n", - " 'Content-Length': '55370'\n", - " 'api-key': 'REDACTED'\n", - " 'Accept': 'application/json;odata.metadata=none'\n", - " 'x-ms-client-request-id': '1af7e516-7784-11ef-9963-0242ac110002'\n", - " 'User-Agent': 'azsdk-python-search-documents/11.6.0b4 Python/3.12.6 (Linux-5.15.153.1-microsoft-standard-WSL2-x86_64-with-glibc2.36)'\n", - "A body is sent with the request\n", - "INFO:azure.core.pipeline.policies.http_logging_policy:Response status: 200\n", - "Response headers:\n", - " 'Transfer-Encoding': 'chunked'\n", - " 'Content-Type': 'application/json; odata.metadata=none; odata.streaming=true; charset=utf-8'\n", - " 'Content-Encoding': 'REDACTED'\n", - " 'Vary': 'REDACTED'\n", - " 'Server': 'Microsoft-IIS/10.0'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Preference-Applied': 'REDACTED'\n", - " 'OData-Version': 'REDACTED'\n", - " 'request-id': '1af7e516-7784-11ef-9963-0242ac110002'\n", - " 'elapsed-time': 'REDACTED'\n", - " 'Strict-Transport-Security': 'REDACTED'\n", - " 'Date': 'Fri, 20 Sep 2024 19:11:16 GMT'\n", - "INFO:httpx:HTTP Request: POST https://aoai-text2sql-adi.openai.azure.com/openai/deployments/gpt-4o/chat/completions?api-version=2024-02-01 \"HTTP/1.1 200 OK\"\n", - "INFO:semantic_kernel.connectors.ai.open_ai.services.open_ai_handler:OpenAI usage: CompletionUsage(completion_tokens=173, prompt_tokens=7429, total_tokens=7602, completion_tokens_details=None)\n", - "INFO:semantic_kernel.functions.kernel_function:Function ChatBot-Chat succeeded.\n", - "INFO:semantic_kernel.functions.kernel_function:Function completed. Duration: 6.503125s\n", - "INFO:root:Answer: {\n", - " \"answer\": \"In June 2008, the country with the highest sales was the United Kingdom, with total sales amounting to \u00a3572,496.56.\",\n", - " \"sources\": [\n", - " {\n", - " \"title\": \"Sales Order Header\",\n", - " \"chunk\": \"| CountryRegion | TotalSales |\\n|------------------|--------------|\\n| United Kingdom | 572496.5594 |\\n\",\n", - " \"reference\": \"SELECT TOP 1 a.CountryRegion, SUM(s.TotalDue) as TotalSales FROM SalesLT.SalesOrderHeader s INNER JOIN SalesLT.Address a ON s.ShipToAddressID = a.AddressID WHERE s.OrderDate BETWEEN '2008-06-01' AND '2008-06-30' GROUP BY a.CountryRegion ORDER BY TotalSales DESC;\"\n", - " }\n", - " ]\n", - "}\n" - ] - }, - { - "data": { - "text/markdown": [ - "In June 2008, the country with the highest sales was the United Kingdom, with total sales amounting to \u00a3572,496.56." - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "await ask_question(\"Which country did we sell the most to in June 2008?\", history)" ] diff --git a/text_2_sql/semantic_kernel/utils/ai_search_utils.py b/text_2_sql/semantic_kernel/utils/ai_search_utils.py new file mode 100644 index 0000000..f16ecd0 --- /dev/null +++ b/text_2_sql/semantic_kernel/utils/ai_search_utils.py @@ -0,0 +1,150 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +from azure.identity import DefaultAzureCredential +from openai import AsyncAzureOpenAI +from azure.core.credentials import AzureKeyCredential +from azure.search.documents.models import VectorizedQuery +from azure.search.documents.aio import SearchClient +from environment import IdentityType, get_identity_type +import os +import logging +import base64 +from datetime import datetime, timezone + + +async def run_ai_search_query( + query, + vector_fields: list[str], + retrieval_fields: list[str], + index_name: str, + semantic_config: str, + top=5, + include_scores=False, + minimum_score: float = None, +): + """Run the AI search query.""" + identity_type = get_identity_type() + + async with AsyncAzureOpenAI( + # This is the default and can be omitted + api_key=os.environ["OpenAI__ApiKey"], + azure_endpoint=os.environ["OpenAI__Endpoint"], + api_version=os.environ["OpenAI__ApiVersion"], + ) as open_ai_client: + embeddings = await open_ai_client.embeddings.create( + model=os.environ["OpenAI__EmbeddingModel"], input=query + ) + + # Extract the embedding vector + embedding_vector = embeddings.data[0].embedding + + vector_query = VectorizedQuery( + vector=embedding_vector, + k_nearest_neighbors=7, + fields=",".join(vector_fields), + ) + + if identity_type == IdentityType.SYSTEM_ASSIGNED: + credential = DefaultAzureCredential() + elif identity_type == IdentityType.USER_ASSIGNED: + credential = DefaultAzureCredential( + managed_identity_client_id=os.environ["ClientID"] + ) + else: + credential = AzureKeyCredential( + os.environ["AIService__AzureSearchOptions__Key"] + ) + async with SearchClient( + endpoint=os.environ["AIService__AzureSearchOptions__Endpoint"], + index_name=index_name, + credential=credential, + ) as search_client: + results = await search_client.search( + top=top, + semantic_configuration_name=semantic_config, + search_text=query, + select=",".join(retrieval_fields), + vector_queries=[vector_query], + query_type="semantic", + query_language="en-GB", + ) + + combined_results = [] + + async for result in results.by_page(): + async for item in result: + if ( + minimum_score is not None + and item["@search.reranker_score"] < minimum_score + ): + continue + + if include_scores is False: + del item["@search.reranker_score"] + del item["@search.score"] + del item["@search.highlights"] + del item["@search.captions"] + + logging.info("Item: %s", item) + combined_results.append(item) + + logging.info("Results: %s", combined_results) + + return combined_results + + +async def add_entry_to_index(document: dict, vector_fields: dict, index_name: str): + """Add an entry to the search index.""" + + logging.info("Document: %s", document) + logging.info("Vector Fields: %s", vector_fields) + + for field in vector_fields.keys(): + if field not in document.keys(): + logging.error(f"Field {field} is not in the document.") + + identity_type = get_identity_type() + + fields_to_embed = {field: document[field] for field in vector_fields} + + document["DateLastModified"] = datetime.now(timezone.utc) + + try: + async with AsyncAzureOpenAI( + # This is the default and can be omitted + api_key=os.environ["OpenAI__ApiKey"], + azure_endpoint=os.environ["OpenAI__Endpoint"], + api_version=os.environ["OpenAI__ApiVersion"], + ) as open_ai_client: + embeddings = await open_ai_client.embeddings.create( + model=os.environ["OpenAI__EmbeddingModel"], + input=fields_to_embed.values(), + ) + + # Extract the embedding vector + for i, field in enumerate(vector_fields.values()): + document[field] = embeddings.data[i].embedding + + document["Id"] = base64.urlsafe_b64encode(document["Question"].encode()).decode( + "utf-8" + ) + + if identity_type == IdentityType.SYSTEM_ASSIGNED: + credential = DefaultAzureCredential() + elif identity_type == IdentityType.USER_ASSIGNED: + credential = DefaultAzureCredential( + managed_identity_client_id=os.environ["ClientID"] + ) + else: + credential = AzureKeyCredential( + os.environ["AIService__AzureSearchOptions__Key"] + ) + async with SearchClient( + endpoint=os.environ["AIService__AzureSearchOptions__Endpoint"], + index_name=index_name, + credential=credential, + ) as search_client: + await search_client.upload_documents(documents=[document]) + except Exception as e: + logging.error("Failed to add item to index.") + logging.error("Error: %s", e)