forked from BasedHardware/omi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
153 lines (136 loc) · 5.45 KB
/
Copy pathmain.py
File metadata and controls
153 lines (136 loc) · 5.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
from __future__ import annotations
from typing import Any
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field
from uber_links import build_location, build_uber_deep_links
app = FastAPI(title="Omi Uber Call App")
class CallUberRequest(BaseModel):
uid: str | None = None
app_id: str | None = None
tool_name: str | None = None
destination: str | None = Field(
default=None,
description="The destination the user wants to go to, such as 'SFO airport'.",
)
pickup_address: str | None = None
pickup_latitude: float | None = None
pickup_longitude: float | None = None
dropoff_address: str | None = None
dropoff_latitude: float | None = None
dropoff_longitude: float | None = None
product_id: str | None = None
geolocation: dict[str, Any] | None = None
def _geo_value(geolocation: dict[str, Any] | None, *keys: str) -> Any:
if not geolocation:
return None
for key in keys:
value = geolocation.get(key)
if value not in (None, ""):
return value
return None
@app.get("/health")
def health() -> dict[str, str]:
return {"status": "ok"}
@app.get("/.well-known/omi-tools.json")
def omi_tools_manifest() -> dict[str, Any]:
return {
"tools": [
{
"name": "call_uber",
"description": (
"Prepare an Uber ride link for the user's requested destination. "
"Use this when the user asks to call, book, or open Uber. "
"The user must confirm the ride inside Uber."
),
"endpoint": "/api/call_uber",
"method": "POST",
"parameters": {
"type": "object",
"properties": {
"destination": {
"type": "string",
"description": "Required destination name or address, for example 'SFO airport'.",
},
"dropoff_address": {
"type": "string",
"description": "Optional exact dropoff formatted address.",
},
"dropoff_latitude": {
"type": "number",
"description": "Optional dropoff latitude.",
},
"dropoff_longitude": {
"type": "number",
"description": "Optional dropoff longitude.",
},
"pickup_address": {
"type": "string",
"description": "Optional pickup formatted address. Defaults to user's current location.",
},
"pickup_latitude": {
"type": "number",
"description": "Optional pickup latitude.",
},
"pickup_longitude": {
"type": "number",
"description": "Optional pickup longitude.",
},
"product_id": {
"type": "string",
"description": "Optional Uber product_id if the app owner wants to preselect a ride type.",
},
},
"required": ["destination"],
},
"auth_required": False,
"status_message": "Preparing Uber ride link...",
}
]
}
@app.post("/api/call_uber")
def call_uber(payload: CallUberRequest) -> dict[str, str]:
pickup_latitude = (
payload.pickup_latitude
if payload.pickup_latitude is not None
else _geo_value(payload.geolocation, "latitude", "lat")
)
pickup_longitude = (
payload.pickup_longitude
if payload.pickup_longitude is not None
else _geo_value(payload.geolocation, "longitude", "lng", "lon")
)
pickup_address = payload.pickup_address or _geo_value(payload.geolocation, "formatted_address", "address")
try:
pickup = build_location(
latitude=pickup_latitude,
longitude=pickup_longitude,
formatted_address=pickup_address,
nickname=(
"Current location"
if pickup_address or (pickup_latitude is not None and pickup_longitude is not None)
else None
),
)
dropoff = build_location(
latitude=payload.dropoff_latitude,
longitude=payload.dropoff_longitude,
formatted_address=payload.dropoff_address or payload.destination,
nickname=payload.destination or payload.dropoff_address,
)
links = build_uber_deep_links(
destination=payload.destination,
pickup=pickup,
dropoff=dropoff,
product_id=payload.product_id,
)
except ValueError as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc
destination = payload.destination or payload.dropoff_address or "the selected destination"
return {
"result": (
f"Uber is ready for {destination}. Open this link to review and confirm the ride in Uber: "
f"{links.web_link}"
),
"web_link": links.web_link,
"app_link": links.app_link,
}