{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# ReAct OpenAPI MS Graph Agent"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Install Required Libraries\n",
    "Before starting, ensure the required libraries are installed:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install dapr-agents python-dotenv "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Import Environment Variables"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from dapr_agents import OpenAPIReActAgent\n",
    "from dapr_agents.tool.utils import OpenAPISpecParser\n",
    "from dotenv import load_dotenv\n",
    "import logging"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Enable Logging"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "logging.basicConfig(level=logging.INFO)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Load Environment Variables"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "load_dotenv()  # take environment variables from .env."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Define MS Graph HTTP Header with Access Token"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "import requests\n",
    "import os\n",
    "\n",
    "def construct_auth_headers():\n",
    "    CLIENT_ID = os.getenv(\"AAD_APP_ID\")\n",
    "    CLIENT_SECRET = os.getenv(\"AAD_APP_CLIENT_SECRET\")\n",
    "    TENANT_ID = os.getenv(\"TENANT_ID\")\n",
    "\n",
    "    AUTH_URL = f\"https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token\"\n",
    "\n",
    "    # POST\n",
    "    auth_response = requests.post(AUTH_URL, {\n",
    "        'grant_type': 'client_credentials',\n",
    "        'client_id': CLIENT_ID,\n",
    "        'client_secret': CLIENT_SECRET,\n",
    "        'scope': 'https://graph.microsoft.com/.default'\n",
    "    })\n",
    "\n",
    "    # convert the response to JSON\n",
    "    auth_response_data = auth_response.json()\n",
    "\n",
    "    # save the access token\n",
    "    access_token = auth_response_data['access_token']\n",
    "\n",
    "    return {\"Authorization\": f\"Bearer {access_token}\"}\n",
    "\n",
    "\n",
    "# Get API credentials.\n",
    "headers = construct_auth_headers()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Process MS Graph Users OpenAPI Spec Remotely"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "openapi_spec_url = \"https://raw.githubusercontent.com/microsoftgraph/msgraph-sdk-powershell/dev/openApiDocs/v1.0/Users.yml\"\n",
    "spec_parser = OpenAPISpecParser.from_url(openapi_spec_url)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('GET /users',\n",
       " 'List properties and relationships of the user objects.',\n",
       " Operation(tags=['users.user'], summary='List users', description='List properties and relationships of the user objects.', externalDocs=ExternalDocumentation(description='Find more info here', url='https://learn.microsoft.com/graph/api/intune-mam-user-list?view=graph-rest-1.0'), operationId='user_ListUser', parameters=[Parameter(description='Indicates the requested consistency level. Documentation URL: https://docs.microsoft.com/graph/aad-advanced-queries', required=False, deprecated=False, style='simple', explode=None, param_schema=Schema(title=None, multipleOf=None, maximum=None, exclusiveMaximum=None, minimum=None, exclusiveMinimum=None, maxLength=None, minLength=None, pattern=None, maxItems=None, minItems=None, uniqueItems=None, maxProperties=None, minProperties=None, required=None, enum=None, type=<DataType.STRING: 'string'>, allOf=None, oneOf=None, anyOf=None, schema_not=None, items=None, properties=None, additionalProperties=None, description=None, schema_format=None, default=None, nullable=None, discriminator=None, readOnly=None, writeOnly=None, xml=None, externalDocs=None, example=None, deprecated=None), example=None, examples={'example-1': Example(summary=None, description=\"$search and $count queries require the client to set the ConsistencyLevel HTTP header to 'eventual'.\", value='eventual', externalValue=None)}, content=None, name='ConsistencyLevel', param_in=<ParameterLocation.HEADER: 'header'>, allowEmptyValue=False, allowReserved=False), Reference(ref='#/components/parameters/top'), Reference(ref='#/components/parameters/search'), Reference(ref='#/components/parameters/filter'), Reference(ref='#/components/parameters/count'), Parameter(description='Order items by property values', required=False, deprecated=False, style='form', explode=False, param_schema=Schema(title=None, multipleOf=None, maximum=None, exclusiveMaximum=None, minimum=None, exclusiveMinimum=None, maxLength=None, minLength=None, pattern=None, maxItems=None, minItems=None, uniqueItems=True, maxProperties=None, minProperties=None, required=None, enum=None, type=<DataType.ARRAY: 'array'>, allOf=None, oneOf=None, anyOf=None, schema_not=None, items=Schema(title=None, multipleOf=None, maximum=None, exclusiveMaximum=None, minimum=None, exclusiveMinimum=None, maxLength=None, minLength=None, pattern=None, maxItems=None, minItems=None, uniqueItems=None, maxProperties=None, minProperties=None, required=None, enum=None, type=<DataType.STRING: 'string'>, allOf=None, oneOf=None, anyOf=None, schema_not=None, items=None, properties=None, additionalProperties=None, description=None, schema_format=None, default=None, nullable=None, discriminator=None, readOnly=None, writeOnly=None, xml=None, externalDocs=None, example=None, deprecated=None), properties=None, additionalProperties=None, description=None, schema_format=None, default=None, nullable=None, discriminator=None, readOnly=None, writeOnly=None, xml=None, externalDocs=None, example=None, deprecated=None), example=None, examples=None, content=None, name='$orderby', param_in=<ParameterLocation.QUERY: 'query'>, allowEmptyValue=False, allowReserved=False), Parameter(description='Select properties to be returned', required=False, deprecated=False, style='form', explode=False, param_schema=Schema(title=None, multipleOf=None, maximum=None, exclusiveMaximum=None, minimum=None, exclusiveMinimum=None, maxLength=None, minLength=None, pattern=None, maxItems=None, minItems=None, uniqueItems=True, maxProperties=None, minProperties=None, required=None, enum=None, type=<DataType.ARRAY: 'array'>, allOf=None, oneOf=None, anyOf=None, schema_not=None, items=Schema(title=None, multipleOf=None, maximum=None, exclusiveMaximum=None, minimum=None, exclusiveMinimum=None, maxLength=None, minLength=None, pattern=None, maxItems=None, minItems=None, uniqueItems=None, maxProperties=None, minProperties=None, required=None, enum=None, type=<DataType.STRING: 'string'>, allOf=None, oneOf=None, anyOf=None, schema_not=None, items=None, properties=None, additionalProperties=None, description=None, schema_format=None, default=None, nullable=None, discriminator=None, readOnly=None, writeOnly=None, xml=None, externalDocs=None, example=None, deprecated=None), properties=None, additionalProperties=None, description=None, schema_format=None, default=None, nullable=None, discriminator=None, readOnly=None, writeOnly=None, xml=None, externalDocs=None, example=None, deprecated=None), example=None, examples=None, content=None, name='$select', param_in=<ParameterLocation.QUERY: 'query'>, allowEmptyValue=False, allowReserved=False), Parameter(description='Expand related entities', required=False, deprecated=False, style='form', explode=False, param_schema=Schema(title=None, multipleOf=None, maximum=None, exclusiveMaximum=None, minimum=None, exclusiveMinimum=None, maxLength=None, minLength=None, pattern=None, maxItems=None, minItems=None, uniqueItems=True, maxProperties=None, minProperties=None, required=None, enum=None, type=<DataType.ARRAY: 'array'>, allOf=None, oneOf=None, anyOf=None, schema_not=None, items=Schema(title=None, multipleOf=None, maximum=None, exclusiveMaximum=None, minimum=None, exclusiveMinimum=None, maxLength=None, minLength=None, pattern=None, maxItems=None, minItems=None, uniqueItems=None, maxProperties=None, minProperties=None, required=None, enum=None, type=<DataType.STRING: 'string'>, allOf=None, oneOf=None, anyOf=None, schema_not=None, items=None, properties=None, additionalProperties=None, description=None, schema_format=None, default=None, nullable=None, discriminator=None, readOnly=None, writeOnly=None, xml=None, externalDocs=None, example=None, deprecated=None), properties=None, additionalProperties=None, description=None, schema_format=None, default=None, nullable=None, discriminator=None, readOnly=None, writeOnly=None, xml=None, externalDocs=None, example=None, deprecated=None), example=None, examples=None, content=None, name='$expand', param_in=<ParameterLocation.QUERY: 'query'>, allowEmptyValue=False, allowReserved=False)], requestBody=None, responses={'2XX': Reference(ref='#/components/responses/microsoft.graph.userCollectionResponse'), 'default': Reference(ref='#/components/responses/error')}, callbacks=None, deprecated=False, security=None, servers=None, x-ms-pageable={'nextLinkName': '@odata.nextLink', 'operationName': 'listMore'}, x-ms-docs-operation-type='operation'))"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "spec_parser.endpoints[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "236"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(spec_parser.endpoints)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## (Optional) OpenAPI Specification to OpenAI Function Call"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "from dapr_agents.tool.utils.openapi import openapi_spec_to_openai_fn\n",
    "\n",
    "functions = openapi_spec_to_openai_fn(spec_parser)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'definition': {'type': 'function',\n",
       "  'function': {'name': 'user_ListUser',\n",
       "   'description': 'List properties and relationships of the user objects.',\n",
       "   'parameters': {'type': 'object',\n",
       "    'properties': {'params': {'type': 'object',\n",
       "      'properties': {'$top': {'minimum': 0.0,\n",
       "        'type': 'integer',\n",
       "        'description': 'Show only the first n items'},\n",
       "       '$search': {'type': 'string',\n",
       "        'description': 'Search items by search phrases'},\n",
       "       '$filter': {'type': 'string',\n",
       "        'description': 'Filter items by property values'},\n",
       "       '$count': {'type': 'boolean', 'description': 'Include count of items'},\n",
       "       '$orderby': {'uniqueItems': True,\n",
       "        'type': 'array',\n",
       "        'items': {'type': 'string'},\n",
       "        'description': 'Order items by property values'},\n",
       "       '$select': {'uniqueItems': True,\n",
       "        'type': 'array',\n",
       "        'items': {'type': 'string'},\n",
       "        'description': 'Select properties to be returned'},\n",
       "       '$expand': {'uniqueItems': True,\n",
       "        'type': 'array',\n",
       "        'items': {'type': 'string'},\n",
       "        'description': 'Expand related entities'}},\n",
       "      'required': []},\n",
       "     'headers': {'type': 'object',\n",
       "      'properties': {'ConsistencyLevel': {'type': 'string',\n",
       "        'description': 'Indicates the requested consistency level. Documentation URL: https://docs.microsoft.com/graph/aad-advanced-queries'}},\n",
       "      'required': []}}}}},\n",
       " 'metadata': {'method': 'get',\n",
       "  'url': 'https://graph.microsoft.com/v1.0//users'}}"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "functions[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Initialize Chroma Vectorstore"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Define Embedding Function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:dapr_agents.document.embedder.sentence:Downloading SentenceTransformer model: all-MiniLM-L6-v2\n",
      "INFO:sentence_transformers.SentenceTransformer:Load pretrained SentenceTransformer: all-MiniLM-L6-v2\n",
      "INFO:dapr_agents.document.embedder.sentence:Model loaded successfully.\n"
     ]
    }
   ],
   "source": [
    "from dapr_agents.document.embedder import SentenceTransformerEmbedder\n",
    "\n",
    "embedding_function = SentenceTransformerEmbedder(\n",
    "    model=\"all-MiniLM-L6-v2\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Initialize Vectorstore"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:dapr_agents.storage.vectorstores.chroma:ChromaVectorStore initialized with collection: api_toolbox\n"
     ]
    }
   ],
   "source": [
    "from dapr_agents.storage import ChromaVectorStore\n",
    "\n",
    "api_vector_store = ChromaVectorStore(\n",
    "    name=\"api_toolbox\",\n",
    "    embedding_function=embedding_function,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Define OpenAPI ReAct Agent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:dapr_agents.llm.openai.client.base:Initializing OpenAI client...\n",
      "INFO:dapr_agents.agent.patterns.openapi.react:Setting up VectorToolStore for OpenAPIReActAgent...\n",
      "INFO:dapr_agents.tool.storage.vectorstore:Adding tools to Vector Tool Store.\n",
      "INFO:dapr_agents.document.embedder.sentence:Generating embeddings for 236 input(s).\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "b206f22263d343a8b3976225c67e74b3",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Batches:   0%|          | 0/8 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:dapr_agents.tool.executor:Tool registered: GetOpenapiDefinition\n",
      "INFO:dapr_agents.tool.executor:Tool registered: OpenApiCallExecutor\n",
      "INFO:dapr_agents.tool.executor:Tool Executor initialized with 2 registered tools.\n",
      "INFO:dapr_agents.agent.base:Constructing system_prompt from agent attributes.\n",
      "INFO:dapr_agents.agent.base:Using system_prompt to create the prompt template.\n",
      "INFO:dapr_agents.agent.base:Pre-filled prompt template with attributes: ['name', 'role', 'goal', 'instructions']\n"
     ]
    }
   ],
   "source": [
    "AIAgent = OpenAPIReActAgent(\n",
    "    role = \"MS Graph API Assistant\",\n",
    "    spec_parser=spec_parser,\n",
    "    api_vector_store=api_vector_store,\n",
    "    auth_header=headers\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Inspect Tools Registered in Agent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-style: italic\">                                                  Available Tools                                                  </span>\n",
       "┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n",
       "┃<span style=\"font-weight: bold\"> Name                 </span>┃<span style=\"font-weight: bold\"> Description                                </span>┃<span style=\"font-weight: bold\"> Signature                                   </span>┃\n",
       "┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n",
       "│<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\"> GetOpenapiDefinition </span>│                                            │ GetOpenapiDefinition(user_input: str)       │\n",
       "│<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">                      </span>│         Get potential APIs for the user to │                                             │\n",
       "│<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">                      </span>│ use to accompish task.                     │                                             │\n",
       "│<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">                      </span>│         You have to choose the right one   │                                             │\n",
       "│<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">                      </span>│ after getting a response.                  │                                             │\n",
       "│<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">                      </span>│         This tool MUST be used before      │                                             │\n",
       "│<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">                      </span>│ calling any APIs.                          │                                             │\n",
       "│<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">                      </span>│                                            │                                             │\n",
       "│<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\"> OpenApiCallExecutor  </span>│                                            │ OpenApiCallExecutor(path_template: str,     │\n",
       "│<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">                      </span>│         Execute an API call based on       │ method: str, path_params: Dict, data: Dict, │\n",
       "│<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">                      </span>│ provided parameters and configuration.     │ headers: Optional = None, params: Optional  │\n",
       "│<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">                      </span>│         It MUST be used after the          │ = None, kwargs: Any)                        │\n",
       "│<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">                      </span>│ get_openapi_definition to call APIs.       │                                             │\n",
       "│<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">                      </span>│         Make sure to include the right     │                                             │\n",
       "│<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">                      </span>│ header values to authenticate to the API   │                                             │\n",
       "│<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">                      </span>│ if needed.                                 │                                             │\n",
       "│<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">                      </span>│                                            │                                             │\n",
       "└──────────────────────┴────────────────────────────────────────────┴─────────────────────────────────────────────┘\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[3m                                                  Available Tools                                                  \u001b[0m\n",
       "┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n",
       "┃\u001b[1m \u001b[0m\u001b[1mName                \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mDescription                               \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mSignature                                  \u001b[0m\u001b[1m \u001b[0m┃\n",
       "┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩\n",
       "│\u001b[1;36m \u001b[0m\u001b[1;36mGetOpenapiDefinition\u001b[0m\u001b[1;36m \u001b[0m│                                            │ GetOpenapiDefinition(user_input: str)       │\n",
       "│\u001b[1;36m                      \u001b[0m│         Get potential APIs for the user to │                                             │\n",
       "│\u001b[1;36m                      \u001b[0m│ use to accompish task.                     │                                             │\n",
       "│\u001b[1;36m                      \u001b[0m│         You have to choose the right one   │                                             │\n",
       "│\u001b[1;36m                      \u001b[0m│ after getting a response.                  │                                             │\n",
       "│\u001b[1;36m                      \u001b[0m│         This tool MUST be used before      │                                             │\n",
       "│\u001b[1;36m                      \u001b[0m│ calling any APIs.                          │                                             │\n",
       "│\u001b[1;36m                      \u001b[0m│                                            │                                             │\n",
       "│\u001b[1;36m \u001b[0m\u001b[1;36mOpenApiCallExecutor \u001b[0m\u001b[1;36m \u001b[0m│                                            │ OpenApiCallExecutor(path_template: str,     │\n",
       "│\u001b[1;36m                      \u001b[0m│         Execute an API call based on       │ method: str, path_params: Dict, data: Dict, │\n",
       "│\u001b[1;36m                      \u001b[0m│ provided parameters and configuration.     │ headers: Optional = None, params: Optional  │\n",
       "│\u001b[1;36m                      \u001b[0m│         It MUST be used after the          │ = None, kwargs: Any)                        │\n",
       "│\u001b[1;36m                      \u001b[0m│ get_openapi_definition to call APIs.       │                                             │\n",
       "│\u001b[1;36m                      \u001b[0m│         Make sure to include the right     │                                             │\n",
       "│\u001b[1;36m                      \u001b[0m│ header values to authenticate to the API   │                                             │\n",
       "│\u001b[1;36m                      \u001b[0m│ if needed.                                 │                                             │\n",
       "│\u001b[1;36m                      \u001b[0m│                                            │                                             │\n",
       "└──────────────────────┴────────────────────────────────────────────┴─────────────────────────────────────────────┘\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "AIAgent.tool_executor.help"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Search for APIs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:dapr_agents.tool.storage.vectorstore:Searching for tools similar to query: Get information about a user with ID da48bd32-94bd-4263-b23a-5b9820a67fab\n",
      "INFO:dapr_agents.document.embedder.sentence:Generating embeddings for 1 input(s).\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "da61a88331eb4d61bd6103a3435b3461",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Batches:   0%|          | 0/1 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "{'ids': [['62ea8a80-b9c2-4939-8a1a-9751a352f0cb',\n",
       "   '297e584c-ad03-4b58-b043-6d7013c2189f',\n",
       "   'cc49bf8b-8396-4eed-a844-c662687d5722',\n",
       "   'd2d35002-7aae-4071-aedf-9b7edf0644bc']],\n",
       " 'embeddings': None,\n",
       " 'documents': [[\"user.DirectReport_GetCountAsUser: None. Args schema: {'type': 'object', 'properties': {'params': {'type': 'object', 'properties': {'$search': {'type': 'string', 'description': 'Search items by search phrases'}, '$filter': {'type': 'string', 'description': 'Filter items by property values'}}, 'required': []}, 'headers': {'type': 'object', 'properties': {'ConsistencyLevel': {'type': 'string', 'description': 'Indicates the requested consistency level. Documentation URL: https://docs.microsoft.com/graph/aad-advanced-queries'}}, 'required': []}, 'path_params': {'type': 'object', 'properties': {'user-id': {'type': 'string', 'description': 'The unique identifier of user'}}, 'required': ['user-id']}}}\",\n",
       "   \"user_GetDirectReport: The users and contacts that report to the user. (The users and contacts that have their manager property set to this user.) Read-only. Nullable. Supports $expand.. Args schema: {'type': 'object', 'properties': {'params': {'type': 'object', 'properties': {'$select': {'uniqueItems': True, 'type': 'array', 'items': {'type': 'string'}, 'description': 'Select properties to be returned'}, '$expand': {'uniqueItems': True, 'type': 'array', 'items': {'type': 'string'}, 'description': 'Expand related entities'}}, 'required': []}, 'headers': {'type': 'object', 'properties': {'ConsistencyLevel': {'type': 'string', 'description': 'Indicates the requested consistency level. Documentation URL: https://docs.microsoft.com/graph/aad-advanced-queries'}}, 'required': []}, 'path_params': {'type': 'object', 'properties': {'user-id': {'type': 'string', 'description': 'The unique identifier of user'}, 'directoryObject-id': {'type': 'string', 'description': 'The unique identifier of directoryObject'}}, 'required': ['user-id', 'directoryObject-id']}}}\",\n",
       "   \"user.registeredDevice_GetCount: None. Args schema: {'type': 'object', 'properties': {'params': {'type': 'object', 'properties': {'$search': {'type': 'string', 'description': 'Search items by search phrases'}, '$filter': {'type': 'string', 'description': 'Filter items by property values'}}, 'required': []}, 'headers': {'type': 'object', 'properties': {'ConsistencyLevel': {'type': 'string', 'description': 'Indicates the requested consistency level. Documentation URL: https://docs.microsoft.com/graph/aad-advanced-queries'}}, 'required': []}, 'path_params': {'type': 'object', 'properties': {'user-id': {'type': 'string', 'description': 'The unique identifier of user'}}, 'required': ['user-id']}}}\",\n",
       "   \"user.RegisteredDevice_GetCountAsAppRoleAssignment: None. Args schema: {'type': 'object', 'properties': {'params': {'type': 'object', 'properties': {'$search': {'type': 'string', 'description': 'Search items by search phrases'}, '$filter': {'type': 'string', 'description': 'Filter items by property values'}}, 'required': []}, 'headers': {'type': 'object', 'properties': {'ConsistencyLevel': {'type': 'string', 'description': 'Indicates the requested consistency level. Documentation URL: https://docs.microsoft.com/graph/aad-advanced-queries'}}, 'required': []}, 'path_params': {'type': 'object', 'properties': {'user-id': {'type': 'string', 'description': 'The unique identifier of user'}}, 'required': ['user-id']}}}\"]],\n",
       " 'uris': None,\n",
       " 'data': None,\n",
       " 'metadatas': [[{'method': 'get',\n",
       "    'name': 'user.DirectReport_GetCountAsUser',\n",
       "    'url': 'https://graph.microsoft.com/v1.0//users/{user-id}/directReports/microsoft.graph.user/$count'},\n",
       "   {'method': 'get',\n",
       "    'name': 'user_GetDirectReport',\n",
       "    'url': 'https://graph.microsoft.com/v1.0//users/{user-id}/directReports/{directoryObject-id}'},\n",
       "   {'method': 'get',\n",
       "    'name': 'user.registeredDevice_GetCount',\n",
       "    'url': 'https://graph.microsoft.com/v1.0//users/{user-id}/registeredDevices/$count'},\n",
       "   {'method': 'get',\n",
       "    'name': 'user.RegisteredDevice_GetCountAsAppRoleAssignment',\n",
       "    'url': 'https://graph.microsoft.com/v1.0//users/{user-id}/registeredDevices/microsoft.graph.appRoleAssignment/$count'}]],\n",
       " 'distances': [[0.6506010293960571,\n",
       "   0.6595721244812012,\n",
       "   0.6822196245193481,\n",
       "   0.684098482131958]],\n",
       " 'included': [<IncludeEnum.distances: 'distances'>,\n",
       "  <IncludeEnum.documents: 'documents'>,\n",
       "  <IncludeEnum.metadatas: 'metadatas'>]}"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "prompt = \"Get information about a user with ID da48bd32-94bd-4263-b23a-5b9820a67fab\"\n",
    "AIAgent.tool_vector_store.get_similar_tools(query_texts=prompt)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Run OpenAPI Agent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:dapr_agents.agent.base:Pre-filled prompt template with variables: dict_keys(['chat_history'])\n",
      "INFO:dapr_agents.agent.patterns.react.base:Iteration 1/10 started.\n",
      "INFO:dapr_agents.llm.openai.chat:Invoking ChatCompletion API.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[38;2;242;182;128muser:\u001b[0m\n",
      "\u001b[38;2;242;182;128m\u001b[0m\u001b[38;2;242;182;128mGet information about a user with ID da48bd32-94bd-4263-b23a-5b9820a67fab\u001b[0m\u001b[0m\n",
      "\u001b[0m\u001b[0m\n",
      "\u001b[0m--------------------------------------------------------------------------------\u001b[0m\n",
      "\u001b[0m\u001b[0m\u001b[0m\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
      "INFO:dapr_agents.llm.openai.chat:Chat completion retrieved successfully.\n",
      "INFO:dapr_agents.agent.patterns.react.base:Executing GetOpenapiDefinition with arguments {'user_input': 'Get user information by user ID'}\n",
      "INFO:dapr_agents.tool.executor:Attempting to execute tool: GetOpenapiDefinition\n",
      "INFO:dapr_agents.tool.storage.vectorstore:Searching for tools similar to query: ['Get user information by user ID']\n",
      "INFO:dapr_agents.document.embedder.sentence:Generating embeddings for 1 input(s).\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[38;2;217;95;118mThought: To get information about a user using the provided ID, we need to interact with an API that handles user data. I will first locate the appropriate OpenAPI definition to identify the correct API endpoint for retrieving user information. \u001b[0m\n",
      "\u001b[38;2;217;95;118m\u001b[0m\n",
      "\u001b[38;2;217;95;118mLet's start by using the available tools to find the suitable API.\u001b[0m\u001b[0m\n",
      "\u001b[38;2;191;69;126mAction: {\"name\": \"GetOpenapiDefinition\", \"arguments\": {\"user_input\": \"Get user information by user ID\"}}\u001b[0m\u001b[0m\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "c55dabbc4e9e472cb3fe2e0104e20742",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Batches:   0%|          | 0/1 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:dapr_agents.tool.executor:Tool 'GetOpenapiDefinition' executed successfully.\n",
      "INFO:dapr_agents.agent.patterns.react.base:Thought:To get information about a user using the provided ID, we need to interact with an API that handles user data. I will first locate the appropriate OpenAPI definition to identify the correct API endpoint for retrieving user information. \n",
      "\n",
      "Let's start by using the available tools to find the suitable API.\n",
      "Action:{'name': 'GetOpenapiDefinition', 'arguments': {'user_input': 'Get user information by user ID'}}\n",
      "Observation:[\"user_GetManager: Returns the user or organizational contact assigned as the user's manager. Optionally, you can expand the manager's chain up to the root node.. Args schema: {'type': 'object', 'properties': {'params': {'type': 'object', 'properties': {'$select': {'uniqueItems': True, 'type': 'array', 'items': {'type': 'string'}, 'description': 'Select properties to be returned'}, '$expand': {'uniqueItems': True, 'type': 'array', 'items': {'type': 'string'}, 'description': 'Expand related entities'}}, 'required': []}, 'path_params': {'type': 'object', 'properties': {'user-id': {'type': 'string', 'description': 'The unique identifier of user'}}, 'required': ['user-id']}}}\", \"user_GetUser: Read properties and relationships of the user object.. Args schema: {'type': 'object', 'properties': {'params': {'type': 'object', 'properties': {'$select': {'uniqueItems': True, 'type': 'array', 'items': {'type': 'string'}, 'description': 'Select properties to be returned'}, '$expand': {'uniqueItems': True, 'type': 'array', 'items': {'type': 'string'}, 'description': 'Expand related entities'}}, 'required': []}, 'headers': {'type': 'object', 'properties': {'If-Match': {'type': 'string', 'description': 'ETag'}}, 'required': []}, 'path_params': {'type': 'object', 'properties': {'user-id': {'type': 'string', 'description': 'The unique identifier of user'}}, 'required': ['user-id']}}}\", \"user_GetPhotoContent: The user's profile photo. Read-only.. Args schema: {'type': 'object', 'properties': {'headers': {'type': 'object', 'properties': {'If-Match': {'type': 'string', 'description': 'ETag'}}, 'required': []}, 'path_params': {'type': 'object', 'properties': {'user-id': {'type': 'string', 'description': 'The unique identifier of user'}}, 'required': ['user-id']}}}\", \"user_ListOauth2PermissionGrant: Retrieve a list of oAuth2PermissionGrant entities, which represent delegated permissions granted to enable a client application to access an API on behalf of the user.. Args schema: {'type': 'object', 'properties': {'params': {'type': 'object', 'properties': {'$top': {'minimum': 0.0, 'type': 'integer', 'description': 'Show only the first n items'}, '$skip': {'minimum': 0.0, 'type': 'integer', 'description': 'Skip the first n items'}, '$search': {'type': 'string', 'description': 'Search items by search phrases'}, '$filter': {'type': 'string', 'description': 'Filter items by property values'}, '$count': {'type': 'boolean', 'description': 'Include count of items'}, '$orderby': {'uniqueItems': True, 'type': 'array', 'items': {'type': 'string'}, 'description': 'Order items by property values'}, '$select': {'uniqueItems': True, 'type': 'array', 'items': {'type': 'string'}, 'description': 'Select properties to be returned'}, '$expand': {'uniqueItems': True, 'type': 'array', 'items': {'type': 'string'}, 'description': 'Expand related entities'}}, 'required': []}, 'path_params': {'type': 'object', 'properties': {'user-id': {'type': 'string', 'description': 'The unique identifier of user'}}, 'required': ['user-id']}}}\", \"user_ListDirectReport: The users and contacts that report to the user. (The users and contacts that have their manager property set to this user.) Read-only. Nullable. Supports $expand.. Args schema: {'type': 'object', 'properties': {'params': {'type': 'object', 'properties': {'$top': {'minimum': 0.0, 'type': 'integer', 'description': 'Show only the first n items'}, '$skip': {'minimum': 0.0, 'type': 'integer', 'description': 'Skip the first n items'}, '$search': {'type': 'string', 'description': 'Search items by search phrases'}, '$filter': {'type': 'string', 'description': 'Filter items by property values'}, '$count': {'type': 'boolean', 'description': 'Include count of items'}, '$orderby': {'uniqueItems': True, 'type': 'array', 'items': {'type': 'string'}, 'description': 'Order items by property values'}, '$select': {'uniqueItems': True, 'type': 'array', 'items': {'type': 'string'}, 'description': 'Select properties to be returned'}, '$expand': {'uniqueItems': True, 'type': 'array', 'items': {'type': 'string'}, 'description': 'Expand related entities'}}, 'required': []}, 'headers': {'type': 'object', 'properties': {'ConsistencyLevel': {'type': 'string', 'description': 'Indicates the requested consistency level. Documentation URL: https://docs.microsoft.com/graph/aad-advanced-queries'}}, 'required': []}, 'path_params': {'type': 'object', 'properties': {'user-id': {'type': 'string', 'description': 'The unique identifier of user'}}, 'required': ['user-id']}}}\"]\n",
      "INFO:dapr_agents.agent.patterns.react.base:Iteration 2/10 started.\n",
      "INFO:dapr_agents.llm.openai.chat:Invoking ChatCompletion API.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[38;2;146;94;130mObservation: [\"user_GetManager: Returns the user or organizational contact assigned as the user's manager. Optionally, you can expand the manager's chain up to the root node.. Args schema: {'type': 'object', 'properties': {'params': {'type': 'object', 'properties': {'$select': {'uniqueItems': True, 'type': 'array', 'items': {'type': 'string'}, 'description': 'Select properties to be returned'}, '$expand': {'uniqueItems': True, 'type': 'array', 'items': {'type': 'string'}, 'description': 'Expand related entities'}}, 'required': []}, 'path_params': {'type': 'object', 'properties': {'user-id': {'type': 'string', 'description': 'The unique identifier of user'}}, 'required': ['user-id']}}}\", \"user_GetUser: Read properties and relationships of the user object.. Args schema: {'type': 'object', 'properties': {'params': {'type': 'object', 'properties': {'$select': {'uniqueItems': True, 'type': 'array', 'items': {'type': 'string'}, 'description': 'Select properties to be returned'}, '$expand': {'uniqueItems': True, 'type': 'array', 'items': {'type': 'string'}, 'description': 'Expand related entities'}}, 'required': []}, 'headers': {'type': 'object', 'properties': {'If-Match': {'type': 'string', 'description': 'ETag'}}, 'required': []}, 'path_params': {'type': 'object', 'properties': {'user-id': {'type': 'string', 'description': 'The unique identifier of user'}}, 'required': ['user-id']}}}\", \"user_GetPhotoContent: The user's profile photo. Read-only.. Args schema: {'type': 'object', 'properties': {'headers': {'type': 'object', 'properties': {'If-Match': {'type': 'string', 'description': 'ETag'}}, 'required': []}, 'path_params': {'type': 'object', 'properties': {'user-id': {'type': 'string', 'description': 'The unique identifier of user'}}, 'required': ['user-id']}}}\", \"user_ListOauth2PermissionGrant: Retrieve a list of oAuth2PermissionGrant entities, which represent delegated permissions granted to enable a client application to access an API on behalf of the user.. Args schema: {'type': 'object', 'properties': {'params': {'type': 'object', 'properties': {'$top': {'minimum': 0.0, 'type': 'integer', 'description': 'Show only the first n items'}, '$skip': {'minimum': 0.0, 'type': 'integer', 'description': 'Skip the first n items'}, '$search': {'type': 'string', 'description': 'Search items by search phrases'}, '$filter': {'type': 'string', 'description': 'Filter items by property values'}, '$count': {'type': 'boolean', 'description': 'Include count of items'}, '$orderby': {'uniqueItems': True, 'type': 'array', 'items': {'type': 'string'}, 'description': 'Order items by property values'}, '$select': {'uniqueItems': True, 'type': 'array', 'items': {'type': 'string'}, 'description': 'Select properties to be returned'}, '$expand': {'uniqueItems': True, 'type': 'array', 'items': {'type': 'string'}, 'description': 'Expand related entities'}}, 'required': []}, 'path_params': {'type': 'object', 'properties': {'user-id': {'type': 'string', 'description': 'The unique identifier of user'}}, 'required': ['user-id']}}}\", \"user_ListDirectReport: The users and contacts that report to the user. (The users and contacts that have their manager property set to this user.) Read-only. Nullable. Supports $expand.. Args schema: {'type': 'object', 'properties': {'params': {'type': 'object', 'properties': {'$top': {'minimum': 0.0, 'type': 'integer', 'description': 'Show only the first n items'}, '$skip': {'minimum': 0.0, 'type': 'integer', 'description': 'Skip the first n items'}, '$search': {'type': 'string', 'description': 'Search items by search phrases'}, '$filter': {'type': 'string', 'description': 'Filter items by property values'}, '$count': {'type': 'boolean', 'description': 'Include count of items'}, '$orderby': {'uniqueItems': True, 'type': 'array', 'items': {'type': 'string'}, 'description': 'Order items by property values'}, '$select': {'uniqueItems': True, 'type': 'array', 'items': {'type': 'string'}, 'description': 'Select properties to be returned'}, '$expand': {'uniqueItems': True, 'type': 'array', 'items': {'type': 'string'}, 'description': 'Expand related entities'}}, 'required': []}, 'headers': {'type': 'object', 'properties': {'ConsistencyLevel': {'type': 'string', 'description': 'Indicates the requested consistency level. Documentation URL: https://docs.microsoft.com/graph/aad-advanced-queries'}}, 'required': []}, 'path_params': {'type': 'object', 'properties': {'user-id': {'type': 'string', 'description': 'The unique identifier of user'}}, 'required': ['user-id']}}}\"]\u001b[0m\u001b[0m\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
      "INFO:dapr_agents.llm.openai.chat:Chat completion retrieved successfully.\n",
      "INFO:dapr_agents.agent.patterns.react.base:Executing OpenApiCallExecutor with arguments {'path_template': 'user_GetUser', 'method': 'GET', 'path_params': {'user-id': 'da48bd32-94bd-4263-b23a-5b9820a67fab'}, 'headers': {}, 'params': None, 'data': {}}\n",
      "INFO:dapr_agents.tool.executor:Attempting to execute tool: OpenApiCallExecutor\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[38;2;217;95;118mThought: The `user_GetUser` API endpoint is the most appropriate choice for retrieving information about a user given their user ID. \u001b[0m\n",
      "\u001b[38;2;217;95;118m\u001b[0m\n",
      "\u001b[38;2;217;95;118mLet's proceed to call this API with the user ID you provided: `da48bd32-94bd-4263-b23a-5b9820a67fab`.\u001b[0m\u001b[0m\n",
      "\u001b[38;2;191;69;126mAction: {\"name\": \"OpenApiCallExecutor\", \"arguments\": {\"path_template\": \"user_GetUser\", \"method\": \"GET\", \"path_params\": {\"user-id\": \"da48bd32-94bd-4263-b23a-5b9820a67fab\"}, \"headers\": {}, \"params\": null, \"data\": {}}}\u001b[0m\u001b[0m\n",
      "Base Url: https://graph.microsoft.com/v1.0/\n",
      "Requested Url: https://graph.microsoft.com/v1.0/user_GetUser\n",
      "Requested Parameters: None\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:dapr_agents.tool.executor:Tool 'OpenApiCallExecutor' executed successfully.\n",
      "INFO:dapr_agents.agent.patterns.react.base:Thought:The `user_GetUser` API endpoint is the most appropriate choice for retrieving information about a user given their user ID. \n",
      "\n",
      "Let's proceed to call this API with the user ID you provided: `da48bd32-94bd-4263-b23a-5b9820a67fab`.\n",
      "Action:{'name': 'OpenApiCallExecutor', 'arguments': {'path_template': 'user_GetUser', 'method': 'GET', 'path_params': {'user-id': 'da48bd32-94bd-4263-b23a-5b9820a67fab'}, 'headers': {}, 'params': None, 'data': {}}}\n",
      "Observation:{'error': {'code': 'BadRequest', 'message': \"Resource not found for the segment 'user_GetUser'.\", 'innerError': {'date': '2025-01-25T23:08:08', 'request-id': 'ad614042-e743-491b-aef4-20c84d70794c', 'client-request-id': 'ad614042-e743-491b-aef4-20c84d70794c'}}}\n",
      "INFO:dapr_agents.agent.patterns.react.base:Iteration 3/10 started.\n",
      "INFO:dapr_agents.llm.openai.chat:Invoking ChatCompletion API.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[38;2;146;94;130mObservation: {'error': {'code': 'BadRequest', 'message': \"Resource not found for the segment 'user_GetUser'.\", 'innerError': {'date': '2025-01-25T23:08:08', 'request-id': 'ad614042-e743-491b-aef4-20c84d70794c', 'client-request-id': 'ad614042-e743-491b-aef4-20c84d70794c'}}}\u001b[0m\u001b[0m\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
      "INFO:dapr_agents.llm.openai.chat:Chat completion retrieved successfully.\n",
      "INFO:dapr_agents.agent.patterns.react.base:No action specified; continuing with further reasoning.\n",
      "INFO:dapr_agents.agent.patterns.react.base:Iteration 4/10 started.\n",
      "INFO:dapr_agents.llm.openai.chat:Invoking ChatCompletion API.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[38;2;217;95;118mThought: The attempt to retrieve user information using the `user_GetUser` endpoint resulted in a \"BadRequest\" error. The issue seems to be related to the segment 'user_GetUser' not being recognized or found.\u001b[0m\n",
      "\u001b[38;2;217;95;118m\u001b[0m\n",
      "\u001b[38;2;217;95;118mIt is possible that the path template has been incorrectly interpreted or specified. Let's make sure the path is correctly using the OpenAPI definition.\u001b[0m\n",
      "\u001b[38;2;217;95;118m\u001b[0m\n",
      "\u001b[38;2;217;95;118mI'll re-check the correct path format and try again. Please allow me a moment.\u001b[0m\u001b[0m\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
      "INFO:dapr_agents.llm.openai.chat:Chat completion retrieved successfully.\n",
      "INFO:dapr_agents.agent.patterns.react.base:No action specified; continuing with further reasoning.\n",
      "INFO:dapr_agents.agent.patterns.react.base:Iteration 5/10 started.\n",
      "INFO:dapr_agents.llm.openai.chat:Invoking ChatCompletion API.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[38;2;217;95;118mThought: Let me review the available OpenAPI definitions again to confirm the path template for retrieving user information. It's possible I made an error with the interpretation. I will ensure that the request path is accurate.\u001b[0m\n",
      "\u001b[38;2;217;95;118m\u001b[0m\n",
      "\u001b[38;2;217;95;118mLet's verify and try the correct operation once more.\u001b[0m\u001b[0m\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
      "INFO:dapr_agents.llm.openai.chat:Chat completion retrieved successfully.\n",
      "INFO:dapr_agents.agent.patterns.react.base:Executing OpenApiCallExecutor with arguments {'path_template': '/users/{user-id}', 'method': 'GET', 'path_params': {'user-id': 'da48bd32-94bd-4263-b23a-5b9820a67fab'}, 'headers': {}, 'params': None, 'data': {}}\n",
      "INFO:dapr_agents.tool.executor:Attempting to execute tool: OpenApiCallExecutor\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[38;2;217;95;118mThought: I realize that the earlier attempt to use the `user_GetUser` operation failed due to an error in specifying the path. I will correct this by ensuring that the path template and its usage align with standard URI path conventions.\u001b[0m\n",
      "\u001b[38;2;217;95;118m\u001b[0m\n",
      "\u001b[38;2;217;95;118mLet me re-attempt the API call with the properly formatted path. I need to review and construct the correct API endpoint for execution.\u001b[0m\u001b[0m\n",
      "\u001b[38;2;191;69;126mAction: {\"name\": \"OpenApiCallExecutor\", \"arguments\": {\"path_template\": \"/users/{user-id}\", \"method\": \"GET\", \"path_params\": {\"user-id\": \"da48bd32-94bd-4263-b23a-5b9820a67fab\"}, \"headers\": {}, \"params\": null, \"data\": {}}}\u001b[0m\u001b[0m\n",
      "Base Url: https://graph.microsoft.com/v1.0/\n",
      "Requested Url: https://graph.microsoft.com/v1.0/users/da48bd32-94bd-4263-b23a-5b9820a67fab\n",
      "Requested Parameters: None\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:dapr_agents.tool.executor:Tool 'OpenApiCallExecutor' executed successfully.\n",
      "INFO:dapr_agents.agent.patterns.react.base:Thought:I realize that the earlier attempt to use the `user_GetUser` operation failed due to an error in specifying the path. I will correct this by ensuring that the path template and its usage align with standard URI path conventions.\n",
      "\n",
      "Let me re-attempt the API call with the properly formatted path. I need to review and construct the correct API endpoint for execution.\n",
      "Action:{'name': 'OpenApiCallExecutor', 'arguments': {'path_template': '/users/{user-id}', 'method': 'GET', 'path_params': {'user-id': 'da48bd32-94bd-4263-b23a-5b9820a67fab'}, 'headers': {}, 'params': None, 'data': {}}}\n",
      "Observation:{'@odata.context': 'https://graph.microsoft.com/v1.0/$metadata#users/$entity', 'businessPhones': [], 'displayName': 'Support user', 'givenName': None, 'jobTitle': None, 'mail': None, 'mobilePhone': None, 'officeLocation': None, 'preferredLanguage': None, 'surname': None, 'userPrincipalName': 'support@blueteamarsenal.onmicrosoft.com', 'id': 'da48bd32-94bd-4263-b23a-5b9820a67fab'}\n",
      "INFO:dapr_agents.agent.patterns.react.base:Iteration 6/10 started.\n",
      "INFO:dapr_agents.llm.openai.chat:Invoking ChatCompletion API.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[38;2;146;94;130mObservation: {'@odata.context': 'https://graph.microsoft.com/v1.0/$metadata#users/$entity', 'businessPhones': [], 'displayName': 'Support user', 'givenName': None, 'jobTitle': None, 'mail': None, 'mobilePhone': None, 'officeLocation': None, 'preferredLanguage': None, 'surname': None, 'userPrincipalName': 'support@blueteamarsenal.onmicrosoft.com', 'id': 'da48bd32-94bd-4263-b23a-5b9820a67fab'}\u001b[0m\u001b[0m\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
      "INFO:dapr_agents.llm.openai.chat:Chat completion retrieved successfully.\n",
      "INFO:dapr_agents.agent.patterns.react.base:No action specified; continuing with further reasoning.\n",
      "INFO:dapr_agents.agent.patterns.react.base:Iteration 7/10 started.\n",
      "INFO:dapr_agents.llm.openai.chat:Invoking ChatCompletion API.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[38;2;217;95;118mThought: I successfully retrieved the information for the user with ID `da48bd32-94bd-4263-b23a-5b9820a67fab`. Here are the details:\u001b[0m\n",
      "\u001b[38;2;217;95;118m\u001b[0m\n",
      "\u001b[38;2;217;95;118m- **Display Name**: Support user\u001b[0m\n",
      "\u001b[38;2;217;95;118m- **User Principal Name**: support@blueteamarsenal.onmicrosoft.com\u001b[0m\n",
      "\u001b[38;2;217;95;118m- **Business Phones**: []\u001b[0m\n",
      "\u001b[38;2;217;95;118m- **Job Title**: Not available\u001b[0m\n",
      "\u001b[38;2;217;95;118m- **Mail**: Not available\u001b[0m\n",
      "\u001b[38;2;217;95;118m- **Mobile Phone**: Not available\u001b[0m\n",
      "\u001b[38;2;217;95;118m- **Office Location**: Not available\u001b[0m\n",
      "\u001b[38;2;217;95;118m- **Preferred Language**: Not available\u001b[0m\n",
      "\u001b[38;2;217;95;118m- **Surname**: Not available\u001b[0m\n",
      "\u001b[38;2;217;95;118m\u001b[0m\n",
      "\u001b[38;2;217;95;118mIf you need further details or assistance, feel free to ask!\u001b[0m\u001b[0m\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
      "INFO:dapr_agents.llm.openai.chat:Chat completion retrieved successfully.\n",
      "INFO:dapr_agents.agent.patterns.react.base:Agent provided a direct final answer.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[38;2;217;95;118mThought: Answer: I successfully retrieved the information for the user with ID `da48bd32-94bd-4263-b23a-5b9820a67fab`. Here are the details:\u001b[0m\n",
      "\u001b[38;2;217;95;118m\u001b[0m\n",
      "\u001b[38;2;217;95;118m- **Display Name**: Support user\u001b[0m\n",
      "\u001b[38;2;217;95;118m- **User Principal Name**: support@blueteamarsenal.onmicrosoft.com\u001b[0m\n",
      "\u001b[38;2;217;95;118m- **Business Phones**: []\u001b[0m\n",
      "\u001b[38;2;217;95;118m- **Job Title**: Not available\u001b[0m\n",
      "\u001b[38;2;217;95;118m- **Mail**: Not available\u001b[0m\n",
      "\u001b[38;2;217;95;118m- **Mobile Phone**: Not available\u001b[0m\n",
      "\u001b[38;2;217;95;118m- **Office Location**: Not available\u001b[0m\n",
      "\u001b[38;2;217;95;118m- **Preferred Language**: Not available\u001b[0m\n",
      "\u001b[38;2;217;95;118m- **Surname**: Not available\u001b[0m\n",
      "\u001b[38;2;217;95;118m\u001b[0m\n",
      "\u001b[38;2;217;95;118mIf you need further details or assistance, feel free to ask!\u001b[0m\u001b[0m\n",
      "\u001b[0m\u001b[0m\n",
      "\u001b[0m--------------------------------------------------------------------------------\u001b[0m\n",
      "\u001b[0m\u001b[0m\u001b[0m\n",
      "\u001b[38;2;147;191;183massistant:\u001b[0m\n",
      "\u001b[38;2;147;191;183m\u001b[0m\u001b[38;2;147;191;183mI successfully retrieved the information for the user with ID `da48bd32-94bd-4263-b23a-5b9820a67fab`. Here are the details:\u001b[0m\n",
      "\u001b[38;2;147;191;183m\u001b[0m\n",
      "\u001b[38;2;147;191;183m- **Display Name**: Support user\u001b[0m\n",
      "\u001b[38;2;147;191;183m- **User Principal Name**: support@blueteamarsenal.onmicrosoft.com\u001b[0m\n",
      "\u001b[38;2;147;191;183m- **Business Phones**: []\u001b[0m\n",
      "\u001b[38;2;147;191;183m- **Job Title**: Not available\u001b[0m\n",
      "\u001b[38;2;147;191;183m- **Mail**: Not available\u001b[0m\n",
      "\u001b[38;2;147;191;183m- **Mobile Phone**: Not available\u001b[0m\n",
      "\u001b[38;2;147;191;183m- **Office Location**: Not available\u001b[0m\n",
      "\u001b[38;2;147;191;183m- **Preferred Language**: Not available\u001b[0m\n",
      "\u001b[38;2;147;191;183m- **Surname**: Not available\u001b[0m\n",
      "\u001b[38;2;147;191;183m\u001b[0m\n",
      "\u001b[38;2;147;191;183mIf you need further details or assistance, feel free to ask!\u001b[0m\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'I successfully retrieved the information for the user with ID `da48bd32-94bd-4263-b23a-5b9820a67fab`. Here are the details:\\n\\n- **Display Name**: Support user\\n- **User Principal Name**: support@blueteamarsenal.onmicrosoft.com\\n- **Business Phones**: []\\n- **Job Title**: Not available\\n- **Mail**: Not available\\n- **Mobile Phone**: Not available\\n- **Office Location**: Not available\\n- **Preferred Language**: Not available\\n- **Surname**: Not available\\n\\nIf you need further details or assistance, feel free to ask!'"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "prompt = \"Get information about a user with ID da48bd32-94bd-4263-b23a-5b9820a67fab\"\n",
    "AIAgent.run(prompt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "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.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
