clean up the openf1 tab
Browse files- README.md +6 -3
- mcp_client.py +6 -1
- openf1_registry.py +15 -0
- openf1_tools.py +8 -16
- todo.txt +12 -0
- utils/constants.py +10 -4
README.md
CHANGED
@@ -9,7 +9,10 @@ app_file: app.py
|
|
9 |
pinned: true
|
10 |
license: apache-2.0
|
11 |
short_description: 'Historical & real-time F1 data and strategy'
|
12 |
-
|
|
|
|
|
|
|
13 |
---
|
14 |
|
15 |
|
@@ -19,9 +22,9 @@ The MCP server is defined inside `app.py` and is hosted on HuggingFace spaces us
|
|
19 |
|
20 |
## MCP Client
|
21 |
|
22 |
-
The MCP client is defined inside `mcp_client.py` and allows interaction with the MCP server through server side events (SSE) transport.
|
23 |
|
24 |
-
For MCP clients that support SSE transport (
|
25 |
|
26 |
```json
|
27 |
{
|
|
|
9 |
pinned: true
|
10 |
license: apache-2.0
|
11 |
short_description: 'Historical & real-time F1 data and strategy'
|
12 |
+
video_url: TBD
|
13 |
+
tags:
|
14 |
+
- 'mcp-server-track'
|
15 |
+
- 'agent-demo-track'
|
16 |
---
|
17 |
|
18 |
|
|
|
22 |
|
23 |
## MCP Client
|
24 |
|
25 |
+
The MCP client and AI agent is defined inside `mcp_client.py` and allows interaction with the MCP server through server side events (SSE) transport.
|
26 |
|
27 |
+
For MCP clients that support SSE transport (for Claude Desktop, see below), the following configuration can be used:
|
28 |
|
29 |
```json
|
30 |
{
|
mcp_client.py
CHANGED
@@ -2,10 +2,15 @@ import os
|
|
2 |
import gradio as gr
|
3 |
from typing import List, Dict
|
4 |
from smolagents import InferenceClientModel, LiteLLMModel, ToolCallingAgent, MCPClient
|
|
|
|
|
|
|
5 |
|
6 |
SYSTEM_PROMPT = """You are a helpful Formula 1 assistant and strategist. You have access to various F1 data and tools to help answer questions about races, drivers, teams, and more.
|
7 |
Be concise and accurate in your responses. If you don't know something, use the available tools to find the information.
|
8 |
-
In addition, you will be asked to act as a live race engineer strategist during a Formula 1 race, making crucial calls during the event.
|
|
|
|
|
9 |
|
10 |
|
11 |
def agent_chat(message: str, history: list):
|
|
|
2 |
import gradio as gr
|
3 |
from typing import List, Dict
|
4 |
from smolagents import InferenceClientModel, LiteLLMModel, ToolCallingAgent, MCPClient
|
5 |
+
import datetime
|
6 |
+
|
7 |
+
time = datetime.datetime.now().astimezone().isoformat()
|
8 |
|
9 |
SYSTEM_PROMPT = """You are a helpful Formula 1 assistant and strategist. You have access to various F1 data and tools to help answer questions about races, drivers, teams, and more.
|
10 |
Be concise and accurate in your responses. If you don't know something, use the available tools to find the information.
|
11 |
+
In addition, you will be asked to act as a live race engineer strategist during a Formula 1 race, making crucial calls during the event.
|
12 |
+
|
13 |
+
Current time (ISO 8601): {time}"""
|
14 |
|
15 |
|
16 |
def agent_chat(message: str, history: list):
|
openf1_registry.py
CHANGED
@@ -2,6 +2,21 @@ from enum import Enum
|
|
2 |
from dataclasses import dataclass
|
3 |
from typing import Dict, Set, List, Optional
|
4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
class FilterType(Enum):
|
6 |
EQUALITY = "equality" # exact match
|
7 |
COMPARISON = "comparison" # >, <, >=, <=
|
|
|
2 |
from dataclasses import dataclass
|
3 |
from typing import Dict, Set, List, Optional
|
4 |
|
5 |
+
api_endpoints = {
|
6 |
+
"sessions": "sessions?",
|
7 |
+
"weather": "weather?",
|
8 |
+
"locations": "locations?",
|
9 |
+
"drivers": "drivers?",
|
10 |
+
"intervals": "intervals?",
|
11 |
+
"laps": "laps?",
|
12 |
+
"car_data": "car_data?",
|
13 |
+
"pit": "pit?",
|
14 |
+
"position": "position?",
|
15 |
+
"race_control": "race_control?",
|
16 |
+
"stints": "stints?",
|
17 |
+
"team_radio": "team_radio?",
|
18 |
+
}
|
19 |
+
|
20 |
class FilterType(Enum):
|
21 |
EQUALITY = "equality" # exact match
|
22 |
COMPARISON = "comparison" # >, <, >=, <=
|
openf1_tools.py
CHANGED
@@ -1,25 +1,17 @@
|
|
1 |
import json
|
2 |
from urllib.request import urlopen
|
3 |
-
from openf1_registry import f1_api
|
4 |
|
5 |
|
6 |
-
|
7 |
-
"sessions": "sessions?",
|
8 |
-
"weather": "weather?",
|
9 |
-
"locations": "locations?",
|
10 |
-
"drivers": "drivers?",
|
11 |
-
"intervals": "intervals?",
|
12 |
-
"laps": "laps?",
|
13 |
-
"car_data": "car_data?",
|
14 |
-
"pit": "pit?",
|
15 |
-
"position": "position?",
|
16 |
-
"race_control": "race_control?",
|
17 |
-
"stints": "stints?",
|
18 |
-
"team_radio": "team_radio?",
|
19 |
-
}
|
20 |
|
|
|
|
|
|
|
21 |
|
22 |
-
|
|
|
|
|
23 |
|
24 |
def get_api_endpoint(endpoint: str) -> dict:
|
25 |
"""
|
|
|
1 |
import json
|
2 |
from urllib.request import urlopen
|
3 |
+
from openf1_registry import f1_api, api_endpoints
|
4 |
|
5 |
|
6 |
+
### Essential tools ###
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
|
8 |
+
def get_current_time() -> str:
|
9 |
+
"""
|
10 |
+
Retrieve the current time in ISO 8601 format.
|
11 |
|
12 |
+
Returns:
|
13 |
+
str: The current time in ISO 8601 format.
|
14 |
+
"""
|
15 |
|
16 |
def get_api_endpoint(endpoint: str) -> dict:
|
17 |
"""
|
todo.txt
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
- host agent using Modal labs
|
2 |
+
- Add some more documentation
|
3 |
+
- Record demonstration using Loom and add link to README
|
4 |
+
* Demo the Gradio UI
|
5 |
+
* Demo the MCP client using Claude Desktop
|
6 |
+
* Demo the MCP client using mcp_client.py
|
7 |
+
|
8 |
+
More info about the Gradio agent: https://www.gradio.app/guides/agents-and-tool-usage
|
9 |
+
|
10 |
+
Side sponsor wins
|
11 |
+
- Modal labs choice (host a LLM on their platform using vLLM or ollama)
|
12 |
+
- Mistral AI choice (If using a large model, perhaps pick a Mistral one, Nebius offers a ~270B model from their API)
|
utils/constants.py
CHANGED
@@ -104,10 +104,10 @@ For Claude Desktop, the following configuration can instead be used, but make su
|
|
104 |
OPENF1_TOOL_DESCRIPTION = """
|
105 |
## OpenF1 Tools - API Endpoints.
|
106 |
|
107 |
-
This UI Interface/Tab collects all the MCP tools that are based on the `OpenF1` API, which are a bit
|
108 |
-
In essence, the tools listed below make it possible to access the `OpenF1` API directly within the MCP server, thus allowing a LLM to interact with the `OpenF1` API.
|
109 |
-
The
|
110 |
-
Each of these endpoints have different **_filters_** that can be used to
|
111 |
|
112 |
The implemented functions make it possible to:
|
113 |
- Get all available endpoints - `get_api_endpoints()`
|
@@ -122,16 +122,22 @@ The implemented functions make it possible to:
|
|
122 |
|
123 |
MARKDOWN_OPENF1_EXAMPLES = """
|
124 |
|
|
|
125 |
```https://api.openf1.org/v1/car_data?driver_number=55&session_key=9159&speed>=315```
|
126 |
|
|
|
127 |
```https://api.openf1.org/v1/drivers?driver_number=1&session_key=9158```
|
128 |
|
|
|
129 |
```https://api.openf1.org/v1/intervals?session_key=9165&interval<0.005```
|
130 |
|
|
|
131 |
```https://api.openf1.org/v1/laps?session_key=9161&driver_number=63&lap_number=8```
|
132 |
|
|
|
133 |
```https://api.openf1.org/v1/meetings?year=2023&country_name=Singapore```
|
134 |
|
|
|
135 |
```https://api.openf1.org/v1/pit?session_key=9158&pit_duration<31```
|
136 |
|
137 |
"""
|
|
|
104 |
OPENF1_TOOL_DESCRIPTION = """
|
105 |
## OpenF1 Tools - API Endpoints.
|
106 |
|
107 |
+
This UI Interface/Tab collects all the MCP tools that are based on the `OpenF1` API, which are a bit less user friendly compared to the tools in the other tabs, which are implemented using the `FastF1` library.
|
108 |
+
In essence, the tools listed below make it possible to access the `OpenF1` API directly within the MCP server, thus allowing a LLM to interact with the `OpenF1` API using natural language.
|
109 |
+
The API exposes several **_endpoints_** that can be used to access different types of real-time and historical data about Formula 1 races, sessions, drivers, and constructor teams.
|
110 |
+
Each of these endpoints have different **_filters_** that can be used to specify the data returned from the endpoint. The data communication is entirely in JSON format making it optimized for the LLM.
|
111 |
|
112 |
The implemented functions make it possible to:
|
113 |
- Get all available endpoints - `get_api_endpoints()`
|
|
|
122 |
|
123 |
MARKDOWN_OPENF1_EXAMPLES = """
|
124 |
|
125 |
+
' Retrieve data about car number 55 with session_key 9159 where the speed was greater than 315 '
|
126 |
```https://api.openf1.org/v1/car_data?driver_number=55&session_key=9159&speed>=315```
|
127 |
|
128 |
+
' Retrieve data about driver number 1 with session_key 9158 '
|
129 |
```https://api.openf1.org/v1/drivers?driver_number=1&session_key=9158```
|
130 |
|
131 |
+
' Retrieve data about intervals with session_key 9165 where the interval was less than 0.005s'
|
132 |
```https://api.openf1.org/v1/intervals?session_key=9165&interval<0.005```
|
133 |
|
134 |
+
' Retrieve data about laps with session_key 9161 for driver number 63 on lap number 8'
|
135 |
```https://api.openf1.org/v1/laps?session_key=9161&driver_number=63&lap_number=8```
|
136 |
|
137 |
+
' Retrieve data about meetings in 2023 for Singapore'
|
138 |
```https://api.openf1.org/v1/meetings?year=2023&country_name=Singapore```
|
139 |
|
140 |
+
' Retrieve data about pit stops with session_key 9158 where the pit duration was less than 31s'
|
141 |
```https://api.openf1.org/v1/pit?session_key=9158&pit_duration<31```
|
142 |
|
143 |
"""
|