Skip to content

Commit a7ba758

Browse files
authored
Merge pull request #62 from mstarnik1097/add-morningstar-tools
added sample code for using morningstar tool
2 parents ee7ff21 + f6c3e0f commit a7ba758

23 files changed

+2353
-0
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Morningstar
2+
3+
## Description
4+
The Morningstar tool connects your generative AI applications to Morningstar's trusted content with ease - no custom consumption pipelines required. Simply connect, query, and rely on the same continually-improving engine that powers Morningstar's in-product generative AI capabilities.
5+
6+
## Prerequisites
7+
8+
* Create a Morningstar if you don't already have one.
9+
For access request please email us at [email protected] using the subject line:
10+
Subject: Morningstar Agent Access Request
11+
In the body of the email, include the following:
12+
1. Your full name
13+
2. Contact information
14+
3. A brief description of your request and how you intend to use the Morningstar Agent.
15+
* To fetch your JWT token, you can refer to this page: https://developer.morningstar.com/direct-web-services/documentation/documentation/get-started/authorization-tokens
16+
17+
18+
## Setup
19+
1. Go to [Azure AI Foundry portal](https://ai.azure.com/) and select your AI Project. Select **Management Center**.
20+
21+
:::image type="content" source="./media/project-assets.png" alt-text="A screenshot showing the selectors for the management center for an AI project." lightbox="./media/project-assets.png":::
22+
23+
2. Select **+new connection** in the settings page.
24+
25+
:::image type="content" source="./media/connected-resources.png" alt-text="A screenshot showing the connections for the selected AI project." lightbox="./media/connected-resources.png":::
26+
27+
3. Select **custom keys** in **other resource types**.
28+
29+
:::image type="content" source="./media/custom-keys.png" alt-text="A screenshot showing the custom key option in the settings page." lightbox="./media/custom-keys.png":::
30+
31+
4. Enter the following information to create a connection to store your Morningstar authorization:
32+
1. Set **Custom keys** to "authorization", with the value being "Bearer {JWT token}".
33+
2. Make sure **is secret** is checked.
34+
3. Set the connection name to your connection name. You use this connection name in your sample code or Foundry Portal later.
35+
4. For the **Access** setting, you can choose either *this project only* or *shared to all projects*. Just make sure in your code, the connection string of the project you entered has access to this connection.
36+
37+
:::image type="content" source="./media/connect-custom-resource.png" alt-text="A screenshot showing the screen for adding Morningstar connection information." lightbox="./media/connect-custom-resource.png":::
38+
39+
## Use Morningstar tool through Foundry portal
40+
41+
1. To use the Morningstar tool in the Azure AI Foundry, in the **Create and debug** screen for your agent, scroll down the **Setup** pane on the right to **action**. Then select **Add**.
42+
2. Select **Morningstar** and follow the prompts to add the tool.
43+
3. Give a name for your Morningstar tool and provide an optional description.
44+
4. Select the custom key connection you just created.
45+
5. Finish and start chatting.
46+
47+
## Connect Morningstar through code-first experience
48+
49+
You can follow the [code sample](./morningstar.py) to use Morningstar through Agent SDK.
50+
51+
1. Remember to store and import Morningstar [OpenAPI spec](./morningstar.json).
52+
53+
2. Make sure you have updated the authentication method to be `connection` and fill in the connection ID of your custom key connection.
54+
``` python
55+
auth = OpenApiConnectionAuthDetails(security_scheme=OpenApiConnectionSecurityScheme(connection_id="your_connection_id"))
56+
```
57+
58+
## Customer Support Contact
59+
If you need support or would like to submit a request, please email us at [email protected] using the subject line:
60+
Subject: Morningstar Agent Request
61+
62+
In the body of the email, include the following:
63+
- Your full name
64+
- Contact information
65+
- A brief description of your request or issue
66+
- Any relevant attachments or screenshots
67+
We'll get back to you as soon as possible. Thanks for reaching out!
146 KB
Loading
28.4 KB
Loading
34.7 KB
Loading
40.8 KB
Loading
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
{
2+
"openapi": "3.1.0",
3+
"info": {
4+
"title": "Morningstar Agent API",
5+
"description": "The Morningstar Agent API makes it easy to retrieve answers from our content, without the need to build your own sync and ingestion pipelines. By connecting your generative AI application to the Morningstar Agent, you’ll be tapping into the same engine that powers Morningstar’s in-product generative AI capabilities to benefit from continuous enhancements implemented by our domain experts..",
6+
"version": "0.0.1"
7+
},
8+
"servers": [
9+
{
10+
"url": "https://www.us-api.morningstar.com/casper-ingn/ingn-api-prod"
11+
}
12+
],
13+
"paths": {
14+
"/v2/apps/morningstar-agent/chat": {
15+
"post": {
16+
"tags": [
17+
"App Chat"
18+
],
19+
"description": "Submit a question and get an answer in the response. A list of sources cited to create the answer are also returned.",
20+
"operationId": "submitQuestion",
21+
"security": [
22+
{
23+
"apiKeyHeader": []
24+
}
25+
],
26+
"requestBody": {
27+
"required": true,
28+
"content": {
29+
"application/json": {
30+
"schema": {
31+
"$ref": "#/components/schemas/ChatRequest"
32+
}
33+
}
34+
}
35+
},
36+
"responses": {
37+
"200": {
38+
"description": "Successful Response",
39+
"content": {
40+
"application/json": {
41+
"schema": {
42+
"$ref": "#/components/schemas/ChatResponse"
43+
}
44+
}
45+
}
46+
}
47+
}
48+
}
49+
}
50+
},
51+
"components": {
52+
"schemas": {
53+
"ChatRequest": {
54+
"properties": {
55+
"question": {
56+
"type": "string",
57+
"title": "Question"
58+
}
59+
},
60+
"type": "object",
61+
"required": [
62+
"question"
63+
],
64+
"title": "ChatRequest"
65+
},
66+
"ChatResponse": {
67+
"properties": {
68+
"chat_id": {
69+
"type": "string",
70+
"format": "uuid",
71+
"title": "Chat Id",
72+
"description": "Unique ID for the chat request"
73+
},
74+
"response": {
75+
"type": "string",
76+
"title": "Response",
77+
"description": "Chat response"
78+
},
79+
"question": {
80+
"type": "string",
81+
"title": "Question",
82+
"description": "Original input question"
83+
}
84+
},
85+
"type": "object",
86+
"required": [
87+
"chat_id",
88+
"response",
89+
"question"
90+
],
91+
"title": "ChatResponse",
92+
"description": "Args:\n chat_id (uuid): Unique ID for the chat request\n response (str): The final response string provided by the tool.\n question (str): The original question string provided by the user.\n tools (list): The list of tools used.\n debug_info (dict): Chat request debug information, including agent info and detected question language."
93+
}
94+
},
95+
"securitySchemes": {
96+
"apiKeyHeader": {
97+
"type": "apiKey",
98+
"name": "authorization",
99+
"in": "header"
100+
}
101+
}
102+
}
103+
}
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
"""
2+
DESCRIPTION:
3+
This sample demonstrates how to use agent operations with the
4+
Morningstar OpenAPI tool, from the Azure Agents service using a synchronous client.
5+
To learn more about OpenAPI specs, visit https://learn.microsoft.com/openapi
6+
Link to the Morningstar Agent OpenAPI spec: https://developer.morningstar.com/direct-web-services/documentation/intelligence-engine/apps/morningstar-agent-api
7+
Download the OpenAPI spec and store it as morningstar.json
8+
USAGE:
9+
python sample_agents_openapi_morningstar.py
10+
Before running the sample:
11+
pip install azure-ai-projects azure-identity jsonref
12+
Set these environment variables with your own values:
13+
1) PROJECT_ENDPOINT - The project endpoint in the format
14+
"https://<your-ai-services-resource-name>.services.ai.azure.com/api/projects/<your-project-name>"
15+
2) MODEL - The model deployment name
16+
3) CONNECTION_ID - The connection id in the format
17+
"/subscriptions/<sub-id>/resourceGroups/<your-rg-name>/providers/Microsoft.CognitiveServices/accounts/<your-ai-services-name>/projects/<your-project-name>/connections/<your-connection-name>"
18+
You'll also need a JWT token to authorize with the Morningstar service.
19+
You can fetch this JWT token by using the below code:
20+
import requests
21+
from requests.auth import HTTPBasicAuth
22+
url = "https://www.us-api.morningstar.com/token/oauth"
23+
response = requests.post(url, auth=auth)
24+
print(response.text)
25+
Note: This token expires, please remember to refresh your credentials.
26+
"""
27+
28+
import os
29+
import jsonref
30+
from azure.ai.projects import AIProjectClient
31+
from azure.ai.agents.models import (
32+
OpenApiConnectionAuthDetails,
33+
OpenApiConnectionSecurityScheme,
34+
OpenApiTool,
35+
)
36+
from azure.identity import DefaultAzureCredential
37+
38+
# Initialize the project client using the endpoint and default credentials
39+
project_client = AIProjectClient(
40+
endpoint=os.environ["PROJECT_ENDPOINT"],
41+
credential=DefaultAzureCredential(exclude_interactive_browser_credential=False),
42+
)
43+
44+
with open("./morningstar.json", "r") as f:
45+
openapi_spec = jsonref.loads(f.read())
46+
47+
# Create Auth object for the OpenApiTool (note that connection or managed identity auth setup requires additional setup in Azure)
48+
connection_id = os.environ["CONNECTION_ID"]
49+
auth = OpenApiConnectionAuthDetails(
50+
security_scheme=OpenApiConnectionSecurityScheme(connection_id=connection_id)
51+
)
52+
53+
# Create the OpenAPI tool
54+
openapi = OpenApiTool(
55+
name="morningstar",
56+
spec=openapi_spec,
57+
description="Retrieves information from Morningstar.",
58+
auth=auth,
59+
)
60+
61+
INSTRUCTIONS = """
62+
You are a helpful assistant that answers questions using Morningstar's data. Only refer to the information found in the **"answer"** and **"sources"** fields of provided responses to generate your answers. If the user asks a complex question, break it down into simpler, more manageable sub-queries to guide your process effectively.
63+
# Guidelines
64+
- **Data Usage**: Strictly rely on the "answer" and "sources" fields for information. Do not infer or assume beyond what is explicitly provided.
65+
- **Complex Questions**: If the question is challenging or multi-faceted, first decompose it into smaller, simpler queries, ensuring each step aligns with the provided data.
66+
- **Clarity in Explanation**: When delivering the final answer, clearly articulate the reasoning used to arrive at the conclusion based on the Morningstar data provided.
67+
- **Consistency**: Ensure the terminology and phrasing used aligns with the financial and investment language standard for Morningstar.
68+
# Steps
69+
1. Determine if the question is straightforward or complex:
70+
- If straightforward, proceed directly to formulating an answer based on the "answer" and "sources" fields.
71+
- If complex, break it into simpler sub-queries, each directly addressable via data from the "answer" and "sources" fields.
72+
2. Reference only the "answer" and "sources" fields to gather information for responding.
73+
3. Construct a clear, concise answer or explanation using the gathered data.
74+
4. If necessary, list the sources referenced to provide users with transparency.
75+
# Output Format
76+
The response should be in plain text, clearly structured, and concise.
77+
For simple queries:
78+
- A direct, succinct answer based on the given data.
79+
- Include a reference to the sources field if needed.
80+
For complex queries:
81+
- Briefly outline the parallel or sequential reasoning steps taken to address the question.
82+
- Conclude with the final, comprehensive answer.
83+
- Optionally: Cite sources derived from the provided data.
84+
# Example
85+
### Input:
86+
"What are the key financial metrics of XYZ Company? What is my best course of action for diversification?"
87+
### Process:
88+
1. **Simplify the queries**:
89+
- What are the key financial metrics of XYZ Company?
90+
- What strategies can be considered for diversification?
91+
2. Consult the "answer" and "sources" fields for data relevant to each sub-query.
92+
### Output:
93+
- XYZ Company's key financial metrics are as follows:
94+
- Revenue: [Insert data from answer field]
95+
- Net Income: [Insert data from answer field]
96+
- P/E Ratio: [Insert data from answer field]
97+
(Source: [Insert relevant sources here])
98+
- Regarding diversification:
99+
- Based on provided data, one approach might be to [Insert strategy].
100+
(Source: [Insert relevant sources here])
101+
# Notes
102+
- Do not speculate or provide opinions—use only the supplied "answer" and "sources" fields.
103+
- When data from Morningstar is insufficient to form a complete answer, explicitly communicate the limitation in the response."""
104+
105+
# Create agent with OpenApi tool and process assistant run
106+
with project_client:
107+
agent = project_client.agents.create_agent(
108+
model=os.environ["MODEL"],
109+
name="morningstar-agent",
110+
instructions=INSTRUCTIONS,
111+
tools=openapi.definitions,
112+
)
113+
114+
print(f"Created agent, ID: {agent.id}")
115+
116+
# Create thread for communication
117+
thread = project_client.agents.threads.create()
118+
print(f"Created thread, ID: {thread.id}")
119+
120+
# Create message to thread
121+
message = project_client.agents.messages.create(
122+
thread_id=thread.id,
123+
role="user",
124+
content="What is value investing according to Morningstar?",
125+
)
126+
print(f"Created message, ID: {message.id}")
127+
128+
# Create and process agent run in thread with tools
129+
run = project_client.agents.runs.create_and_process(
130+
thread_id=thread.id,
131+
agent_id=agent.id,
132+
)
133+
print(f"Run finished with status: {run.status}")
134+
if run.status == "failed":
135+
print(f"Run failed: {run.last_error}")
136+
137+
run_steps = project_client.agents.run_steps.list(thread_id=thread.id, run_id=run.id)
138+
139+
# Loop through each step
140+
for step in run_steps:
141+
print(f"Step {step['id']} status: {step['status']}")
142+
143+
# Check if there are tool calls in the step details
144+
step_details = step.get("step_details", {})
145+
tool_calls = step_details.get("tool_calls", [])
146+
147+
if tool_calls:
148+
print(" Tool calls:")
149+
for call in tool_calls:
150+
print(f" Tool Call ID: {call.get('id')}")
151+
print(f" Type: {call.get('type')}")
152+
153+
function_details = call.get("function", {})
154+
if function_details:
155+
print(f" Function name: {function_details.get('name')}")
156+
print() # add an extra newline between steps
157+
158+
# Fetch and log all messages
159+
messages = project_client.agents.messages.list(thread_id=thread.id)
160+
for message in messages:
161+
print(
162+
f"Message ID: {message.id}, Role: {message.role}, Content: {message.content}"
163+
)
164+
165+
# Delete the agent when done
166+
project_client.agents.delete_agent(agent.id)
167+
print("Deleted agent")
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# 3p Tool Partner Contributing Guide
2+
3+
## Who should read this?
4+
This contributing guide is designed for partners who want to bring their APIs as part of the **Azure AI Foundry Tool Catalog** so that customers can integrate your APIs with Azure AI Agent service through a tool to retrieve data or integrating with a workflow.
5+
6+
## Prepare your PR
7+
Your PR needs to create a new folder with the tool name and include the following information:
8+
- `README.md` (required): follow this [template](./README_template_for_parter.md) as an example and this README file will serve as public documentation for help customers set up and use the tool with your API through Azure AI Agent service
9+
- The name, logo, and description in this README file will be used in the Azure AI Foundry Portal user experience and marketing materials.
10+
- It must include how customers set up an account with your API directly and your customer support contact or website.
11+
- Customers should be able to follow this README file and successfully use the tool with Azure AI Agent service.
12+
- `sample code` (required): using at least one of the SDK below
13+
- (recommended) Python: [Azure AI Projects client library for Python | Microsoft Learn](https://learn.microsoft.com/en-us/python/api/overview/azure/ai-projects-readme?view=azure-python-preview#create-agent-with-openapi)
14+
- .NET/C#: [Azure AI Projects client library for .NET - Azure for .NET Developers | Microsoft Learn](https://learn.microsoft.com/en-us/dotnet/api/overview/azure/ai.projects-readme?view=azure-dotnet-preview)
15+
- JavaScript: [Azure AI Projects client library for JavaScript | Microsoft Learn](https://learn.microsoft.com/en-us/javascript/api/overview/azure/ai-projects-readme?view=azure-node-preview)
16+
- Requirements fot the code sample:
17+
- you should have tested the code sample works end to end with the OpenAPI spec in this PR before submitting
18+
- include the process of creating an `openApi` tool with your OpenAPI spec
19+
- for `agent creation`, provide a user-friendly name and useful instructions customized for your API
20+
- for `message creation`, provide an example of a user query that can be used with your API and expected response in comments
21+
- `OpenAPI spec` (required): the OpenAPI spec for your API
22+
- Your OpenAPI should be updated based on the requirements [here](https://learn.microsoft.com/en-us/azure/ai-services/agents/how-to/tools/openapi-spec?tabs=python&pivots=overview#authenticating-with-api-key) to support appropriate authentication method
23+
- If you require customers to update the OpenAPI spec, please provide **clear** instructions and **placeholder** on where they should update in the OpenAPI spec file and the README.file.
24+
- This OpenAPI spec will also be used in the Azure AI Foundry Portal user experience.
25+
- `media` folder (optional): if you need to include any screenshots, please add the screenshots in this folder and refer to them.
26+
27+
## Submit your PR
28+
Before you submit the PR, please double check:
29+
- you have **everything** required above ready
30+
- you have **fully** tested your code sample
31+
32+
Then, you can go ahead and create a PR. By creating a PR, you automatically agree to the Contributor License Agreement and see more details [here](../../../CONTRIBUTING.md).
33+
34+
When creating the PR, please make sure you give your PR a reviewer-friendly name. We will come back to you within 10 business days.
35+
36+
## Once your PR is approved
37+
- customers will see a folder for the tool in `main` branch
38+
- Azure AI Foundry Portal team will work to bring your tool to the Portal user experience.

0 commit comments

Comments
 (0)